All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2 0/3] refine clock tree for esai in imx6q
@ 2014-08-06  8:35 ` Shengjiu Wang
  0 siblings, 0 replies; 16+ messages in thread
From: Shengjiu Wang @ 2014-08-06  8:35 UTC (permalink / raw)
  To: shawn.guo, kernel, linux, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: shengjiu.wang, Guangyu.Chen, linux-arm-kernel, linux-kernel

refine clock tree for esai in imx6q

Changes for V2
- Add pll5_sel And update the comments for patch 2.
- As the bypass mode is not supported in clk tree, so update the 
- comments for patch 3.

Shengjiu Wang (3):
  ARM: clk-imx6q: refine clock tree for ESAI
  ARM: clk-imx6q: Add missing lvds and anaclk clock to the clock tree
  ARM: imx6q: Add the clock route from external OSC to ESAI clock

 arch/arm/mach-imx/clk-imx6q.c             |   24 +++++++++++++++++++-----
 arch/arm/mach-imx/mach-imx6q.c            |   28 ++++++++++++++++++++++++++++
 include/dt-bindings/clock/imx6qdl-clock.h |   13 ++++++++++---
 3 files changed, 57 insertions(+), 8 deletions(-)

-- 
1.7.9.5


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

* [PATCH V2 0/3] refine clock tree for esai in imx6q
@ 2014-08-06  8:35 ` Shengjiu Wang
  0 siblings, 0 replies; 16+ messages in thread
From: Shengjiu Wang @ 2014-08-06  8:35 UTC (permalink / raw)
  To: linux-arm-kernel

refine clock tree for esai in imx6q

Changes for V2
- Add pll5_sel And update the comments for patch 2.
- As the bypass mode is not supported in clk tree, so update the 
- comments for patch 3.

Shengjiu Wang (3):
  ARM: clk-imx6q: refine clock tree for ESAI
  ARM: clk-imx6q: Add missing lvds and anaclk clock to the clock tree
  ARM: imx6q: Add the clock route from external OSC to ESAI clock

 arch/arm/mach-imx/clk-imx6q.c             |   24 +++++++++++++++++++-----
 arch/arm/mach-imx/mach-imx6q.c            |   28 ++++++++++++++++++++++++++++
 include/dt-bindings/clock/imx6qdl-clock.h |   13 ++++++++++---
 3 files changed, 57 insertions(+), 8 deletions(-)

-- 
1.7.9.5

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

* [PATCH V2 1/3] ARM: clk-imx6q: refine clock tree for ESAI
  2014-08-06  8:35 ` Shengjiu Wang
@ 2014-08-06  8:35   ` Shengjiu Wang
  -1 siblings, 0 replies; 16+ messages in thread
From: Shengjiu Wang @ 2014-08-06  8:35 UTC (permalink / raw)
  To: shawn.guo, kernel, linux, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: shengjiu.wang, Guangyu.Chen, linux-arm-kernel, linux-kernel

There are three clock for ESAI, esai_extal, esai_ipg, esai_mem. Rename
'esai' to 'esai_extal', 'esai_ahb' to 'esai_mem', and add 'esai_ipg'.
Make the clock for ESAI more clear and align them with imx6sx.

Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
---
 arch/arm/mach-imx/clk-imx6q.c             |    7 ++++---
 include/dt-bindings/clock/imx6qdl-clock.h |    7 ++++---
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
index 6cceb77..1d6dd59 100644
--- a/arch/arm/mach-imx/clk-imx6q.c
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -64,7 +64,7 @@ static const char *cko2_sels[] = {
 	"ipu2", "vdo_axi", "osc", "gpu2d_core",
 	"gpu3d_core", "usdhc2", "ssi1", "ssi2",
 	"ssi3", "gpu3d_shader", "vpu_axi", "can_root",
-	"ldb_di0", "ldb_di1", "esai", "eim_slow",
+	"ldb_di0", "ldb_di1", "esai_extal", "eim_slow",
 	"uart_serial", "spdif", "asrc", "hsi_tx",
 };
 static const char *cko_sels[] = { "cko1", "cko2", };
@@ -325,8 +325,9 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 	else
 		clk[IMX6Q_CLK_ECSPI5] = imx_clk_gate2("ecspi5",        "ecspi_root",        base + 0x6c, 8);
 	clk[IMX6QDL_CLK_ENET]         = imx_clk_gate2("enet",          "ipg",               base + 0x6c, 10);
-	clk[IMX6QDL_CLK_ESAI]         = imx_clk_gate2_shared("esai",   "esai_podf",         base + 0x6c, 16, &share_count_esai);
-	clk[IMX6QDL_CLK_ESAI_AHB]     = imx_clk_gate2_shared("esai_ahb", "ahb",             base + 0x6c, 16, &share_count_esai);
+	clk[IMX6QDL_CLK_ESAI_EXTAL]   = imx_clk_gate2_shared("esai_extal",   "esai_podf",   base + 0x6c, 16, &share_count_esai);
+	clk[IMX6QDL_CLK_ESAI_IPG]     = imx_clk_gate2_shared("esai_ipg",   "ipg",           base + 0x6c, 16, &share_count_esai);
+	clk[IMX6QDL_CLK_ESAI_MEM]     = imx_clk_gate2_shared("esai_mem", "ahb",             base + 0x6c, 16, &share_count_esai);
 	clk[IMX6QDL_CLK_GPT_IPG]      = imx_clk_gate2("gpt_ipg",       "ipg",               base + 0x6c, 20);
 	clk[IMX6QDL_CLK_GPT_IPG_PER]  = imx_clk_gate2("gpt_ipg_per",   "ipg_per",           base + 0x6c, 22);
 	if (cpu_is_imx6dl())
diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h
index 654151e..323e865 100644
--- a/include/dt-bindings/clock/imx6qdl-clock.h
+++ b/include/dt-bindings/clock/imx6qdl-clock.h
@@ -128,7 +128,7 @@
 #define IMX6Q_CLK_ECSPI5			116
 #define IMX6DL_CLK_I2C4				116
 #define IMX6QDL_CLK_ENET			117
-#define IMX6QDL_CLK_ESAI			118
+#define IMX6QDL_CLK_ESAI_EXTAL			118
 #define IMX6QDL_CLK_GPT_IPG			119
 #define IMX6QDL_CLK_GPT_IPG_PER			120
 #define IMX6QDL_CLK_GPU2D_CORE			121
@@ -218,7 +218,8 @@
 #define IMX6QDL_CLK_LVDS2_SEL			205
 #define IMX6QDL_CLK_LVDS1_GATE			206
 #define IMX6QDL_CLK_LVDS2_GATE			207
-#define IMX6QDL_CLK_ESAI_AHB			208
-#define IMX6QDL_CLK_END				209
+#define IMX6QDL_CLK_ESAI_IPG			208
+#define IMX6QDL_CLK_ESAI_MEM			209
+#define IMX6QDL_CLK_END				210
 
 #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */
-- 
1.7.9.5


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

* [PATCH V2 1/3] ARM: clk-imx6q: refine clock tree for ESAI
@ 2014-08-06  8:35   ` Shengjiu Wang
  0 siblings, 0 replies; 16+ messages in thread
From: Shengjiu Wang @ 2014-08-06  8:35 UTC (permalink / raw)
  To: linux-arm-kernel

There are three clock for ESAI, esai_extal, esai_ipg, esai_mem. Rename
'esai' to 'esai_extal', 'esai_ahb' to 'esai_mem', and add 'esai_ipg'.
Make the clock for ESAI more clear and align them with imx6sx.

Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
---
 arch/arm/mach-imx/clk-imx6q.c             |    7 ++++---
 include/dt-bindings/clock/imx6qdl-clock.h |    7 ++++---
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
index 6cceb77..1d6dd59 100644
--- a/arch/arm/mach-imx/clk-imx6q.c
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -64,7 +64,7 @@ static const char *cko2_sels[] = {
 	"ipu2", "vdo_axi", "osc", "gpu2d_core",
 	"gpu3d_core", "usdhc2", "ssi1", "ssi2",
 	"ssi3", "gpu3d_shader", "vpu_axi", "can_root",
-	"ldb_di0", "ldb_di1", "esai", "eim_slow",
+	"ldb_di0", "ldb_di1", "esai_extal", "eim_slow",
 	"uart_serial", "spdif", "asrc", "hsi_tx",
 };
 static const char *cko_sels[] = { "cko1", "cko2", };
@@ -325,8 +325,9 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 	else
 		clk[IMX6Q_CLK_ECSPI5] = imx_clk_gate2("ecspi5",        "ecspi_root",        base + 0x6c, 8);
 	clk[IMX6QDL_CLK_ENET]         = imx_clk_gate2("enet",          "ipg",               base + 0x6c, 10);
-	clk[IMX6QDL_CLK_ESAI]         = imx_clk_gate2_shared("esai",   "esai_podf",         base + 0x6c, 16, &share_count_esai);
-	clk[IMX6QDL_CLK_ESAI_AHB]     = imx_clk_gate2_shared("esai_ahb", "ahb",             base + 0x6c, 16, &share_count_esai);
+	clk[IMX6QDL_CLK_ESAI_EXTAL]   = imx_clk_gate2_shared("esai_extal",   "esai_podf",   base + 0x6c, 16, &share_count_esai);
+	clk[IMX6QDL_CLK_ESAI_IPG]     = imx_clk_gate2_shared("esai_ipg",   "ipg",           base + 0x6c, 16, &share_count_esai);
+	clk[IMX6QDL_CLK_ESAI_MEM]     = imx_clk_gate2_shared("esai_mem", "ahb",             base + 0x6c, 16, &share_count_esai);
 	clk[IMX6QDL_CLK_GPT_IPG]      = imx_clk_gate2("gpt_ipg",       "ipg",               base + 0x6c, 20);
 	clk[IMX6QDL_CLK_GPT_IPG_PER]  = imx_clk_gate2("gpt_ipg_per",   "ipg_per",           base + 0x6c, 22);
 	if (cpu_is_imx6dl())
diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h
index 654151e..323e865 100644
--- a/include/dt-bindings/clock/imx6qdl-clock.h
+++ b/include/dt-bindings/clock/imx6qdl-clock.h
@@ -128,7 +128,7 @@
 #define IMX6Q_CLK_ECSPI5			116
 #define IMX6DL_CLK_I2C4				116
 #define IMX6QDL_CLK_ENET			117
-#define IMX6QDL_CLK_ESAI			118
+#define IMX6QDL_CLK_ESAI_EXTAL			118
 #define IMX6QDL_CLK_GPT_IPG			119
 #define IMX6QDL_CLK_GPT_IPG_PER			120
 #define IMX6QDL_CLK_GPU2D_CORE			121
@@ -218,7 +218,8 @@
 #define IMX6QDL_CLK_LVDS2_SEL			205
 #define IMX6QDL_CLK_LVDS1_GATE			206
 #define IMX6QDL_CLK_LVDS2_GATE			207
-#define IMX6QDL_CLK_ESAI_AHB			208
-#define IMX6QDL_CLK_END				209
+#define IMX6QDL_CLK_ESAI_IPG			208
+#define IMX6QDL_CLK_ESAI_MEM			209
+#define IMX6QDL_CLK_END				210
 
 #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */
-- 
1.7.9.5

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

* [PATCH V2 2/3] ARM: clk-imx6q: Add missing lvds and anaclk clock to the clock tree
  2014-08-06  8:35 ` Shengjiu Wang
