Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion sound/pci/hda/hda_controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -1061,6 +1061,16 @@ static void stream_update(struct hdac_bus *bus, struct hdac_stream *s)
}
}

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);
}
}

irqreturn_t azx_interrupt(int irq, void *dev_id)
{
struct azx *chip = dev_id;
Expand Down Expand Up @@ -1103,9 +1113,14 @@ irqreturn_t azx_interrupt(int irq, void *dev_id)
azx_writeb(chip, RIRBSTS, 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);
}
}
} while (active && ++repeat < 10);
Expand Down
3 changes: 3 additions & 0 deletions sound/pci/hda/hda_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,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) /* Put a delay before read */

enum {
AZX_SNOOP_TYPE_NONE,
Expand Down Expand Up @@ -143,6 +144,8 @@ struct azx {
unsigned int disabled:1; /* disabled by vga_switcheroo */
unsigned int pm_prepared:1;

void __iomem *remap_diu_addr;

/* GTS present */
unsigned int gts_present:1;

Expand Down
69 changes: 67 additions & 2 deletions sound/pci/hda/hda_intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ enum {
AZX_DRIVER_CTHDA,
AZX_DRIVER_CMEDIA,
AZX_DRIVER_ZHAOXIN,
AZX_DRIVER_ZXHDMI,
AZX_DRIVER_LOONGSON,
AZX_DRIVER_HYGON,
AZX_DRIVER_GENERIC,
Expand Down Expand Up @@ -350,6 +351,7 @@ static const char * const driver_short_names[] = {
[AZX_DRIVER_CTHDA] = "HDA Creative",
[AZX_DRIVER_CMEDIA] = "HDA C-Media",
[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",
Expand All @@ -373,6 +375,31 @@ 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;

azx_bus(chip)->polling_mode = 1;
diu_pci = pci_get_device(0x1d17, 0x3a03, NULL);
if (!diu_pci) {
dev_info(card->dev, "zx_hda no KX-5000 device.\n");
return -ENXIO;
}
pci_read_config_dword(diu_pci, PCI_BASE_ADDRESS_0, &diu_reg);
chip->remap_diu_addr = ioremap(diu_reg, 0x50000);
dev_info(card->dev, "zx_hda %x %p\n", diu_reg, chip->remap_diu_addr);
pci_dev_put(diu_pci);
return 0;
}

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);
Expand Down Expand Up @@ -1362,6 +1389,9 @@ static void 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);
Expand Down Expand Up @@ -1549,7 +1579,8 @@ static int check_position_fix(struct azx *chip, int fix)
}

/* Check VIA/ATI HD Audio Controller exist */
if (chip->driver_type == AZX_DRIVER_VIA) {
if (chip->driver_type == AZX_DRIVER_VIA ||
chip->driver_type == AZX_DRIVER_ZHAOXIN) {
dev_dbg(chip->card->dev, "Using VIACOMBO position fix\n");
return POS_FIX_VIACOMBO;
}
Expand Down Expand Up @@ -1703,7 +1734,7 @@ static void azx_check_snoop_available(struct azx *chip)

snoop = true;
if (azx_get_snoop_type(chip) == AZX_SNOOP_TYPE_NONE &&
chip->driver_type == AZX_DRIVER_VIA) {
(chip->driver_type == AZX_DRIVER_VIA || chip->driver_type == AZX_DRIVER_ZHAOXIN)) {
/* force to non-snoop mode for a new VIA controller
* when BIOS is set
*/
Expand Down Expand Up @@ -1755,6 +1786,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;
}
Expand Down Expand Up @@ -1884,6 +1917,11 @@ static int azx_first_init(struct azx *chip)
chip->pci->device == PCI_DEVICE_ID_HYGON_18H_M05H_HDA)
bus->hygon_dword_access = 1;

chip->remap_diu_addr = NULL;

if (chip->driver_type == AZX_DRIVER_ZXHDMI)
azx_init_pci_zx(chip);

err = pcim_iomap_regions(pci, 1 << 0, "ICH HD audio");
if (err < 0)
return err;
Expand Down Expand Up @@ -1985,6 +2023,7 @@ static int azx_first_init(struct azx *chip)
chip->capture_streams = ATIHDMI_NUM_CAPTURE;
break;
case AZX_DRIVER_GFHDMI:
case AZX_DRIVER_ZXHDMI:
case AZX_DRIVER_GENERIC:
default:
chip->playback_streams = ICH6_NUM_PLAYBACK;
Expand Down Expand Up @@ -2699,6 +2738,19 @@ static const struct pci_device_id azx_ids[] = {
{ PCI_VDEVICE(VIA, 0x9170), .driver_data = AZX_DRIVER_GENERIC },
/* VIA GFX VT6122/VX11 */
{ PCI_VDEVICE(VIA, 0x9140), .driver_data = AZX_DRIVER_GENERIC },
{ PCI_VDEVICE(VIA, 0x9141), .driver_data = AZX_DRIVER_GENERIC },
{ PCI_VDEVICE(VIA, 0x9142),
.driver_data = AZX_DRIVER_ZXHDMI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_NO_MSI |
AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_NO_64BIT },
{ PCI_VDEVICE(VIA, 0x9144),
.driver_data = AZX_DRIVER_ZXHDMI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_NO_MSI |
AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_NO_64BIT },
{ PCI_VDEVICE(VIA, 0x9145),
.driver_data = AZX_DRIVER_ZXHDMI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_NO_MSI |
AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_NO_64BIT },
{ PCI_VDEVICE(VIA, 0x9146),
.driver_data = AZX_DRIVER_ZXHDMI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_NO_MSI |
AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_NO_64BIT },
/* SIS966 */
{ PCI_VDEVICE(SI, 0x7502), .driver_data = AZX_DRIVER_SIS },
/* ULI M5461 */
Expand Down Expand Up @@ -2754,6 +2806,19 @@ static const struct pci_device_id azx_ids[] = {
.driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI },
/* Zhaoxin */
{ PCI_VDEVICE(ZHAOXIN, 0x3288), .driver_data = AZX_DRIVER_ZHAOXIN },
{ PCI_VDEVICE(ZHAOXIN, 0x9141), .driver_data = AZX_DRIVER_GENERIC },
{ PCI_VDEVICE(ZHAOXIN, 0x9142),
.driver_data = AZX_DRIVER_ZXHDMI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_NO_MSI |
AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_NO_64BIT },
{ PCI_VDEVICE(ZHAOXIN, 0x9144),
.driver_data = AZX_DRIVER_ZXHDMI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_NO_MSI |
AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_NO_64BIT },
{ PCI_VDEVICE(ZHAOXIN, 0x9145),
.driver_data = AZX_DRIVER_ZXHDMI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_NO_MSI |
AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_NO_64BIT },
{ PCI_VDEVICE(ZHAOXIN, 0x9146),
.driver_data = AZX_DRIVER_ZXHDMI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_NO_MSI |
AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_NO_64BIT },
/* Loongson HDAudio*/
{ PCI_VDEVICE(LOONGSON, PCI_DEVICE_ID_LOONGSON_HDA),
.driver_data = AZX_DRIVER_LOONGSON },
Expand Down
32 changes: 32 additions & 0 deletions sound/pci/hda/patch_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -4494,6 +4494,20 @@ static int patch_via_hdmi(struct hda_codec *codec)
return patch_simple_hdmi(codec, VIAHDMI_CVT_NID, VIAHDMI_PIN_NID);
}

/* Zhaoxin HDMI Implementation */
static int patch_zhaoxin_hdmi(struct hda_codec *codec)
{
int err;

err = patch_generic_hdmi(codec);
codec->no_sticky_stream = 1;

if (err)
return err;

return 0;
}

static int patch_gf_hdmi(struct hda_codec *codec)
{
int err;
Expand Down Expand Up @@ -4616,6 +4630,15 @@ 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),
HDA_CODEC_ENTRY(0x11069f85, "VX11 HDMI/DP", patch_generic_hdmi),
HDA_CODEC_ENTRY(0x11069f88, "KX-5000 HDMI/DP", patch_zhaoxin_hdmi),
HDA_CODEC_ENTRY(0x11069f89, "KX-5000 HDMI/DP", patch_zhaoxin_hdmi),
HDA_CODEC_ENTRY(0x11069f8a, "KX-6000 HDMI/DP", patch_zhaoxin_hdmi),
HDA_CODEC_ENTRY(0x11069f8b, "KX-6000 HDMI/DP", patch_zhaoxin_hdmi),
HDA_CODEC_ENTRY(0x11069f8c, "KX-6000G HDMI/DP", patch_zhaoxin_hdmi),
HDA_CODEC_ENTRY(0x11069f8d, "KX-6000G HDMI/DP", patch_zhaoxin_hdmi),
HDA_CODEC_ENTRY(0x11069f8e, "KX-7000 HDMI/DP", patch_zhaoxin_hdmi),
HDA_CODEC_ENTRY(0x11069f8f, "KX-7000 HDMI/DP", patch_zhaoxin_hdmi),
HDA_CODEC_ENTRY(0x11069f90, "KX-7000 HDMI/DP", patch_zhaoxin_hdmi),
HDA_CODEC_ENTRY(0x80860054, "IbexPeak HDMI", patch_i915_cpt_hdmi),
HDA_CODEC_ENTRY(0x80862800, "Geminilake HDMI", patch_i915_glk_hdmi),
HDA_CODEC_ENTRY(0x80862801, "Bearlake HDMI", patch_generic_hdmi),
Expand Down Expand Up @@ -4648,6 +4671,15 @@ HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi),
HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_i915_byt_hdmi),
HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_i915_byt_hdmi),
HDA_CODEC_ENTRY(0x808629fb, "Crestline HDMI", patch_generic_hdmi),
HDA_CODEC_ENTRY(0x1d179f88, "KX-5000 HDMI/DP", patch_zhaoxin_hdmi),
HDA_CODEC_ENTRY(0x1d179f89, "KX-5000 HDMI/DP", patch_zhaoxin_hdmi),
HDA_CODEC_ENTRY(0x1d179f8a, "KX-6000 HDMI/DP", patch_zhaoxin_hdmi),
HDA_CODEC_ENTRY(0x1d179f8b, "KX-6000 HDMI/DP", patch_zhaoxin_hdmi),
HDA_CODEC_ENTRY(0x1d179f8c, "KX-6000G HDMI/DP", patch_zhaoxin_hdmi),
HDA_CODEC_ENTRY(0x1d179f8d, "KX-6000G HDMI/DP", patch_zhaoxin_hdmi),
HDA_CODEC_ENTRY(0x1d179f8e, "KX-7000 HDMI/DP", patch_zhaoxin_hdmi),
HDA_CODEC_ENTRY(0x1d179f8f, "KX-7000 HDMI/DP", patch_zhaoxin_hdmi),
HDA_CODEC_ENTRY(0x1d179f90, "KX-7000 HDMI/DP", patch_zhaoxin_hdmi),
/* special ID for generic HDMI */
HDA_CODEC_ENTRY(HDA_CODEC_ID_GENERIC_HDMI, "Generic HDMI", patch_generic_hdmi),
{} /* terminator */
Expand Down