1
2
3
4
5
6
7#include <asm/io.h>
8#include <asm/arch/imx-regs.h>
9#include <asm/arch/mc_cgm_regs.h>
10#include <asm/arch/mc_me_regs.h>
11#include <asm/arch/clock.h>
12
13
14
15
16
17
18static int select_pll_source_clk(enum pll_type pll, u32 refclk_freq)
19{
20 u32 clk_src;
21 u32 pll_idx;
22 volatile struct src *src = (struct src *)SRC_SOC_BASE_ADDR;
23
24
25 switch (refclk_freq) {
26 case FIRC_CLK_FREQ:
27 clk_src = SRC_GPR1_FIRC_CLK_SOURCE;
28 break;
29 case XOSC_CLK_FREQ:
30 clk_src = SRC_GPR1_XOSC_CLK_SOURCE;
31 break;
32 default:
33
34 return -1;
35 }
36
37
38
39
40 switch (pll) {
41 case PERIPH_PLL:
42 pll_idx = 3;
43 break;
44 case ENET_PLL:
45 pll_idx = 1;
46 break;
47 case DDR_PLL:
48 pll_idx = 2;
49 break;
50 default:
51 pll_idx = pll;
52 }
53
54 writel(readl(&src->gpr1) | SRC_GPR1_PLL_SOURCE(pll_idx, clk_src),
55 &src->gpr1);
56
57 return 0;
58}
59
60static void entry_to_target_mode(u32 mode)
61{
62 writel(mode | MC_ME_MCTL_KEY, MC_ME_MCTL);
63 writel(mode | MC_ME_MCTL_INVERTEDKEY, MC_ME_MCTL);
64 while ((readl(MC_ME_GS) & MC_ME_GS_S_MTRANS) != 0x00000000) ;
65}
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82static int program_pll(enum pll_type pll, u32 refclk_freq, u32 freq0, u32 freq1,
83 u32 dfs_nr, u32 dfs[][DFS_PARAMS_Nr], u32 plldv_prediv,
84 u32 plldv_mfd, u32 pllfd_mfn)
85{
86 u32 i, rfdphi1, rfdphi, dfs_on = 0, fvco;
87
88
89
90
91 fvco =
92 (refclk_freq / plldv_prediv) * (plldv_mfd +
93 pllfd_mfn / (float)20480);
94
95
96
97
98
99
100 if (fvco < PLL_MIN_FREQ || fvco > PLL_MAX_FREQ) {
101 return -1;
102 }
103
104 if (select_pll_source_clk(pll, refclk_freq) < 0) {
105 return -1;
106 }
107
108 rfdphi = fvco / freq0;
109
110 rfdphi1 = (freq1 == 0) ? 0 : fvco / freq1;
111
112 writel(PLLDIG_PLLDV_RFDPHI1_SET(rfdphi1) |
113 PLLDIG_PLLDV_RFDPHI_SET(rfdphi) |
114 PLLDIG_PLLDV_PREDIV_SET(plldv_prediv) |
115 PLLDIG_PLLDV_MFD(plldv_mfd), PLLDIG_PLLDV(pll));
116
117 writel(readl(PLLDIG_PLLFD(pll)) | PLLDIG_PLLFD_MFN_SET(pllfd_mfn) |
118 PLLDIG_PLLFD_SMDEN, PLLDIG_PLLFD(pll));
119
120
121 writel(readl(MC_ME_RUNn_MC(0)) | MC_ME_RUNMODE_MC_PLL(pll),
122 MC_ME_RUNn_MC(0));
123
124 entry_to_target_mode(MC_ME_MCTL_RUN0);
125
126
127 if ((pll == ARM_PLL) || (pll == ENET_PLL) || (pll == DDR_PLL)) {
128
129 writel(DFS_CTRL_DLL_RESET, DFS_CTRL(pll));
130
131 writel(DFS_DLLPRG1_CPICTRL_SET(0x5) |
132 DFS_DLLPRG1_VSETTLCTRL_SET(0x1) |
133 DFS_DLLPRG1_CALBYPEN_SET(0x0) |
134 DFS_DLLPRG1_DACIN_SET(0x1) | DFS_DLLPRG1_LCKWT_SET(0x0) |
135 DFS_DLLPRG1_V2IGC_SET(0x5), DFS_DLLPRG1(pll));
136
137 for (i = 0; i < dfs_nr; i++) {
138 if (dfs[i][0]) {
139 writel(DFS_DVPORTn_MFI_SET(dfs[i][2]) |
140 DFS_DVPORTn_MFN_SET(dfs[i][1]),
141 DFS_DVPORTn(pll, i));
142 dfs_on |= (dfs[i][0] << i);
143 }
144 }
145
146 writel(readl(DFS_CTRL(pll)) & ~DFS_CTRL_DLL_RESET,
147 DFS_CTRL(pll));
148 writel(readl(DFS_PORTRESET(pll)) &
149 ~DFS_PORTRESET_PORTRESET_SET(dfs_on),
150 DFS_PORTRESET(pll));
151 while ((readl(DFS_PORTSR(pll)) & dfs_on) != dfs_on) ;
152 }
153
154 entry_to_target_mode(MC_ME_MCTL_RUN0);
155
156 return 0;
157
158}
159
160static void aux_source_clk_config(uintptr_t cgm_addr, u8 ac, u32 source)
161{
162
163 writel(MC_CGM_ACn_SEL_SET(source), CGM_ACn_SC(cgm_addr, ac));
164}
165
166static void aux_div_clk_config(uintptr_t cgm_addr, u8 ac, u8 dc, u32 divider)
167{
168
169 writel(MC_CGM_ACn_DCm_DE | MC_CGM_ACn_DCm_PREDIV(divider),
170 CGM_ACn_DCm(cgm_addr, ac, dc));
171}
172
173static void setup_sys_clocks(void)
174{
175
176
177 writel((readl(MC_ME_RUNn_MC(0)) & ~MC_ME_RUNMODE_MC_SYSCLK_MASK) |
178 MC_ME_RUNMODE_MC_SYSCLK(0x2), MC_ME_RUNn_MC(0));
179
180 entry_to_target_mode(MC_ME_MCTL_RUN0);
181
182
183 writel(MC_ME_RUNMODE_SEC_CC_I_SYSCLK
184 (0x2,
185 MC_ME_RUNMODE_SEC_CC_I_SYSCLK1_OFFSET) |
186 MC_ME_RUNMODE_SEC_CC_I_SYSCLK(0x2,
187 MC_ME_RUNMODE_SEC_CC_I_SYSCLK2_OFFSET)
188 | MC_ME_RUNMODE_SEC_CC_I_SYSCLK(0x2,
189 MC_ME_RUNMODE_SEC_CC_I_SYSCLK3_OFFSET),
190 MC_ME_RUNn_SEC_CC_I(0));
191
192
193 writel(MC_CGM_SC_DCn_DE | MC_CGM_SC_DCn_PREDIV(0x0),
194 CGM_SC_DCn(MC_CGM1_BASE_ADDR, 0));
195
196
197 writel(MC_CGM_SC_DCn_DE | MC_CGM_SC_DCn_PREDIV(0x1),
198 CGM_SC_DCn(MC_CGM1_BASE_ADDR, 1));
199
200 writel(MC_CGM_SC_DCn_DE | MC_CGM_SC_DCn_PREDIV(0x0),
201 CGM_SC_DCn(MC_CGM0_BASE_ADDR, 0));
202
203
204 writel(MC_CGM_SC_DCn_DE | MC_CGM_SC_DCn_PREDIV(0x1),
205 CGM_SC_DCn(MC_CGM0_BASE_ADDR, 1));
206
207 entry_to_target_mode(MC_ME_MCTL_RUN0);
208
209}
210
211static void setup_aux_clocks(void)
212{
213
214
215
216
217 aux_source_clk_config(MC_CGM0_BASE_ADDR, 5, MC_CGM_ACn_SEL_PERPLLDIVX);
218 aux_div_clk_config(MC_CGM0_BASE_ADDR, 5, 0, 4);
219
220
221 aux_source_clk_config(MC_CGM0_BASE_ADDR, 3, MC_CGM_ACn_SEL_PERPLLDIVX);
222 aux_div_clk_config(MC_CGM0_BASE_ADDR, 3, 0, 1);
223
224
225 aux_source_clk_config(MC_CGM0_BASE_ADDR, 7, MC_CGM_ACn_SEL_ENETPLL);
226 aux_div_clk_config(MC_CGM0_BASE_ADDR, 7, 1, 9);
227
228
229 aux_source_clk_config(MC_CGM2_BASE_ADDR, 2, MC_CGM_ACn_SEL_ENETPLL);
230 aux_div_clk_config(MC_CGM2_BASE_ADDR, 2, 0, 9);
231
232
233 aux_source_clk_config(MC_CGM0_BASE_ADDR, 15, MC_CGM_ACn_SEL_ENETPLL);
234 aux_div_clk_config(MC_CGM0_BASE_ADDR, 15, 0, 9);
235
236
237 aux_source_clk_config(MC_CGM0_BASE_ADDR, 8, MC_CGM_ACn_SEL_DDRPLL);
238 aux_div_clk_config(MC_CGM0_BASE_ADDR, 8, 0, 0);
239
240 aux_div_clk_config(MC_CGM0_BASE_ADDR, 8, 1, 3);
241
242 entry_to_target_mode(MC_ME_MCTL_RUN0);
243
244}
245
246static void enable_modules_clock(void)
247{
248
249 writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL58);
250
251 writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL170);
252
253 writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL83);
254
255 writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL188);
256
257 writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL50);
258
259 writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL93);
260
261 writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL81);
262
263 writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL184);
264
265 writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL186);
266
267 writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL54);
268
269 writeb(MC_ME_PCTLn_RUNPCm(0), MC_ME_PCTL162);
270
271 entry_to_target_mode(MC_ME_MCTL_RUN0);
272}
273
274void clock_init(void)
275{
276 unsigned int arm_dfs[ARM_PLL_PHI1_DFS_Nr][DFS_PARAMS_Nr] = {
277 {ARM_PLL_PHI1_DFS1_EN, ARM_PLL_PHI1_DFS1_MFN,
278 ARM_PLL_PHI1_DFS1_MFI},
279 {ARM_PLL_PHI1_DFS2_EN, ARM_PLL_PHI1_DFS2_MFN,
280 ARM_PLL_PHI1_DFS2_MFI},
281 {ARM_PLL_PHI1_DFS3_EN, ARM_PLL_PHI1_DFS3_MFN,
282 ARM_PLL_PHI1_DFS3_MFI}
283 };
284
285 unsigned int enet_dfs[ENET_PLL_PHI1_DFS_Nr][DFS_PARAMS_Nr] = {
286 {ENET_PLL_PHI1_DFS1_EN, ENET_PLL_PHI1_DFS1_MFN,
287 ENET_PLL_PHI1_DFS1_MFI},
288 {ENET_PLL_PHI1_DFS2_EN, ENET_PLL_PHI1_DFS2_MFN,
289 ENET_PLL_PHI1_DFS2_MFI},
290 {ENET_PLL_PHI1_DFS3_EN, ENET_PLL_PHI1_DFS3_MFN,
291 ENET_PLL_PHI1_DFS3_MFI},
292 {ENET_PLL_PHI1_DFS4_EN, ENET_PLL_PHI1_DFS4_MFN,
293 ENET_PLL_PHI1_DFS4_MFI}
294 };
295
296 unsigned int ddr_dfs[DDR_PLL_PHI1_DFS_Nr][DFS_PARAMS_Nr] = {
297 {DDR_PLL_PHI1_DFS1_EN, DDR_PLL_PHI1_DFS1_MFN,
298 DDR_PLL_PHI1_DFS1_MFI},
299 {DDR_PLL_PHI1_DFS2_EN, DDR_PLL_PHI1_DFS2_MFN,
300 DDR_PLL_PHI1_DFS2_MFI},
301 {DDR_PLL_PHI1_DFS3_EN, DDR_PLL_PHI1_DFS3_MFN,
302 DDR_PLL_PHI1_DFS3_MFI}
303 };
304
305 writel(MC_ME_RUN_PCn_DRUN | MC_ME_RUN_PCn_RUN0 | MC_ME_RUN_PCn_RUN1 |
306 MC_ME_RUN_PCn_RUN2 | MC_ME_RUN_PCn_RUN3, MC_ME_RUN_PCn(0));
307
308
309 writel(MC_ME_RUNMODE_MC_MVRON | MC_ME_RUNMODE_MC_XOSCON |
310 MC_ME_RUNMODE_MC_FIRCON | MC_ME_RUNMODE_MC_SYSCLK(0x1),
311 MC_ME_RUNn_MC(0));
312
313 entry_to_target_mode(MC_ME_MCTL_RUN0);
314
315 program_pll(ARM_PLL, XOSC_CLK_FREQ, ARM_PLL_PHI0_FREQ,
316 ARM_PLL_PHI1_FREQ, ARM_PLL_PHI1_DFS_Nr, arm_dfs,
317 ARM_PLL_PLLDV_PREDIV, ARM_PLL_PLLDV_MFD, ARM_PLL_PLLDV_MFN);
318
319 setup_sys_clocks();
320
321 program_pll(PERIPH_PLL, XOSC_CLK_FREQ, PERIPH_PLL_PHI0_FREQ,
322 PERIPH_PLL_PHI1_FREQ, PERIPH_PLL_PHI1_DFS_Nr, NULL,
323 PERIPH_PLL_PLLDV_PREDIV, PERIPH_PLL_PLLDV_MFD,
324 PERIPH_PLL_PLLDV_MFN);
325
326 program_pll(ENET_PLL, XOSC_CLK_FREQ, ENET_PLL_PHI0_FREQ,
327 ENET_PLL_PHI1_FREQ, ENET_PLL_PHI1_DFS_Nr, enet_dfs,
328 ENET_PLL_PLLDV_PREDIV, ENET_PLL_PLLDV_MFD,
329 ENET_PLL_PLLDV_MFN);
330
331 program_pll(DDR_PLL, XOSC_CLK_FREQ, DDR_PLL_PHI0_FREQ,
332 DDR_PLL_PHI1_FREQ, DDR_PLL_PHI1_DFS_Nr, ddr_dfs,
333 DDR_PLL_PLLDV_PREDIV, DDR_PLL_PLLDV_MFD, DDR_PLL_PLLDV_MFN);
334
335 program_pll(VIDEO_PLL, XOSC_CLK_FREQ, VIDEO_PLL_PHI0_FREQ,
336 VIDEO_PLL_PHI1_FREQ, VIDEO_PLL_PHI1_DFS_Nr, NULL,
337 VIDEO_PLL_PLLDV_PREDIV, VIDEO_PLL_PLLDV_MFD,
338 VIDEO_PLL_PLLDV_MFN);
339
340 setup_aux_clocks();
341
342 enable_modules_clock();
343
344}
345