@ 2014-08-06  8:35   ` Shengjiu Wang
  -1 siblings, 0 replies; 16+ messages in thread
From: Shengjiu Wang @ 2014-08-06  8:35 UTC (permalink / raw)
  To: shawn.guo, kernel, linux, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: shengjiu.wang, Guangyu.Chen, linux-arm-kernel, linux-kernel

anaclk1 and anaclk2 is the clock source for lvds1_in and lvds2_in. lvds1_in
and lvds2_in can be used to provide external clock source to the internal
pll, such as pll4_audio and pll5_video.
pll4_audio and pll5_video can have multiple source, not only "osc", so
add them.

Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
---
 arch/arm/mach-imx/clk-imx6q.c             |   12 ++++++++++--
 include/dt-bindings/clock/imx6qdl-clock.h |    8 +++++++-
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
index 1d6dd59..330aad3 100644
--- a/arch/arm/mach-imx/clk-imx6q.c
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -73,6 +73,7 @@ static const char *lvds_sels[] = {
 	"pll4_audio", "pll5_video", "pll8_mlb", "enet_ref",
 	"pcie_ref_125m", "sata_ref_100m",
 };
+static const char *pll_av_sels[] = { "osc", "lvds1_in", "lvds2_in", "dummy", };
 
 static struct clk *clk[IMX6QDL_CLK_END];
 static struct clk_onecell_data clk_data;
@@ -119,6 +120,9 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 	clk[IMX6QDL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
 	clk[IMX6QDL_CLK_CKIH] = imx_obtain_fixed_clock("ckih1", 0);
 	clk[IMX6QDL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0);
+	/* Clock source from external clock via ANACLK1/2 PADs */
+	clk[IMX6QDL_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0);
+	clk[IMX6QDL_CLK_ANACLK2] = imx_obtain_fixed_clock("anaclk2", 0);
 
 	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
 	base = of_iomap(np, 0);
@@ -136,8 +140,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 	clk[IMX6QDL_CLK_PLL1_SYS]      = imx_clk_pllv3(IMX_PLLV3_SYS,	"pll1_sys",	"osc", base,        0x7f);
 	clk[IMX6QDL_CLK_PLL2_BUS]      = imx_clk_pllv3(IMX_PLLV3_GENERIC,	"pll2_bus",	"osc", base + 0x30, 0x1);
 	clk[IMX6QDL_CLK_PLL3_USB_OTG]  = imx_clk_pllv3(IMX_PLLV3_USB,	"pll3_usb_otg",	"osc", base + 0x10, 0x3);
-	clk[IMX6QDL_CLK_PLL4_AUDIO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll4_audio",	"osc", base + 0x70, 0x7f);
-	clk[IMX6QDL_CLK_PLL5_VIDEO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll5_video",	"osc", base + 0xa0, 0x7f);
+	clk[IMX6QDL_CLK_PLL4_AUDIO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll4_audio",	"pll4_sel", base + 0x70, 0x7f);
+	clk[IMX6QDL_CLK_PLL5_VIDEO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll5_video",	"pll5_sel", base + 0xa0, 0x7f);
 	clk[IMX6QDL_CLK_PLL6_ENET]     = imx_clk_pllv3(IMX_PLLV3_ENET,	"pll6_enet",	"osc", base + 0xe0, 0x3);
 	clk[IMX6QDL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB,	"pll7_usb_host","osc", base + 0x20, 0x3);
 
@@ -169,6 +173,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 
 	clk[IMX6QDL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
 	clk[IMX6QDL_CLK_LVDS2_SEL] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
+	clk[IMX6QDL_CLK_PLL4_SEL]  = imx_clk_mux("pll4_sel",  base + 0x70, 14, 2, pll_av_sels, ARRAY_SIZE(pll_av_sels));
+	clk[IMX6QDL_CLK_PLL5_SEL]  = imx_clk_mux("pll5_sel",  base + 0xa0, 14, 2, pll_av_sels, ARRAY_SIZE(pll_av_sels));
 
 	/*
 	 * lvds1_gate and lvds2_gate are pseudo-gates.  Both can be
@@ -178,6 +184,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 	 */
 	clk[IMX6QDL_CLK_LVDS1_GATE] = imx_clk_gate("lvds1_gate", "lvds1_sel", base + 0x160, 10);
 	clk[IMX6QDL_CLK_LVDS2_GATE] = imx_clk_gate("lvds2_gate", "lvds2_sel", base + 0x160, 11);
+	clk[IMX6QDL_CLK_LVDS1_IN] = imx_clk_gate("lvds1_in", "anaclk1", base + 0x160, 12);
+	clk[IMX6QDL_CLK_LVDS2_IN] = imx_clk_gate("lvds2_in", "anaclk2", base + 0x160, 13);
 
 	/*                                            name              parent_name        reg       idx */
 	clk[IMX6QDL_CLK_PLL2_PFD0_352M] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus",     base + 0x100, 0);
diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h
index 323e865..5519526 100644
--- a/include/dt-bindings/clock/imx6qdl-clock.h
+++ b/include/dt-bindings/clock/imx6qdl-clock.h
@@ -220,6 +220,12 @@
 #define IMX6QDL_CLK_LVDS2_GATE			207
 #define IMX6QDL_CLK_ESAI_IPG			208
 #define IMX6QDL_CLK_ESAI_MEM			209
-#define IMX6QDL_CLK_END				210
+#define IMX6QDL_CLK_LVDS1_IN			210
+#define IMX6QDL_CLK_LVDS2_IN			211
+#define IMX6QDL_CLK_ANACLK1			212
+#define IMX6QDL_CLK_ANACLK2			213
+#define IMX6QDL_CLK_PLL4_SEL			214
+#define IMX6QDL_CLK_PLL5_SEL			215
+#define IMX6QDL_CLK_END				216
 
 #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */
-- 
1.7.9.5


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

* [PATCH V2 2/3] ARM: clk-imx6q: Add missing lvds and anaclk clock to the clock tree
@ 2014-08-06  8:35   ` Shengjiu Wang
  0 siblings, 0 replies; 16+ messages in thread
From: Shengjiu Wang @ 2014-08-06  8:35 UTC (permalink / raw)
  To: linux-arm-kernel

anaclk1 and anaclk2 is the clock source for lvds1_in and lvds2_in. lvds1_in
and lvds2_in can be used to provide external clock source to the internal
pll, such as pll4_audio and pll5_video.
pll4_audio and pll5_video can have multiple source, not only "osc", so
add them.

Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
---
 arch/arm/mach-imx/clk-imx6q.c             |   12 ++++++++++--
 include/dt-bindings/clock/imx6qdl-clock.h |    8 +++++++-
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
index 1d6dd59..330aad3 100644
--- a/arch/arm/mach-imx/clk-imx6q.c
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -73,6 +73,7 @@ static const char *lvds_sels[] = {
 	"pll4_audio", "pll5_video", "pll8_mlb", "enet_ref",
 	"pcie_ref_125m", "sata_ref_100m",
 };
+static const char *pll_av_sels[] = { "osc", "lvds1_in", "lvds2_in", "dummy", };
 
 static struct clk *clk[IMX6QDL_CLK_END];
 static struct clk_onecell_data clk_data;
