From: jasontao <[email protected]>
Add a set of HD Audio PCI IDS, and the HDMI codec vendor IDs for
Glenfly Arise.
Signed-off-by: jasontao <[email protected]>
Signed-off-by: reaperli <[email protected]>
---
sound/pci/hda/hda_intel.c | 14 ++++++++++++++
sound/pci/hda/patch_hdmi.c | 18 ++++++++++++++++++
2 files changed, 32 insertions(+)
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 77a592f21..6c4a559d9 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -227,6 +227,7 @@ enum {
AZX_DRIVER_ATI,
AZX_DRIVER_ATIHDMI,
AZX_DRIVER_ATIHDMI_NS,
+ AZX_DRIVER_GFHDMI,
AZX_DRIVER_VIA,
AZX_DRIVER_SIS,
AZX_DRIVER_ULI,
@@ -349,6 +350,7 @@ static const char * const driver_short_names[] = {
[AZX_DRIVER_ATI] = "HDA ATI SB",
[AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI",
[AZX_DRIVER_ATIHDMI_NS] = "HDA ATI HDMI",
+ [AZX_DRIVER_GFHDMI] = "HDA GF HDMI",
[AZX_DRIVER_VIA] = "HDA VIA VT82xx",
[AZX_DRIVER_SIS] = "HDA SIS966",
[AZX_DRIVER_ULI] = "HDA ULI M5461",
@@ -1743,6 +1745,8 @@ static int default_bdl_pos_adj(struct azx *chip)
}
switch (chip->driver_type) {
+ case AZX_DRIVER_GFHDMI:
+ return 128;
case AZX_DRIVER_ICH:
case AZX_DRIVER_PCH:
return 1;
@@ -1859,6 +1863,9 @@ static int azx_first_init(struct azx *chip)
}
#endif
+ if (chip->driver_type == AZX_DRIVER_GFHDMI)
+ bus->polling_mode = 1;
+
err = pcim_iomap_regions(pci, 1 << 0, "ICH HD audio");
if (err < 0)
return err;
@@ -1959,6 +1966,7 @@ static int azx_first_init(struct azx *chip)
chip->playback_streams = ATIHDMI_NUM_PLAYBACK;
chip->capture_streams = ATIHDMI_NUM_CAPTURE;
break;
+ case AZX_DRIVER_GFHDMI:
case AZX_DRIVER_GENERIC:
default:
chip->playback_streams = ICH6_NUM_PLAYBACK;
@@ -2724,6 +2732,12 @@ static const struct pci_device_id azx_ids[] = {
{ PCI_DEVICE(0x1002, 0xab38),
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
AZX_DCAPS_PM_RUNTIME },
+ /* GLENFLY */
+ { PCI_DEVICE(0x6766, PCI_ANY_ID),
+ .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
+ .class_mask = 0xffffff,
+ .driver_data = AZX_DRIVER_GFHDMI | AZX_DCAPS_POSFIX_LPIB |
+ AZX_DCAPS_NO_MSI | AZX_DCAPS_NO_64BIT },
/* VIA VT8251/VT8237A */
{ PCI_DEVICE(0x1106, 0x3288), .driver_data = AZX_DRIVER_VIA },
/* VIA GFX VT7122/VX900 */
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 4ffa3a59f..e51c610a2 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -4489,6 +4489,18 @@ static int patch_via_hdmi(struct hda_codec *codec)
return patch_simple_hdmi(codec, VIAHDMI_CVT_NID, VIAHDMI_PIN_NID);
}
+static int patch_gf_hdmi(struct hda_codec *codec)
+{
+ int err;
+
+ err = patch_generic_hdmi(codec);
+ if (err)
+ return err;
+
+ codec->no_sticky_stream = 1;
+ return 0;
+}
+
/*
* patch entries
*/
@@ -4579,6 +4591,12 @@ HDA_CODEC_ENTRY(0x10de009f, "GPU 9f HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de00a0, "GPU a0 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de8001, "MCP73 HDMI", patch_nvhdmi_2ch),
HDA_CODEC_ENTRY(0x10de8067, "MCP67/68 HDMI", patch_nvhdmi_2ch),
+HDA_CODEC_ENTRY(0x67663d82, "Arise 82 HDMI/DP", patch_gf_hdmi),
+HDA_CODEC_ENTRY(0x67663d83, "Arise 83 HDMI/DP", patch_gf_hdmi),
+HDA_CODEC_ENTRY(0x67663d84, "Arise 84 HDMI/DP", patch_gf_hdmi),
+HDA_CODEC_ENTRY(0x67663d85, "Arise 85 HDMI/DP", patch_gf_hdmi),
+HDA_CODEC_ENTRY(0x67663d86, "Arise 86 HDMI/DP", patch_gf_hdmi),
+HDA_CODEC_ENTRY(0x67663d87, "Arise 87 HDMI/DP", patch_gf_hdmi),
HDA_CODEC_ENTRY(0x11069f80, "VX900 HDMI/DP", patch_via_hdmi),
HDA_CODEC_ENTRY(0x11069f81, "VX900 HDMI/DP", patch_via_hdmi),
HDA_CODEC_ENTRY(0x11069f84, "VX11 HDMI/DP", patch_generic_hdmi),
--
2.20.1
On Tue, 18 Apr 2023 10:33:12 +0200,
reaperli wrote:
>
> From: jasontao <[email protected]>
>
> Add a set of HD Audio PCI IDS, and the HDMI codec vendor IDs for
> Glenfly Arise.
>
> Signed-off-by: jasontao <[email protected]>
> Signed-off-by: reaperli <[email protected]>
The patch looks OK now, but could you submit to alsa-devel ML at the
next time?
About details in the patch:
> @@ -1743,6 +1745,8 @@ static int default_bdl_pos_adj(struct azx *chip)
> }
>
> switch (chip->driver_type) {
> + case AZX_DRIVER_GFHDMI:
> + return 128;
So this looks pretty high in comparison with other chips.
It means that the actual position is much behind the reported
position. Due to a large FIFO? Or what reason?
> @@ -1859,6 +1863,9 @@ static int azx_first_init(struct azx *chip)
> }
> #endif
>
> + if (chip->driver_type == AZX_DRIVER_GFHDMI)
> + bus->polling_mode = 1;
This looks odd, too. Doesn't the hardware give any interrupt back
upon the CORB/RIRB response?
> --- a/sound/pci/hda/patch_hdmi.c
> +++ b/sound/pci/hda/patch_hdmi.c
> @@ -4489,6 +4489,18 @@ static int patch_via_hdmi(struct hda_codec *codec)
> return patch_simple_hdmi(codec, VIAHDMI_CVT_NID, VIAHDMI_PIN_NID);
> }
>
> +static int patch_gf_hdmi(struct hda_codec *codec)
> +{
> + int err;
> +
> + err = patch_generic_hdmi(codec);
> + if (err)
> + return err;
> +
> + codec->no_sticky_stream = 1;
This hack is needed for what reason?
thanks,
Takashi
Hi
Thanks, I will also submit to alsa-devel ML at the next time.
For the listed questions:
> @@ -1743,6 +1745,8 @@ static int default_bdl_pos_adj(struct azx *chip)
> }
>
> switch (chip->driver_type) {
> + case AZX_DRIVER_GFHDMI:
> + return 128;
our chip need increase the bdl as there is limitation on hardware, once hdac interrupt interval is too short, the audio data may get lost.
> @@ -1859,6 +1863,9 @@ static int azx_first_init(struct azx *chip)
> }
> #endif
>
> + if (chip->driver_type == AZX_DRIVER_GFHDMI)
> + bus->polling_mode = 1;
Our chip has interrupt upon the CORB/RIRB response, when the codec complete the command, It sends interrupt and writes response entries to memory, However on our hardware, the response entries sometimes are not actually synchronized to memory when driver handle the hdac interrupt. If the RIRB status is not updated in the hdac interrupt handler, azx_rirb_get_response keeps trying to receive a response from rirb until 1s timout before enabling polling_mode, some apps treat it as an error. So for our hardware, need to enable polling_mode to fix it.
> --- a/sound/pci/hda/patch_hdmi.c
> +++ b/sound/pci/hda/patch_hdmi.c
> @@ -4489,6 +4489,18 @@ static int patch_via_hdmi(struct hda_codec *codec)
> return patch_simple_hdmi(codec, VIAHDMI_CVT_NID, VIAHDMI_PIN_NID);
> }
>
> +static int patch_gf_hdmi(struct hda_codec *codec)
> +{
> + int err;
> +
> + err = patch_generic_hdmi(codec);
> + if (err)
> + return err;
> +
> + codec->no_sticky_stream = 1;
On our chip, there are two codecs. when stream switch from one codec to another codec, our hardware need driver to do actual clean-ups in codec_cleanup_stream for the linked codec, otherwise it can't complete switch successfully.
Best Regards,
ReaperLi
________________________________________
??????: Takashi Iwai <[email protected]>
????ʱ??: 2023??4??18?? 17:44
?ռ???: Reaper Li_OC
????: [email protected]; [email protected]; [email protected]; Jason Tao(SH-RD); [email protected]
????: [???????????ʼ?] Re: [PATCH] ALSA: hda: Glenfly: add HD Audio PCI IDs and HDMI Codec Vendor IDs.
On Tue, 18 Apr 2023 10:33:12 +0200,
reaperli wrote:
>
> From: jasontao <[email protected]>
>
> Add a set of HD Audio PCI IDS, and the HDMI codec vendor IDs for
> Glenfly Arise.
>
> Signed-off-by: jasontao <[email protected]>
> Signed-off-by: reaperli <[email protected]>
The patch looks OK now, but could you submit to alsa-devel ML at the
next time?
About details in the patch:
> @@ -1743,6 +1745,8 @@ static int default_bdl_pos_adj(struct azx *chip)
> }
>
> switch (chip->driver_type) {
> + case AZX_DRIVER_GFHDMI:
> + return 128;
So this looks pretty high in comparison with other chips.
It means that the actual position is much behind the reported
position. Due to a large FIFO? Or what reason?
> @@ -1859,6 +1863,9 @@ static int azx_first_init(struct azx *chip)
> }
> #endif
>
> + if (chip->driver_type == AZX_DRIVER_GFHDMI)
> + bus->polling_mode = 1;
This looks odd, too. Doesn't the hardware give any interrupt back
upon the CORB/RIRB response?
> --- a/sound/pci/hda/patch_hdmi.c
> +++ b/sound/pci/hda/patch_hdmi.c
> @@ -4489,6 +4489,18 @@ static int patch_via_hdmi(struct hda_codec *codec)
> return patch_simple_hdmi(codec, VIAHDMI_CVT_NID, VIAHDMI_PIN_NID);
> }
>
> +static int patch_gf_hdmi(struct hda_codec *codec)
> +{
> + int err;
> +
> + err = patch_generic_hdmi(codec);
> + if (err)
> + return err;
> +
> + codec->no_sticky_stream = 1;
This hack is needed for what reason?
thanks,
Takashi