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