Skip to content

Commit e90f419

Browse files
author
Shawn Guo
committed
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 <[email protected]>
1 parent b1f156d commit e90f419

File tree

2 files changed

+87
-9
lines changed

2 files changed

+87
-9
lines changed

arch/arm/mach-imx/clk-imx6sl.c

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,20 @@ static const char *epdc_pix_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_d
5757
static const char *audio_sels[] = { "pll4_audio_div", "pll3_pfd2", "pll3_pfd3", "pll3_usb_otg", };
5858
static const char *ecspi_sels[] = { "pll3_60m", "osc", };
5959
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", };
6074

6175
static struct clk_div_table clk_enet_ref_table[] = {
6276
{ .val = 0, .div = 20, },
@@ -177,20 +191,59 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
177191
clks[IMX6SL_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
178192
clks[IMX6SL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
179193
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);
180196

181197
np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-anatop");
182198
base = of_iomap(np, 0);
183199
WARN_ON(!base);
184200
anatop_base = base;
185201

186-
/* type name parent base div_mask */
187-
clks[IMX6SL_CLK_PLL1_SYS] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f);
188-
clks[IMX6SL_CLK_PLL2_BUS] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1);
189-
clks[IMX6SL_CLK_PLL3_USB_OTG] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3);
190-
clks[IMX6SL_CLK_PLL4_AUDIO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x7f);
191-
clks[IMX6SL_CLK_PLL5_VIDEO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f);
192-
clks[IMX6SL_CLK_PLL6_ENET] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3);
193-
clks[IMX6SL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host", "osc", base + 0x20, 0x3);
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));
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));
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));
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));
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));
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));
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));
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));
194247

195248
/*
196249
* usbphy1 and usbphy2 are implemented as dummy gates using reserve

include/dt-bindings/clock/imx6sl-clock.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,31 @@
146146
#define IMX6SL_CLK_PLL4_AUDIO_DIV 133
147147
#define IMX6SL_CLK_SPBA 134
148148
#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
150175

151176
#endif /* __DT_BINDINGS_CLOCK_IMX6SL_H */

0 commit comments

Comments
 (0)