xref: /openbmc/u-boot/arch/arm/cpu/arm1136/mx35/generic.c (revision d6208a3c)
1 /*
2  * (C) Copyright 2007
3  * Sascha Hauer, Pengutronix
4  *
5  * (C) Copyright 2008-2010 Freescale Semiconductor, Inc.
6  *
7  * See file CREDITS for list of people who contributed to this
8  * project.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of
13  * the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23  * MA 02111-1307 USA
24  */
25 
26 #include <common.h>
27 #include <div64.h>
28 #include <asm/io.h>
29 #include <asm/errno.h>
30 #include <asm/arch/imx-regs.h>
31 #include <asm/arch/crm_regs.h>
32 #include <asm/arch/clock.h>
33 #include <asm/arch/sys_proto.h>
34 #ifdef CONFIG_FSL_ESDHC
35 #include <fsl_esdhc.h>
36 #endif
37 #include <netdev.h>
38 #include <spl.h>
39 
40 #define CLK_CODE(arm, ahb, sel) (((arm) << 16) + ((ahb) << 8) + (sel))
41 #define CLK_CODE_ARM(c)		(((c) >> 16) & 0xFF)
42 #define CLK_CODE_AHB(c)		(((c) >>  8) & 0xFF)
43 #define CLK_CODE_PATH(c)	((c) & 0xFF)
44 
45 #define CCM_GET_DIVIDER(x, m, o) (((x) & (m)) >> (o))
46 
47 #ifdef CONFIG_FSL_ESDHC
48 DECLARE_GLOBAL_DATA_PTR;
49 #endif
50 
51 static int g_clk_mux_auto[8] = {
52 	CLK_CODE(1, 3, 0), CLK_CODE(1, 2, 1), CLK_CODE(2, 1, 1), -1,
53 	CLK_CODE(1, 6, 0), CLK_CODE(1, 4, 1), CLK_CODE(2, 2, 1), -1,
54 };
55 
56 static int g_clk_mux_consumer[16] = {
57 	CLK_CODE(1, 4, 0), CLK_CODE(1, 3, 1), CLK_CODE(1, 3, 1), -1,
58 	-1, -1, CLK_CODE(4, 1, 0), CLK_CODE(1, 5, 0),
59 	CLK_CODE(1, 8, 1), CLK_CODE(1, 6, 1), CLK_CODE(2, 4, 0), -1,
60 	-1, -1, CLK_CODE(4, 2, 0), -1,
61 };
62 
63 static int hsp_div_table[3][16] = {
64 	{4, 3, 2, -1, -1, -1, 1, 5, 4, 3, 2, -1, -1, -1, 1, -1},
65 	{-1, -1, -1, -1, -1, -1, -1, -1, 8, 6, 4, -1, -1, -1, 2, -1},
66 	{3, -1, -1, -1, -1, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1},
67 };
68 
69 u32 get_cpu_rev(void)
70 {
71 	int reg;
72 	struct iim_regs *iim =
73 		(struct iim_regs *)IIM_BASE_ADDR;
74 	reg = readl(&iim->iim_srev);
75 	if (!reg) {
76 		reg = readw(ROMPATCH_REV);
77 		reg <<= 4;
78 	} else {
79 		reg += CHIP_REV_1_0;
80 	}
81 
82 	return 0x35000 + (reg & 0xFF);
83 }
84 
85 static u32 get_arm_div(u32 pdr0, u32 *fi, u32 *fd)
86 {
87 	int *pclk_mux;
88 	if (pdr0 & MXC_CCM_PDR0_AUTO_CON) {
89 		pclk_mux = g_clk_mux_consumer +
90 			((pdr0 & MXC_CCM_PDR0_CON_MUX_DIV_MASK) >>
91 			MXC_CCM_PDR0_CON_MUX_DIV_OFFSET);
92 	} else {
93 		pclk_mux = g_clk_mux_auto +
94 			((pdr0 & MXC_CCM_PDR0_AUTO_MUX_DIV_MASK) >>
95 			MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET);
96 	}
97 
98 	if ((*pclk_mux) == -1)
99 		return -1;
100 
101 	if (fi && fd) {
102 		if (!CLK_CODE_PATH(*pclk_mux)) {
103 			*fi = *fd = 1;
104 			return CLK_CODE_ARM(*pclk_mux);
105 		}
106 		if (pdr0 & MXC_CCM_PDR0_AUTO_CON) {
107 			*fi = 3;
108 			*fd = 4;
109 		} else {
110 			*fi = 2;
111 			*fd = 3;
112 		}
113 	}
114 	return CLK_CODE_ARM(*pclk_mux);
115 }
116 
117 static int get_ahb_div(u32 pdr0)
118 {
119 	int *pclk_mux;
120 
121 	pclk_mux = g_clk_mux_consumer +
122 		((pdr0 & MXC_CCM_PDR0_CON_MUX_DIV_MASK) >>
123 		MXC_CCM_PDR0_CON_MUX_DIV_OFFSET);
124 
125 	if ((*pclk_mux) == -1)
126 		return -1;
127 
128 	return CLK_CODE_AHB(*pclk_mux);
129 }
130 
131 static u32 decode_pll(u32 reg, u32 infreq)
132 {
133 	u32 mfi = (reg >> 10) & 0xf;
134 	s32 mfn = reg & 0x3ff;
135 	u32 mfd = (reg >> 16) & 0x3ff;
136 	u32 pd = (reg >> 26) & 0xf;
137 
138 	mfi = mfi <= 5 ? 5 : mfi;
139 	mfn = mfn >= 512 ? mfn - 1024 : mfn;
140 	mfd += 1;
141 	pd += 1;
142 
143 	return lldiv(2 * (u64)infreq * (mfi * mfd + mfn),
144 		mfd * pd);
145 }
146 
147 static u32 get_mcu_main_clk(void)
148 {
149 	u32 arm_div = 0, fi = 0, fd = 0;
150 	struct ccm_regs *ccm =
151 		(struct ccm_regs *)IMX_CCM_BASE;
152 	arm_div = get_arm_div(readl(&ccm->pdr0), &fi, &fd);
153 	fi *= decode_pll(readl(&ccm->mpctl), MXC_HCLK);
154 	return fi / (arm_div * fd);
155 }
156 
157 static u32 get_ipg_clk(void)
158 {
159 	u32 freq = get_mcu_main_clk();
160 	struct ccm_regs *ccm =
161 		(struct ccm_regs *)IMX_CCM_BASE;
162 	u32 pdr0 = readl(&ccm->pdr0);
163 
164 	return freq / (get_ahb_div(pdr0) * 2);
165 }
166 
167 static u32 get_ipg_per_clk(void)
168 {
169 	u32 freq = get_mcu_main_clk();
170 	struct ccm_regs *ccm =
171 		(struct ccm_regs *)IMX_CCM_BASE;
172 	u32 pdr0 = readl(&ccm->pdr0);
173 	u32 pdr4 = readl(&ccm->pdr4);
174 	u32 div;
175 	if (pdr0 & MXC_CCM_PDR0_PER_SEL) {
176 		div = CCM_GET_DIVIDER(pdr4,
177 			MXC_CCM_PDR4_PER0_PODF_MASK,
178 			MXC_CCM_PDR4_PER0_PODF_OFFSET) + 1;
179 	} else {
180 		div = CCM_GET_DIVIDER(pdr0,
181 			MXC_CCM_PDR0_PER_PODF_MASK,
182 			MXC_CCM_PDR0_PER_PODF_OFFSET) + 1;
183 		div *= get_ahb_div(pdr0);
184 	}
185 	return freq / div;
186 }
187 
188 u32 imx_get_uartclk(void)
189 {
190 	u32 freq;
191 	struct ccm_regs *ccm =
192 		(struct ccm_regs *)IMX_CCM_BASE;
193 	u32 pdr4 = readl(&ccm->pdr4);
194 
195 	if (readl(&ccm->pdr3) & MXC_CCM_PDR3_UART_M_U)
196 		freq = get_mcu_main_clk();
197 	else
198 		freq = decode_pll(readl(&ccm->ppctl), MXC_HCLK);
199 	freq /= CCM_GET_DIVIDER(pdr4,
200 			MXC_CCM_PDR4_UART_PODF_MASK,
201 			MXC_CCM_PDR4_UART_PODF_OFFSET) + 1;
202 	return freq;
203 }
204 
205 unsigned int mxc_get_main_clock(enum mxc_main_clock clk)
206 {
207 	u32 nfc_pdf, hsp_podf;
208 	u32 pll, ret_val = 0, usb_podf;
209 	struct ccm_regs *ccm =
210 		(struct ccm_regs *)IMX_CCM_BASE;
211 
212 	u32 reg = readl(&ccm->pdr0);
213 	u32 reg4 = readl(&ccm->pdr4);
214 
215 	reg |= 0x1;
216 
217 	switch (clk) {
218 	case CPU_CLK:
219 		ret_val = get_mcu_main_clk();
220 		break;
221 	case AHB_CLK:
222 		ret_val = get_mcu_main_clk();
223 		break;
224 	case HSP_CLK:
225 		if (reg & CLKMODE_CONSUMER) {
226 			hsp_podf = (reg >> 20) & 0x3;
227 			pll = get_mcu_main_clk();
228 			hsp_podf = hsp_div_table[hsp_podf][(reg>>16)&0xF];
229 			if (hsp_podf > 0) {
230 				ret_val = pll / hsp_podf;
231 			} else {
232 				puts("mismatch HSP with ARM clock setting\n");
233 				ret_val = 0;
234 			}
235 		} else {
236 			ret_val = get_mcu_main_clk();
237 		}
238 		break;
239 	case IPG_CLK:
240 		ret_val = get_ipg_clk();
241 		break;
242 	case IPG_PER_CLK:
243 		ret_val = get_ipg_per_clk();
244 		break;
245 	case NFC_CLK:
246 		nfc_pdf = (reg4 >> 28) & 0xF;
247 		pll = get_mcu_main_clk();
248 		/* AHB/nfc_pdf */
249 		ret_val = pll / (nfc_pdf + 1);
250 		break;
251 	case USB_CLK:
252 		usb_podf = (reg4 >> 22) & 0x3F;
253 		if (reg4 & 0x200)
254 			pll = get_mcu_main_clk();
255 		else
256 			pll = decode_pll(readl(&ccm->ppctl), MXC_HCLK);
257 
258 		ret_val = pll / (usb_podf + 1);
259 		break;
260 	default:
261 		printf("Unknown clock: %d\n", clk);
262 		break;
263 	}
264 
265 	return ret_val;
266 }
267 unsigned int mxc_get_peri_clock(enum mxc_peri_clock clk)
268 {
269 	u32 ret_val = 0, pdf, pre_pdf, clk_sel;
270 	struct ccm_regs *ccm =
271 		(struct ccm_regs *)IMX_CCM_BASE;
272 	u32 mpdr2 = readl(&ccm->pdr2);
273 	u32 mpdr3 = readl(&ccm->pdr3);
274 	u32 mpdr4 = readl(&ccm->pdr4);
275 
276 	switch (clk) {
277 	case UART1_BAUD:
278 	case UART2_BAUD:
279 	case UART3_BAUD:
280 		clk_sel = mpdr3 & (1 << 14);
281 		pdf = (mpdr4 >> 10) & 0x3F;
282 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
283 			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1);
284 		break;
285 	case SSI1_BAUD:
286 		pre_pdf = (mpdr2 >> 24) & 0x7;
287 		pdf = mpdr2 & 0x3F;
288 		clk_sel = mpdr2 & (1 << 6);
289 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
290 			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) /
291 				((pre_pdf + 1) * (pdf + 1));
292 		break;
293 	case SSI2_BAUD:
294 		pre_pdf = (mpdr2 >> 27) & 0x7;
295 		pdf = (mpdr2 >> 8) & 0x3F;
296 		clk_sel = mpdr2 & (1 << 6);
297 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
298 			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) /
299 				((pre_pdf + 1) * (pdf + 1));
300 		break;
301 	case CSI_BAUD:
302 		clk_sel = mpdr2 & (1 << 7);
303 		pdf = (mpdr2 >> 16) & 0x3F;
304 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
305 			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1);
306 		break;
307 	case MSHC_CLK:
308 		pre_pdf = readl(&ccm->pdr1);
309 		clk_sel = (pre_pdf & 0x80);
310 		pdf = (pre_pdf >> 22) & 0x3F;
311 		pre_pdf = (pre_pdf >> 28) & 0x7;
312 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
313 			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) /
314 				((pre_pdf + 1) * (pdf + 1));
315 		break;
316 	case ESDHC1_CLK:
317 		clk_sel = mpdr3 & 0x40;
318 		pdf = mpdr3 & 0x3F;
319 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
320 			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1);
321 		break;
322 	case ESDHC2_CLK:
323 		clk_sel = mpdr3 & 0x40;
324 		pdf = (mpdr3 >> 8) & 0x3F;
325 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
326 			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1);
327 		break;
328 	case ESDHC3_CLK:
329 		clk_sel = mpdr3 & 0x40;
330 		pdf = (mpdr3 >> 16) & 0x3F;
331 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
332 			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1);
333 		break;
334 	case SPDIF_CLK:
335 		clk_sel = mpdr3 & 0x400000;
336 		pre_pdf = (mpdr3 >> 29) & 0x7;
337 		pdf = (mpdr3 >> 23) & 0x3F;
338 		ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
339 			decode_pll(readl(&ccm->ppctl), MXC_HCLK)) /
340 				((pre_pdf + 1) * (pdf + 1));
341 		break;
342 	default:
343 		printf("%s(): This clock: %d not supported yet\n",
344 				__func__, clk);
345 		break;
346 	}
347 
348 	return ret_val;
349 }
350 
351 unsigned int mxc_get_clock(enum mxc_clock clk)
352 {
353 	switch (clk) {
354 	case MXC_ARM_CLK:
355 		return get_mcu_main_clk();
356 	case MXC_AHB_CLK:
357 		break;
358 	case MXC_IPG_CLK:
359 		return get_ipg_clk();
360 	case MXC_IPG_PERCLK:
361 	case MXC_I2C_CLK:
362 		return get_ipg_per_clk();
363 	case MXC_UART_CLK:
364 		return imx_get_uartclk();
365 	case MXC_ESDHC1_CLK:
366 		return mxc_get_peri_clock(ESDHC1_CLK);
367 	case MXC_ESDHC2_CLK:
368 		return mxc_get_peri_clock(ESDHC2_CLK);
369 	case MXC_ESDHC3_CLK:
370 		return mxc_get_peri_clock(ESDHC3_CLK);
371 	case MXC_USB_CLK:
372 		return mxc_get_main_clock(USB_CLK);
373 	case MXC_FEC_CLK:
374 		return get_ipg_clk();
375 	case MXC_CSPI_CLK:
376 		return get_ipg_clk();
377 	}
378 	return -1;
379 }
380 
381 #ifdef CONFIG_FEC_MXC
382 /*
383  * The MX35 has no fuse for MAC, return a NULL MAC
384  */
385 void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
386 {
387 	memset(mac, 0, 6);
388 }
389 
390 u32 imx_get_fecclk(void)
391 {
392 	return mxc_get_clock(MXC_IPG_CLK);
393 }
394 #endif
395 
396 int do_mx35_showclocks(cmd_tbl_t *cmdtp,
397 	int flag, int argc, char * const argv[])
398 {
399 	u32 cpufreq = get_mcu_main_clk();
400 	printf("mx35 cpu clock: %dMHz\n", cpufreq / 1000000);
401 	printf("ipg clock     : %dHz\n", get_ipg_clk());
402 	printf("ipg per clock : %dHz\n", get_ipg_per_clk());
403 	printf("uart clock    : %dHz\n", mxc_get_clock(MXC_UART_CLK));
404 
405 	return 0;
406 }
407 
408 U_BOOT_CMD(
409 	clocks,	CONFIG_SYS_MAXARGS, 1, do_mx35_showclocks,
410 	"display clocks",
411 	""
412 );
413 
414 #if defined(CONFIG_DISPLAY_CPUINFO)
415 static char *get_reset_cause(void)
416 {
417 	/* read RCSR register from CCM module */
418 	struct ccm_regs *ccm =
419 		(struct ccm_regs *)IMX_CCM_BASE;
420 
421 	u32 cause = readl(&ccm->rcsr) & 0x0F;
422 
423 	switch (cause) {
424 	case 0x0000:
425 		return "POR";
426 	case 0x0002:
427 		return "JTAG";
428 	case 0x0004:
429 		return "RST";
430 	case 0x0008:
431 		return "WDOG";
432 	default:
433 		return "unknown reset";
434 	}
435 }
436 
437 int print_cpuinfo(void)
438 {
439 	u32 srev = get_cpu_rev();
440 
441 	printf("CPU:   Freescale i.MX35 rev %d.%d at %d MHz.\n",
442 		(srev & 0xF0) >> 4, (srev & 0x0F),
443 		get_mcu_main_clk() / 1000000);
444 
445 	printf("Reset cause: %s\n", get_reset_cause());
446 
447 	return 0;
448 }
449 #endif
450 
451 /*
452  * Initializes on-chip ethernet controllers.
453  * to override, implement board_eth_init()
454  */
455 int cpu_eth_init(bd_t *bis)
456 {
457 	int rc = -ENODEV;
458 
459 #if defined(CONFIG_FEC_MXC)
460 	rc = fecmxc_initialize(bis);
461 #endif
462 
463 	return rc;
464 }
465 
466 #ifdef CONFIG_FSL_ESDHC
467 /*
468  * Initializes on-chip MMC controllers.
469  * to override, implement board_mmc_init()
470  */
471 int cpu_mmc_init(bd_t *bis)
472 {
473 	return fsl_esdhc_mmc_init(bis);
474 }
475 #endif
476 
477 int get_clocks(void)
478 {
479 #ifdef CONFIG_FSL_ESDHC
480 #if CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC2_BASE_ADDR
481 	gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
482 #elif CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC3_BASE_ADDR
483 	gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
484 #else
485 	gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK);
486 #endif
487 #endif
488 	return 0;
489 }
490 
491 #define RCSR_MEM_CTL_WEIM	0
492 #define RCSR_MEM_CTL_NAND	1
493 #define RCSR_MEM_CTL_ATA	2
494 #define RCSR_MEM_CTL_EXPANSION	3
495 #define RCSR_MEM_TYPE_NOR	0
496 #define RCSR_MEM_TYPE_ONENAND	2
497 #define RCSR_MEM_TYPE_SD	0
498 #define RCSR_MEM_TYPE_I2C	2
499 #define RCSR_MEM_TYPE_SPI	3
500 
501 u32 spl_boot_device(void)
502 {
503 	struct ccm_regs *ccm =
504 		(struct ccm_regs *)IMX_CCM_BASE;
505 
506 	u32 rcsr = readl(&ccm->rcsr);
507 	u32 mem_type, mem_ctl;
508 
509 	/* In external mode, no boot device is returned */
510 	if ((rcsr >> 10) & 0x03)
511 		return BOOT_DEVICE_NONE;
512 
513 	mem_ctl = (rcsr >> 25) & 0x03;
514 	mem_type = (rcsr >> 23) & 0x03;
515 
516 	switch (mem_ctl) {
517 	case RCSR_MEM_CTL_WEIM:
518 		switch (mem_type) {
519 		case RCSR_MEM_TYPE_NOR:
520 			return BOOT_DEVICE_NOR;
521 		case RCSR_MEM_TYPE_ONENAND:
522 			return BOOT_DEVICE_ONENAND;
523 		default:
524 			return BOOT_DEVICE_NONE;
525 		}
526 	case RCSR_MEM_CTL_NAND:
527 		return BOOT_DEVICE_NAND;
528 	case RCSR_MEM_CTL_EXPANSION:
529 		switch (mem_type) {
530 		case RCSR_MEM_TYPE_SD:
531 			return BOOT_DEVICE_MMC1;
532 		case RCSR_MEM_TYPE_I2C:
533 			return BOOT_DEVICE_I2C;
534 		case RCSR_MEM_TYPE_SPI:
535 			return BOOT_DEVICE_SPI;
536 		default:
537 			return BOOT_DEVICE_NONE;
538 		}
539 	}
540 
541 	return BOOT_DEVICE_NONE;
542 }
543 
544 #ifdef CONFIG_SPL_BUILD
545 u32 spl_boot_mode(void)
546 {
547 	switch (spl_boot_device()) {
548 	case BOOT_DEVICE_MMC1:
549 #ifdef CONFIG_SPL_FAT_SUPPORT
550 		return MMCSD_MODE_FAT;
551 #else
552 		return MMCSD_MODE_RAW;
553 #endif
554 		break;
555 	case BOOT_DEVICE_NAND:
556 		return 0;
557 		break;
558 	default:
559 		puts("spl: ERROR:  unsupported device\n");
560 		hang();
561 	}
562 }
563 #endif
564