@@ -119,6 +120,9 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 	clk[IMX6QDL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
 	clk[IMX6QDL_CLK_CKIH] = imx_obtain_fixed_clock("ckih1", 0);
 	clk[IMX6QDL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0);
+	/* Clock source from external clock via ANACLK1/2 PADs */
+	clk[IMX6QDL_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0);
+	clk[IMX6QDL_CLK_ANACLK2] = imx_obtain_fixed_clock("anaclk2", 0);
 
 	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
 	base = of_iomap(np, 0);
@@ -136,8 +140,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 	clk[IMX6QDL_CLK_PLL1_SYS]      = imx_clk_pllv3(IMX_PLLV3_SYS,	"pll1_sys",	"osc", base,        0x7f);
 	clk[IMX6QDL_CLK_PLL2_BUS]      = imx_clk_pllv3(IMX_PLLV3_GENERIC,	"pll2_bus",	"osc", base + 0x30, 0x1);
 	clk[IMX6QDL_CLK_PLL3_USB_OTG]  = imx_clk_pllv3(IMX_PLLV3_USB,	"pll3_usb_otg",	"osc", base + 0x10, 0x3);
-	clk[IMX6QDL_CLK_PLL4_AUDIO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll4_audio",	"osc", base + 0x70, 0x7f);
-	clk[IMX6QDL_CLK_PLL5_VIDEO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll5_video",	"osc", base + 0xa0, 0x7f);
+	clk[IMX6QDL_CLK_PLL4_AUDIO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll4_audio",	"pll4_sel", base + 0x70, 0x7f);
+	clk[IMX6QDL_CLK_PLL5_VIDEO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll5_video",	"pll5_sel", base + 0xa0, 0x7f);
 	clk[IMX6QDL_CLK_PLL6_ENET]     = imx_clk_pllv3(IMX_PLLV3_ENET,	"pll6_enet",	"osc", base + 0xe0, 0x3);
 	clk[IMX6QDL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB,	"pll7_usb_host","osc", base + 0x20, 0x3);
 
@@ -169,6 +173,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 
 	clk[IMX6QDL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
 	clk[IMX6QDL_CLK_LVDS2_SEL] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
+	clk[IMX6QDL_CLK_PLL4_SEL]  = imx_clk_mux("pll4_sel",  base + 0x70, 14, 2, pll_av_sels, ARRAY_SIZE(pll_av_sels));
+	clk[IMX6QDL_CLK_PLL5_SEL]  = imx_clk_mux("pll5_sel",  base + 0xa0, 14, 2, pll_av_sels, ARRAY_SIZE(pll_av_sels));
 
 	/*
 	 * lvds1_gate and lvds2_gate are pseudo-gates.  Both can be
@@ -178,6 +184,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 	 */
 	clk[IMX6QDL_CLK_LVDS1_GATE] = imx_clk_gate("lvds1_gate", "lvds1_sel", base + 0x160, 10);
 	clk[IMX6QDL_CLK_LVDS2_GATE] = imx_clk_gate("lvds2_gate", "lvds2_sel", base + 0x160, 11);
+	clk[IMX6QDL_CLK_LVDS1_IN] = imx_clk_gate("lvds1_in", "anaclk1", base + 0x160, 12);
+	clk[IMX6QDL_CLK_LVDS2_IN] = imx_clk_gate("lvds2_in", "anaclk2", base + 0x160, 13);
 
 	/*                                            name              parent_name        reg       idx */
 	clk[IMX6QDL_CLK_PLL2_PFD0_352M] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus",     base + 0x100, 0);
diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h
index 323e865..5519526 100644
--- a/include/dt-bindings/clock/imx6qdl-clock.h
+++ b/include/dt-bindings/clock/imx6qdl-clock.h
@@ -220,6 +220,12 @@
 #define IMX6QDL_CLK_LVDS2_GATE			207
 #define IMX6QDL_CLK_ESAI_IPG			208
 #define IMX6QDL_CLK_ESAI_MEM			209
-#define IMX6QDL_CLK_END				210
+#define IMX6QDL_CLK_LVDS1_IN			210
+#define IMX6QDL_CLK_LVDS2_IN			211
+#define IMX6QDL_CLK_ANACLK1			212
+#define IMX6QDL_CLK_ANACLK2			213
+#define IMX6QDL_CLK_PLL4_SEL			214
+#define IMX6QDL_CLK_PLL5_SEL			215
+#define IMX6QDL_CLK_END				216
 
 #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */
-- 
1.7.9.5

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

* [PATCH V2 3/3] ARM: imx6q: Add the clock route from external OSC to ESAI clock
  2014-08-06  8:35 ` Shengjiu Wang
@ 2014-08-06  8:35   ` Shengjiu Wang
  -1 siblings, 0 replies; 16+ messages in thread
From: Shengjiu Wang @ 2014-08-06  8:35 UTC (permalink / raw)
  To: shawn.guo, kernel, linux, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: shengjiu.wang, Guangyu.Chen, linux-arm-kernel, linux-kernel

This patch mainly adds the clock route from external 24.576MHz OSC to internal
ESAI clock via analog clock2 PADs on the SoC and pll4 so that ESAI can get an
entirely synchronous clock source against CS42888.

[ 1, We found if using pll4 to generate a 24.576MHz from inernal 24.0MHz OSC,
  we would get noise during the audio playback via ESAI->CS42888 even though
  this generated clock's rate is equal to the external one statistically. It
  might be resulted from the tiny difference between two clock source, which
  might be crucial to the sensitive CODEC we use -- CS42888.

  2, Ideally, we should use bypass mode for pll4 since we only need to get
  the raw rate (24.576MHz) while currently bypass mode in clk-pllv3.c isn't
  supported. After bypass mode implement, then we can refine this patch.]

  Expected result:

  anaclk2                 0           1            24576000
   lvds2_in               0           1            24576000
    pll4_sel              0           1            24576000
     pll4_audio           0           1            786432000
      pll4_post_div       0           1            786432000
       pll4_audio_div     0           1            786432000
        esai_sel          0           1            786432000
         esai_pred        0           1            98304000
          esai_podf       0           1            24576000
           esai_extal     0           1            24576000

Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
---
 arch/arm/mach-imx/clk-imx6q.c  |    5 +++++
 arch/arm/mach-imx/mach-imx6q.c |   28 ++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
index 330aad3..29151cb 100644
--- a/arch/arm/mach-imx/clk-imx6q.c
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -414,6 +414,10 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
 
 	clk_register_clkdev(clk[IMX6QDL_CLK_ENET_REF], "enet_ref", NULL);
+	clk_register_clkdev(clk[IMX6QDL_CLK_PLL4_AUDIO_DIV], "pll4_audio_div", NULL);
+	clk_register_clkdev(clk[IMX6QDL_CLK_PLL4_SEL], "pll4_sel", NULL);
+	clk_register_clkdev(clk[IMX6QDL_CLK_LVDS2_IN], "lvds2_in", NULL);
+	clk_register_clkdev(clk[IMX6QDL_CLK_ESAI_EXTAL], "esai_extal", NULL);
 
 	if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) ||
 	    cpu_is_imx6dl()) {
@@ -457,6 +461,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 
 	/* Audio-related clocks configuration */
 	clk_set_parent(clk[IMX6QDL_CLK_SPDIF_SEL], clk[IMX6QDL_CLK_PLL3_PFD3_454M]);
+	clk_set_parent(clk[IMX6QDL_CLK_ESAI_SEL], clk[IMX6QDL_CLK_PLL4_AUDIO_DIV]);
 
 	/* All existing boards with PCIe use LVDS1 */
 	if (IS_ENABLED(CONFIG_PCI_IMX6))
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index d51c6e9..ea24a96 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -362,6 +362,28 @@ put_node:
 	of_node_put(np);
 }
 
+#define ESAI_AUDIO_MCLK 24576000
+
+static void __init imx6q_audio_lvds2_init(void)
+{
+        struct clk *pll4_sel, *lvds2_in, *pll4_audio_div, *esai_extal;
+
+        pll4_audio_div = clk_get_sys(NULL, "pll4_audio_div");
+        pll4_sel = clk_get_sys(NULL, "pll4_sel");
+        lvds2_in = clk_get_sys(NULL, "lvds2_in");
+        esai_extal = clk_get_sys(NULL, "esai_extal");
+        if (IS_ERR(pll4_audio_div) || IS_ERR(pll4_sel) ||
+            IS_ERR(lvds2_in) || IS_ERR(esai_extal))
+                return;
+
+        if (clk_get_rate(lvds2_in) != ESAI_AUDIO_MCLK)
+                return;
+
+        clk_set_parent(pll4_sel, lvds2_in);
+        clk_set_rate(pll4_audio_div, 786432000);
+        clk_set_rate(esai_extal, ESAI_AUDIO_MCLK);
+}
+
 static struct platform_device imx6q_cpufreq_pdev = {
 	.name = "imx6q-cpufreq",
 };
@@ -379,6 +401,12 @@ static void __init imx6q_init_late(void)
 		imx6q_opp_init();
 		platform_device_register(&imx6q_cpufreq_pdev);
 	}
+
+	if (of_machine_is_compatible("fsl,imx6q-sabreauto")
+		|| of_machine_is_compatible("fsl,imx6dl-sabreauto")) {
+		imx6q_audio_lvds2_init();
+	}
+
 }
 
 static void __init imx6q_map_io(void)
-- 
1.7.9.5


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

* [PATCH V2 3/3] ARM: imx6q: Add the clock route from external OSC to ESAI clock
@ 2014-08-06  8:35   ` Shengjiu Wang
  0 siblings, 0 replies; 16+ messages in thread
From: Shengjiu Wang @ 2014-08-06  8:35 UTC (permalink / raw)
  To: linux-arm-kernel

This patch mainly adds the clock route from external 24.576MHz OSC to internal
ESAI clock via analog clock2 PADs on the SoC and pll4 so that ESAI can get an
entirely synchronous clock source against CS42888.

[ 1, We found if using pll4 to generate a 24.576MHz from inernal 24.0MHz OSC,
  we would get noise during the audio playback via ESAI->CS42888 even though
  this generated clock's rate is equal to the external one statistically. It
  might be resulted from the tiny difference between two clock source, which
  might be crucial to the sensitive CODEC we use -- CS42888.

  2, Ideally, we should use bypass mode for pll4 since we only need to get
  the raw rate (24.576MHz) while currently bypass mode in clk-pllv3.c isn't
  supported. After bypass mode implement, then we can refine this patch.]

  Expected result:

  anaclk2                 0           1            24576000
   lvds2_in               0           1            24576000
    pll4_sel              0           1            24576000
     pll4_audio           0           1            786432000
      pll4_post_div       0           1            786432000
       pll4_audio_div     0           1            786432000
        esai_sel          0           1            786432000
         esai_pred        0           1            98304000
          esai_podf       0           1            24576000
           esai_extal     0           1            24576000

Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
---
 arch/arm/mach-imx/clk-imx6q.c  |    5 +++++
 arch/arm/mach-imx/mach-imx6q.c |   28 ++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
index 330aad3..29151cb 100644
--- a/arch/arm/mach-imx/clk-imx6q.c
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -414,6 +414,10 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
 
 	clk_register_clkdev(clk[IMX6QDL_CLK_ENET_REF], "enet_ref", NULL);
+	clk_register_clkdev(clk[IMX6QDL_CLK_PLL4_AUDIO_DIV], "pll4_audio_div", NULL);
+	clk_register_clkdev(clk[IMX6QDL_CLK_PLL4_SEL], "pll4_sel", NULL);
+	clk_register_clkdev(clk[IMX6QDL_CLK_LVDS2_IN], "lvds2_in", NULL);
+	clk_register_clkdev(clk[IMX6QDL_CLK_ESAI_EXTAL], "esai_extal", NULL);
 
 	if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) ||
 	    cpu_is_imx6dl()) {
@@ -457,6 +461,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 
 	/* Audio-related clocks configuration */
 	clk_set_parent(clk[IMX6QDL_CLK_SPDIF_SEL], clk[IMX6QDL_CLK_PLL3_PFD3_454M]);
+	clk_set_parent(clk[IMX6QDL_CLK_ESAI_SEL], clk[IMX6QDL_CLK_PLL4_AUDIO_DIV]);
 
 	/* All existing boards with PCIe use LVDS1 */
 	if (IS_ENABLED(CONFIG_PCI_IMX6))
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index d51c6e9..ea24a96 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -362,6 +362,28 @@ put_node:
 	of_node_put(np);
 }
 
+#define ESAI_AUDIO_MCLK 24576000
+
+static void __init imx6q_audio_lvds2_init(void)
+{
+        struct clk *pll4_sel, *lvds2_in, *pll4_audio_div, *esai_extal;
+
+        pll4_audio_div = clk_get_sys(NULL, "pll4_audio_div");
+        pll4_sel = clk_get_sys(NULL, "pll4_sel");
+        lvds2_in = clk_get_sys(NULL, "lvds2_in");
+        esai_extal = clk_get_sys(NULL, "esai_extal");
+        if (IS_ERR(pll4_audio_div) || IS_ERR(pll4_sel) ||
+            IS_ERR(lvds2_in) || IS_ERR(esai_extal))
+                return;
+
+        if (clk_get_rate(lvds2_in) != ESAI_AUDIO_MCLK)
+                return;
+
+        clk_set_parent(pll4_sel, lvds2_in);
+        clk_set_rate(pll4_audio_div, 786432000);
+        clk_set_rate(esai_extal, ESAI_AUDIO_MCLK);
+}
+
 static struct platform_device imx6q_cpufreq_pdev = {
 	.name = "imx6q-cpufreq",
 };
@@ -379,6 +401,12 @@ static void __init imx6q_init_late(void)
 		imx6q_opp_init();
 		platform_device_register(&imx6q_cpufreq_pdev);
 	}
+
+	if (of_machine_is_compatible("fsl,imx6q-sabreauto")
+		|| of_machine_is_compatible("fsl,imx6dl-sabreauto")) {
+		imx6q_audio_lvds2_init();
+	}
+
 }
 
 static void __init imx6q_map_io(void)
-- 
1.7.9.5

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

* Re: [PATCH V2 2/3] ARM: clk-imx6q: Add missing lvds and anaclk clock to the clock tree
  2014-08-06  8:35   ` Shengjiu Wang
@ 2014-08-06 14:42     ` Lucas Stach
  -1 siblings, 0 replies; 16+ messages in thread
From: Lucas Stach @ 2014-08-06 14:42 UTC (permalink / raw)
  To: Shengjiu Wang
  Cc: shawn.guo, kernel, linux, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak, Guangyu.Chen, linux-arm-kernel,
	linux-kernel

Am Mittwoch, den 06.08.2014, 16:35 +0800 schrieb Shengjiu Wang:
> anaclk1 and anaclk2 is the clock source for lvds1_in and lvds2_in. lvds1_in
> and lvds2_in can be used to provide external clock source to the internal
> pll, such as pll4_audio and pll5_video.
> pll4_audio and pll5_video can have multiple source, not only "osc", so
> add them.
> 
> Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
> ---
>  arch/arm/mach-imx/clk-imx6q.c             |   12 ++++++++++--
>  include/dt-bindings/clock/imx6qdl-clock.h |    8 +++++++-
>  2 files changed, 17 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
> index 1d6dd59..330aad3 100644
> --- a/arch/arm/mach-imx/clk-imx6q.c
> +++ b/arch/arm/mach-imx/clk-imx6q.c
> @@ -73,6 +73,7 @@ static const char *lvds_sels[] = {
>  	"pll4_audio", "pll5_video", "pll8_mlb", "enet_ref",
>  	"pcie_ref_125m", "sata_ref_100m",
>  };
> +static const char *pll_av_sels[] = { "osc", "lvds1_in", "lvds2_in", "dummy", };
>  
>  static struct clk *clk[IMX6QDL_CLK_END];
>  static struct clk_onecell_data clk_data;
> @@ -119,6 +120,9 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
>  	clk[IMX6QDL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
>  	clk[IMX6QDL_CLK_CKIH] = imx_obtain_fixed_clock("ckih1", 0);
>  	clk[IMX6QDL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0);
> +	/* Clock source from external clock via ANACLK1/2 PADs */
> +	clk[IMX6QDL_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0);
> +	clk[IMX6QDL_CLK_ANACLK2] = imx_obtain_fixed_clock("anaclk2", 0);
>  
>  	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
>  	base = of_iomap(np, 0);
> @@ -136,8 +140,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
>  	clk[IMX6QDL_CLK_PLL1_SYS]      = imx_clk_pllv3(IMX_PLLV3_SYS,	"pll1_sys",	"osc", base,        0x7f);
>  	clk[IMX6QDL_CLK_PLL2_BUS]      = imx_clk_pllv3(IMX_PLLV3_GENERIC,	"pll2_bus",	"osc", base + 0x30, 0x1);
>  	clk[IMX6QDL_CLK_PLL3_USB_OTG]  = imx_clk_pllv3(IMX_PLLV3_USB,	"pll3_usb_otg",	"osc", base + 0x10, 0x3);
> -	clk[IMX6QDL_CLK_PLL4_AUDIO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll4_audio",	"osc", base + 0x70, 0x7f);
> -	clk[IMX6QDL_CLK_PLL5_VIDEO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll5_video",	"osc", base + 0xa0, 0x7f);
> +	clk[IMX6QDL_CLK_PLL4_AUDIO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll4_audio",	"pll4_sel", base + 0x70, 0x7f);
> +	clk[IMX6QDL_CLK_PLL5_VIDEO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll5_video",	"pll5_sel", base + 0xa0, 0x7f);
>  	clk[IMX6QDL_CLK_PLL6_ENET]     = imx_clk_pllv3(IMX_PLLV3_ENET,	"pll6_enet",	"osc", base + 0xe0, 0x3);
>  	clk[IMX6QDL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB,	"pll7_usb_host","osc", base + 0x20, 0x3);
>  
> @@ -169,6 +173,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
>  
>  	clk[IMX6QDL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
>  	clk[IMX6QDL_CLK_LVDS2_SEL] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
> +	clk[IMX6QDL_CLK_PLL4_SEL]  = imx_clk_mux("pll4_sel",  base + 0x70, 14, 2, pll_av_sels, ARRAY_SIZE(pll_av_sels));
> +	clk[IMX6QDL_CLK_PLL5_SEL]  = imx_clk_mux("pll5_sel",  base + 0xa0, 14, 2, pll_av_sels, ARRAY_SIZE(pll_av_sels));
>  
>  	/*
>  	 * lvds1_gate and lvds2_gate are pseudo-gates.  Both can be
> @@ -178,6 +184,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
>  	 */
>  	clk[IMX6QDL_CLK_LVDS1_GATE] = imx_clk_gate("lvds1_gate", "lvds1_sel", base + 0x160, 10);
>  	clk[IMX6QDL_CLK_LVDS2_GATE] = imx_clk_gate("lvds2_gate", "lvds2_sel", base + 0x160, 11);
> +	clk[IMX6QDL_CLK_LVDS1_IN] = imx_clk_gate("lvds1_in", "anaclk1", base + 0x160, 12);
> +	clk[IMX6QDL_CLK_LVDS2_IN] = imx_clk_gate("lvds2_in", "anaclk2", base + 0x160, 13);
>  
I think we need something more clever here. With both lvds in and out
modeled as a clock gate it is possible for the user to enable both at
the same time. The reference manual on the contrary states that both
states are mutually exclusive: "Do not enable input and output buffers
simultaneously".

Regards,
Lucas
-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |


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

* [PATCH V2 2/3] ARM: clk-imx6q: Add missing lvds and anaclk clock to the clock tree
@ 2014-08-06 14:42     ` Lucas Stach
  0 siblings, 0 replies; 16+ messages in thread
From: Lucas Stach @ 2014-08-06 14:42 UTC (permalink / raw)
  To: linux-arm-kernel

Am Mittwoch, den 06.08.2014, 16:35 +0800 schrieb Shengjiu Wang:
> anaclk1 and anaclk2 is the clock source for lvds1_in and lvds2_in. lvds1_in
> and lvds2_in can be used to provide external clock source to the internal
> pll, such as pll4_audio and pll5_video.
> pll4_audio and pll5_video can have multiple source, not only "osc", so
> add them.
> 
> Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
> ---
>  arch/arm/mach-imx/clk-imx6q.c             |   12 ++++++++++--
>  include/dt-bindings/clock/imx6qdl-clock.h |    8 +++++++-
>  2 files changed, 17 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
> index 1d6dd59..330aad3 100644
> --- a/arch/arm/mach-imx/clk-imx6q.c
> +++ b/arch/arm/mach-imx/clk-imx6q.c
> @@ -73,6 +73,7 @@ static const char *lvds_sels[] = {
>  	"pll4_audio", "pll5_video", "pll8_mlb", "enet_ref",
>  	"pcie_ref_125m", "sata_ref_100m",
>  };
> +static const char *pll_av_sels[] = { "osc", "lvds1_in", "lvds2_in", "dummy", };
>  
>  static struct clk *clk[IMX6QDL_CLK_END];
>  static struct clk_onecell_data clk_data;
> @@ -119,6 +120,9 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
>  	clk[IMX6QDL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
>  	clk[IMX6QDL_CLK_CKIH] = imx_obtain_fixed_clock("ckih1", 0);
>  	clk[IMX6QDL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0);
> +	/* Clock source from external clock via ANACLK1/2 PADs */
> +	clk[IMX6QDL_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0);
> +	clk[IMX6QDL_CLK_ANACLK2] = imx_obtain_fixed_clock("anaclk2", 0);
>  
>  	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
>  	base = of_iomap(np, 0);
> @@ -136,8 +140,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
>  	clk[IMX6QDL_CLK_PLL1_SYS]      = imx_clk_pllv3(IMX_PLLV3_SYS,	"pll1_sys",	"osc", base,        0x7f);
>  	clk[IMX6QDL_CLK_PLL2_BUS]      = imx_clk_pllv3(IMX_PLLV3_GENERIC,	"pll2_bus",	"osc", base + 0x30, 0x1);
>  	clk[IMX6QDL_CLK_PLL3_USB_OTG]  = imx_clk_pllv3(IMX_PLLV3_USB,	"pll3_usb_otg",	"osc", base + 0x10, 0x3);
> -	clk[IMX6QDL_CLK_PLL4_AUDIO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll4_audio",	"osc", base + 0x70, 0x7f);
> -	clk[IMX6QDL_CLK_PLL5_VIDEO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll5_video",	"osc", base + 0xa0, 0x7f);
> +	clk[IMX6QDL_CLK_PLL4_AUDIO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll4_audio",	"pll4_sel", base + 0x70, 0x7f);
> +	clk[IMX6QDL_CLK_PLL5_VIDEO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll5_video",	"pll5_sel", base + 0xa0, 0x7f);
>  	clk[IMX6QDL_CLK_PLL6_ENET]     = imx_clk_pllv3(IMX_PLLV3_ENET,	"pll6_enet",	"osc", base + 0xe0, 0x3);
>  	clk[IMX6QDL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB,	"pll7_usb_host","osc", base + 0x20, 0x3);
>  
> @@ -169,6 +173,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
>  
>  	clk[IMX6QDL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
>  	clk[IMX6QDL_CLK_LVDS2_SEL] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
> +	clk[IMX6QDL_CLK_PLL4_SEL]  = imx_clk_mux("pll4_sel",  base + 0x70, 14, 2, pll_av_sels, ARRAY_SIZE(pll_av_sels));
> +	clk[IMX6QDL_CLK_PLL5_SEL]  = imx_clk_mux("pll5_sel",  base + 0xa0, 14, 2, pll_av_sels, ARRAY_SIZE(pll_av_sels));
>  
>  	/*
>  	 * lvds1_gate and lvds2_gate are pseudo-gates.  Both can be
> @@ -178,6 +184,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
>  	 */
>  	clk[IMX6QDL_CLK_LVDS1_GATE] = imx_clk_gate("lvds1_gate", "lvds1_sel", base + 0x160, 10);
>  	clk[IMX6QDL_CLK_LVDS2_GATE] = imx_clk_gate("lvds2_gate", "lvds2_sel", base + 0x160, 11);
> +	clk[IMX6QDL_CLK_LVDS1_IN] = imx_clk_gate("lvds1_in", "anaclk1", base + 0x160, 12);
> +	clk[IMX6QDL_CLK_LVDS2_IN] = imx_clk_gate("lvds2_in", "anaclk2", base + 0x160, 13);
>  
I think we need something more clever here. With both lvds in and out
modeled as a clock gate it is possible for the user to enable both at
the same time. The reference manual on the contrary states that both
states are mutually exclusive: "Do not enable input and output buffers
simultaneously".

Regards,
Lucas
-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |

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

* Re: [PATCH V2 3/3] ARM: imx6q: Add the clock route from external OSC to ESAI clock
  2014-08-06  8:35   ` Shengjiu Wang
@ 2014-08-07  3:11     ` Shawn Guo
  -1 siblings, 0 replies; 16+ messages in thread
From: Shawn Guo @ 2014-08-07  3:11 UTC (permalink / raw)
  To: Shengjiu Wang
  Cc: kernel, linux, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, Guangyu.Chen, linux-arm-kernel, linux-kernel

On Wed, Aug 06, 2014 at 04:35:15PM +0800, Shengjiu Wang wrote:
> This patch mainly adds the clock route from external 24.576MHz OSC to internal
> ESAI clock via analog clock2 PADs on the SoC and pll4 so that ESAI can get an
> entirely synchronous clock source against CS42888.
> 
> [ 1, We found if using pll4 to generate a 24.576MHz from inernal 24.0MHz OSC,
>   we would get noise during the audio playback via ESAI->CS42888 even though
>   this generated clock's rate is equal to the external one statistically. It
>   might be resulted from the tiny difference between two clock source, which
>   might be crucial to the sensitive CODEC we use -- CS42888.
> 
>   2, Ideally, we should use bypass mode for pll4 since we only need to get
>   the raw rate (24.576MHz) while currently bypass mode in clk-pllv3.c isn't
>   supported. After bypass mode implement, then we can refine this patch.]

I meant we should implement bypass mode first.  I will give it a try.

Shawn

> 
>   Expected result:
> 
>   anaclk2                 0           1            24576000
>    lvds2_in               0           1            24576000
>     pll4_sel              0           1            24576000
>      pll4_audio           0           1            786432000
>       pll4_post_div       0           1            786432000
>        pll4_audio_div     0           1            786432000
>         esai_sel          0           1            786432000
>          esai_pred        0           1            98304000
>           esai_podf       0           1            24576000
>            esai_extal     0           1            24576000
> 
> Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
> ---
>  arch/arm/mach-imx/clk-imx6q.c  |    5 +++++
>  arch/arm/mach-imx/mach-imx6q.c |   28 ++++++++++++++++++++++++++++
>  2 files changed, 33 insertions(+)
> 
> diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
> index 330aad3..29151cb 100644
> --- a/arch/arm/mach-imx/clk-imx6q.c
> +++ b/arch/arm/mach-imx/clk-imx6q.c
> @@ -414,6 +414,10 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
>  	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
>  
>  	clk_register_clkdev(clk[IMX6QDL_CLK_ENET_REF], "enet_ref", NULL);
> +	clk_register_clkdev(clk[IMX6QDL_CLK_PLL4_AUDIO_DIV], "pll4_audio_div", NULL);
> +	clk_register_clkdev(clk[IMX6QDL_CLK_PLL4_SEL], "pll4_sel", NULL);
> +	clk_register_clkdev(clk[IMX6QDL_CLK_LVDS2_IN], "lvds2_in", NULL);
> +	clk_register_clkdev(clk[IMX6QDL_CLK_ESAI_EXTAL], "esai_extal", NULL);
>  
>  	if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) ||
>  	    cpu_is_imx6dl()) {
> @@ -457,6 +461,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
>  
>  	/* Audio-related clocks configuration */
>  	clk_set_parent(clk[IMX6QDL_CLK_SPDIF_SEL], clk[IMX6QDL_CLK_PLL3_PFD3_454M]);
> +	clk_set_parent(clk[IMX6QDL_CLK_ESAI_SEL], clk[IMX6QDL_CLK_PLL4_AUDIO_DIV]);
>  
>  	/* All existing boards with PCIe use LVDS1 */
>  	if (IS_ENABLED(CONFIG_PCI_IMX6))
> diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
> index d51c6e9..ea24a96 100644
> --- a/arch/arm/mach-imx/mach-imx6q.c
> +++ b/arch/arm/mach-imx/mach-imx6q.c
> @@ -362,6 +362,28 @@ put_node:
>  	of_node_put(np);
>  }
>  
> +#define ESAI_AUDIO_MCLK 24576000
> +
> +static void __init imx6q_audio_lvds2_init(void)
> +{
> +        struct clk *pll4_sel, *lvds2_in, *pll4_audio_div, *esai_extal;
> +
> +        pll4_audio_div = clk_get_sys(NULL, "pll4_audio_div");
> +        pll4_sel = clk_get_sys(NULL, "pll4_sel");
> +        lvds2_in = clk_get_sys(NULL, "lvds2_in");
> +        esai_extal = clk_get_sys(NULL, "esai_extal");
> +        if (IS_ERR(pll4_audio_div) || IS_ERR(pll4_sel) ||
> +            IS_ERR(lvds2_in) || IS_ERR(esai_extal))
> +                return;
> +
> +        if (clk_get_rate(lvds2_in) != ESAI_AUDIO_MCLK)
> +                return;
> +
> +        clk_set_parent(pll4_sel, lvds2_in);
> +        clk_set_rate(pll4_audio_div, 786432000);
> +        clk_set_rate(esai_extal, ESAI_AUDIO_MCLK);
> +}
> +
>  static struct platform_device imx6q_cpufreq_pdev = {
>  	.name = "imx6q-cpufreq",
>  };
> @@ -379,6 +401,12 @@ static void __init imx6q_init_late(void)
>  		imx6q_opp_init();
>  		platform_device_register(&imx6q_cpufreq_pdev);
>  	}
> +
> +	if (of_machine_is_compatible("fsl,imx6q-sabreauto")
> +		|| of_machine_is_compatible("fsl,imx6dl-sabreauto")) {
> +		imx6q_audio_lvds2_init();
> +	}
> +
>  }
>  
>  static void __init imx6q_map_io(void)
> -- 
> 1.7.9.5
> 

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

* [PATCH V2 3/3] ARM: imx6q: Add the clock route from external OSC to ESAI clock
@ 2014-08-07  3:11     ` Shawn Guo
  0 siblings, 0 replies; 16+ messages in thread
From: Shawn Guo @ 2014-08-07  3:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Aug 06, 2014 at 04:35:15PM +0800, Shengjiu Wang wrote:
> This patch mainly adds the clock route from external 24.576MHz OSC to internal
> ESAI clock via analog clock2 PADs on the SoC and pll4 so that ESAI can get an
> entirely synchronous clock source against CS42888.
> 
> [ 1, We found if using pll4 to generate a 24.576MHz from inernal 24.0MHz OSC,
>   we would get noise during the audio playback via ESAI->CS42888 even though
>   this generated clock's rate is equal to the external one statistically. It
>   might be resulted from the tiny difference between two clock source, which
>   might be crucial to the sensitive CODEC we use -- CS42888.
> 
>   2, Ideally, we should use bypass mode for pll4 since we only need to get
>   the raw rate (24.576MHz) while currently bypass mode in clk-pllv3.c isn't
>   supported. After bypass mode implement, then we can refine this patch.]

I meant we should implement bypass mode first.  I will give it a try.

Shawn

> 
>   Expected result:
> 
>   anaclk2                 0           1            24576000
>    lvds2_in               0           1            24576000
>     pll4_sel              0           1            24576000
>      pll4_audio           0           1            786432000
>       pll4_post_div       0           1            786432000
>        pll4_audio_div     0           1            786432000
>         esai_sel          0           1            786432000
>          esai_pred        0           1            98304000
>           esai_podf       0           1            24576000
>            esai_extal     0           1            24576000
> 
> Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
> ---
>  arch/arm/mach-imx/clk-imx6q.c  |    5 +++++
>  arch/arm/mach-imx/mach-imx6q.c |   28 ++++++++++++++++++++++++++++
>  2 files changed, 33 insertions(+)
> 
> diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
> index 330aad3..29151cb 100644
> --- a/arch/arm/mach-imx/clk-imx6q.c
> +++ b/arch/arm/mach-imx/clk-imx6q.c
> @@ -414,6 +414,10 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
>  	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
>  
>  	clk_register_clkdev(clk[IMX6QDL_CLK_ENET_REF], "enet_ref", NULL);
> +	clk_register_clkdev(clk[IMX6QDL_CLK_PLL4_AUDIO_DIV], "pll4_audio_div", NULL);
> +	clk_register_clkdev(clk[IMX6QDL_CLK_PLL4_SEL], "pll4_sel", NULL);
> +	clk_register_clkdev(clk[IMX6QDL_CLK_LVDS2_IN], "lvds2_in", NULL);
> +	clk_register_clkdev(clk[IMX6QDL_CLK_ESAI_EXTAL], "esai_extal", NULL);
>  
>  	if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) ||
>  	    cpu_is_imx6dl()) {
> @@ -457,6 +461,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
>  
>  	/* Audio-related clocks configuration */
>  	clk_set_parent(clk[IMX6QDL_CLK_SPDIF_SEL], clk[IMX6QDL_CLK_PLL3_PFD3_454M]);
> +	clk_set_parent(clk[IMX6QDL_CLK_ESAI_SEL], clk[IMX6QDL_CLK_PLL4_AUDIO_DIV]);
>  
>  	/* All existing boards with PCIe use LVDS1 */
>  	if (IS_ENABLED(CONFIG_PCI_IMX6))
> diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
> index d51c6e9..ea24a96 100644
> --- a/arch/arm/mach-imx/mach-imx6q.c
> +++ b/arch/arm/mach-imx/mach-imx6q.c
> @@ -362,6 +362,28 @@ put_node:
>  	of_node_put(np);
>  }
>  
> +#define ESAI_AUDIO_MCLK 24576000
> +
> +static void __init imx6q_audio_lvds2_init(void)
> +{
> +        struct clk *pll4_sel, *lvds2_in, *pll4_audio_div, *esai_extal;
> +
> +        pll4_audio_div = clk_get_sys(NULL, "pll4_audio_div");
> +        pll4_sel = clk_get_sys(NULL, "pll4_sel");
> +        lvds2_in = clk_get_sys(NULL, "lvds2_in");
> +        esai_extal = clk_get_sys(NULL, "esai_extal");
> +        if (IS_ERR(pll4_audio_div) || IS_ERR(pll4_sel) ||
> +            IS_ERR(lvds2_in) || IS_ERR(esai_extal))
> +                return;
> +
> +        if (clk_get_rate(lvds2_in) != ESAI_AUDIO_MCLK)
> +                return;
> +
> +        clk_set_parent(pll4_sel, lvds2_in);
> +        clk_set_rate(pll4_audio_div, 786432000);
> +        clk_set_rate(esai_extal, ESAI_AUDIO_MCLK);
> +}
> +
>  static struct platform_device imx6q_cpufreq_pdev = {
>  	.name = "imx6q-cpufreq",
>  };
> @@ -379,6 +401,12 @@ static void __init imx6q_init_late(void)
>  		imx6q_opp_init();
>  		platform_device_register(&imx6q_cpufreq_pdev);
>  	}
> +
> +	if (of_machine_is_compatible("fsl,imx6q-sabreauto")
> +		|| of_machine_is_compatible("fsl,imx6dl-sabreauto")) {
> +		imx6q_audio_lvds2_init();
> +	}
> +
>  }
>  
>  static void __init imx6q_map_io(void)
> -- 
> 1.7.9.5
> 

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

* RE: [PATCH V2 3/3] ARM: imx6q: Add the clock route from external OSC to ESAI clock
  2014-08-07  3:11     ` Shawn Guo
@ 2014-08-07  3:14       ` shengjiu.wang at freescale.com
  -1 siblings, 0 replies; 16+ messages in thread
From: shengjiu.wang @ 2014-08-07  3:14 UTC (permalink / raw)
  To: Shawn Guo
  Cc: kernel, linux, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, guangyu.chen, linux-arm-kernel, linux-kernel

Ok, thanks.

-----Original Message-----
From: Shawn Guo [mailto:shawn.guo@freescale.com] 
Sent: Thursday, August 07, 2014 11:12 AM
To: Wang Shengjiu-B02247
Cc: kernel@pengutronix.de; linux@arm.linux.org.uk; robh+dt@kernel.org; pawel.moll@arm.com; mark.rutland@arm.com; ijc+devicetree@hellion.org.uk; galak@codeaurora.org; Chen Guangyu-B42378; linux-arm-kernel@lists.infradead.org; linux-kernel@vger.kernel.org
Subject: Re: [PATCH V2 3/3] ARM: imx6q: Add the clock route from external OSC to ESAI clock

On Wed, Aug 06, 2014 at 04:35:15PM +0800, Shengjiu Wang wrote:
> This patch mainly adds the clock route from external 24.576MHz OSC to 
> internal ESAI clock via analog clock2 PADs on the SoC and pll4 so that 
> ESAI can get an entirely synchronous clock source against CS42888.
> 
> [ 1, We found if using pll4 to generate a 24.576MHz from inernal 24.0MHz OSC,
>   we would get noise during the audio playback via ESAI->CS42888 even though
>   this generated clock's rate is equal to the external one statistically. It
>   might be resulted from the tiny difference between two clock source, which
>   might be crucial to the sensitive CODEC we use -- CS42888.
> 
>   2, Ideally, we should use bypass mode for pll4 since we only need to get
>   the raw rate (24.576MHz) while currently bypass mode in clk-pllv3.c isn't
>   supported. After bypass mode implement, then we can refine this 
> patch.]

I meant we should implement bypass mode first.  I will give it a try.

Shawn

> 
>   Expected result:
> 
>   anaclk2                 0           1            24576000
>    lvds2_in               0           1            24576000
>     pll4_sel              0           1            24576000
>      pll4_audio           0           1            786432000
>       pll4_post_div       0           1            786432000
>        pll4_audio_div     0           1            786432000
>         esai_sel          0           1            786432000
>          esai_pred        0           1            98304000
>           esai_podf       0           1            24576000
>            esai_extal     0           1            24576000
> 
> Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
> ---
>  arch/arm/mach-imx/clk-imx6q.c  |    5 +++++
>  arch/arm/mach-imx/mach-imx6q.c |   28 ++++++++++++++++++++++++++++
>  2 files changed, 33 insertions(+)
> 
> diff --git a/arch/arm/mach-imx/clk-imx6q.c 
> b/arch/arm/mach-imx/clk-imx6q.c index 330aad3..29151cb 100644
> --- a/arch/arm/mach-imx/clk-imx6q.c
> +++ b/arch/arm/mach-imx/clk-imx6q.c
> @@ -414,6 +414,10 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
>  	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
>  
>  	clk_register_clkdev(clk[IMX6QDL_CLK_ENET_REF], "enet_ref", NULL);
> +	clk_register_clkdev(clk[IMX6QDL_CLK_PLL4_AUDIO_DIV], "pll4_audio_div", NULL);
> +	clk_register_clkdev(clk[IMX6QDL_CLK_PLL4_SEL], "pll4_sel", NULL);
> +	clk_register_clkdev(clk[IMX6QDL_CLK_LVDS2_IN], "lvds2_in", NULL);
> +	clk_register_clkdev(clk[IMX6QDL_CLK_ESAI_EXTAL], "esai_extal", 
> +NULL);
>  
>  	if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) ||
>  	    cpu_is_imx6dl()) {
> @@ -457,6 +461,7 @@ static void __init imx6q_clocks_init(struct 
> device_node *ccm_node)
>  
>  	/* Audio-related clocks configuration */
>  	clk_set_parent(clk[IMX6QDL_CLK_SPDIF_SEL], 
> clk[IMX6QDL_CLK_PLL3_PFD3_454M]);
> +	clk_set_parent(clk[IMX6QDL_CLK_ESAI_SEL], 
> +clk[IMX6QDL_CLK_PLL4_AUDIO_DIV]);
>  
>  	/* All existing boards with PCIe use LVDS1 */
>  	if (IS_ENABLED(CONFIG_PCI_IMX6))
> diff --git a/arch/arm/mach-imx/mach-imx6q.c 
> b/arch/arm/mach-imx/mach-imx6q.c index d51c6e9..ea24a96 100644
> --- a/arch/arm/mach-imx/mach-imx6q.c
> +++ b/arch/arm/mach-imx/mach-imx6q.c
> @@ -362,6 +362,28 @@ put_node:
>  	of_node_put(np);
>  }
>  
> +#define ESAI_AUDIO_MCLK 24576000
> +
> +static void __init imx6q_audio_lvds2_init(void) {
> +        struct clk *pll4_sel, *lvds2_in, *pll4_audio_div, 
> +*esai_extal;
> +
> +        pll4_audio_div = clk_get_sys(NULL, "pll4_audio_div");
> +        pll4_sel = clk_get_sys(NULL, "pll4_sel");
> +        lvds2_in = clk_get_sys(NULL, "lvds2_in");
> +        esai_extal = clk_get_sys(NULL, "esai_extal");
> +        if (IS_ERR(pll4_audio_div) || IS_ERR(pll4_sel) ||
> +            IS_ERR(lvds2_in) || IS_ERR(esai_extal))
> +                return;
> +
> +        if (clk_get_rate(lvds2_in) != ESAI_AUDIO_MCLK)
> +                return;
> +
> +        clk_set_parent(pll4_sel, lvds2_in);
> +        clk_set_rate(pll4_audio_div, 786432000);
> +        clk_set_rate(esai_extal, ESAI_AUDIO_MCLK); }
> +
>  static struct platform_device imx6q_cpufreq_pdev = {
>  	.name = "imx6q-cpufreq",
>  };
> @@ -379,6 +401,12 @@ static void __init imx6q_init_late(void)
>  		imx6q_opp_init();
>  		platform_device_register(&imx6q_cpufreq_pdev);
>  	}
> +
> +	if (of_machine_is_compatible("fsl,imx6q-sabreauto")
> +		|| of_machine_is_compatible("fsl,imx6dl-sabreauto")) {
> +		imx6q_audio_lvds2_init();
> +	}
> +
>  }
>  
>  static void __init imx6q_map_io(void)
> --
> 1.7.9.5
> 

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

* [PATCH V2 3/3] ARM: imx6q: Add the clock route from external OSC to ESAI clock
@ 2014-08-07  3:14       ` shengjiu.wang at freescale.com
  0 siblings, 0 replies; 16+ messages in thread
From: shengjiu.wang at freescale.com @ 2014-08-07  3:14 UTC (permalink / raw)
  To: linux-arm-kernel

Ok, thanks.

-----Original Message-----
From: Shawn Guo [mailto:shawn.guo at freescale.com] 
Sent: Thursday, August 07, 2014 11:12 AM
To: Wang Shengjiu-B02247
Cc: kernel at pengutronix.de; linux at arm.linux.org.uk; robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com; ijc+devicetree at hellion.org.uk; galak at codeaurora.org; Chen Guangyu-B42378; linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org
Subject: Re: [PATCH V2 3/3] ARM: imx6q: Add the clock route from external OSC to ESAI clock

On Wed, Aug 06, 2014 at 04:35:15PM +0800, Shengjiu Wang wrote:
> This patch mainly adds the clock route from external 24.576MHz OSC to 
> internal ESAI clock via analog clock2 PADs on the SoC and pll4 so that 
> ESAI can get an entirely synchronous clock source against CS42888.
> 
> [ 1, We found if using pll4 to generate a 24.576MHz from inernal 24.0MHz OSC,
>   we would get noise during the audio playback via ESAI->CS42888 even though
>   this generated clock's rate is equal to the external one statistically. It
>   might be resulted from the tiny difference between two clock source, which
>   might be crucial to the sensitive CODEC we use -- CS42888.
> 
>   2, Ideally, we should use bypass mode for pll4 since we only need to get
>   the raw rate (24.576MHz) while currently bypass mode in clk-pllv3.c isn't
>   supported. After bypass mode implement, then we can refine this 
> patch.]

I meant we should implement bypass mode first.  I will give it a try.

Shawn

> 
>   Expected result:
> 
>   anaclk2                 0           1            24576000
>    lvds2_in               0           1            24576000
>     pll4_sel              0           1            24576000
>      pll4_audio           0           1            786432000
>       pll4_post_div       0           1            786432000
>        pll4_audio_div     0           1            786432000
>         esai_sel          0           1            786432000
>          esai_pred        0           1            98304000
>           esai_podf       0           1            24576000
>            esai_extal     0           1            24576000
> 
> Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
> ---
>  arch/arm/mach-imx/clk-imx6q.c  |    5 +++++
>  arch/arm/mach-imx/mach-imx6q.c |   28 ++++++++++++++++++++++++++++
>  2 files changed, 33 insertions(+)
> 
> diff --git a/arch/arm/mach-imx/clk-imx6q.c 
> b/arch/arm/mach-imx/clk-imx6q.c index 330aad3..29151cb 100644
> --- a/arch/arm/mach-imx/clk-imx6q.c
> +++ b/arch/arm/mach-imx/clk-imx6q.c
> @@ -414,6 +414,10 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
>  	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
>  
>  	clk_register_clkdev(clk[IMX6QDL_CLK_ENET_REF], "enet_ref", NULL);
> +	clk_register_clkdev(clk[IMX6QDL_CLK_PLL4_AUDIO_DIV], "pll4_audio_div", NULL);
> +	clk_register_clkdev(clk[IMX6QDL_CLK_PLL4_SEL], "pll4_sel", NULL);
> +	clk_register_clkdev(clk[IMX6QDL_CLK_LVDS2_IN], "lvds2_in", NULL);
> +	clk_register_clkdev(clk[IMX6QDL_CLK_ESAI_EXTAL], "esai_extal", 
> +NULL);
>  
>  	if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) ||
>  	    cpu_is_imx6dl()) {
> @@ -457,6 +461,7 @@ static void __init imx6q_clocks_init(struct 
> device_node *ccm_node)
>  
>  	/* Audio-related clocks configuration */
>  	clk_set_parent(clk[IMX6QDL_CLK_SPDIF_SEL], 
> clk[IMX6QDL_CLK_PLL3_PFD3_454M]);
> +	clk_set_parent(clk[IMX6QDL_CLK_ESAI_SEL], 
> +clk[IMX6QDL_CLK_PLL4_AUDIO_DIV]);
>  
>  	/* All existing boards with PCIe use LVDS1 */
>  	if (IS_ENABLED(CONFIG_PCI_IMX6))
> diff --git a/arch/arm/mach-imx/mach-imx6q.c 
> b/arch/arm/mach-imx/mach-imx6q.c index d51c6e9..ea24a96 100644
> --- a/arch/arm/mach-imx/mach-imx6q.c
> +++ b/arch/arm/mach-imx/mach-imx6q.c
> @@ -362,6 +362,28 @@ put_node:
>  	of_node_put(np);
>  }
>  
> +#define ESAI_AUDIO_MCLK 24576000
> +
> +static void __init imx6q_audio_lvds2_init(void) {
> +        struct clk *pll4_sel, *lvds2_in, *pll4_audio_div, 
> +*esai_extal;
> +
> +        pll4_audio_div = clk_get_sys(NULL, "pll4_audio_div");
> +        pll4_sel = clk_get_sys(NULL, "pll4_sel");
> +        lvds2_in = clk_get_sys(NULL, "lvds2_in");
> +        esai_extal = clk_get_sys(NULL, "esai_extal");
> +        if (IS_ERR(pll4_audio_div) || IS_ERR(pll4_sel) ||
> +            IS_ERR(lvds2_in) || IS_ERR(esai_extal))
> +                return;
> +
> +        if (clk_get_rate(lvds2_in) != ESAI_AUDIO_MCLK)
> +                return;
> +
> +        clk_set_parent(pll4_sel, lvds2_in);
> +        clk_set_rate(pll4_audio_div, 786432000);
> +        clk_set_rate(esai_extal, ESAI_AUDIO_MCLK); }
> +
>  static struct platform_device imx6q_cpufreq_pdev = {
>  	.name = "imx6q-cpufreq",
>  };
> @@ -379,6 +401,12 @@ static void __init imx6q_init_late(void)
>  		imx6q_opp_init();
>  		platform_device_register(&imx6q_cpufreq_pdev);
>  	}
> +
> +	if (of_machine_is_compatible("fsl,imx6q-sabreauto")
> +		|| of_machine_is_compatible("fsl,imx6dl-sabreauto")) {
> +		imx6q_audio_lvds2_init();
> +	}
> +
>  }
>  
>  static void __init imx6q_map_io(void)
> --
> 1.7.9.5
> 

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

