[PATCH] ALSA: hda: parse bus capablities after reset

Vinod Koul vinod.koul at intel.com
Mon Sep 4 04:54:20 UTC 2017


Per spec, HDA capablities are supposed to parsed only after performing a
full reset on the controller, so move the bus parse code after the reset

still kept some debug logs to ensure we have logs for fix

Signed-off-by: Vinod Koul <vinod.koul at intel.com>
---
 sound/hda/hdac_controller.c | 23 +++++++++++++++--------
 sound/pci/hda/hda_intel.c   | 33 +++++++++++++++++----------------
 2 files changed, 32 insertions(+), 24 deletions(-)

diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c
index 978dc1801b3a..598c6e5fad02 100644
--- a/sound/hda/hdac_controller.c
+++ b/sound/hda/hdac_controller.c
@@ -273,48 +273,50 @@ int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus)
 	unsigned int counter = 0;
 
 	offset = snd_hdac_chip_readw(bus, LLCH);
+	pr_err("HDA: LLCH offset is %x\n", offset);
 
 	/* Lets walk the linked capabilities list */
 	do {
 		cur_cap = _snd_hdac_chip_readl(bus, offset);
+		pr_err("HDA: cur_cap: %x for offset %x\n", cur_cap, offset);
 
-		dev_dbg(bus->dev, "Capability version: 0x%x\n",
+		dev_err(bus->dev, "Capability version: 0x%x\n",
 			(cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF);
 
-		dev_dbg(bus->dev, "HDA capability ID: 0x%x\n",
+		dev_err(bus->dev, "HDA capability ID: 0x%x\n",
 			(cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF);
 
 		switch ((cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF) {
 		case AZX_ML_CAP_ID:
-			dev_dbg(bus->dev, "Found ML capability\n");
+			dev_err(bus->dev, "Found ML capability\n");
 			bus->mlcap = bus->remap_addr + offset;
 			break;
 
 		case AZX_GTS_CAP_ID:
-			dev_dbg(bus->dev, "Found GTS capability offset=%x\n", offset);
+			dev_err(bus->dev, "Found GTS capability offset=%x\n", offset);
 			bus->gtscap = bus->remap_addr + offset;
 			break;
 
 		case AZX_PP_CAP_ID:
 			/* PP capability found, the Audio DSP is present */
-			dev_dbg(bus->dev, "Found PP capability offset=%x\n", offset);
+			dev_err(bus->dev, "Found PP capability offset=%x\n", offset);
 			bus->ppcap = bus->remap_addr + offset;
 			break;
 
 		case AZX_SPB_CAP_ID:
 			/* SPIB capability found, handler function */
-			dev_dbg(bus->dev, "Found SPB capability\n");
+			dev_err(bus->dev, "Found SPB capability\n");
 			bus->spbcap = bus->remap_addr + offset;
 			break;
 
 		case AZX_DRSM_CAP_ID:
 			/* DMA resume  capability found, handler function */
-			dev_dbg(bus->dev, "Found DRSM capability\n");
+			dev_err(bus->dev, "Found DRSM capability\n");
 			bus->drsmcap = bus->remap_addr + offset;
 			break;
 
 		default:
-			dev_dbg(bus->dev, "Unknown capability %d\n", cur_cap);
+			dev_err(bus->dev, "Unknown capability %d\n", cur_cap);
 			break;
 		}
 
@@ -328,6 +330,11 @@ int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus)
 		/* read the offset of next capability */
 		offset = cur_cap & AZX_CAP_HDR_NXT_PTR_MASK;
 
+		if (cur_cap == 0xffffffff) {
+			pr_err("HDA: we got bad capability so stop processing\n");
+			break;
+		}
+
 	} while (offset);
 
 	return 0;
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index f958d8d54d15..3ad3c8c04a49 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -645,6 +645,7 @@ static void hda_intel_init_chip(struct azx *chip, bool full_reset)
 		val = val & ~INTEL_HDA_CGCTL_MISCBDCGE;
 		pci_write_config_dword(pci, INTEL_HDA_CGCTL, val);
 	}
+	pr_err("HDA: we are doing full chip reset now\n");
 	azx_init_chip(chip, full_reset);
 	if (chip->driver_type == AZX_DRIVER_SKL) {
 		pci_read_config_dword(pci, INTEL_HDA_CGCTL, &val);
@@ -1799,22 +1800,6 @@ static int azx_first_init(struct azx *chip)
 		return -ENXIO;
 	}
 
-	if (chip->driver_type == AZX_DRIVER_SKL)
-		snd_hdac_bus_parse_capabilities(bus);
-
-	/*
-	 * Some Intel CPUs has always running timer (ART) feature and
-	 * controller may have Global time sync reporting capability, so
-	 * check both of these before declaring synchronized time reporting
-	 * capability SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME
-	 */
-	chip->gts_present = false;
-
-#ifdef CONFIG_X86
-	if (bus->ppcap && boot_cpu_has(X86_FEATURE_ART))
-		chip->gts_present = true;
-#endif
-
 	if (chip->msi) {
 		if (chip->driver_caps & AZX_DCAPS_NO_MSI64) {
 			dev_dbg(card->dev, "Disabling 64bit MSI\n");
@@ -1935,6 +1920,22 @@ static int azx_first_init(struct azx *chip)
 
 	hda_intel_init_chip(chip, (probe_only[dev] & 2) == 0);
 
+	if (chip->driver_type == AZX_DRIVER_SKL)
+		snd_hdac_bus_parse_capabilities(bus);
+
+	/*
+	 * Some Intel CPUs has always running timer (ART) feature and
+	 * controller may have Global time sync reporting capability, so
+	 * check both of these before declaring synchronized time reporting
+	 * capability SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME
+	 */
+	chip->gts_present = false;
+
+#ifdef CONFIG_X86
+	if (bus->ppcap && boot_cpu_has(X86_FEATURE_ART))
+		chip->gts_present = true;
+#endif
+
 	/* codec detection */
 	if (!azx_bus(chip)->codec_mask) {
 		dev_err(card->dev, "no codecs found!\n");
-- 
2.7.4



More information about the Intel-gfx-trybot mailing list