Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2 v2] ALSA: hda - add more ML register definitions
@ 2017-04-06 11:18 libin.yang
  2017-04-06 11:18 ` [PATCH 2/2 v2] ALSA: hda - set intel audio clock to a proper value libin.yang
  2017-04-07  8:40 ` [PATCH 1/2 v2] ALSA: hda - add more ML register definitions Takashi Iwai
  0 siblings, 2 replies; 4+ messages in thread
From: libin.yang @ 2017-04-06 11:18 UTC (permalink / raw)
  To: alsa-devel, tiwai
  Cc: libin.yang, mengdong.lin, infernix, rakesh.a.ughreja, jeeja.kp

From: Libin Yang <libin.yang@intel.com>

This patch refines the definition of AZX_MLCTL_SPA and AZX_MLCTL_CPA
and add more definitions of ML registers

Signed-off-by: Libin Yang <libin.yang@intel.com>
---
 include/sound/hda_register.h        | 8 +++++---
 sound/hda/ext/hdac_ext_controller.c | 6 +++---
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/include/sound/hda_register.h b/include/sound/hda_register.h
index 0013063..8df12e4 100644
--- a/include/sound/hda_register.h
+++ b/include/sound/hda_register.h
@@ -243,9 +243,11 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
 #define AZX_REG_ML_LOUTPAY		0x20
 #define AZX_REG_ML_LINPAY		0x30
 
-#define AZX_MLCTL_SPA			(1<<16)
-#define AZX_MLCTL_CPA			23
-
+#define ML_LCTL_SCF_MASK			0xF
+#define AZX_MLCTL_SPA				(0x1 << 16)
+#define AZX_MLCTL_CPA				(0x1 << 23)
+#define AZX_MLCTL_SPA_SHIFT			16
+#define AZX_MLCTL_CPA_SHIFT			23
 
 /* registers for DMA Resume Capability Structure */
 #define AZX_DRSM_CAP_ID			0x5
diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c
index 2614691..84f3b81 100644
--- a/sound/hda/ext/hdac_ext_controller.c
+++ b/sound/hda/ext/hdac_ext_controller.c
@@ -171,7 +171,7 @@ static int check_hdac_link_power_active(struct hdac_ext_link *link, bool enable)
 {
 	int timeout;
 	u32 val;
-	int mask = (1 << AZX_MLCTL_CPA);
+	int mask = (1 << AZX_MLCTL_CPA_SHIFT);
 
 	udelay(3);
 	timeout = 150;
@@ -179,10 +179,10 @@ static int check_hdac_link_power_active(struct hdac_ext_link *link, bool enable)
 	do {
 		val = readl(link->ml_addr + AZX_REG_ML_LCTL);
 		if (enable) {
-			if (((val & mask) >> AZX_MLCTL_CPA))
+			if (((val & mask) >> AZX_MLCTL_CPA_SHIFT))
 				return 0;
 		} else {
-			if (!((val & mask) >> AZX_MLCTL_CPA))
+			if (!((val & mask) >> AZX_MLCTL_CPA_SHIFT))
 				return 0;
 		}
 		udelay(3);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2 v2] ALSA: hda - set intel audio clock to a proper value
  2017-04-06 11:18 [PATCH 1/2 v2] ALSA: hda - add more ML register definitions libin.yang
@ 2017-04-06 11:18 ` libin.yang
  2017-04-07  8:40   ` Takashi Iwai
  2017-04-07  8:40 ` [PATCH 1/2 v2] ALSA: hda - add more ML register definitions Takashi Iwai
  1 sibling, 1 reply; 4+ messages in thread
From: libin.yang @ 2017-04-06 11:18 UTC (permalink / raw)
  To: alsa-devel, tiwai
  Cc: libin.yang, mengdong.lin, infernix, rakesh.a.ughreja, jeeja.kp

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>
---
 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

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2 v2] ALSA: hda - add more ML register definitions
  2017-04-06 11:18 [PATCH 1/2 v2] ALSA: hda - add more ML register definitions libin.yang
  2017-04-06 11:18 ` [PATCH 2/2 v2] ALSA: hda - set intel audio clock to a proper value libin.yang
@ 2017-04-07  8:40 ` Takashi Iwai
  1 sibling, 0 replies; 4+ messages in thread
From: Takashi Iwai @ 2017-04-07  8:40 UTC (permalink / raw)
  To: libin.yang; +Cc: mengdong.lin, alsa-devel, infernix, rakesh.a.ughreja, jeeja.kp

On Thu, 06 Apr 2017 13:18:20 +0200,
libin.yang@intel.com wrote:
> 
> From: Libin Yang <libin.yang@intel.com>
> 
> This patch refines the definition of AZX_MLCTL_SPA and AZX_MLCTL_CPA
> and add more definitions of ML registers
> 
> Signed-off-by: Libin Yang <libin.yang@intel.com>

Applied, thanks.


Takashi

> ---
>  include/sound/hda_register.h        | 8 +++++---
>  sound/hda/ext/hdac_ext_controller.c | 6 +++---
>  2 files changed, 8 insertions(+), 6 deletions(-)
> 
> diff --git a/include/sound/hda_register.h b/include/sound/hda_register.h
> index 0013063..8df12e4 100644
> --- a/include/sound/hda_register.h
> +++ b/include/sound/hda_register.h
> @@ -243,9 +243,11 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
>  #define AZX_REG_ML_LOUTPAY		0x20
>  #define AZX_REG_ML_LINPAY		0x30
>  
> -#define AZX_MLCTL_SPA			(1<<16)
> -#define AZX_MLCTL_CPA			23
> -
> +#define ML_LCTL_SCF_MASK			0xF
> +#define AZX_MLCTL_SPA				(0x1 << 16)
> +#define AZX_MLCTL_CPA				(0x1 << 23)
> +#define AZX_MLCTL_SPA_SHIFT			16
> +#define AZX_MLCTL_CPA_SHIFT			23
>  
>  /* registers for DMA Resume Capability Structure */
>  #define AZX_DRSM_CAP_ID			0x5
> diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c
> index 2614691..84f3b81 100644
> --- a/sound/hda/ext/hdac_ext_controller.c
> +++ b/sound/hda/ext/hdac_ext_controller.c
> @@ -171,7 +171,7 @@ static int check_hdac_link_power_active(struct hdac_ext_link *link, bool enable)
>  {
>  	int timeout;
>  	u32 val;
> -	int mask = (1 << AZX_MLCTL_CPA);
> +	int mask = (1 << AZX_MLCTL_CPA_SHIFT);
>  
>  	udelay(3);
>  	timeout = 150;
> @@ -179,10 +179,10 @@ static int check_hdac_link_power_active(struct hdac_ext_link *link, bool enable)
>  	do {
>  		val = readl(link->ml_addr + AZX_REG_ML_LCTL);
>  		if (enable) {
> -			if (((val & mask) >> AZX_MLCTL_CPA))
> +			if (((val & mask) >> AZX_MLCTL_CPA_SHIFT))
>  				return 0;
>  		} else {
> -			if (!((val & mask) >> AZX_MLCTL_CPA))
> +			if (!((val & mask) >> AZX_MLCTL_CPA_SHIFT))
>  				return 0;
>  		}
>  		udelay(3);
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 2/2 v2] ALSA: hda - set intel audio clock to a proper value
  2017-04-06 11:18 ` [PATCH 2/2 v2] ALSA: hda - set intel audio clock to a proper value libin.yang
@ 2017-04-07  8:40   ` Takashi Iwai
  0 siblings, 0 replies; 4+ messages in thread
From: Takashi Iwai @ 2017-04-07  8:40 UTC (permalink / raw)
  To: libin.yang; +Cc: mengdong.lin, alsa-devel, infernix, rakesh.a.ughreja, jeeja.kp

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
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-04-07  8:40 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-04-06 11:18 [PATCH 1/2 v2] ALSA: hda - add more ML register definitions libin.yang
2017-04-06 11:18 ` [PATCH 2/2 v2] ALSA: hda - set intel audio clock to a proper value libin.yang
2017-04-07  8:40   ` Takashi Iwai
2017-04-07  8:40 ` [PATCH 1/2 v2] ALSA: hda - add more ML register definitions Takashi Iwai

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox