linux-clk.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] ARM: sun8i: a33: Audio codec improvements
@ 2018-12-05 10:11 Chen-Yu Tsai
  2018-12-05 10:11 ` [PATCH 1/3] clk: sunxi-ng: a33: Use sigma-delta modulation for audio PLL Chen-Yu Tsai
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Chen-Yu Tsai @ 2018-12-05 10:11 UTC (permalink / raw)
  To: Maxime Ripard, Michael Turquette, Stephen Boyd
  Cc: Chen-Yu Tsai, linux-arm-kernel, linux-clk, linux-kernel,
	devicetree, linux-sunxi

Hi everyone,

This series improves audio support on the A33. Like other Allwinner
SoCs, the A33 requires the use of a sigma-delta modulation fractional-N
PLL to generate the correct clock used for audio playback. Otherwise the
pitch would be slightly off.

Patch 1 enables sigma-delta modulation for the audio PLL on the A33.

Patch 2 is only slightly related. It sets the CLK_SET_RATE_PARENT flag
for all audio-related module clocks

Patch 3 lowers the audio codec's oversampling rate, so that it can
play back audio sampled at beyond 48 KHz.

This is the same as what has recently been done for the A64, which
shares the same audio codec hardware design.

However, on the A33 it seems the PLL doesn't always immediately lock on
to the new clock frequency when there is a rate change. Also since the
codec is only put in standby instead of turned off, runtime PM never
kicks in, and the audio related clocks never get turned off. I'm still
looking into this.

On an unrelated note, if you get pops when playing back audio on sunxi,
it might be related to cpufreq. Try setting the governor to performance
and see if that removes the pops.

Regards
ChenYu


Chen-Yu Tsai (3):
  clk: sunxi-ng: a33: Use sigma-delta modulation for audio PLL
  clk: sunxi-ng: a33: Set CLK_SET_RATE_PARENT for all audio module
    clocks
  ARM: dts: sun8i: a33: Drop audio codec oversampling rate to 128 fs

 arch/arm/boot/dts/sun8i-a33.dtsi     |  2 +-
 drivers/clk/sunxi-ng/ccu-sun8i-a33.c | 43 +++++++++++++++++-----------
 2 files changed, 28 insertions(+), 17 deletions(-)

-- 
2.20.0.rc1


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

* [PATCH 1/3] clk: sunxi-ng: a33: Use sigma-delta modulation for audio PLL
  2018-12-05 10:11 [PATCH 0/3] ARM: sun8i: a33: Audio codec improvements Chen-Yu Tsai
@ 2018-12-05 10:11 ` Chen-Yu Tsai
  2018-12-05 10:11 ` [PATCH 2/3] clk: sunxi-ng: a33: Set CLK_SET_RATE_PARENT for all audio module clocks Chen-Yu Tsai
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Chen-Yu Tsai @ 2018-12-05 10:11 UTC (permalink / raw)
  To: Maxime Ripard, Michael Turquette, Stephen Boyd
  Cc: Chen-Yu Tsai, linux-arm-kernel, linux-clk, linux-kernel,
	devicetree, linux-sunxi

The audio blocks require specific clock rates. Until now we were using
the closest clock rate possible with integer N-M factors. This resulted
in audio playback being slightly slower than it should be.

The vendor kernel gets around this (for newer SoCs) by using sigma-delta
modulation to generate a fractional-N factor. As the PLL hardware is
identical in most chips, we can back port the settings from the newer
SoC, in this case the H3, onto the A33.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 drivers/clk/sunxi-ng/ccu-sun8i-a33.c | 37 ++++++++++++++++++----------
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
index 13eb5b23c5e7..f763648a5f20 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
@@ -51,18 +51,29 @@ static struct ccu_nkmp pll_cpux_clk = {
  * the base (2x, 4x and 8x), and one variable divider (the one true
  * pll audio).
  *
- * We don't have any need for the variable divider for now, so we just
- * hardcode it to match with the clock names
+ * With sigma-delta modulation for fractional-N on the audio PLL,
+ * we have to use specific dividers. This means the variable divider
+ * can no longer be used, as the audio codec requests the exact clock
+ * rates we support through this mechanism. So we now hard code the
+ * variable divider to 1. This means the clock rates will no longer
+ * match the clock names.
  */
 #define SUN8I_A33_PLL_AUDIO_REG	0x008
 
-static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
-				   "osc24M", 0x008,
-				   8, 7,		/* N */
-				   0, 5,		/* M */
-				   BIT(31),		/* gate */
-				   BIT(28),		/* lock */
-				   CLK_SET_RATE_UNGATE);
+static struct ccu_sdm_setting pll_audio_sdm_table[] = {
+	{ .rate = 22579200, .pattern = 0xc0010d84, .m = 8, .n = 7 },
+	{ .rate = 24576000, .pattern = 0xc000ac02, .m = 14, .n = 14 },
+};
+
+static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
+				       "osc24M", 0x008,
+				       8, 7,	/* N */
+				       0, 5,	/* M */
+				       pll_audio_sdm_table, BIT(24),
+				       0x284, BIT(31),
+				       BIT(31),	/* gate */
+				       BIT(28),	/* lock */
+				       CLK_SET_RATE_UNGATE);
 
 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video",
 					"osc24M", 0x010,
@@ -576,9 +587,9 @@ static struct ccu_common *sun8i_a33_ccu_clks[] = {
 	&ats_clk.common,
 };
 
-/* We hardcode the divider to 4 for now */
+/* We hardcode the divider to 1 for now */
 static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
-			"pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
+			"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
 static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
 			"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
 static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
@@ -781,10 +792,10 @@ static void __init sun8i_a33_ccu_setup(struct device_node *node)
 		return;
 	}
 
-	/* Force the PLL-Audio-1x divider to 4 */
+	/* Force the PLL-Audio-1x divider to 1 */
 	val = readl(reg + SUN8I_A33_PLL_AUDIO_REG);
 	val &= ~GENMASK(19, 16);
-	writel(val | (3 << 16), reg + SUN8I_A33_PLL_AUDIO_REG);
+	writel(val | (0 << 16), reg + SUN8I_A33_PLL_AUDIO_REG);
 
 	/* Force PLL-MIPI to MIPI mode */
 	val = readl(reg + SUN8I_A33_PLL_MIPI_REG);
-- 
2.20.0.rc1


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

* [PATCH 2/3] clk: sunxi-ng: a33: Set CLK_SET_RATE_PARENT for all audio module clocks
  2018-12-05 10:11 [PATCH 0/3] ARM: sun8i: a33: Audio codec improvements Chen-Yu Tsai
  2018-12-05 10:11 ` [PATCH 1/3] clk: sunxi-ng: a33: Use sigma-delta modulation for audio PLL Chen-Yu Tsai
