aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Guo <shawn.guo@freescale.com>2014-07-10 05:05:49 -0400
committerShawn Guo <shawn.guo@freescale.com>2014-07-11 04:14:45 -0400
commitf9a708175789b138e559f6afcea75cd4b2acd25e (patch)
tree59004074ef83f621a3b8a54c92c42faa41a78e66
parentdc49a7739f46c92cc52e43e538d98f45e8cd5920 (diff)
ENGR00322272-1: ARM: imx6sx: hide the buggy ldb_di_sel mux from clk API
This is a smilar change for imx6sx clock tree as what we did for imx6q with commit 0bec46131d88 (ENGR00318063-8: ARM: imx6q: hide buggy ldb_di_sel from clk API). As the valid procedure of switching ldb_di_sel on imx6sx is not available yet, we hide this buggy mux by looking at the parent selection done by bootloader and register it statically to clock framework, so that switching this buggy mux becomes impossible. Also, since the bit width of ldb_di_sels is 3, we add two "dummy" entries for ldb_di_sels to avoid out-of-bounds error. Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
-rw-r--r--arch/arm/mach-imx/clk-imx6sx.c29
-rw-r--r--include/dt-bindings/clock/imx6sx-clock.h2
2 files changed, 21 insertions, 10 deletions
diff --git a/arch/arm/mach-imx/clk-imx6sx.c b/arch/arm/mach-imx/clk-imx6sx.c
index f742857a2cdf..b3ddb75be7d8 100644
--- a/arch/arm/mach-imx/clk-imx6sx.c
+++ b/arch/arm/mach-imx/clk-imx6sx.c
@@ -43,8 +43,8 @@ static const char *gpu_axi_sels[] = { "pll2_pfd2_396m", "pll3_pfd0_720m", "pll3_
43static const char *gpu_core_sels[] = { "pll3_pfd1_540m", "pll3_pfd0_720m", "pll2_bus", "pll2_pfd2_396m", }; 43static const char *gpu_core_sels[] = { "pll3_pfd1_540m", "pll3_pfd0_720m", "pll2_bus", "pll2_pfd2_396m", };
44static const char *ldb_di0_div_sels[] = { "ldb_di0_div_3_5", "ldb_di0_div_7", }; 44static const char *ldb_di0_div_sels[] = { "ldb_di0_div_3_5", "ldb_di0_div_7", };
45static const char *ldb_di1_div_sels[] = { "ldb_di1_div_3_5", "ldb_di1_div_7", }; 45static const char *ldb_di1_div_sels[] = { "ldb_di1_div_3_5", "ldb_di1_div_7", };
46static const char *ldb_di0_sels[] = { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_pfd3_594m", "pll2_pfd1_594m", "pll3_pfd3_454m", }; 46static const char *ldb_di0_sels[] = { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_pfd3_594m", "pll2_pfd1_594m", "pll3_pfd3_454m", "dummy", "dummy"};
47static const char *ldb_di1_sels[] = { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", }; 47static const char *ldb_di1_sels[] = { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", "dummy", "dummy"};
48static const char *pcie_axi_sels[] = { "axi", "ahb", }; 48static const char *pcie_axi_sels[] = { "axi", "ahb", };
49static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll5_video_div", "pll4_audio_div", }; 49static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll5_video_div", "pll4_audio_div", };
50static const char *qspi1_sels[] = { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", }; 50static const char *qspi1_sels[] = { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", };
@@ -127,6 +127,21 @@ static u32 share_count_asrc;
127static u32 share_count_audio; 127static u32 share_count_audio;
128static u32 share_count_esai; 128static u32 share_count_esai;
129 129
130/*
131 * The ldb_di_sel is buggy and could generate a glitch during clock switch.
132 * Find out the parent set up by bootloader and register it statically to
133 * clock framework, so that we hide this buggy mux clock completely from the
134 * clock tree.
135 */
136static inline const char *ldb_di_parent(void __iomem *base, int ldb_di_idx)
137{
138 u32 val = readl_relaxed(base + 0x2c);
139 unsigned int shift = (ldb_di_idx == 0) ? 9 : 12;
140 unsigned int index = (val >> shift) & 0x7;
141
142 return (ldb_di_idx == 0) ? ldb_di0_sels[index] : ldb_di1_sels[index];
143}
144
130static void __init imx6sx_clocks_init(struct device_node *ccm_node) 145static void __init imx6sx_clocks_init(struct device_node *ccm_node)
131{ 146{
132 struct device_node *np; 147 struct device_node *np;
@@ -266,8 +281,6 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
266 281
267 clks[IMX6SX_CLK_LDB_DI1_DIV_SEL] = imx_clk_mux_flags("ldb_di1_div_sel", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels), CLK_SET_RATE_PARENT); 282 clks[IMX6SX_CLK_LDB_DI1_DIV_SEL] = imx_clk_mux_flags("ldb_di1_div_sel", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels), CLK_SET_RATE_PARENT);
268 clks[IMX6SX_CLK_LDB_DI0_DIV_SEL] = imx_clk_mux_flags("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels), CLK_SET_RATE_PARENT); 283 clks[IMX6SX_CLK_LDB_DI0_DIV_SEL] = imx_clk_mux_flags("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels), CLK_SET_RATE_PARENT);
269 clks[IMX6SX_CLK_LDB_DI1_SEL] = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di1_sels, ARRAY_SIZE(ldb_di1_sels), CLK_SET_RATE_PARENT);
270 clks[IMX6SX_CLK_LDB_DI0_SEL] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels), CLK_SET_RATE_PARENT);
271 clks[IMX6SX_CLK_LCDIF1_PRE_SEL] = imx_clk_mux_flags("lcdif1_pre_sel", base + 0x38, 15, 3, lcdif1_pre_sels, ARRAY_SIZE(lcdif1_pre_sels), CLK_SET_RATE_PARENT); 284 clks[IMX6SX_CLK_LCDIF1_PRE_SEL] = imx_clk_mux_flags("lcdif1_pre_sel", base + 0x38, 15, 3, lcdif1_pre_sels, ARRAY_SIZE(lcdif1_pre_sels), CLK_SET_RATE_PARENT);
272 clks[IMX6SX_CLK_LCDIF1_SEL] = imx_clk_mux_flags("lcdif1_sel", base + 0x38, 9, 3, lcdif1_sels, ARRAY_SIZE(lcdif1_sels), CLK_SET_RATE_PARENT); 285 clks[IMX6SX_CLK_LCDIF1_SEL] = imx_clk_mux_flags("lcdif1_sel", base + 0x38, 9, 3, lcdif1_sels, ARRAY_SIZE(lcdif1_sels), CLK_SET_RATE_PARENT);
273 286
@@ -313,10 +326,10 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
313 clks[IMX6SX_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3); 326 clks[IMX6SX_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3);
314 clks[IMX6SX_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", base + 0x60, 21, 3); 327 clks[IMX6SX_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", base + 0x60, 21, 3);
315 328
316 clks[IMX6SX_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); 329 clks[IMX6SX_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", ldb_di_parent(base, 0), 2, 7);
317 clks[IMX6SX_CLK_LDB_DI0_DIV_7] = imx_clk_fixed_factor("ldb_di0_div_7", "ldb_di0_sel", 1, 7); 330 clks[IMX6SX_CLK_LDB_DI0_DIV_7] = imx_clk_fixed_factor("ldb_di0_div_7", ldb_di_parent(base, 0), 1, 7);
318 clks[IMX6SX_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); 331 clks[IMX6SX_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", ldb_di_parent(base, 1), 2, 7);
319 clks[IMX6SX_CLK_LDB_DI1_DIV_7] = imx_clk_fixed_factor("ldb_di1_div_7", "ldb_di1_sel", 1, 7); 332 clks[IMX6SX_CLK_LDB_DI1_DIV_7] = imx_clk_fixed_factor("ldb_di1_div_7", ldb_di_parent(base, 1), 1, 7);
320 333
321 /* name reg shift width busy: reg, shift parent_names num_parents */ 334 /* name reg shift width busy: reg, shift parent_names num_parents */
322 clks[IMX6SX_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels)); 335 clks[IMX6SX_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels));
diff --git a/include/dt-bindings/clock/imx6sx-clock.h b/include/dt-bindings/clock/imx6sx-clock.h
index 0e3710cdd5f6..0206616014dc 100644
--- a/include/dt-bindings/clock/imx6sx-clock.h
+++ b/include/dt-bindings/clock/imx6sx-clock.h
@@ -72,8 +72,6 @@
72#define IMX6SX_CLK_CAN_SEL 59 72#define IMX6SX_CLK_CAN_SEL 59
73#define IMX6SX_CLK_UART_SEL 60 73#define IMX6SX_CLK_UART_SEL 60
74#define IMX6SX_CLK_QSPI2_SEL 61 74#define IMX6SX_CLK_QSPI2_SEL 61
75#define IMX6SX_CLK_LDB_DI1_SEL 62
76#define IMX6SX_CLK_LDB_DI0_SEL 63
77#define IMX6SX_CLK_SPDIF_SEL 64 75#define IMX6SX_CLK_SPDIF_SEL 64
78#define IMX6SX_CLK_AUDIO_SEL 65 76#define IMX6SX_CLK_AUDIO_SEL 65
79#define IMX6SX_CLK_ENET_PRE_SEL 66 77#define IMX6SX_CLK_ENET_PRE_SEL 66