xref: /openbmc/u-boot/arch/arm/cpu/arm926ejs/mxs/mxs.c (revision 64a93860)
1 /*
2  * Freescale i.MX23/i.MX28 common code
3  *
4  * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
5  * on behalf of DENX Software Engineering GmbH
6  *
7  * Based on code from LTIB:
8  * Copyright (C) 2010 Freescale Semiconductor, Inc.
9  *
10  * See file CREDITS for list of people who contributed to this
11  * project.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License as
15  * published by the Free Software Foundation; either version 2 of
16  * the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26  * MA 02111-1307 USA
27  */
28 
29 #include <common.h>
30 #include <asm/errno.h>
31 #include <asm/io.h>
32 #include <asm/arch/clock.h>
33 #include <asm/arch/dma.h>
34 #include <asm/arch/gpio.h>
35 #include <asm/arch/iomux.h>
36 #include <asm/arch/imx-regs.h>
37 #include <asm/arch/sys_proto.h>
38 
39 DECLARE_GLOBAL_DATA_PTR;
40 
41 /* 1 second delay should be plenty of time for block reset. */
42 #define	RESET_MAX_TIMEOUT	1000000
43 
44 #define	MXS_BLOCK_SFTRST	(1 << 31)
45 #define	MXS_BLOCK_CLKGATE	(1 << 30)
46 
47 /* Lowlevel init isn't used on i.MX28, so just have a dummy here */
48 inline void lowlevel_init(void) {}
49 
50 void reset_cpu(ulong ignored) __attribute__((noreturn));
51 
52 void reset_cpu(ulong ignored)
53 {
54 	struct mxs_rtc_regs *rtc_regs =
55 		(struct mxs_rtc_regs *)MXS_RTC_BASE;
56 	struct mxs_lcdif_regs *lcdif_regs =
57 		(struct mxs_lcdif_regs *)MXS_LCDIF_BASE;
58 
59 	/*
60 	 * Shut down the LCD controller as it interferes with BootROM boot mode
61 	 * pads sampling.
62 	 */
63 	writel(LCDIF_CTRL_RUN, &lcdif_regs->hw_lcdif_ctrl_clr);
64 
65 	/* Wait 1 uS before doing the actual watchdog reset */
66 	writel(1, &rtc_regs->hw_rtc_watchdog);
67 	writel(RTC_CTRL_WATCHDOGEN, &rtc_regs->hw_rtc_ctrl_set);
68 
69 	/* Endless loop, reset will exit from here */
70 	for (;;)
71 		;
72 }
73 
74 void enable_caches(void)
75 {
76 #ifndef CONFIG_SYS_ICACHE_OFF
77 	icache_enable();
78 #endif
79 #ifndef CONFIG_SYS_DCACHE_OFF
80 	dcache_enable();
81 #endif
82 }
83 
84 int mxs_wait_mask_set(struct mxs_register_32 *reg, uint32_t mask, unsigned
85 								int timeout)
86 {
87 	while (--timeout) {
88 		if ((readl(&reg->reg) & mask) == mask)
89 			break;
90 		udelay(1);
91 	}
92 
93 	return !timeout;
94 }
95 
96 int mxs_wait_mask_clr(struct mxs_register_32 *reg, uint32_t mask, unsigned
97 								int timeout)
98 {
99 	while (--timeout) {
100 		if ((readl(&reg->reg) & mask) == 0)
101 			break;
102 		udelay(1);
103 	}
104 
105 	return !timeout;
106 }
107 
108 int mxs_reset_block(struct mxs_register_32 *reg)
109 {
110 	/* Clear SFTRST */
111 	writel(MXS_BLOCK_SFTRST, &reg->reg_clr);
112 
113 	if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT))
114 		return 1;
115 
116 	/* Clear CLKGATE */
117 	writel(MXS_BLOCK_CLKGATE, &reg->reg_clr);
118 
119 	/* Set SFTRST */
120 	writel(MXS_BLOCK_SFTRST, &reg->reg_set);
121 
122 	/* Wait for CLKGATE being set */
123 	if (mxs_wait_mask_set(reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT))
124 		return 1;
125 
126 	/* Clear SFTRST */
127 	writel(MXS_BLOCK_SFTRST, &reg->reg_clr);
128 
129 	if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT))
130 		return 1;
131 
132 	/* Clear CLKGATE */
133 	writel(MXS_BLOCK_CLKGATE, &reg->reg_clr);
134 
135 	if (mxs_wait_mask_clr(reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT))
136 		return 1;
137 
138 	return 0;
139 }
140 
141 void mx28_fixup_vt(uint32_t start_addr)
142 {
143 	uint32_t *vt = (uint32_t *)0x20;
144 	int i;
145 
146 	for (i = 0; i < 8; i++)
147 		vt[i] = start_addr + (4 * i);
148 }
149 
150 #ifdef	CONFIG_ARCH_MISC_INIT
151 int arch_misc_init(void)
152 {
153 	mx28_fixup_vt(gd->relocaddr);
154 	return 0;
155 }
156 #endif
157 
158 int arch_cpu_init(void)
159 {
160 	struct mxs_clkctrl_regs *clkctrl_regs =
161 		(struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
162 	extern uint32_t _start;
163 
164 	mx28_fixup_vt((uint32_t)&_start);
165 
166 	/*
167 	 * Enable NAND clock
168 	 */
169 	/* Clear bypass bit */
170 	writel(CLKCTRL_CLKSEQ_BYPASS_GPMI,
171 		&clkctrl_regs->hw_clkctrl_clkseq_set);
172 
173 	/* Set GPMI clock to ref_gpmi / 12 */
174 	clrsetbits_le32(&clkctrl_regs->hw_clkctrl_gpmi,
175 		CLKCTRL_GPMI_CLKGATE | CLKCTRL_GPMI_DIV_MASK, 1);
176 
177 	udelay(1000);
178 
179 	/*
180 	 * Configure GPIO unit
181 	 */
182 	mxs_gpio_init();
183 
184 #ifdef	CONFIG_APBH_DMA
185 	/* Start APBH DMA */
186 	mxs_dma_init();
187 #endif
188 
189 	return 0;
190 }
191 
192 #if defined(CONFIG_DISPLAY_CPUINFO)
193 static const char *get_cpu_type(void)
194 {
195 	struct mxs_digctl_regs *digctl_regs =
196 		(struct mxs_digctl_regs *)MXS_DIGCTL_BASE;
197 
198 	switch (readl(&digctl_regs->hw_digctl_chipid) & HW_DIGCTL_CHIPID_MASK) {
199 	case HW_DIGCTL_CHIPID_MX23:
200 		return "23";
201 	case HW_DIGCTL_CHIPID_MX28:
202 		return "28";
203 	default:
204 		return "??";
205 	}
206 }
207 
208 static const char *get_cpu_rev(void)
209 {
210 	struct mxs_digctl_regs *digctl_regs =
211 		(struct mxs_digctl_regs *)MXS_DIGCTL_BASE;
212 	uint8_t rev = readl(&digctl_regs->hw_digctl_chipid) & 0x000000FF;
213 
214 	switch (readl(&digctl_regs->hw_digctl_chipid) & HW_DIGCTL_CHIPID_MASK) {
215 	case HW_DIGCTL_CHIPID_MX23:
216 		switch (rev) {
217 		case 0x0:
218 			return "1.0";
219 		case 0x1:
220 			return "1.1";
221 		case 0x2:
222 			return "1.2";
223 		case 0x3:
224 			return "1.3";
225 		case 0x4:
226 			return "1.4";
227 		default:
228 			return "??";
229 		}
230 	case HW_DIGCTL_CHIPID_MX28:
231 		switch (rev) {
232 		case 0x1:
233 			return "1.2";
234 		default:
235 			return "??";
236 		}
237 	default:
238 		return "??";
239 	}
240 }
241 
242 int print_cpuinfo(void)
243 {
244 	struct mxs_spl_data *data = (struct mxs_spl_data *)
245 		((CONFIG_SYS_TEXT_BASE - sizeof(struct mxs_spl_data)) & ~0xf);
246 
247 	printf("CPU:   Freescale i.MX%s rev%s at %d MHz\n",
248 		get_cpu_type(),
249 		get_cpu_rev(),
250 		mxc_get_clock(MXC_ARM_CLK) / 1000000);
251 	printf("BOOT:  %s\n", mxs_boot_modes[data->boot_mode_idx].mode);
252 	return 0;
253 }
254 #endif
255 
256 int do_mx28_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
257 {
258 	printf("CPU:   %3d MHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000000);
259 	printf("BUS:   %3d MHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000000);
260 	printf("EMI:   %3d MHz\n", mxc_get_clock(MXC_EMI_CLK));
261 	printf("GPMI:  %3d MHz\n", mxc_get_clock(MXC_GPMI_CLK) / 1000000);
262 	return 0;
263 }
264 
265 /*
266  * Initializes on-chip ethernet controllers.
267  */
268 #if defined(CONFIG_MX28) && defined(CONFIG_CMD_NET)
269 int cpu_eth_init(bd_t *bis)
270 {
271 	struct mxs_clkctrl_regs *clkctrl_regs =
272 		(struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
273 
274 	/* Turn on ENET clocks */
275 	clrbits_le32(&clkctrl_regs->hw_clkctrl_enet,
276 		CLKCTRL_ENET_SLEEP | CLKCTRL_ENET_DISABLE);
277 
278 	/* Set up ENET PLL for 50 MHz */
279 	/* Power on ENET PLL */
280 	writel(CLKCTRL_PLL2CTRL0_POWER,
281 		&clkctrl_regs->hw_clkctrl_pll2ctrl0_set);
282 
283 	udelay(10);
284 
285 	/* Gate on ENET PLL */
286 	writel(CLKCTRL_PLL2CTRL0_CLKGATE,
287 		&clkctrl_regs->hw_clkctrl_pll2ctrl0_clr);
288 
289 	/* Enable pad output */
290 	setbits_le32(&clkctrl_regs->hw_clkctrl_enet, CLKCTRL_ENET_CLK_OUT_EN);
291 
292 	return 0;
293 }
294 #endif
295 
296 static void __mx28_adjust_mac(int dev_id, unsigned char *mac)
297 {
298 	mac[0] = 0x00;
299 	mac[1] = 0x04; /* Use FSL vendor MAC address by default */
300 
301 	if (dev_id == 1) /* Let MAC1 be MAC0 + 1 by default */
302 		mac[5] += 1;
303 }
304 
305 void mx28_adjust_mac(int dev_id, unsigned char *mac)
306 	__attribute__((weak, alias("__mx28_adjust_mac")));
307 
308 #ifdef	CONFIG_MX28_FEC_MAC_IN_OCOTP
309 
310 #define	MXS_OCOTP_MAX_TIMEOUT	1000000
311 void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
312 {
313 	struct mxs_ocotp_regs *ocotp_regs =
314 		(struct mxs_ocotp_regs *)MXS_OCOTP_BASE;
315 	uint32_t data;
316 
317 	memset(mac, 0, 6);
318 
319 	writel(OCOTP_CTRL_RD_BANK_OPEN, &ocotp_regs->hw_ocotp_ctrl_set);
320 
321 	if (mxs_wait_mask_clr(&ocotp_regs->hw_ocotp_ctrl_reg, OCOTP_CTRL_BUSY,
322 				MXS_OCOTP_MAX_TIMEOUT)) {
323 		printf("MXS FEC: Can't get MAC from OCOTP\n");
324 		return;
325 	}
326 
327 	data = readl(&ocotp_regs->hw_ocotp_cust0);
328 
329 	mac[2] = (data >> 24) & 0xff;
330 	mac[3] = (data >> 16) & 0xff;
331 	mac[4] = (data >> 8) & 0xff;
332 	mac[5] = data & 0xff;
333 	mx28_adjust_mac(dev_id, mac);
334 }
335 #else
336 void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
337 {
338 	memset(mac, 0, 6);
339 }
340 #endif
341 
342 int mxs_dram_init(void)
343 {
344 	struct mxs_spl_data *data = (struct mxs_spl_data *)
345 		((CONFIG_SYS_TEXT_BASE - sizeof(struct mxs_spl_data)) & ~0xf);
346 
347 	if (data->mem_dram_size == 0) {
348 		printf("MXS:\n"
349 			"Error, the RAM size passed up from SPL is 0!\n");
350 		hang();
351 	}
352 
353 	gd->ram_size = data->mem_dram_size;
354 	return 0;
355 }
356 
357 U_BOOT_CMD(
358 	clocks,	CONFIG_SYS_MAXARGS, 1, do_mx28_showclocks,
359 	"display clocks",
360 	""
361 );
362