在 2021/3/31 上午10:21, LeoLiuoc 写道:
  Add the new PCI ID 0x1d17 0x9141/0x9142/0x9144 Zhaoxin
NB HDAC
 support. And add some special initialization for Zhaoxin NB HDAC.
 The patch is scheduled to be submitted to the kernel mainline in 2021.
 Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
 ---
  sound/pci/hda/hda_controller.c | 17 +++++++++++-
  sound/pci/hda/hda_controller.h |  2 ++
  sound/pci/hda/hda_intel.c      | 51 +++++++++++++++++++++++++++++++++-
  3 files changed, 68 insertions(+), 2 deletions(-)
 diff --git a/sound/pci/hda/hda_controller.c 
 b/sound/pci/hda/hda_controller.c
 index 8fcb421193e0..d648119c72c9 100644
 --- a/sound/pci/hda/hda_controller.c
 +++ b/sound/pci/hda/hda_controller.c
 @@ -1123,6 +1123,16 @@ void azx_stop_chip(struct azx *chip)
  }
  EXPORT_SYMBOL_GPL(azx_stop_chip);
 +static void azx_rirb_zxdelay(struct azx *chip, int enable)
 +{
 +   if (chip->remap_diu_addr) {
 +       if (!enable)
 +           writel(0x0, (char *)chip->remap_diu_addr + 0x490a8);
 +       else
 +           writel(0x1000000, (char *)chip->remap_diu_addr + 0x490a8);
 +   }
 +}
 +
  /*
   * interrupt handler
   */
 @@ -1174,9 +1184,14 @@ irqreturn_t azx_interrupt(int irq, void *dev_id)
         if (status & RIRB_INT_MASK) {
             active = true;
             if (status & RIRB_INT_RESPONSE) {
 -               if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND)
 +               if ((chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND) ||
 +                   (chip->driver_caps & AZX_DCAPS_RIRB_PRE_DELAY)) {
 +                   azx_rirb_zxdelay(chip, 1);
                     udelay(80);
 +               }
                 snd_hdac_bus_update_rirb(bus);
 +               if (chip->driver_caps & AZX_DCAPS_RIRB_PRE_DELAY)
 +                   azx_rirb_zxdelay(chip, 0);
             }
             azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
         }
 diff --git a/sound/pci/hda/hda_controller.h 
 b/sound/pci/hda/hda_controller.h
 index 8a9dd4767b1e..36de9806e890 100644
 --- a/sound/pci/hda/hda_controller.h
 +++ b/sound/pci/hda/hda_controller.h
 @@ -58,6 +58,7 @@
  #define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28)  /* CORBRP clears 
 itself after reset */
  #define AZX_DCAPS_NO_MSI64      (1 << 29)  /* Stick to 32-bit MSIs */
  #define AZX_DCAPS_SEPARATE_STREAM_TAG  (1 << 30) /* capture and 
 playback use separate stream tag */
 +#define AZX_DCAPS_RIRB_PRE_DELAY  (1 << 31)
  enum {
     AZX_SNOOP_TYPE_NONE,
 @@ -167,6 +168,7 @@ struct azx {
     /* GTS present */
     unsigned int gts_present:1;
 +   void __iomem *remap_diu_addr;
  #ifdef CONFIG_SND_HDA_DSP_LOADER
     struct azx_dev saved_azx_dev;
 diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
 index 7cae673e4a62..465a7668d286 100644
 --- a/sound/pci/hda/hda_intel.c
 +++ b/sound/pci/hda/hda_intel.c
 @@ -251,7 +251,8 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
              "{VIA, VT8237A},"
              "{SiS, SIS966},"
              "{ULI, M5461},"
 -            "{ZX, ZhaoxinHDA}}");
 +            "{ZX, ZhaoxinHDA},"
 +            "{ZX, ZhaoxinHDMI}}");
  MODULE_DESCRIPTION("Intel HDA driver");
  #if defined(CONFIG_PM) && defined(CONFIG_VGA_SWITCHEROO)
 @@ -283,6 +284,7 @@ enum {
     AZX_DRIVER_CTHDA,
     AZX_DRIVER_CMEDIA,
     AZX_DRIVER_ZHAOXIN,
 +   AZX_DRIVER_ZXHDMI,
     AZX_DRIVER_GENERIC,
     AZX_NUM_DRIVERS, /* keep this as last entry */
  };
 @@ -404,6 +406,7 @@ static char *driver_short_names[] = {
     [AZX_DRIVER_CTHDA] = "HDA Creative",
     [AZX_DRIVER_CMEDIA] = "HDA C-Media",
     [AZX_DRIVER_ZHAOXIN] = "HDA Zhaoxin",
 +   [AZX_DRIVER_ZXHDMI] = "HDA Zhaoxin GFX",
     [AZX_DRIVER_GENERIC] = "HD-Audio Generic",
  };
 @@ -480,6 +483,29 @@ static void update_pci_byte(struct pci_dev *pci, 
 unsigned int reg,
     pci_write_config_byte(pci, reg, data);
  }
 +static int azx_init_pci_zx(struct azx *chip)
 +{
 +   struct snd_card *card = chip->card;
 +   unsigned int diu_reg;
 +   struct pci_dev *diu_pci = NULL;
 +
 +   diu_pci = pci_get_device(0x1d17, 0x3a03, NULL);
 +   if (!diu_pci) {
 +       dev_err(card->dev, "hda no chx001 device. \n");
 +       return -ENXIO;
 +   }
 +   pci_read_config_dword(diu_pci, PCI_BASE_ADDRESS_0, &diu_reg);
 +   chip->remap_diu_addr = ioremap_nocache(diu_reg, 0x50000);
 +   dev_info(card->dev, "hda %x %p \n", diu_reg, chip->remap_diu_addr);
 +   return 0;
 +}
 +
 
