]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
ALSA: hda: Fix Nvidia dp infoframe
authorMohan Kumar <mkumard@nvidia.com>
Tue, 13 Sep 2022 06:58:18 +0000 (12:28 +0530)
committerStefan Bader <stefan.bader@canonical.com>
Wed, 23 Nov 2022 14:11:54 +0000 (15:11 +0100)
BugLink: https://bugs.launchpad.net/bugs/1995517
[ Upstream commit f89e409402e2aeb3bc3aa44d2b7a597959e4e6af ]

Nvidia HDA HW expects infoframe data bytes order same for both
HDMI and DP i.e infoframe data starts from 5th bytes offset. As
dp infoframe structure has 4th byte as valid infoframe data, use
hdmi infoframe structure for nvidia dp infoframe to match HW behvaior.

Signed-off-by: Mohan Kumar <mkumard@nvidia.com>
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20220913065818.13015-1-mkumard@nvidia.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
sound/pci/hda/patch_hdmi.c

index 7ad07e5a028b71970e3c21ab2f726d5ddb5d1332..b4cbef7ce9a7de4ab43b7441a17464f47ee59d77 100644 (file)
@@ -162,6 +162,8 @@ struct hdmi_spec {
        bool dyn_pin_out;
        bool dyn_pcm_assign;
        bool dyn_pcm_no_legacy;
+       bool nv_dp_workaround; /* workaround DP audio infoframe for Nvidia */
+
        bool intel_hsw_fixup;   /* apply Intel platform-specific fixups */
        /*
         * Non-generic VIA/NVIDIA specific
@@ -671,15 +673,24 @@ static void hdmi_pin_setup_infoframe(struct hda_codec *codec,
                                     int ca, int active_channels,
                                     int conn_type)
 {
+       struct hdmi_spec *spec = codec->spec;
        union audio_infoframe ai;
 
        memset(&ai, 0, sizeof(ai));
-       if (conn_type == 0) { /* HDMI */
+       if ((conn_type == 0) || /* HDMI */
+               /* Nvidia DisplayPort: Nvidia HW expects same layout as HDMI */
+               (conn_type == 1 && spec->nv_dp_workaround)) {
                struct hdmi_audio_infoframe *hdmi_ai = &ai.hdmi;
 
-               hdmi_ai->type           = 0x84;
-               hdmi_ai->ver            = 0x01;
-               hdmi_ai->len            = 0x0a;
+               if (conn_type == 0) { /* HDMI */
+                       hdmi_ai->type           = 0x84;
+                       hdmi_ai->ver            = 0x01;
+                       hdmi_ai->len            = 0x0a;
+               } else {/* Nvidia DP */
+                       hdmi_ai->type           = 0x84;
+                       hdmi_ai->ver            = 0x1b;
+                       hdmi_ai->len            = 0x11 << 2;
+               }
                hdmi_ai->CC02_CT47      = active_channels - 1;
                hdmi_ai->CA             = ca;
                hdmi_checksum_audio_infoframe(hdmi_ai);
@@ -3539,6 +3550,7 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
        spec->pcm_playback.rates = SUPPORTED_RATES;
        spec->pcm_playback.maxbps = SUPPORTED_MAXBPS;
        spec->pcm_playback.formats = SUPPORTED_FORMATS;
+       spec->nv_dp_workaround = true;
        return 0;
 }
 
@@ -3678,6 +3690,7 @@ static int patch_nvhdmi(struct hda_codec *codec)
        spec->chmap.ops.chmap_cea_alloc_validate_get_type =
                nvhdmi_chmap_cea_alloc_validate_get_type;
        spec->chmap.ops.chmap_validate = nvhdmi_chmap_validate;
+       spec->nv_dp_workaround = true;
 
        codec->link_down_at_suspend = 1;
 
@@ -3701,6 +3714,7 @@ static int patch_nvhdmi_legacy(struct hda_codec *codec)
        spec->chmap.ops.chmap_cea_alloc_validate_get_type =
                nvhdmi_chmap_cea_alloc_validate_get_type;
        spec->chmap.ops.chmap_validate = nvhdmi_chmap_validate;
+       spec->nv_dp_workaround = true;
 
        codec->link_down_at_suspend = 1;
 
@@ -3874,6 +3888,7 @@ static int patch_tegra_hdmi(struct hda_codec *codec)
        spec->chmap.ops.chmap_cea_alloc_validate_get_type =
                nvhdmi_chmap_cea_alloc_validate_get_type;
        spec->chmap.ops.chmap_validate = nvhdmi_chmap_validate;
+       spec->nv_dp_workaround = true;
 
        return 0;
 }