* RE: [PATCH V2 2/3] ARM: clk-imx6q: Add missing lvds and anaclk clock to the clock tree
  2014-08-06 14:42     ` Lucas Stach
@ 2014-08-07  3:19       ` shengjiu.wang at freescale.com
  -1 siblings, 0 replies; 16+ messages in thread
From: shengjiu.wang @ 2014-08-07  3:19 UTC (permalink / raw)
  To: Lucas Stach
  Cc: Shawn Guo, kernel, linux, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak, guangyu.chen, linux-arm-kernel,
	linux-kernel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 5179 bytes --]

Hi Stash, Shawn

  Do we have such API for exclusive clock? Or Do you have example for these exclusive clocks?

Best regards
Wang shengjiu

-----Original Message-----
From: Lucas Stach [mailto:l.stach@pengutronix.de] 
Sent: Wednesday, August 06, 2014 10:42 PM
To: Wang Shengjiu-B02247
Cc: Guo Shawn-R65073; kernel@pengutronix.de; linux@arm.linux.org.uk; robh+dt@kernel.org; pawel.moll@arm.com; mark.rutland@arm.com; ijc+devicetree@hellion.org.uk; galak@codeaurora.org; Chen Guangyu-B42378; linux-arm-kernel@lists.infradead.org; linux-kernel@vger.kernel.org
Subject: Re: [PATCH V2 2/3] ARM: clk-imx6q: Add missing lvds and anaclk clock to the clock tree

