]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
64fdf452 SB |
2 | /* |
3 | * (C) Copyright 2007 | |
4 | * Sascha Hauer, Pengutronix | |
5 | * | |
6 | * (C) Copyright 2009 Freescale Semiconductor, Inc. | |
64fdf452 SB |
7 | */ |
8 | ||
9 | #include <common.h> | |
10 | #include <asm/io.h> | |
1221ce45 | 11 | #include <linux/errno.h> |
64fdf452 SB |
12 | #include <asm/arch/imx-regs.h> |
13 | #include <asm/arch/crm_regs.h> | |
e4d34492 | 14 | #include <asm/arch/clock.h> |
bf2eaf51 | 15 | #include <div64.h> |
6a376046 | 16 | #include <asm/arch/sys_proto.h> |
64fdf452 SB |
17 | |
18 | enum pll_clocks { | |
19 | PLL1_CLOCK = 0, | |
20 | PLL2_CLOCK, | |
21 | PLL3_CLOCK, | |
649dc8ab | 22 | #ifdef CONFIG_MX53 |
bf2eaf51 | 23 | PLL4_CLOCK, |
649dc8ab | 24 | #endif |
64fdf452 SB |
25 | PLL_CLOCKS, |
26 | }; | |
27 | ||
28 | struct mxc_pll_reg *mxc_plls[PLL_CLOCKS] = { | |
29 | [PLL1_CLOCK] = (struct mxc_pll_reg *)PLL1_BASE_ADDR, | |
30 | [PLL2_CLOCK] = (struct mxc_pll_reg *)PLL2_BASE_ADDR, | |
31 | [PLL3_CLOCK] = (struct mxc_pll_reg *)PLL3_BASE_ADDR, | |
bf2eaf51 MV |
32 | #ifdef CONFIG_MX53 |
33 | [PLL4_CLOCK] = (struct mxc_pll_reg *)PLL4_BASE_ADDR, | |
34 | #endif | |
64fdf452 SB |
35 | }; |
36 | ||
70cc86a6 FE |
37 | #define AHB_CLK_ROOT 133333333 |
38 | #define SZ_DEC_1M 1000000 | |
39 | #define PLL_PD_MAX 16 /* Actual pd+1 */ | |
40 | #define PLL_MFI_MAX 15 | |
41 | #define PLL_MFI_MIN 5 | |
42 | #define ARM_DIV_MAX 8 | |
43 | #define IPG_DIV_MAX 4 | |
44 | #define AHB_DIV_MAX 8 | |
45 | #define EMI_DIV_MAX 8 | |
46 | #define NFC_DIV_MAX 8 | |
47 | ||
48 | #define MX5_CBCMR 0x00015154 | |
49 | #define MX5_CBCDR 0x02888945 | |
50 | ||
51 | struct fixed_pll_mfd { | |
52 | u32 ref_clk_hz; | |
53 | u32 mfd; | |
54 | }; | |
55 | ||
56 | const struct fixed_pll_mfd fixed_mfd[] = { | |
833b6435 | 57 | {MXC_HCLK, 24 * 16}, |
70cc86a6 FE |
58 | }; |
59 | ||
60 | struct pll_param { | |
61 | u32 pd; | |
62 | u32 mfi; | |
63 | u32 mfn; | |
64 | u32 mfd; | |
65 | }; | |
66 | ||
67 | #define PLL_FREQ_MAX(ref_clk) (4 * (ref_clk) * PLL_MFI_MAX) | |
68 | #define PLL_FREQ_MIN(ref_clk) \ | |
69 | ((2 * (ref_clk) * (PLL_MFI_MIN - 1)) / PLL_PD_MAX) | |
70 | #define MAX_DDR_CLK 420000000 | |
71 | #define NFC_CLK_MAX 34000000 | |
72 | ||
e4d34492 | 73 | struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE; |
64fdf452 | 74 | |
5d2947a3 WG |
75 | void set_usboh3_clk(void) |
76 | { | |
846b3898 BT |
77 | clrsetbits_le32(&mxc_ccm->cscmr1, |
78 | MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK, | |
79 | MXC_CCM_CSCMR1_USBOH3_CLK_SEL(1)); | |
80 | clrsetbits_le32(&mxc_ccm->cscdr1, | |
81 | MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK | | |
82 | MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK, | |
83 | MXC_CCM_CSCDR1_USBOH3_CLK_PRED(4) | | |
84 | MXC_CCM_CSCDR1_USBOH3_CLK_PODF(1)); | |
5d2947a3 WG |
85 | } |
86 | ||
76b6b196 | 87 | void enable_usboh3_clk(bool enable) |
5d2947a3 | 88 | { |
248cdf0b BT |
89 | unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; |
90 | ||
91 | clrsetbits_le32(&mxc_ccm->CCGR2, | |
92 | MXC_CCM_CCGR2_USBOH3_60M(MXC_CCM_CCGR_CG_MASK), | |
93 | MXC_CCM_CCGR2_USBOH3_60M(cg)); | |
5d2947a3 WG |
94 | } |
95 | ||
fac96408 | 96 | #ifdef CONFIG_SYS_I2C_MXC |
be2f93b1 | 97 | /* i2c_num can be from 0, to 1 for i.MX51 and 2 for i.MX53 */ |
cc54a0f7 TK |
98 | int enable_i2c_clk(unsigned char enable, unsigned i2c_num) |
99 | { | |
cc54a0f7 TK |
100 | u32 mask; |
101 | ||
be2f93b1 BT |
102 | #if defined(CONFIG_MX51) |
103 | if (i2c_num > 1) | |
104 | #elif defined(CONFIG_MX53) | |
cc54a0f7 | 105 | if (i2c_num > 2) |
be2f93b1 | 106 | #endif |
cc54a0f7 | 107 | return -EINVAL; |
1f5e4ee0 BT |
108 | mask = MXC_CCM_CCGR_CG_MASK << |
109 | (MXC_CCM_CCGR1_I2C1_OFFSET + (i2c_num << 1)); | |
cc54a0f7 | 110 | if (enable) |
846b3898 | 111 | setbits_le32(&mxc_ccm->CCGR1, mask); |
cc54a0f7 | 112 | else |
846b3898 | 113 | clrbits_le32(&mxc_ccm->CCGR1, mask); |
cc54a0f7 TK |
114 | return 0; |
115 | } | |
116 | #endif | |
117 | ||
414e1660 | 118 | void set_usb_phy_clk(void) |
5d2947a3 | 119 | { |
846b3898 | 120 | clrbits_le32(&mxc_ccm->cscmr1, MXC_CCM_CSCMR1_USB_PHY_CLK_SEL); |
5d2947a3 WG |
121 | } |
122 | ||
414e1660 | 123 | #if defined(CONFIG_MX51) |
76b6b196 | 124 | void enable_usb_phy1_clk(bool enable) |
5d2947a3 | 125 | { |
248cdf0b BT |
126 | unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; |
127 | ||
414e1660 BT |
128 | clrsetbits_le32(&mxc_ccm->CCGR2, |
129 | MXC_CCM_CCGR2_USB_PHY(MXC_CCM_CCGR_CG_MASK), | |
130 | MXC_CCM_CCGR2_USB_PHY(cg)); | |
5d2947a3 WG |
131 | } |
132 | ||
76b6b196 | 133 | void enable_usb_phy2_clk(bool enable) |
5d2947a3 | 134 | { |
414e1660 BT |
135 | /* i.MX51 has a single USB PHY clock, so do nothing here. */ |
136 | } | |
137 | #elif defined(CONFIG_MX53) | |
76b6b196 | 138 | void enable_usb_phy1_clk(bool enable) |
414e1660 BT |
139 | { |
140 | unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; | |
141 | ||
142 | clrsetbits_le32(&mxc_ccm->CCGR4, | |
143 | MXC_CCM_CCGR4_USB_PHY1(MXC_CCM_CCGR_CG_MASK), | |
144 | MXC_CCM_CCGR4_USB_PHY1(cg)); | |
5d2947a3 WG |
145 | } |
146 | ||
76b6b196 | 147 | void enable_usb_phy2_clk(bool enable) |
5d2947a3 | 148 | { |
248cdf0b BT |
149 | unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; |
150 | ||
151 | clrsetbits_le32(&mxc_ccm->CCGR4, | |
152 | MXC_CCM_CCGR4_USB_PHY2(MXC_CCM_CCGR_CG_MASK), | |
153 | MXC_CCM_CCGR4_USB_PHY2(cg)); | |
5d2947a3 | 154 | } |
414e1660 | 155 | #endif |
5d2947a3 | 156 | |
64fdf452 | 157 | /* |
bf2eaf51 | 158 | * Calculate the frequency of PLLn. |
64fdf452 | 159 | */ |
bf2eaf51 | 160 | static uint32_t decode_pll(struct mxc_pll_reg *pll, uint32_t infreq) |
64fdf452 | 161 | { |
bf2eaf51 MV |
162 | uint32_t ctrl, op, mfd, mfn, mfi, pdf, ret; |
163 | uint64_t refclk, temp; | |
164 | int32_t mfn_abs; | |
165 | ||
166 | ctrl = readl(&pll->ctrl); | |
167 | ||
168 | if (ctrl & MXC_DPLLC_CTL_HFSM) { | |
846b3898 BT |
169 | mfn = readl(&pll->hfs_mfn); |
170 | mfd = readl(&pll->hfs_mfd); | |
171 | op = readl(&pll->hfs_op); | |
bf2eaf51 | 172 | } else { |
846b3898 BT |
173 | mfn = readl(&pll->mfn); |
174 | mfd = readl(&pll->mfd); | |
175 | op = readl(&pll->op); | |
bf2eaf51 | 176 | } |
64fdf452 | 177 | |
bf2eaf51 MV |
178 | mfd &= MXC_DPLLC_MFD_MFD_MASK; |
179 | mfn &= MXC_DPLLC_MFN_MFN_MASK; | |
180 | pdf = op & MXC_DPLLC_OP_PDF_MASK; | |
846b3898 | 181 | mfi = MXC_DPLLC_OP_MFI_RD(op); |
bf2eaf51 MV |
182 | |
183 | /* 21.2.3 */ | |
184 | if (mfi < 5) | |
185 | mfi = 5; | |
186 | ||
187 | /* Sign extend */ | |
188 | if (mfn >= 0x04000000) { | |
189 | mfn |= 0xfc000000; | |
190 | mfn_abs = -mfn; | |
191 | } else | |
192 | mfn_abs = mfn; | |
193 | ||
194 | refclk = infreq * 2; | |
195 | if (ctrl & MXC_DPLLC_CTL_DPDCK0_2_EN) | |
196 | refclk *= 2; | |
197 | ||
5acc9072 | 198 | do_div(refclk, pdf + 1); |
bf2eaf51 MV |
199 | temp = refclk * mfn_abs; |
200 | do_div(temp, mfd + 1); | |
201 | ret = refclk * mfi; | |
202 | ||
203 | if ((int)mfn < 0) | |
204 | ret -= temp; | |
205 | else | |
206 | ret += temp; | |
64fdf452 | 207 | |
bf2eaf51 | 208 | return ret; |
64fdf452 SB |
209 | } |
210 | ||
b9479298 BT |
211 | #ifdef CONFIG_MX51 |
212 | /* | |
213 | * This function returns the Frequency Pre-Multiplier clock. | |
214 | */ | |
215 | static u32 get_fpm(void) | |
216 | { | |
217 | u32 mult; | |
218 | u32 ccr = readl(&mxc_ccm->ccr); | |
219 | ||
220 | if (ccr & MXC_CCM_CCR_FPM_MULT) | |
221 | mult = 1024; | |
222 | else | |
223 | mult = 512; | |
224 | ||
225 | return MXC_CLK32 * mult; | |
226 | } | |
227 | #endif | |
228 | ||
55c8df0c BT |
229 | /* |
230 | * This function returns the low power audio clock. | |
231 | */ | |
232 | static u32 get_lp_apm(void) | |
233 | { | |
234 | u32 ret_val = 0; | |
235 | u32 ccsr = readl(&mxc_ccm->ccsr); | |
236 | ||
237 | if (ccsr & MXC_CCM_CCSR_LP_APM) | |
238 | #if defined(CONFIG_MX51) | |
239 | ret_val = get_fpm(); | |
240 | #elif defined(CONFIG_MX53) | |
241 | ret_val = decode_pll(mxc_plls[PLL4_CLOCK], MXC_HCLK); | |
242 | #endif | |
243 | else | |
244 | ret_val = MXC_HCLK; | |
245 | ||
246 | return ret_val; | |
247 | } | |
248 | ||
64fdf452 SB |
249 | /* |
250 | * Get mcu main rate | |
251 | */ | |
252 | u32 get_mcu_main_clk(void) | |
253 | { | |
254 | u32 reg, freq; | |
255 | ||
846b3898 | 256 | reg = MXC_CCM_CACRR_ARM_PODF_RD(readl(&mxc_ccm->cacrr)); |
833b6435 | 257 | freq = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK); |
64fdf452 SB |
258 | return freq / (reg + 1); |
259 | } | |
260 | ||
261 | /* | |
262 | * Get the rate of peripheral's root clock. | |
263 | */ | |
6a376046 | 264 | u32 get_periph_clk(void) |
64fdf452 SB |
265 | { |
266 | u32 reg; | |
267 | ||
846b3898 | 268 | reg = readl(&mxc_ccm->cbcdr); |
64fdf452 | 269 | if (!(reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL)) |
833b6435 | 270 | return decode_pll(mxc_plls[PLL2_CLOCK], MXC_HCLK); |
846b3898 BT |
271 | reg = readl(&mxc_ccm->cbcmr); |
272 | switch (MXC_CCM_CBCMR_PERIPH_CLK_SEL_RD(reg)) { | |
64fdf452 | 273 | case 0: |
833b6435 | 274 | return decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK); |
64fdf452 | 275 | case 1: |
833b6435 | 276 | return decode_pll(mxc_plls[PLL3_CLOCK], MXC_HCLK); |
55c8df0c BT |
277 | case 2: |
278 | return get_lp_apm(); | |
64fdf452 SB |
279 | default: |
280 | return 0; | |
281 | } | |
282 | /* NOTREACHED */ | |
283 | } | |
284 | ||
285 | /* | |
286 | * Get the rate of ipg clock. | |
287 | */ | |
288 | static u32 get_ipg_clk(void) | |
289 | { | |
95c0eb19 MV |
290 | uint32_t freq, reg, div; |
291 | ||
292 | freq = get_ahb_clk(); | |
293 | ||
846b3898 BT |
294 | reg = readl(&mxc_ccm->cbcdr); |
295 | div = MXC_CCM_CBCDR_IPG_PODF_RD(reg) + 1; | |
95c0eb19 MV |
296 | |
297 | return freq / div; | |
64fdf452 SB |
298 | } |
299 | ||
300 | /* | |
301 | * Get the rate of ipg_per clock. | |
302 | */ | |
303 | static u32 get_ipg_per_clk(void) | |
304 | { | |
f124e718 | 305 | u32 freq, pred1, pred2, podf; |
64fdf452 | 306 | |
846b3898 | 307 | if (readl(&mxc_ccm->cbcmr) & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL) |
64fdf452 | 308 | return get_ipg_clk(); |
f124e718 BT |
309 | |
310 | if (readl(&mxc_ccm->cbcmr) & MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL) | |
311 | freq = get_lp_apm(); | |
312 | else | |
313 | freq = get_periph_clk(); | |
846b3898 BT |
314 | podf = readl(&mxc_ccm->cbcdr); |
315 | pred1 = MXC_CCM_CBCDR_PERCLK_PRED1_RD(podf); | |
316 | pred2 = MXC_CCM_CBCDR_PERCLK_PRED2_RD(podf); | |
317 | podf = MXC_CCM_CBCDR_PERCLK_PODF_RD(podf); | |
f124e718 | 318 | return freq / ((pred1 + 1) * (pred2 + 1) * (podf + 1)); |
64fdf452 SB |
319 | } |
320 | ||
08028b11 BT |
321 | /* Get the output clock rate of a standard PLL MUX for peripherals. */ |
322 | static u32 get_standard_pll_sel_clk(u32 clk_sel) | |
64fdf452 | 323 | { |
01968b96 | 324 | u32 freq = 0; |
64fdf452 | 325 | |
08028b11 BT |
326 | switch (clk_sel & 0x3) { |
327 | case 0: | |
833b6435 | 328 | freq = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK); |
64fdf452 | 329 | break; |
08028b11 | 330 | case 1: |
833b6435 | 331 | freq = decode_pll(mxc_plls[PLL2_CLOCK], MXC_HCLK); |
64fdf452 | 332 | break; |
08028b11 | 333 | case 2: |
833b6435 | 334 | freq = decode_pll(mxc_plls[PLL3_CLOCK], MXC_HCLK); |
64fdf452 | 335 | break; |
08028b11 BT |
336 | case 3: |
337 | freq = get_lp_apm(); | |
338 | break; | |
64fdf452 SB |
339 | } |
340 | ||
08028b11 BT |
341 | return freq; |
342 | } | |
343 | ||
344 | /* | |
345 | * Get the rate of uart clk. | |
346 | */ | |
347 | static u32 get_uart_clk(void) | |
348 | { | |
349 | unsigned int clk_sel, freq, reg, pred, podf; | |
350 | ||
351 | reg = readl(&mxc_ccm->cscmr1); | |
352 | clk_sel = MXC_CCM_CSCMR1_UART_CLK_SEL_RD(reg); | |
353 | freq = get_standard_pll_sel_clk(clk_sel); | |
354 | ||
846b3898 BT |
355 | reg = readl(&mxc_ccm->cscdr1); |
356 | pred = MXC_CCM_CSCDR1_UART_CLK_PRED_RD(reg); | |
357 | podf = MXC_CCM_CSCDR1_UART_CLK_PODF_RD(reg); | |
64fdf452 SB |
358 | freq /= (pred + 1) * (podf + 1); |
359 | ||
360 | return freq; | |
361 | } | |
362 | ||
64fdf452 SB |
363 | /* |
364 | * get cspi clock rate. | |
365 | */ | |
70cc86a6 | 366 | static u32 imx_get_cspiclk(void) |
64fdf452 | 367 | { |
3cbd107b | 368 | u32 ret_val = 0, pdf, pre_pdf, clk_sel, freq; |
846b3898 BT |
369 | u32 cscmr1 = readl(&mxc_ccm->cscmr1); |
370 | u32 cscdr2 = readl(&mxc_ccm->cscdr2); | |
64fdf452 | 371 | |
846b3898 BT |
372 | pre_pdf = MXC_CCM_CSCDR2_CSPI_CLK_PRED_RD(cscdr2); |
373 | pdf = MXC_CCM_CSCDR2_CSPI_CLK_PODF_RD(cscdr2); | |
374 | clk_sel = MXC_CCM_CSCMR1_CSPI_CLK_SEL_RD(cscmr1); | |
3cbd107b BT |
375 | freq = get_standard_pll_sel_clk(clk_sel); |
376 | ret_val = freq / ((pre_pdf + 1) * (pdf + 1)); | |
64fdf452 SB |
377 | return ret_val; |
378 | } | |
379 | ||
32384656 BT |
380 | /* |
381 | * get esdhc clock rate. | |
382 | */ | |
383 | static u32 get_esdhc_clk(u32 port) | |
384 | { | |
385 | u32 clk_sel = 0, pred = 0, podf = 0, freq = 0; | |
386 | u32 cscmr1 = readl(&mxc_ccm->cscmr1); | |
387 | u32 cscdr1 = readl(&mxc_ccm->cscdr1); | |
388 | ||
389 | switch (port) { | |
390 | case 0: | |
391 | clk_sel = MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_RD(cscmr1); | |
392 | pred = MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_RD(cscdr1); | |
393 | podf = MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_RD(cscdr1); | |
394 | break; | |
395 | case 1: | |
396 | clk_sel = MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_RD(cscmr1); | |
397 | pred = MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_RD(cscdr1); | |
398 | podf = MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_RD(cscdr1); | |
399 | break; | |
400 | case 2: | |
401 | if (cscmr1 & MXC_CCM_CSCMR1_ESDHC3_CLK_SEL) | |
402 | return get_esdhc_clk(1); | |
403 | else | |
404 | return get_esdhc_clk(0); | |
405 | case 3: | |
406 | if (cscmr1 & MXC_CCM_CSCMR1_ESDHC4_CLK_SEL) | |
407 | return get_esdhc_clk(1); | |
408 | else | |
409 | return get_esdhc_clk(0); | |
410 | default: | |
411 | break; | |
412 | } | |
413 | ||
414 | freq = get_standard_pll_sel_clk(clk_sel) / ((pred + 1) * (podf + 1)); | |
415 | return freq; | |
416 | } | |
417 | ||
70cc86a6 FE |
418 | static u32 get_axi_a_clk(void) |
419 | { | |
846b3898 BT |
420 | u32 cbcdr = readl(&mxc_ccm->cbcdr); |
421 | u32 pdf = MXC_CCM_CBCDR_AXI_A_PODF_RD(cbcdr); | |
70cc86a6 FE |
422 | |
423 | return get_periph_clk() / (pdf + 1); | |
424 | } | |
425 | ||
426 | static u32 get_axi_b_clk(void) | |
427 | { | |
846b3898 BT |
428 | u32 cbcdr = readl(&mxc_ccm->cbcdr); |
429 | u32 pdf = MXC_CCM_CBCDR_AXI_B_PODF_RD(cbcdr); | |
70cc86a6 FE |
430 | |
431 | return get_periph_clk() / (pdf + 1); | |
432 | } | |
433 | ||
434 | static u32 get_emi_slow_clk(void) | |
435 | { | |
846b3898 | 436 | u32 cbcdr = readl(&mxc_ccm->cbcdr); |
70cc86a6 | 437 | u32 emi_clk_sel = cbcdr & MXC_CCM_CBCDR_EMI_CLK_SEL; |
846b3898 | 438 | u32 pdf = MXC_CCM_CBCDR_EMI_PODF_RD(cbcdr); |
70cc86a6 FE |
439 | |
440 | if (emi_clk_sel) | |
441 | return get_ahb_clk() / (pdf + 1); | |
442 | ||
443 | return get_periph_clk() / (pdf + 1); | |
444 | } | |
445 | ||
446 | static u32 get_ddr_clk(void) | |
447 | { | |
448 | u32 ret_val = 0; | |
846b3898 BT |
449 | u32 cbcmr = readl(&mxc_ccm->cbcmr); |
450 | u32 ddr_clk_sel = MXC_CCM_CBCMR_DDR_CLK_SEL_RD(cbcmr); | |
70cc86a6 | 451 | #ifdef CONFIG_MX51 |
846b3898 | 452 | u32 cbcdr = readl(&mxc_ccm->cbcdr); |
70cc86a6 | 453 | if (cbcdr & MXC_CCM_CBCDR_DDR_HIFREQ_SEL) { |
846b3898 | 454 | u32 ddr_clk_podf = MXC_CCM_CBCDR_DDR_PODF_RD(cbcdr); |
70cc86a6 | 455 | |
833b6435 | 456 | ret_val = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK); |
70cc86a6 FE |
457 | ret_val /= ddr_clk_podf + 1; |
458 | ||
459 | return ret_val; | |
460 | } | |
461 | #endif | |
462 | switch (ddr_clk_sel) { | |
463 | case 0: | |
464 | ret_val = get_axi_a_clk(); | |
465 | break; | |
466 | case 1: | |
467 | ret_val = get_axi_b_clk(); | |
468 | break; | |
469 | case 2: | |
470 | ret_val = get_emi_slow_clk(); | |
471 | break; | |
472 | case 3: | |
473 | ret_val = get_ahb_clk(); | |
474 | break; | |
475 | default: | |
476 | break; | |
477 | } | |
478 | ||
479 | return ret_val; | |
480 | } | |
481 | ||
64fdf452 | 482 | /* |
70cc86a6 | 483 | * The API of get mxc clocks. |
64fdf452 SB |
484 | */ |
485 | unsigned int mxc_get_clock(enum mxc_clock clk) | |
486 | { | |
487 | switch (clk) { | |
488 | case MXC_ARM_CLK: | |
489 | return get_mcu_main_clk(); | |
490 | case MXC_AHB_CLK: | |
95c0eb19 | 491 | return get_ahb_clk(); |
64fdf452 SB |
492 | case MXC_IPG_CLK: |
493 | return get_ipg_clk(); | |
494 | case MXC_IPG_PERCLK: | |
e7bed5c2 | 495 | case MXC_I2C_CLK: |
64fdf452 SB |
496 | return get_ipg_per_clk(); |
497 | case MXC_UART_CLK: | |
498 | return get_uart_clk(); | |
499 | case MXC_CSPI_CLK: | |
500 | return imx_get_cspiclk(); | |
32384656 BT |
501 | case MXC_ESDHC_CLK: |
502 | return get_esdhc_clk(0); | |
503 | case MXC_ESDHC2_CLK: | |
504 | return get_esdhc_clk(1); | |
505 | case MXC_ESDHC3_CLK: | |
506 | return get_esdhc_clk(2); | |
507 | case MXC_ESDHC4_CLK: | |
508 | return get_esdhc_clk(3); | |
64fdf452 | 509 | case MXC_FEC_CLK: |
d5fe220d | 510 | return get_ipg_clk(); |
d87c85ce SB |
511 | case MXC_SATA_CLK: |
512 | return get_ahb_clk(); | |
70cc86a6 FE |
513 | case MXC_DDR_CLK: |
514 | return get_ddr_clk(); | |
64fdf452 SB |
515 | default: |
516 | break; | |
517 | } | |
70cc86a6 | 518 | return -EINVAL; |
64fdf452 SB |
519 | } |
520 | ||
521 | u32 imx_get_uartclk(void) | |
522 | { | |
523 | return get_uart_clk(); | |
524 | } | |
525 | ||
64fdf452 SB |
526 | u32 imx_get_fecclk(void) |
527 | { | |
d5fe220d | 528 | return get_ipg_clk(); |
64fdf452 SB |
529 | } |
530 | ||
70cc86a6 FE |
531 | static int gcd(int m, int n) |
532 | { | |
533 | int t; | |
534 | while (m > 0) { | |
535 | if (n > m) { | |
536 | t = m; | |
537 | m = n; | |
538 | n = t; | |
539 | } /* swap */ | |
540 | m -= n; | |
541 | } | |
542 | return n; | |
543 | } | |
544 | ||
545 | /* | |
546 | * This is to calculate various parameters based on reference clock and | |
547 | * targeted clock based on the equation: | |
548 | * t_clk = 2*ref_freq*(mfi + mfn/(mfd+1))/(pd+1) | |
549 | * This calculation is based on a fixed MFD value for simplicity. | |
550 | */ | |
551 | static int calc_pll_params(u32 ref, u32 target, struct pll_param *pll) | |
552 | { | |
553 | u64 pd, mfi = 1, mfn, mfd, t1; | |
554 | u32 n_target = target; | |
555 | u32 n_ref = ref, i; | |
556 | ||
557 | /* | |
558 | * Make sure targeted freq is in the valid range. | |
559 | * Otherwise the following calculation might be wrong!!! | |
560 | */ | |
561 | if (n_target < PLL_FREQ_MIN(ref) || | |
562 | n_target > PLL_FREQ_MAX(ref)) { | |
563 | printf("Targeted peripheral clock should be" | |
564 | "within [%d - %d]\n", | |
565 | PLL_FREQ_MIN(ref) / SZ_DEC_1M, | |
566 | PLL_FREQ_MAX(ref) / SZ_DEC_1M); | |
567 | return -EINVAL; | |
568 | } | |
569 | ||
570 | for (i = 0; i < ARRAY_SIZE(fixed_mfd); i++) { | |
571 | if (fixed_mfd[i].ref_clk_hz == ref) { | |
572 | mfd = fixed_mfd[i].mfd; | |
573 | break; | |
574 | } | |
575 | } | |
576 | ||
577 | if (i == ARRAY_SIZE(fixed_mfd)) | |
578 | return -EINVAL; | |
579 | ||
580 | /* Use n_target and n_ref to avoid overflow */ | |
581 | for (pd = 1; pd <= PLL_PD_MAX; pd++) { | |
582 | t1 = n_target * pd; | |
583 | do_div(t1, (4 * n_ref)); | |
584 | mfi = t1; | |
585 | if (mfi > PLL_MFI_MAX) | |
586 | return -EINVAL; | |
587 | else if (mfi < 5) | |
588 | continue; | |
589 | break; | |
590 | } | |
591 | /* | |
592 | * Now got pd and mfi already | |
593 | * | |
594 | * mfn = (((n_target * pd) / 4 - n_ref * mfi) * mfd) / n_ref; | |
595 | */ | |
596 | t1 = n_target * pd; | |
597 | do_div(t1, 4); | |
598 | t1 -= n_ref * mfi; | |
599 | t1 *= mfd; | |
600 | do_div(t1, n_ref); | |
601 | mfn = t1; | |
602 | debug("ref=%d, target=%d, pd=%d," "mfi=%d,mfn=%d, mfd=%d\n", | |
603 | ref, n_target, (u32)pd, (u32)mfi, (u32)mfn, (u32)mfd); | |
604 | i = 1; | |
605 | if (mfn != 0) | |
606 | i = gcd(mfd, mfn); | |
607 | pll->pd = (u32)pd; | |
608 | pll->mfi = (u32)mfi; | |
609 | do_div(mfn, i); | |
610 | pll->mfn = (u32)mfn; | |
611 | do_div(mfd, i); | |
612 | pll->mfd = (u32)mfd; | |
613 | ||
614 | return 0; | |
615 | } | |
616 | ||
617 | #define calc_div(tgt_clk, src_clk, limit) ({ \ | |
618 | u32 v = 0; \ | |
619 | if (((src_clk) % (tgt_clk)) <= 100) \ | |
620 | v = (src_clk) / (tgt_clk); \ | |
621 | else \ | |
622 | v = ((src_clk) / (tgt_clk)) + 1;\ | |
623 | if (v > limit) \ | |
624 | v = limit; \ | |
625 | (v - 1); \ | |
626 | }) | |
627 | ||
628 | #define CHANGE_PLL_SETTINGS(pll, pd, fi, fn, fd) \ | |
629 | { \ | |
846b3898 BT |
630 | writel(0x1232, &pll->ctrl); \ |
631 | writel(0x2, &pll->config); \ | |
632 | writel((((pd) - 1) << 0) | ((fi) << 4), \ | |
633 | &pll->op); \ | |
634 | writel(fn, &(pll->mfn)); \ | |
635 | writel((fd) - 1, &pll->mfd); \ | |
636 | writel((((pd) - 1) << 0) | ((fi) << 4), \ | |
637 | &pll->hfs_op); \ | |
638 | writel(fn, &pll->hfs_mfn); \ | |
639 | writel((fd) - 1, &pll->hfs_mfd); \ | |
640 | writel(0x1232, &pll->ctrl); \ | |
641 | while (!readl(&pll->ctrl) & 0x1) \ | |
70cc86a6 FE |
642 | ;\ |
643 | } | |
644 | ||
645 | static int config_pll_clk(enum pll_clocks index, struct pll_param *pll_param) | |
646 | { | |
846b3898 | 647 | u32 ccsr = readl(&mxc_ccm->ccsr); |
70cc86a6 FE |
648 | struct mxc_pll_reg *pll = mxc_plls[index]; |
649 | ||
650 | switch (index) { | |
651 | case PLL1_CLOCK: | |
652 | /* Switch ARM to PLL2 clock */ | |
649dc8ab BT |
653 | writel(ccsr | MXC_CCM_CCSR_PLL1_SW_CLK_SEL, |
654 | &mxc_ccm->ccsr); | |
70cc86a6 FE |
655 | CHANGE_PLL_SETTINGS(pll, pll_param->pd, |
656 | pll_param->mfi, pll_param->mfn, | |
657 | pll_param->mfd); | |
658 | /* Switch back */ | |
649dc8ab BT |
659 | writel(ccsr & ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL, |
660 | &mxc_ccm->ccsr); | |
70cc86a6 FE |
661 | break; |
662 | case PLL2_CLOCK: | |
663 | /* Switch to pll2 bypass clock */ | |
649dc8ab BT |
664 | writel(ccsr | MXC_CCM_CCSR_PLL2_SW_CLK_SEL, |
665 | &mxc_ccm->ccsr); | |
70cc86a6 FE |
666 | CHANGE_PLL_SETTINGS(pll, pll_param->pd, |
667 | pll_param->mfi, pll_param->mfn, | |
668 | pll_param->mfd); | |
669 | /* Switch back */ | |
649dc8ab BT |
670 | writel(ccsr & ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL, |
671 | &mxc_ccm->ccsr); | |
70cc86a6 FE |
672 | break; |
673 | case PLL3_CLOCK: | |
674 | /* Switch to pll3 bypass clock */ | |
649dc8ab BT |
675 | writel(ccsr | MXC_CCM_CCSR_PLL3_SW_CLK_SEL, |
676 | &mxc_ccm->ccsr); | |
70cc86a6 FE |
677 | CHANGE_PLL_SETTINGS(pll, pll_param->pd, |
678 | pll_param->mfi, pll_param->mfn, | |
679 | pll_param->mfd); | |
680 | /* Switch back */ | |
649dc8ab BT |
681 | writel(ccsr & ~MXC_CCM_CCSR_PLL3_SW_CLK_SEL, |
682 | &mxc_ccm->ccsr); | |
70cc86a6 | 683 | break; |
649dc8ab | 684 | #ifdef CONFIG_MX53 |
70cc86a6 FE |
685 | case PLL4_CLOCK: |
686 | /* Switch to pll4 bypass clock */ | |
649dc8ab BT |
687 | writel(ccsr | MXC_CCM_CCSR_PLL4_SW_CLK_SEL, |
688 | &mxc_ccm->ccsr); | |
70cc86a6 FE |
689 | CHANGE_PLL_SETTINGS(pll, pll_param->pd, |
690 | pll_param->mfi, pll_param->mfn, | |
691 | pll_param->mfd); | |
692 | /* Switch back */ | |
649dc8ab BT |
693 | writel(ccsr & ~MXC_CCM_CCSR_PLL4_SW_CLK_SEL, |
694 | &mxc_ccm->ccsr); | |
70cc86a6 | 695 | break; |
649dc8ab | 696 | #endif |
70cc86a6 FE |
697 | default: |
698 | return -EINVAL; | |
699 | } | |
700 | ||
701 | return 0; | |
702 | } | |
703 | ||
704 | /* Config CPU clock */ | |
705 | static int config_core_clk(u32 ref, u32 freq) | |
706 | { | |
707 | int ret = 0; | |
708 | struct pll_param pll_param; | |
709 | ||
710 | memset(&pll_param, 0, sizeof(struct pll_param)); | |
711 | ||
712 | /* The case that periph uses PLL1 is not considered here */ | |
713 | ret = calc_pll_params(ref, freq, &pll_param); | |
714 | if (ret != 0) { | |
715 | printf("Error:Can't find pll parameters: %d\n", ret); | |
716 | return ret; | |
717 | } | |
718 | ||
719 | return config_pll_clk(PLL1_CLOCK, &pll_param); | |
720 | } | |
721 | ||
722 | static int config_nfc_clk(u32 nfc_clk) | |
723 | { | |
70cc86a6 | 724 | u32 parent_rate = get_emi_slow_clk(); |
f399f636 | 725 | u32 div; |
70cc86a6 | 726 | |
f399f636 | 727 | if (nfc_clk == 0) |
70cc86a6 | 728 | return -EINVAL; |
f399f636 | 729 | div = parent_rate / nfc_clk; |
70cc86a6 FE |
730 | if (div == 0) |
731 | div++; | |
732 | if (parent_rate / div > NFC_CLK_MAX) | |
733 | div++; | |
846b3898 BT |
734 | clrsetbits_le32(&mxc_ccm->cbcdr, |
735 | MXC_CCM_CBCDR_NFC_PODF_MASK, | |
736 | MXC_CCM_CBCDR_NFC_PODF(div - 1)); | |
737 | while (readl(&mxc_ccm->cdhipr) != 0) | |
70cc86a6 FE |
738 | ; |
739 | return 0; | |
740 | } | |
741 | ||
f399f636 MV |
742 | void enable_nfc_clk(unsigned char enable) |
743 | { | |
744 | unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; | |
745 | ||
746 | clrsetbits_le32(&mxc_ccm->CCGR5, | |
747 | MXC_CCM_CCGR5_EMI_ENFC(MXC_CCM_CCGR_CG_MASK), | |
748 | MXC_CCM_CCGR5_EMI_ENFC(cg)); | |
749 | } | |
750 | ||
4611d5ba SA |
751 | #ifdef CONFIG_FSL_IIM |
752 | void enable_efuse_prog_supply(bool enable) | |
753 | { | |
754 | if (enable) | |
755 | setbits_le32(&mxc_ccm->cgpr, | |
756 | MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE); | |
757 | else | |
758 | clrbits_le32(&mxc_ccm->cgpr, | |
759 | MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE); | |
760 | } | |
761 | #endif | |
762 | ||
70cc86a6 FE |
763 | /* Config main_bus_clock for periphs */ |
764 | static int config_periph_clk(u32 ref, u32 freq) | |
765 | { | |
766 | int ret = 0; | |
767 | struct pll_param pll_param; | |
768 | ||
769 | memset(&pll_param, 0, sizeof(struct pll_param)); | |
770 | ||
846b3898 | 771 | if (readl(&mxc_ccm->cbcdr) & MXC_CCM_CBCDR_PERIPH_CLK_SEL) { |
70cc86a6 FE |
772 | ret = calc_pll_params(ref, freq, &pll_param); |
773 | if (ret != 0) { | |
774 | printf("Error:Can't find pll parameters: %d\n", | |
775 | ret); | |
776 | return ret; | |
777 | } | |
846b3898 BT |
778 | switch (MXC_CCM_CBCMR_PERIPH_CLK_SEL_RD( |
779 | readl(&mxc_ccm->cbcmr))) { | |
70cc86a6 FE |
780 | case 0: |
781 | return config_pll_clk(PLL1_CLOCK, &pll_param); | |
782 | break; | |
783 | case 1: | |
784 | return config_pll_clk(PLL3_CLOCK, &pll_param); | |
785 | break; | |
786 | default: | |
787 | return -EINVAL; | |
788 | } | |
789 | } | |
790 | ||
791 | return 0; | |
792 | } | |
793 | ||
794 | static int config_ddr_clk(u32 emi_clk) | |
795 | { | |
796 | u32 clk_src; | |
797 | s32 shift = 0, clk_sel, div = 1; | |
846b3898 | 798 | u32 cbcmr = readl(&mxc_ccm->cbcmr); |
70cc86a6 FE |
799 | |
800 | if (emi_clk > MAX_DDR_CLK) { | |
801 | printf("Warning:DDR clock should not exceed %d MHz\n", | |
802 | MAX_DDR_CLK / SZ_DEC_1M); | |
803 | emi_clk = MAX_DDR_CLK; | |
804 | } | |
805 | ||
806 | clk_src = get_periph_clk(); | |
807 | /* Find DDR clock input */ | |
846b3898 | 808 | clk_sel = MXC_CCM_CBCMR_DDR_CLK_SEL_RD(cbcmr); |
70cc86a6 FE |
809 | switch (clk_sel) { |
810 | case 0: | |
811 | shift = 16; | |
812 | break; | |
813 | case 1: | |
814 | shift = 19; | |
815 | break; | |
816 | case 2: | |
817 | shift = 22; | |
818 | break; | |
819 | case 3: | |
820 | shift = 10; | |
821 | break; | |
822 | default: | |
823 | return -EINVAL; | |
824 | } | |
825 | ||
826 | if ((clk_src % emi_clk) < 10000000) | |
827 | div = clk_src / emi_clk; | |
828 | else | |
829 | div = (clk_src / emi_clk) + 1; | |
830 | if (div > 8) | |
831 | div = 8; | |
832 | ||
846b3898 BT |
833 | clrsetbits_le32(&mxc_ccm->cbcdr, 0x7 << shift, (div - 1) << shift); |
834 | while (readl(&mxc_ccm->cdhipr) != 0) | |
70cc86a6 | 835 | ; |
846b3898 | 836 | writel(0x0, &mxc_ccm->ccdr); |
70cc86a6 FE |
837 | |
838 | return 0; | |
839 | } | |
840 | ||
841 | /* | |
842 | * This function assumes the expected core clock has to be changed by | |
843 | * modifying the PLL. This is NOT true always but for most of the times, | |
844 | * it is. So it assumes the PLL output freq is the same as the expected | |
845 | * core clock (presc=1) unless the core clock is less than PLL_FREQ_MIN. | |
846 | * In the latter case, it will try to increase the presc value until | |
847 | * (presc*core_clk) is greater than PLL_FREQ_MIN. It then makes call to | |
848 | * calc_pll_params() and obtains the values of PD, MFI,MFN, MFD based | |
849 | * on the targeted PLL and reference input clock to the PLL. Lastly, | |
850 | * it sets the register based on these values along with the dividers. | |
851 | * Note 1) There is no value checking for the passed-in divider values | |
852 | * so the caller has to make sure those values are sensible. | |
853 | * 2) Also adjust the NFC divider such that the NFC clock doesn't | |
854 | * exceed NFC_CLK_MAX. | |
855 | * 3) IPU HSP clock is independent of AHB clock. Even it can go up to | |
856 | * 177MHz for higher voltage, this function fixes the max to 133MHz. | |
857 | * 4) This function should not have allowed diag_printf() calls since | |
858 | * the serial driver has been stoped. But leave then here to allow | |
859 | * easy debugging by NOT calling the cyg_hal_plf_serial_stop(). | |
860 | */ | |
861 | int mxc_set_clock(u32 ref, u32 freq, enum mxc_clock clk) | |
862 | { | |
863 | freq *= SZ_DEC_1M; | |
864 | ||
865 | switch (clk) { | |
866 | case MXC_ARM_CLK: | |
867 | if (config_core_clk(ref, freq)) | |
868 | return -EINVAL; | |
869 | break; | |
870 | case MXC_PERIPH_CLK: | |
871 | if (config_periph_clk(ref, freq)) | |
872 | return -EINVAL; | |
873 | break; | |
874 | case MXC_DDR_CLK: | |
875 | if (config_ddr_clk(freq)) | |
876 | return -EINVAL; | |
877 | break; | |
878 | case MXC_NFC_CLK: | |
879 | if (config_nfc_clk(freq)) | |
880 | return -EINVAL; | |
881 | break; | |
882 | default: | |
883 | printf("Warning:Unsupported or invalid clock type\n"); | |
884 | } | |
885 | ||
886 | return 0; | |
887 | } | |
888 | ||
8c38b5d0 SB |
889 | #ifdef CONFIG_MX53 |
890 | /* | |
891 | * The clock for the external interface can be set to use internal clock | |
892 | * if fuse bank 4, row 3, bit 2 is set. | |
893 | * This is an undocumented feature and it was confirmed by Freescale's support: | |
894 | * Fuses (but not pins) may be used to configure SATA clocks. | |
895 | * Particularly the i.MX53 Fuse_Map contains the next information | |
896 | * about configuring SATA clocks : SATA_ALT_REF_CLK[1:0] (offset 0x180C) | |
897 | * '00' - 100MHz (External) | |
898 | * '01' - 50MHz (External) | |
899 | * '10' - 120MHz, internal (USB PHY) | |
900 | * '11' - Reserved | |
901 | */ | |
902 | void mxc_set_sata_internal_clock(void) | |
903 | { | |
904 | u32 *tmp_base = | |
905 | (u32 *)(IIM_BASE_ADDR + 0x180c); | |
906 | ||
414e1660 | 907 | set_usb_phy_clk(); |
8c38b5d0 | 908 | |
846b3898 | 909 | clrsetbits_le32(tmp_base, 0x6, 0x4); |
8c38b5d0 SB |
910 | } |
911 | #endif | |
912 | ||
20b9f2ea | 913 | #ifndef CONFIG_SPL_BUILD |
64fdf452 SB |
914 | /* |
915 | * Dump some core clockes. | |
916 | */ | |
20b9f2ea | 917 | static int do_mx5_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
64fdf452 SB |
918 | { |
919 | u32 freq; | |
920 | ||
833b6435 | 921 | freq = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK); |
37a6d208 | 922 | printf("PLL1 %8d MHz\n", freq / 1000000); |
833b6435 | 923 | freq = decode_pll(mxc_plls[PLL2_CLOCK], MXC_HCLK); |
37a6d208 | 924 | printf("PLL2 %8d MHz\n", freq / 1000000); |
833b6435 | 925 | freq = decode_pll(mxc_plls[PLL3_CLOCK], MXC_HCLK); |
37a6d208 | 926 | printf("PLL3 %8d MHz\n", freq / 1000000); |
bf2eaf51 | 927 | #ifdef CONFIG_MX53 |
833b6435 | 928 | freq = decode_pll(mxc_plls[PLL4_CLOCK], MXC_HCLK); |
37a6d208 | 929 | printf("PLL4 %8d MHz\n", freq / 1000000); |
bf2eaf51 | 930 | #endif |
37a6d208 MV |
931 | |
932 | printf("\n"); | |
933 | printf("AHB %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000); | |
934 | printf("IPG %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000); | |
935 | printf("IPG PERCLK %8d kHz\n", mxc_get_clock(MXC_IPG_PERCLK) / 1000); | |
70cc86a6 | 936 | printf("DDR %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000); |
081237c1 FE |
937 | #ifdef CONFIG_MXC_SPI |
938 | printf("CSPI %8d kHz\n", mxc_get_clock(MXC_CSPI_CLK) / 1000); | |
939 | #endif | |
64fdf452 SB |
940 | return 0; |
941 | } | |
942 | ||
943 | /***************************************************/ | |
944 | ||
945 | U_BOOT_CMD( | |
7acec259 SB |
946 | clocks, CONFIG_SYS_MAXARGS, 1, do_mx5_showclocks, |
947 | "display clocks", | |
64fdf452 SB |
948 | "" |
949 | ); | |
20b9f2ea | 950 | #endif |