@ 2018-12-05 10:11 ` Chen-Yu Tsai
  2018-12-05 10:11 ` [PATCH 3/3] ARM: dts: sun8i: a33: Drop audio codec oversampling rate to 128 fs Chen-Yu Tsai
  2018-12-05 11:09 ` [PATCH 0/3] ARM: sun8i: a33: Audio codec improvements Maxime Ripard
  3 siblings, 0 replies; 5+ messages in thread
From: Chen-Yu Tsai @ 2018-12-05 10:11 UTC (permalink / raw)
  To: Maxime Ripard, Michael Turquette, Stephen Boyd
  Cc: Chen-Yu Tsai, linux-arm-kernel, linux-clk, linux-kernel,
	devicetree, linux-sunxi

All the audio interfaces on Allwinner SoCs need to change their module
clocks during operation, to switch between support for 44.1 kHz and 48
kHz family sample rates. The clock rate for the module clocks is
governed by their upstream audio PLL. The module clocks themselves only
have a gate, and sometimes a divider or mux. Thus any rate changes need
to be propagated upstream.

Set the CLK_SET_RATE_PARENT flag for all audio module clocks to achieve
this.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 drivers/clk/sunxi-ng/ccu-sun8i-a33.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
index f763648a5f20..c7bf814dfd2b 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
@@ -377,10 +377,10 @@ static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4,
 static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x",
 					    "pll-audio-2x", "pll-audio" };
 static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", i2s_parents,
-			       0x0b0, 16, 2, BIT(31), 0);
+			       0x0b0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
 
 static SUNXI_CCU_MUX_WITH_GATE(i2s1_clk, "i2s1", i2s_parents,
-			       0x0b4, 16, 2, BIT(31), 0);
+			       0x0b4, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
 
 /* TODO: the parent for most of the USB clocks is not known */
 static SUNXI_CCU_GATE(usb_phy0_clk,	"usb-phy0",	"osc24M",
@@ -457,7 +457,7 @@ static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve",
 static SUNXI_CCU_GATE(ac_dig_clk,	"ac-dig",	"pll-audio",
 		      0x140, BIT(31), CLK_SET_RATE_PARENT);
 static SUNXI_CCU_GATE(ac_dig_4x_clk,	"ac-dig-4x",	"pll-audio-4x",
-		      0x140, BIT(30), 0);
+		      0x140, BIT(30), CLK_SET_RATE_PARENT);
 static SUNXI_CCU_GATE(avs_clk,		"avs",		"osc24M",
 		      0x144, BIT(31), 0);
 
-- 
2.20.0.rc1


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

* [PATCH 3/3] ARM: dts: sun8i: a33: Drop audio codec oversampling rate to 128 fs
  2018-12-05 10:11 [PATCH 0/3] ARM: sun8i: a33: Audio codec improvements Chen-Yu Tsai
  2018-12-05 10:11 ` [PATCH 1/3] clk: sunxi-ng: a33: Use sigma-delta modulation for audio PLL Chen-Yu Tsai
  2018-12-05 10:11 ` [PATCH 2/3] clk: sunxi-ng: a33: Set CLK_SET_RATE_PARENT for all audio module clocks Chen-Yu Tsai
@ 2018-12-05 10:11 ` Chen-Yu Tsai
  2018-12-05 11:09 ` [PATCH 0/3] ARM: sun8i: a33: Audio codec improvements Maxime Ripard
  3 siblings, 0 replies; 5+ messages in thread
From: Chen-Yu Tsai @ 2018-12-05 10:11 UTC (permalink / raw)
  To: Maxime Ripard, Michael Turquette, Stephen Boyd
  Cc: Chen-Yu Tsai, linux-arm-kernel, linux-clk, linux-kernel,
	devicetree, linux-sunxi

The current oversampling rate of 512 means that for 48 kHz 16 bit
stereo, the MCLK is running at the same rate as the module clock,
so there is no head room to support higher sampling rates. The codec
however supports up to 192 kHz for playback.

This patch drops the oversampling rate from 512 to 128, so that 192 kHz
audio can be played back directly without downsampling. Ideally we
should be using different oversampling rates for different sampling
rates, but that's not possible without a platform-specific machine
driver.

Fixes: 870f1bd1f5e9 ("ARM: dts: sun8i: Add audio codec, dai and card for A33")
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 arch/arm/boot/dts/sun8i-a33.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sun8i-a33.dtsi b/arch/arm/boot/dts/sun8i-a33.dtsi
index c2c10cd4a210..11f58893678d 100644
--- a/arch/arm/boot/dts/sun8i-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a33.dtsi
@@ -207,7 +207,7 @@
 		simple-audio-card,format = "i2s";
 		simple-audio-card,frame-master = <&link_codec>;
 		simple-audio-card,bitclock-master = <&link_codec>;
-		simple-audio-card,mclk-fs = <512>;
+		simple-audio-card,mclk-fs = <128>;
 		simple-audio-card,aux-devs = <&codec_analog>;
 		simple-audio-card,routing =
 			"Left DAC", "AIF1 Slot 0 Left",
-- 
2.20.0.rc1


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

* Re: [PATCH 0/3] ARM: sun8i: a33: Audio codec improvements
  2018-12-05 10:11 [PATCH 0/3] ARM: sun8i: a33: Audio codec improvements Chen-Yu Tsai
                   ` (2 preceding siblings ...)
  2018-12-05 10:11 ` [PATCH 3/3] ARM: dts: sun8i: a33: Drop audio codec oversampling rate to 128 fs Chen-Yu Tsai
@ 2018-12-05 11:09 ` Maxime Ripard
  3 siblings, 0 replies; 5+ messages in thread
