aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Guo <shawn.guo@freescale.com>2014-09-01 03:15:57 -0400
committerShawn Guo <shawn.guo@freescale.com>2014-09-15 22:06:49 -0400
commitdb7c0659452c5f490ea5048390ad94de786f4b85 (patch)
tree9560dcf7e9607e5a2c0d9caf4796f99d0297ef78
parente90f41990dce3557e345410ef33b0a47e8cb49fc (diff)
ARM: imx6sx: add BYPASS support for PLL clocks
This is the same change for imx6sx clock driver as "ARM: imx6q: add BYPASS support for PLL clocks" for imx6q. The difference is that only anaclk1 is available on imx6sx. Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
-rw-r--r--arch/arm/mach-imx/clk-imx6sx.c63
-rw-r--r--include/dt-bindings/clock/imx6sx-clock.h25
2 files changed, 78 insertions, 10 deletions
diff --git a/arch/arm/mach-imx/clk-imx6sx.c b/arch/arm/mach-imx/clk-imx6sx.c
index ecde72bdfe88..27070a716935 100644
--- a/arch/arm/mach-imx/clk-imx6sx.c
+++ b/arch/arm/mach-imx/clk-imx6sx.c
@@ -81,6 +81,14 @@ static const char *lvds_sels[] = {
81 "arm", "pll1_sys", "dummy", "dummy", "dummy", "dummy", "dummy", "pll5_video_div", 81 "arm", "pll1_sys", "dummy", "dummy", "dummy", "dummy", "dummy", "pll5_video_div",
82 "dummy", "dummy", "pcie_ref_125m", "dummy", "usbphy1", "usbphy2", 82 "dummy", "dummy", "pcie_ref_125m", "dummy", "usbphy1", "usbphy2",
83}; 83};
84static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", };
85static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
86static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
87static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
88static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", };
89static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
90static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
91static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
84 92
85static struct clk *clks[IMX6SX_CLK_CLK_END]; 93static struct clk *clks[IMX6SX_CLK_CLK_END];
86static struct clk_onecell_data clk_data; 94static struct clk_onecell_data clk_data;
@@ -143,18 +151,54 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
143 clks[IMX6SX_CLK_IPP_DI0] = of_clk_get_by_name(ccm_node, "ipp_di0"); 151 clks[IMX6SX_CLK_IPP_DI0] = of_clk_get_by_name(ccm_node, "ipp_di0");
144 clks[IMX6SX_CLK_IPP_DI1] = of_clk_get_by_name(ccm_node, "ipp_di1"); 152 clks[IMX6SX_CLK_IPP_DI1] = of_clk_get_by_name(ccm_node, "ipp_di1");
145 153
154 /* Clock source from external clock via CLK1 PAD */
155 clks[IMX6SX_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0);
156
146 np = of_find_compatible_node(NULL, NULL, "fsl,imx6sx-anatop"); 157 np = of_find_compatible_node(NULL, NULL, "fsl,imx6sx-anatop");
147 base = of_iomap(np, 0); 158 base = of_iomap(np, 0);
148 WARN_ON(!base); 159 WARN_ON(!base);
149 160
150 /* type name parent_name base div_mask */ 161 clks[IMX6SX_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
151 clks[IMX6SX_CLK_PLL1_SYS] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f); 162 clks[IMX6SX_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
152 clks[IMX6SX_CLK_PLL2_BUS] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1); 163 clks[IMX6SX_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
153 clks[IMX6SX_CLK_PLL3_USB_OTG] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3); 164 clks[IMX6SX_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
154 clks[IMX6SX_CLK_PLL4_AUDIO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x7f); 165 clks[IMX6SX_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
155 clks[IMX6SX_CLK_PLL5_VIDEO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f); 166 clks[IMX6SX_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
156 clks[IMX6SX_CLK_PLL6_ENET] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3); 167 clks[IMX6SX_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
157 clks[IMX6SX_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host", "osc", base + 0x20, 0x3); 168
169 /* type name parent_name base div_mask */
170 clks[IMX6SX_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f);
171 clks[IMX6SX_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1);
172 clks[IMX6SX_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3);
173 clks[IMX6SX_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f);
174 clks[IMX6SX_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f);
175 clks[IMX6SX_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3);
176 clks[IMX6SX_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3);
177
178 clks[IMX6SX_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
179 clks[IMX6SX_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
180 clks[IMX6SX_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
181 clks[IMX6SX_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT);
182 clks[IMX6SX_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
183 clks[IMX6SX_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT);
184 clks[IMX6SX_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT);
185
186 /* Do not bypass PLLs initially */
187 clk_set_parent(clks[IMX6SX_PLL1_BYPASS], clks[IMX6SX_CLK_PLL1]);
188 clk_set_parent(clks[IMX6SX_PLL2_BYPASS], clks[IMX6SX_CLK_PLL2]);
189 clk_set_parent(clks[IMX6SX_PLL3_BYPASS], clks[IMX6SX_CLK_PLL3]);
190 clk_set_parent(clks[IMX6SX_PLL4_BYPASS], clks[IMX6SX_CLK_PLL4]);
191 clk_set_parent(clks[IMX6SX_PLL5_BYPASS], clks[IMX6SX_CLK_PLL5]);
192 clk_set_parent(clks[IMX6SX_PLL6_BYPASS], clks[IMX6SX_CLK_PLL6]);
193 clk_set_parent(clks[IMX6SX_PLL7_BYPASS], clks[IMX6SX_CLK_PLL7]);
194
195 clks[IMX6SX_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13);
196 clks[IMX6SX_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13);
197 clks[IMX6SX_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
198 clks[IMX6SX_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
199 clks[IMX6SX_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13);
200 clks[IMX6SX_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13);
201 clks[IMX6SX_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0xe0, 13);
158 202
159 /* 203 /*
160 * Bit 20 is the reserved and read-only bit, we do this only for: 204 * Bit 20 is the reserved and read-only bit, we do this only for:
@@ -176,7 +220,8 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
176 clks[IMX6SX_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 5); 220 clks[IMX6SX_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 5);
177 clks[IMX6SX_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19); 221 clks[IMX6SX_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
178 222
179 clks[IMX6SX_CLK_LVDS1_OUT] = imx_clk_gate("lvds1_out", "lvds1_sel", base + 0x160, 10); 223 clks[IMX6SX_CLK_LVDS1_OUT] = imx_clk_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x160, 10, BIT(12));
224 clks[IMX6SX_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10));
180 225
181 clks[IMX6SX_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0, 226 clks[IMX6SX_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0,
182 base + 0xe0, 0, 2, 0, clk_enet_ref_table, 227 base + 0xe0, 0, 2, 0, clk_enet_ref_table,
diff --git a/include/dt-bindings/clock/imx6sx-clock.h b/include/dt-bindings/clock/imx6sx-clock.h
index 421d8bb76f2f..995709119ec5 100644
--- a/include/dt-bindings/clock/imx6sx-clock.h
+++ b/include/dt-bindings/clock/imx6sx-clock.h
@@ -251,6 +251,29 @@
251#define IMX6SX_CLK_SAI2_IPG 238 251#define IMX6SX_CLK_SAI2_IPG 238
252#define IMX6SX_CLK_ESAI_IPG 239 252#define IMX6SX_CLK_ESAI_IPG 239
253#define IMX6SX_CLK_ESAI_MEM 240 253#define IMX6SX_CLK_ESAI_MEM 240
254#define IMX6SX_CLK_CLK_END 241 254#define IMX6SX_CLK_LVDS1_IN 241
255#define IMX6SX_CLK_ANACLK1 242
256#define IMX6SX_PLL1_BYPASS_SRC 243
257#define IMX6SX_PLL2_BYPASS_SRC 244
258#define IMX6SX_PLL3_BYPASS_SRC 245
259#define IMX6SX_PLL4_BYPASS_SRC 246
260#define IMX6SX_PLL5_BYPASS_SRC 247
261#define IMX6SX_PLL6_BYPASS_SRC 248
262#define IMX6SX_PLL7_BYPASS_SRC 249
263#define IMX6SX_CLK_PLL1 250
264#define IMX6SX_CLK_PLL2 251
265#define IMX6SX_CLK_PLL3 252
266#define IMX6SX_CLK_PLL4 253
267#define IMX6SX_CLK_PLL5 254
268#define IMX6SX_CLK_PLL6 255
269#define IMX6SX_CLK_PLL7 256
270#define IMX6SX_PLL1_BYPASS 257
271#define IMX6SX_PLL2_BYPASS 258
272#define IMX6SX_PLL3_BYPASS 259
273#define IMX6SX_PLL4_BYPASS 260
274#define IMX6SX_PLL5_BYPASS 261
275#define IMX6SX_PLL6_BYPASS 262
276#define IMX6SX_PLL7_BYPASS 263
277#define IMX6SX_CLK_CLK_END 264
255 278
256#endif /* __DT_BINDINGS_CLOCK_IMX6SX_H */ 279#endif /* __DT_BINDINGS_CLOCK_IMX6SX_H */