diff options
| author | Shawn Guo <shawn.guo@freescale.com> | 2014-09-01 02:29:53 -0400 |
|---|---|---|
| committer | Shawn Guo <shawn.guo@freescale.com> | 2014-09-15 22:06:48 -0400 |
| commit | e90f41990dce3557e345410ef33b0a47e8cb49fc (patch) | |
| tree | f01f3cfc4d7c27959d17797f9c78884615ba166b | |
| parent | b1f156db47ae914a308488ce28e84f3d4ad4f667 (diff) | |
ARM: imx6sl: add BYPASS support for PLL clocks
This is the same change for imx6sl clock driver as "ARM: imx6q: add BYPASS
support for PLL clocks" for imx6q. The difference is that only anaclk1
is available on imx6sl.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
| -rw-r--r-- | arch/arm/mach-imx/clk-imx6sl.c | 69 | ||||
| -rw-r--r-- | include/dt-bindings/clock/imx6sl-clock.h | 27 |
2 files changed, 87 insertions, 9 deletions
diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c index f4d732661d6d..6791ff3e8914 100644 --- a/arch/arm/mach-imx/clk-imx6sl.c +++ b/arch/arm/mach-imx/clk-imx6sl.c | |||
| @@ -57,6 +57,20 @@ static const char *epdc_pix_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_d | |||
| 57 | static const char *audio_sels[] = { "pll4_audio_div", "pll3_pfd2", "pll3_pfd3", "pll3_usb_otg", }; | 57 | static const char *audio_sels[] = { "pll4_audio_div", "pll3_pfd2", "pll3_pfd3", "pll3_usb_otg", }; |
| 58 | static const char *ecspi_sels[] = { "pll3_60m", "osc", }; | 58 | static const char *ecspi_sels[] = { "pll3_60m", "osc", }; |
| 59 | static const char *uart_sels[] = { "pll3_80m", "osc", }; | 59 | static const char *uart_sels[] = { "pll3_80m", "osc", }; |
| 60 | static const char *lvds_sels[] = { | ||
| 61 | "pll1_sys", "pll2_bus", "pll2_pfd0", "pll2_pfd1", "pll2_pfd2", "dummy", "pll4_audio", "pll5_video", | ||
| 62 | "dummy", "enet_ref", "dummy", "dummy", "pll3_usb_otg", "pll7_usb_host", "pll3_pfd0", "pll3_pfd1", | ||
| 63 | "pll3_pfd2", "pll3_pfd3", "osc", "dummy", "dummy", "dummy", "dummy", "dummy", | ||
| 64 | "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", | ||
| 65 | }; | ||
| 66 | static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", }; | ||
| 67 | static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", }; | ||
| 68 | static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", }; | ||
| 69 | static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", }; | ||
| 70 | static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", }; | ||
| 71 | static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", }; | ||
| 72 | static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", }; | ||
| 73 | static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", }; | ||
| 60 | 74 | ||
| 61 | static struct clk_div_table clk_enet_ref_table[] = { | 75 | static struct clk_div_table clk_enet_ref_table[] = { |
| 62 | { .val = 0, .div = 20, }, | 76 | { .val = 0, .div = 20, }, |
| @@ -177,20 +191,59 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) | |||
| 177 | clks[IMX6SL_CLK_DUMMY] = imx_clk_fixed("dummy", 0); | 191 | clks[IMX6SL_CLK_DUMMY] = imx_clk_fixed("dummy", 0); |
| 178 | clks[IMX6SL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0); | 192 | clks[IMX6SL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0); |
| 179 | clks[IMX6SL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0); | 193 | clks[IMX6SL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0); |
| 194 | /* Clock source from external clock via CLK1 PAD */ | ||
| 195 | clks[IMX6SL_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0); | ||
| 180 | 196 | ||
| 181 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-anatop"); | 197 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-anatop"); |
| 182 | base = of_iomap(np, 0); | 198 | base = of_iomap(np, 0); |
| 183 | WARN_ON(!base); | 199 | WARN_ON(!base); |
| 184 | anatop_base = base; | 200 | anatop_base = base; |
| 185 | 201 | ||
| 186 | /* type name parent base div_mask */ | 202 | clks[IMX6SL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
| 187 | clks[IMX6SL_CLK_PLL1_SYS] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f); | 203 | clks[IMX6SL_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
| 188 | clks[IMX6SL_CLK_PLL2_BUS] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1); | 204 | clks[IMX6SL_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
| 189 | clks[IMX6SL_CLK_PLL3_USB_OTG] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3); | 205 | clks[IMX6SL_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
| 190 | clks[IMX6SL_CLK_PLL4_AUDIO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x7f); | 206 | clks[IMX6SL_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
| 191 | clks[IMX6SL_CLK_PLL5_VIDEO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f); | 207 | clks[IMX6SL_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
| 192 | clks[IMX6SL_CLK_PLL6_ENET] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3); | 208 | clks[IMX6SL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); |
| 193 | clks[IMX6SL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host", "osc", base + 0x20, 0x3); | 209 | |
| 210 | /* type name parent_name base div_mask */ | ||
| 211 | clks[IMX6SL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f); | ||
| 212 | clks[IMX6SL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1); | ||
| 213 | clks[IMX6SL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3); | ||
| 214 | clks[IMX6SL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f); | ||
| 215 | clks[IMX6SL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f); | ||
| 216 | clks[IMX6SL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3); | ||
| 217 | clks[IMX6SL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3); | ||
| 218 | |||
| 219 | clks[IMX6SL_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT); | ||
| 220 | clks[IMX6SL_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT); | ||
| 221 | clks[IMX6SL_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT); | ||
| 222 | clks[IMX6SL_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT); | ||
| 223 | clks[IMX6SL_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT); | ||
| 224 | clks[IMX6SL_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT); | ||
| 225 | clks[IMX6SL_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT); | ||
| 226 | |||
| 227 | /* Do not bypass PLLs initially */ | ||
| 228 | clk_set_parent(clks[IMX6SL_PLL1_BYPASS], clks[IMX6SL_CLK_PLL1]); | ||
| 229 | clk_set_parent(clks[IMX6SL_PLL2_BYPASS], clks[IMX6SL_CLK_PLL2]); | ||
| 230 | clk_set_parent(clks[IMX6SL_PLL3_BYPASS], clks[IMX6SL_CLK_PLL3]); | ||
| 231 | clk_set_parent(clks[IMX6SL_PLL4_BYPASS], clks[IMX6SL_CLK_PLL4]); | ||
| 232 | clk_set_parent(clks[IMX6SL_PLL5_BYPASS], clks[IMX6SL_CLK_PLL5]); | ||
| 233 | clk_set_parent(clks[IMX6SL_PLL6_BYPASS], clks[IMX6SL_CLK_PLL6]); | ||
| 234 | clk_set_parent(clks[IMX6SL_PLL7_BYPASS], clks[IMX6SL_CLK_PLL7]); | ||
| 235 | |||
| 236 | clks[IMX6SL_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13); | ||
| 237 | clks[IMX6SL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13); | ||
| 238 | clks[IMX6SL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13); | ||
| 239 | clks[IMX6SL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); | ||
| 240 | clks[IMX6SL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); | ||
| 241 | clks[IMX6SL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); | ||
| 242 | clks[IMX6SL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0xe0, 13); | ||
| 243 | |||
| 244 | clks[IMX6SL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); | ||
| 245 | clks[IMX6SL_CLK_LVDS1_OUT] = imx_clk_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x160, 10, BIT(12)); | ||
| 246 | clks[IMX6SL_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10)); | ||
| 194 | 247 | ||
| 195 | /* | 248 | /* |
| 196 | * usbphy1 and usbphy2 are implemented as dummy gates using reserve | 249 | * usbphy1 and usbphy2 are implemented as dummy gates using reserve |
diff --git a/include/dt-bindings/clock/imx6sl-clock.h b/include/dt-bindings/clock/imx6sl-clock.h index b91dd462ba85..f10a928fe2dd 100644 --- a/include/dt-bindings/clock/imx6sl-clock.h +++ b/include/dt-bindings/clock/imx6sl-clock.h | |||
| @@ -146,6 +146,31 @@ | |||
| 146 | #define IMX6SL_CLK_PLL4_AUDIO_DIV 133 | 146 | #define IMX6SL_CLK_PLL4_AUDIO_DIV 133 |
| 147 | #define IMX6SL_CLK_SPBA 134 | 147 | #define IMX6SL_CLK_SPBA 134 |
| 148 | #define IMX6SL_CLK_ENET 135 | 148 | #define IMX6SL_CLK_ENET 135 |
| 149 | #define IMX6SL_CLK_END 136 | 149 | #define IMX6SL_CLK_LVDS1_SEL 136 |
| 150 | #define IMX6SL_CLK_LVDS1_OUT 137 | ||
| 151 | #define IMX6SL_CLK_LVDS1_IN 138 | ||
| 152 | #define IMX6SL_CLK_ANACLK1 139 | ||
| 153 | #define IMX6SL_PLL1_BYPASS_SRC 140 | ||
| 154 | #define IMX6SL_PLL2_BYPASS_SRC 141 | ||
| 155 | #define IMX6SL_PLL3_BYPASS_SRC 142 | ||
| 156 | #define IMX6SL_PLL4_BYPASS_SRC 143 | ||
| 157 | #define IMX6SL_PLL5_BYPASS_SRC 144 | ||
| 158 | #define IMX6SL_PLL6_BYPASS_SRC 145 | ||
| 159 | #define IMX6SL_PLL7_BYPASS_SRC 146 | ||
| 160 | #define IMX6SL_CLK_PLL1 147 | ||
| 161 | #define IMX6SL_CLK_PLL2 148 | ||
| 162 | #define IMX6SL_CLK_PLL3 149 | ||
| 163 | #define IMX6SL_CLK_PLL4 150 | ||
| 164 | #define IMX6SL_CLK_PLL5 151 | ||
| 165 | #define IMX6SL_CLK_PLL6 152 | ||
| 166 | #define IMX6SL_CLK_PLL7 153 | ||
| 167 | #define IMX6SL_PLL1_BYPASS 154 | ||
| 168 | #define IMX6SL_PLL2_BYPASS 155 | ||
| 169 | #define IMX6SL_PLL3_BYPASS 156 | ||
| 170 | #define IMX6SL_PLL4_BYPASS 157 | ||
| 171 | #define IMX6SL_PLL5_BYPASS 158 | ||
| 172 | #define IMX6SL_PLL6_BYPASS 159 | ||
| 173 | #define IMX6SL_PLL7_BYPASS 160 | ||
| 174 | #define IMX6SL_CLK_END 161 | ||
| 150 | 175 | ||
| 151 | #endif /* __DT_BINDINGS_CLOCK_IMX6SL_H */ | 176 | #endif /* __DT_BINDINGS_CLOCK_IMX6SL_H */ |