Am Mittwoch, den 06.08.2014, 16:35 +0800 schrieb Shengjiu Wang:
> anaclk1 and anaclk2 is the clock source for lvds1_in and lvds2_in. 
> lvds1_in and lvds2_in can be used to provide external clock source to 
> the internal pll, such as pll4_audio and pll5_video.
> pll4_audio and pll5_video can have multiple source, not only "osc", so 
> add them.
> 
> Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
> ---
>  arch/arm/mach-imx/clk-imx6q.c             |   12 ++++++++++--
>  include/dt-bindings/clock/imx6qdl-clock.h |    8 +++++++-
>  2 files changed, 17 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/clk-imx6q.c 
> b/arch/arm/mach-imx/clk-imx6q.c index 1d6dd59..330aad3 100644
> --- a/arch/arm/mach-imx/clk-imx6q.c
> +++ b/arch/arm/mach-imx/clk-imx6q.c
> @@ -73,6 +73,7 @@ static const char *lvds_sels[] = {
>  	"pll4_audio", "pll5_video", "pll8_mlb", "enet_ref",
>  	"pcie_ref_125m", "sata_ref_100m",
>  };
> +static const char *pll_av_sels[] = { "osc", "lvds1_in", "lvds2_in", 
> +"dummy", };
>  
>  static struct clk *clk[IMX6QDL_CLK_END];  static struct 
> clk_onecell_data clk_data; @@ -119,6 +120,9 @@ static void __init 
> imx6q_clocks_init(struct device_node *ccm_node)
>  	clk[IMX6QDL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
>  	clk[IMX6QDL_CLK_CKIH] = imx_obtain_fixed_clock("ckih1", 0);
>  	clk[IMX6QDL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0);
> +	/* Clock source from external clock via ANACLK1/2 PADs */
> +	clk[IMX6QDL_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0);
> +	clk[IMX6QDL_CLK_ANACLK2] = imx_obtain_fixed_clock("anaclk2", 0);
>  
>  	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
>  	base = of_iomap(np, 0);
> @@ -136,8 +140,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
>  	clk[IMX6QDL_CLK_PLL1_SYS]      = imx_clk_pllv3(IMX_PLLV3_SYS,	"pll1_sys",	"osc", base,        0x7f);
>  	clk[IMX6QDL_CLK_PLL2_BUS]      = imx_clk_pllv3(IMX_PLLV3_GENERIC,	"pll2_bus",	"osc", base + 0x30, 0x1);
>  	clk[IMX6QDL_CLK_PLL3_USB_OTG]  = imx_clk_pllv3(IMX_PLLV3_USB,	"pll3_usb_otg",	"osc", base + 0x10, 0x3);
> -	clk[IMX6QDL_CLK_PLL4_AUDIO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll4_audio",	"osc", base + 0x70, 0x7f);
> -	clk[IMX6QDL_CLK_PLL5_VIDEO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll5_video",	"osc", base + 0xa0, 0x7f);
> +	clk[IMX6QDL_CLK_PLL4_AUDIO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll4_audio",	"pll4_sel", base + 0x70, 0x7f);
> +	clk[IMX6QDL_CLK_PLL5_VIDEO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll5_video",	"pll5_sel", base + 0xa0, 0x7f);
>  	clk[IMX6QDL_CLK_PLL6_ENET]     = imx_clk_pllv3(IMX_PLLV3_ENET,	"pll6_enet",	"osc", base + 0xe0, 0x3);
>  	clk[IMX6QDL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB,	"pll7_usb_host","osc", base + 0x20, 0x3);
>  
> @@ -169,6 +173,8 @@ static void __init imx6q_clocks_init(struct 
> device_node *ccm_node)
>  
>  	clk[IMX6QDL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
>  	clk[IMX6QDL_CLK_LVDS2_SEL] = imx_clk_mux("lvds2_sel", base + 0x160, 
> 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
> +	clk[IMX6QDL_CLK_PLL4_SEL]  = imx_clk_mux("pll4_sel",  base + 0x70, 14, 2, pll_av_sels, ARRAY_SIZE(pll_av_sels));
> +	clk[IMX6QDL_CLK_PLL5_SEL]  = imx_clk_mux("pll5_sel",  base + 0xa0, 
> +14, 2, pll_av_sels, ARRAY_SIZE(pll_av_sels));
>  
>  	/*
>  	 * lvds1_gate and lvds2_gate are pseudo-gates.  Both can be @@ 
> -178,6 +184,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
>  	 */
>  	clk[IMX6QDL_CLK_LVDS1_GATE] = imx_clk_gate("lvds1_gate", "lvds1_sel", base + 0x160, 10);
>  	clk[IMX6QDL_CLK_LVDS2_GATE] = imx_clk_gate("lvds2_gate", 
> "lvds2_sel", base + 0x160, 11);
> +	clk[IMX6QDL_CLK_LVDS1_IN] = imx_clk_gate("lvds1_in", "anaclk1", base + 0x160, 12);
> +	clk[IMX6QDL_CLK_LVDS2_IN] = imx_clk_gate("lvds2_in", "anaclk2", base 
> ++ 0x160, 13);
>  
I think we need something more clever here. With both lvds in and out modeled as a clock gate it is possible for the user to enable both at the same time. The reference manual on the contrary states that both states are mutually exclusive: "Do not enable input and output buffers simultaneously".

Regards,
Lucas
-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* [PATCH V2 2/3] ARM: clk-imx6q: Add missing lvds and anaclk clock to the clock tree
@ 2014-08-07  3:19       ` shengjiu.wang at freescale.com
  0 siblings, 0 replies; 16+ messages in thread
From: shengjiu.wang at freescale.com @ 2014-08-07  3:19 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Stash, Shawn

  Do we have such API for exclusive clock? Or Do you have example for these exclusive clocks?

Best regards
Wang shengjiu

-----Original Message-----
From: Lucas Stach [mailto:l.stach at pengutronix.de] 
Sent: Wednesday, August 06, 2014 10:42 PM
To: Wang Shengjiu-B02247
Cc: Guo Shawn-R65073; kernel at pengutronix.de; linux at arm.linux.org.uk; robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com; ijc+devicetree at hellion.org.uk; galak at codeaurora.org; Chen Guangyu-B42378; linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org
Subject: Re: [PATCH V2 2/3] ARM: clk-imx6q: Add missing lvds and anaclk clock to the clock tree

Am Mittwoch, den 06.08.2014, 16:35 +0800 schrieb Shengjiu Wang:
> anaclk1 and anaclk2 is the clock source for lvds1_in and lvds2_in. 
> lvds1_in and lvds2_in can be used to provide external clock source to 
> the internal pll, such as pll4_audio and pll5_video.
> pll4_audio and pll5_video can have multiple source, not only "osc", so 
> add them.
> 
> Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
> ---
>  arch/arm/mach-imx/clk-imx6q.c             |   12 ++++++++++--
>  include/dt-bindings/clock/imx6qdl-clock.h |    8 +++++++-
>  2 files changed, 17 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/clk-imx6q.c 
> b/arch/arm/mach-imx/clk-imx6q.c index 1d6dd59..330aad3 100644
> --- a/arch/arm/mach-imx/clk-imx6q.c
> +++ b/arch/arm/mach-imx/clk-imx6q.c
> @@ -73,6 +73,7 @@ static const char *lvds_sels[] = {
>  	"pll4_audio", "pll5_video", "pll8_mlb", "enet_ref",
>  	"pcie_ref_125m", "sata_ref_100m",
>  };
> +static const char *pll_av_sels[] = { "osc", "lvds1_in", "lvds2_in", 
> +"dummy", };
>  
>  static struct clk *clk[IMX6QDL_CLK_END];  static struct 
> clk_onecell_data clk_data; @@ -119,6 +120,9 @@ static void __init 
> imx6q_clocks_init(struct device_node *ccm_node)
>  	clk[IMX6QDL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
>  	clk[IMX6QDL_CLK_CKIH] = imx_obtain_fixed_clock("ckih1", 0);
>  	clk[IMX6QDL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0);
> +	/* Clock source from external clock via ANACLK1/2 PADs */
> +	clk[IMX6QDL_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0);
> +	clk[IMX6QDL_CLK_ANACLK2] = imx_obtain_fixed_clock("anaclk2", 0);
>  
>  	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
>  	base = of_iomap(np, 0);
> @@ -136,8 +140,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
>  	clk[IMX6QDL_CLK_PLL1_SYS]      = imx_clk_pllv3(IMX_PLLV3_SYS,	"pll1_sys",	"osc", base,        0x7f);
>  	clk[IMX6QDL_CLK_PLL2_BUS]      = imx_clk_pllv3(IMX_PLLV3_GENERIC,	"pll2_bus",	"osc", base + 0x30, 0x1);
>  	clk[IMX6QDL_CLK_PLL3_USB_OTG]  = imx_clk_pllv3(IMX_PLLV3_USB,	"pll3_usb_otg",	"osc", base + 0x10, 0x3);
> -	clk[IMX6QDL_CLK_PLL4_AUDIO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll4_audio",	"osc", base + 0x70, 0x7f);
> -	clk[IMX6QDL_CLK_PLL5_VIDEO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll5_video",	"osc", base + 0xa0, 0x7f);
> +	clk[IMX6QDL_CLK_PLL4_AUDIO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll4_audio",	"pll4_sel", base + 0x70, 0x7f);
> +	clk[IMX6QDL_CLK_PLL5_VIDEO]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll5_video",	"pll5_sel", base + 0xa0, 0x7f);
>  	clk[IMX6QDL_CLK_PLL6_ENET]     = imx_clk_pllv3(IMX_PLLV3_ENET,	"pll6_enet",	"osc", base + 0xe0, 0x3);
>  	clk[IMX6QDL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB,	"pll7_usb_host","osc", base + 0x20, 0x3);
>  
> @@ -169,6 +173,8 @@ static void __init imx6q_clocks_init(struct 
> device_node *ccm_node)
>  
>  	clk[IMX6QDL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
>  	clk[IMX6QDL_CLK_LVDS2_SEL] = imx_clk_mux("lvds2_sel", base + 0x160, 
> 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
> +	clk[IMX6QDL_CLK_PLL4_SEL]  = imx_clk_mux("pll4_sel",  base + 0x70, 14, 2, pll_av_sels, ARRAY_SIZE(pll_av_sels));
> +	clk[IMX6QDL_CLK_PLL5_SEL]  = imx_clk_mux("pll5_sel",  base + 0xa0, 
> +14, 2, pll_av_sels, ARRAY_SIZE(pll_av_sels));
>  
>  	/*
>  	 * lvds1_gate and lvds2_gate are pseudo-gates.  Both can be @@ 
> -178,6 +184,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
>  	 */
>  	clk[IMX6QDL_CLK_LVDS1_GATE] = imx_clk_gate("lvds1_gate", "lvds1_sel", base + 0x160, 10);
>  	clk[IMX6QDL_CLK_LVDS2_GATE] = imx_clk_gate("lvds2_gate", 
> "lvds2_sel", base + 0x160, 11);
> +	clk[IMX6QDL_CLK_LVDS1_IN] = imx_clk_gate("lvds1_in", "anaclk1", base + 0x160, 12);
> +	clk[IMX6QDL_CLK_LVDS2_IN] = imx_clk_gate("lvds2_in", "anaclk2", base 
> ++ 0x160, 13);
>  
I think we need something more clever here. With both lvds in and out modeled as a clock gate it is possible for the user to enable both at the same time. The reference manual on the contrary states that both states are mutually exclusive: "Do not enable input and output buffers simultaneously".

Regards,
Lucas
-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |

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

end of thread, other threads:[~2014-08-07  3:19 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-06  8:35 [PATCH V2 0/3] refine clock tree for esai in imx6q Shengjiu Wang
2014-08-06  8:35 ` Shengjiu Wang
2014-08-06  8:35 ` [PATCH V2 1/3] ARM: clk-imx6q: refine clock tree for ESAI Shengjiu Wang
2014-08-06  8:35   ` Shengjiu Wang
2014-08-06  8:35 ` [PATCH V2 2/3] ARM: clk-imx6q: Add missing lvds and anaclk clock to the clock tree Shengjiu Wang
2014-08-06  8:35   ` Shengjiu Wang
2014-08-06 14:42   ` Lucas Stach
2014-08-06 14:42     ` Lucas Stach
2014-08-07  3:19     ` shengjiu.wang
2014-08-07  3:19       ` shengjiu.wang at freescale.com
2014-08-06  8:35 ` [PATCH V2 3/3] ARM: imx6q: Add the clock route from external OSC to ESAI clock Shengjiu Wang
2014-08-06  8:35   ` Shengjiu Wang
2014-08-07  3:11   ` Shawn Guo
2014-08-07  3:11     ` Shawn Guo
2014-08-07  3:14     ` shengjiu.wang
2014-08-07  3:14       ` shengjiu.wang at freescale.com

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.