diff options
author | Shawn Guo <shawn.guo@freescale.com> | 2014-09-01 03:15:57 -0400 |
---|---|---|
committer | Shawn Guo <shawn.guo@freescale.com> | 2014-09-15 22:06:49 -0400 |
commit | db7c0659452c5f490ea5048390ad94de786f4b85 (patch) | |
tree | 9560dcf7e9607e5a2c0d9caf4796f99d0297ef78 | |
parent | e90f41990dce3557e345410ef33b0a47e8cb49fc (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.c | 63 | ||||
-rw-r--r-- | include/dt-bindings/clock/imx6sx-clock.h | 25 |
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 | }; |
84 | static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", }; | ||
85 | static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", }; | ||
86 | static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", }; | ||
87 | static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", }; | ||
88 | static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", }; | ||
89 | static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", }; | ||
90 | static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", }; | ||
91 | static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", }; | ||
84 | 92 | ||
85 | static struct clk *clks[IMX6SX_CLK_CLK_END]; | 93 | static struct clk *clks[IMX6SX_CLK_CLK_END]; |
86 | static struct clk_onecell_data clk_data; | 94 | static 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 */ |