Unverified Commit 533518ef authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!3841 Add support for Hygon family 18h model 5h HD-Audio

parents 477113b3 1360969d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2596,6 +2596,7 @@
#define PCI_VENDOR_ID_ZHAOXIN		0x1d17

#define PCI_VENDOR_ID_HYGON		0x1d94
#define PCI_DEVICE_ID_HYGON_18H_M05H_HDA	0x14a9
#define PCI_DEVICE_ID_HYGON_18H_M05H_DF_F3	0x14b3

#define PCI_VENDOR_ID_FUNGIBLE		0x1dad
+1 −0
Original line number Diff line number Diff line
@@ -350,6 +350,7 @@ struct hdac_bus {
	bool needs_damn_long_delay:1;
	bool not_use_interrupts:1;	/* prohibiting the RIRB IRQ */
	bool access_sdnctl_in_dword:1;	/* accessing the sdnctl register by dword */
	bool hygon_dword_access:1;

	int poll_count;

+8 −2
Original line number Diff line number Diff line
@@ -410,6 +410,9 @@ void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus)
{
	unsigned long timeout;

	if (bus->hygon_dword_access)
		snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_RESET, AZX_GCTL_RESET);
	else
		snd_hdac_chip_updateb(bus, GCTL, AZX_GCTL_RESET, AZX_GCTL_RESET);

	timeout = jiffies + msecs_to_jiffies(100);
@@ -475,6 +478,9 @@ static void azx_int_disable(struct hdac_bus *bus)

	/* disable interrupts in stream descriptor */
	list_for_each_entry(azx_dev, &bus->stream_list, list)
		if (bus->hygon_dword_access)
			snd_hdac_stream_updatel(azx_dev, SD_CTL, SD_INT_MASK, 0);
		else
			snd_hdac_stream_updateb(azx_dev, SD_CTL, SD_INT_MASK, 0);

	/* disable SIE for all streams & disable controller CIE and GIE */
+30 −9
Original line number Diff line number Diff line
@@ -146,11 +146,15 @@ void snd_hdac_stream_start(struct hdac_stream *azx_dev)
			stripe_ctl = snd_hdac_get_stream_stripe_ctl(bus, azx_dev->substream);
		else
			stripe_ctl = 0;
		if (bus->hygon_dword_access)
			snd_hdac_stream_updatel(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK,
					stripe_ctl);
		else
			snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK,
					stripe_ctl);
	}
	/* set DMA start and interrupt mask */
	if (bus->access_sdnctl_in_dword)
	if (bus->access_sdnctl_in_dword || bus->hygon_dword_access)
		snd_hdac_stream_updatel(azx_dev, SD_CTL,
				0, SD_CTL_DMA_START | SD_INT_MASK);
	else
@@ -166,11 +170,21 @@ EXPORT_SYMBOL_GPL(snd_hdac_stream_start);
 */
static void snd_hdac_stream_clear(struct hdac_stream *azx_dev)
{
	struct hdac_bus *bus = azx_dev->bus;

	if (bus->hygon_dword_access) {
		snd_hdac_stream_updatel(azx_dev, SD_CTL,
					SD_CTL_DMA_START | SD_INT_MASK, 0);
		snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */
		if (azx_dev->stripe)
			snd_hdac_stream_updatel(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK, 0);
	} else {
		snd_hdac_stream_updateb(azx_dev, SD_CTL,
					SD_CTL_DMA_START | SD_INT_MASK, 0);
		snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */
		if (azx_dev->stripe)
			snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK, 0);
	}
	azx_dev->running = false;
}

@@ -225,11 +239,15 @@ void snd_hdac_stream_reset(struct hdac_stream *azx_dev)
{
	unsigned char val;
	int dma_run_state;
	struct hdac_bus *bus = azx_dev->bus;

	snd_hdac_stream_clear(azx_dev);

	dma_run_state = snd_hdac_stream_readb(azx_dev, SD_CTL) & SD_CTL_DMA_START;

	if (bus->hygon_dword_access)
		snd_hdac_stream_updatel(azx_dev, SD_CTL, 0, SD_CTL_STREAM_RESET);
	else
		snd_hdac_stream_updateb(azx_dev, SD_CTL, 0, SD_CTL_STREAM_RESET);

	/* wait for hardware to report that the stream entered reset */
@@ -238,6 +256,9 @@ void snd_hdac_stream_reset(struct hdac_stream *azx_dev)
	if (azx_dev->bus->dma_stop_delay && dma_run_state)
		udelay(azx_dev->bus->dma_stop_delay);

	if (bus->hygon_dword_access)
		snd_hdac_stream_updatel(azx_dev, SD_CTL, SD_CTL_STREAM_RESET, 0);
	else
		snd_hdac_stream_updateb(azx_dev, SD_CTL, SD_CTL_STREAM_RESET, 0);

	/* wait for hardware to report that the stream is out of reset */
+9 −0
Original line number Diff line number Diff line
@@ -239,6 +239,7 @@ enum {
	AZX_DRIVER_ZHAOXIN,
	AZX_DRIVER_ZXHDMI,
	AZX_DRIVER_LOONGSON,
	AZX_DRIVER_HYGON,
	AZX_DRIVER_GENERIC,
	AZX_NUM_DRIVERS, /* keep this as last entry */
};
@@ -352,6 +353,7 @@ static const char * const driver_short_names[] = {
	[AZX_DRIVER_ZHAOXIN] = "HDA Zhaoxin",
	[AZX_DRIVER_ZXHDMI] = "HDA Zhaoxin HDMI",
	[AZX_DRIVER_LOONGSON] = "HDA Loongson",
	[AZX_DRIVER_HYGON] = "HDA Hygon",
	[AZX_DRIVER_GENERIC] = "HD-Audio Generic",
};

@@ -1914,6 +1916,10 @@ static int azx_first_init(struct azx *chip)
	if (chip->driver_type == AZX_DRIVER_ZXHDMI)
		azx_init_pci_zx(chip);

	if (chip->driver_type == AZX_DRIVER_HYGON &&
	    chip->pci->device == PCI_DEVICE_ID_HYGON_18H_M05H_HDA)
		bus->hygon_dword_access = 1;

	err = pcim_iomap_regions(pci, 1 << 0, "ICH HD audio");
	if (err < 0)
		return err;
@@ -2806,6 +2812,9 @@ static const struct pci_device_id azx_ids[] = {
	  .driver_data = AZX_DRIVER_LOONGSON },
	{ PCI_VDEVICE(LOONGSON, PCI_DEVICE_ID_LOONGSON_HDMI),
	  .driver_data = AZX_DRIVER_LOONGSON },
	/* Hygon HDAudio */
	{ PCI_VDEVICE(HYGON, PCI_DEVICE_ID_HYGON_18H_M05H_HDA),
	  .driver_data = AZX_DRIVER_HYGON | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_NO_MSI },
	{ 0, }
};
MODULE_DEVICE_TABLE(pci, azx_ids);