建议把这段逻辑放到azx_init_pci中。
Artie
  +static void azx_free_pci_zx(struct azx *chip)
 +{
 +   if (chip->remap_diu_addr)
 +       iounmap(chip->remap_diu_addr);
 +}
 +
  static void azx_init_pci(struct azx *chip)
  {
     int snoop_type = azx_get_snoop_type(chip);
 @@ -1450,6 +1476,10 @@ static int azx_free(struct azx *chip)
     hda->init_failed = 1; /* to be sure */
     complete_all(&hda->probe_wait);
 +   if (chip->driver_type == AZX_DRIVER_ZXHDMI) {
 +       azx_free_pci_zx(chip);
 +   }
 +
     if (use_vga_switcheroo(hda)) {
         if (chip->disabled && hda->probe_continued)
             snd_hda_unlock_devices(&chip->bus);
 @@ -1803,6 +1833,8 @@ static int default_bdl_pos_adj(struct azx *chip)
     case AZX_DRIVER_ICH:
     case AZX_DRIVER_PCH:
         return 1;
 +   case AZX_DRIVER_ZXHDMI:
 +       return 128;
     default:
         return 32;
     }
 @@ -1921,6 +1953,12 @@ static int azx_first_init(struct azx *chip)
     }
  #endif
 +   chip->remap_diu_addr = NULL;
 +
 +   if (chip->driver_type == AZX_DRIVER_ZXHDMI) {
 +       azx_init_pci_zx(chip);
 +   }
 +
     err = pci_request_regions(pci, "ICH HD audio");
     if (err < 0)
         return err;
 @@ -2030,6 +2068,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_ZXHDMI:
         case AZX_DRIVER_GENERIC:
         default:
             chip->playback_streams = ICH6_NUM_PLAYBACK;
 @@ -2762,6 +2801,11 @@ static const struct pci_device_id azx_ids[] = {
     { PCI_DEVICE(0x1106, 0x9170), .driver_data = AZX_DRIVER_GENERIC },
     /* VIA GFX VT6122/VX11 */
     { PCI_DEVICE(0x1106, 0x9140), .driver_data = AZX_DRIVER_GENERIC },
 +   { PCI_DEVICE(0x1106, 0x9141), .driver_data = AZX_DRIVER_GENERIC },
 +   { PCI_DEVICE(0x1106, 0x9142),
 +     .driver_data = AZX_DRIVER_ZXHDMI | AZX_DCAPS_POSFIX_LPIB | 
 AZX_DCAPS_NO_MSI | AZX_DCAPS_RIRB_PRE_DELAY },
 +   { PCI_DEVICE(0x1106, 0x9144),
 +     .driver_data = AZX_DRIVER_ZXHDMI | AZX_DCAPS_POSFIX_LPIB | 
 AZX_DCAPS_NO_MSI | AZX_DCAPS_RIRB_PRE_DELAY },
     /* SIS966 */
     { PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS },
     /* ULI M5461 */
 @@ -2817,6 +2861,11 @@ static const struct pci_device_id azx_ids[] = {
       .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI },
     /* Zhaoxin */
     { PCI_DEVICE(0x1d17, 0x3288), .driver_data = AZX_DRIVER_ZHAOXIN },
 +   { PCI_DEVICE(0x1d17, 0x9141), .driver_data = AZX_DRIVER_GENERIC },
 +   { PCI_DEVICE(0x1d17, 0x9142),
 +     .driver_data = AZX_DRIVER_ZXHDMI | AZX_DCAPS_POSFIX_LPIB | 
 AZX_DCAPS_NO_MSI | AZX_DCAPS_RIRB_PRE_DELAY },
 +   { PCI_DEVICE(0x1d17, 0x9144),
 +     .driver_data = AZX_DRIVER_ZXHDMI | AZX_DCAPS_POSFIX_LPIB | 
 AZX_DCAPS_NO_MSI | AZX_DCAPS_RIRB_PRE_DELAY },
     { 0, }
  };
  MODULE_DEVICE_TABLE(pci, azx_ids);