On Thu, 06 Apr 2017 13:18:21 +0200, libin.yang@intel.com wrote:
From: Libin Yang libin.yang@intel.com
On some Intel platforms, the audio clock may not be set correctly with initial setting. This will cause the audio playback/capture rates wrong.
This patch checks the audio clock setting and will set it to a proper value if it is set incorrectly.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=188411
Signed-off-by: Libin Yang libin.yang@intel.com
Applied, thanks.
Takashi
sound/pci/hda/hda_intel.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+)
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index c8256a8..7b85132 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -539,6 +539,98 @@ static void bxt_reduce_dma_latency(struct azx *chip) azx_writel(chip, SKL_EM4L, val); }
+/*
- ML_LCAP bits:
- bit 0: 6 MHz Supported
- bit 1: 12 MHz Supported
- bit 2: 24 MHz Supported
- bit 3: 48 MHz Supported
- bit 4: 96 MHz Supported
- bit 5: 192 MHz Supported
- */
+static int intel_get_lctl_scf(struct azx *chip) +{
- struct hdac_bus *bus = azx_bus(chip);
- static int preferred_bits[] = { 2, 3, 1, 4, 5 };
- u32 val, t;
- int i;
- val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCAP);
- for (i = 0; i < ARRAY_SIZE(preferred_bits); i++) {
t = preferred_bits[i];
if (val & (1 << t))
return t;
- }
- dev_warn(chip->card->dev, "set audio clock frequency to 6MHz");
- return 0;
+}
+static int intel_ml_lctl_set_power(struct azx *chip, int state) +{
- struct hdac_bus *bus = azx_bus(chip);
- u32 val;
- int timeout;
- /*
* the codecs are sharing the first link setting by default
* If other links are enabled for stream, they need similar fix
*/
- val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
- val &= ~AZX_MLCTL_SPA;
- val |= state << AZX_MLCTL_SPA_SHIFT;
- writel(val, bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
- /* wait for CPA */
- timeout = 50;
- while (timeout) {
if (((readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL)) &
AZX_MLCTL_CPA) == (state << AZX_MLCTL_CPA_SHIFT))
return 0;
timeout--;
udelay(10);
- }
- return -1;
+}
+static void intel_init_lctl(struct azx *chip) +{
- struct hdac_bus *bus = azx_bus(chip);
- u32 val;
- int ret;
- /* 0. check lctl register value is correct or not */
- val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
- /* if SCF is already set, let's use it */
- if ((val & ML_LCTL_SCF_MASK) != 0)
return;
- /*
* Before operating on SPA, CPA must match SPA.
* Any deviation may result in undefined behavior.
*/
- if (((val & AZX_MLCTL_SPA) >> AZX_MLCTL_SPA_SHIFT) !=
((val & AZX_MLCTL_CPA) >> AZX_MLCTL_CPA_SHIFT))
return;
- /* 1. turn link down: set SPA to 0 and wait CPA to 0 */
- ret = intel_ml_lctl_set_power(chip, 0);
- udelay(100);
- if (ret)
goto set_spa;
- /* 2. update SCF to select a properly audio clock*/
- val &= ~ML_LCTL_SCF_MASK;
- val |= intel_get_lctl_scf(chip);
- writel(val, bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
+set_spa:
- /* 4. turn link up: set SPA to 1 and wait CPA to 1 */
- intel_ml_lctl_set_power(chip, 1);
- udelay(100);
+}
static void hda_intel_init_chip(struct azx *chip, bool full_reset) { struct hdac_bus *bus = azx_bus(chip); @@ -564,6 +656,9 @@ static void hda_intel_init_chip(struct azx *chip, bool full_reset) /* reduce dma latency to avoid noise */ if (IS_BXT(pci)) bxt_reduce_dma_latency(chip);
- if (bus->mlcap != NULL)
intel_init_lctl(chip);
}
/* calculate runtime delay from LPIB */
2.7.4