From: Maxime Ripard @ 2018-12-05 11:09 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Michael Turquette, Stephen Boyd, linux-arm-kernel, linux-clk,
	linux-kernel, devicetree, linux-sunxi

[-- Attachment #1: Type: text/plain, Size: 1416 bytes --]

On Wed, Dec 05, 2018 at 06:11:49PM +0800, Chen-Yu Tsai wrote:
> Hi everyone,
> 
> This series improves audio support on the A33. Like other Allwinner
> SoCs, the A33 requires the use of a sigma-delta modulation fractional-N
> PLL to generate the correct clock used for audio playback. Otherwise the
> pitch would be slightly off.
> 
> Patch 1 enables sigma-delta modulation for the audio PLL on the A33.
> 
> Patch 2 is only slightly related. It sets the CLK_SET_RATE_PARENT flag
> for all audio-related module clocks
> 
> Patch 3 lowers the audio codec's oversampling rate, so that it can
> play back audio sampled at beyond 48 KHz.
> 
> This is the same as what has recently been done for the A64, which
> shares the same audio codec hardware design.
> 
> However, on the A33 it seems the PLL doesn't always immediately lock on
> to the new clock frequency when there is a rate change. Also since the
> codec is only put in standby instead of turned off, runtime PM never
> kicks in, and the audio related clocks never get turned off. I'm still
> looking into this.
> 
> On an unrelated note, if you get pops when playing back audio on sunxi,
> it might be related to cpufreq. Try setting the governor to performance
> and see if that removes the pops.

Applied all 3 patches, thanks!
Maxime

-- 
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

end of thread, other threads:[~2018-12-05 11:09 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-05 10:11 [PATCH 0/3] ARM: sun8i: a33: Audio codec improvements Chen-Yu Tsai
2018-12-05 10:11 ` [PATCH 1/3] clk: sunxi-ng: a33: Use sigma-delta modulation for audio PLL Chen-Yu Tsai
2018-12-05 10:11 ` [PATCH 2/3] clk: sunxi-ng: a33: Set CLK_SET_RATE_PARENT for all audio module clocks Chen-Yu Tsai
2018-12-05 10:11 ` [PATCH 3/3] ARM: dts: sun8i: a33: Drop audio codec oversampling rate to 128 fs Chen-Yu Tsai
2018-12-05 11:09 ` [PATCH 0/3] ARM: sun8i: a33: Audio codec improvements Maxime Ripard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).