1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Bluewater Systems Snapper 9260/9G20 modules
4  *
5  * (C) Copyright 2011 Bluewater Systems
6  *   Author: Andre Renaud <andre@bluewatersys.com>
7  *   Author: Ryan Mallon <ryan@bluewatersys.com>
8  */
9 
10 #include <common.h>
11 #include <atmel_lcd.h>
12 #include <atmel_lcdc.h>
13 #include <atmel_mci.h>
14 #include <dm.h>
15 #include <env.h>
16 #include <init.h>
17 #include <lcd.h>
18 #include <net.h>
19 #ifndef CONFIG_DM_ETH
20 #include <netdev.h>
21 #endif
22 #include <asm/global_data.h>
23 #include <asm/gpio.h>
24 #include <asm/io.h>
25 #include <asm/mach-types.h>
26 #include <asm/arch/at91sam9g45_matrix.h>
27 #include <asm/arch/at91sam9_smc.h>
28 #include <asm/arch/at91_common.h>
29 #include <asm/arch/at91_emac.h>
30 #include <asm/arch/at91_rstc.h>
31 #include <asm/arch/at91_rtc.h>
32 #include <asm/arch/at91_sck.h>
33 #include <asm/arch/atmel_serial.h>
34 #include <asm/arch/clk.h>
35 #include <asm/arch/gpio.h>
36 #include <dm/uclass-internal.h>
37 #include <linux/delay.h>
38 
39 #ifdef CONFIG_GURNARD_SPLASH
40 #include "splash_logo.h"
41 #endif
42 
43 DECLARE_GLOBAL_DATA_PTR;
44 
45 /* IO Expander pins */
46 #define IO_EXP_ETH_RESET	(0 << 1)
47 #define IO_EXP_ETH_POWER	(1 << 1)
48 
49 #ifdef CONFIG_MACB
gurnard_macb_hw_init(void)50 static void gurnard_macb_hw_init(void)
51 {
52 	struct at91_port *pioa = (struct at91_port *)ATMEL_BASE_PIOA;
53 
54 	at91_periph_clk_enable(ATMEL_ID_EMAC);
55 
56 	/*
57 	 * Enable pull-up on:
58 	 *	RXDV (PA12) => MODE0 - PHY also has pull-up
59 	 *	ERX0 (PA13) => MODE1 - PHY also has pull-up
60 	 *	ERX1 (PA15) => MODE2 - PHY also has pull-up
61 	 */
62 	writel(pin_to_mask(AT91_PIN_PA15) |
63 	       pin_to_mask(AT91_PIN_PA12) |
64 	       pin_to_mask(AT91_PIN_PA13),
65 	       &pioa->puer);
66 
67 	at91_phy_reset();
68 
69 	at91_macb_hw_init();
70 }
71 #endif
72 
73 #ifdef CONFIG_CMD_NAND
gurnard_nand_hw_init(void)74 static int gurnard_nand_hw_init(void)
75 {
76 	struct at91_matrix *matrix = (struct at91_matrix *)ATMEL_BASE_MATRIX;
77 	struct at91_smc *smc = (struct at91_smc *)ATMEL_BASE_SMC;
78 	ulong flags;
79 	int ret;
80 
81 	/* Enable CS3 as NAND/SmartMedia */
82 	setbits_le32(&matrix->ebicsa, AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
83 
84 	/* Configure SMC CS3 for NAND/SmartMedia */
85 	writel(AT91_SMC_SETUP_NWE(2) | AT91_SMC_SETUP_NCS_WR(0) |
86 	       AT91_SMC_SETUP_NRD(2) | AT91_SMC_SETUP_NCS_RD(0),
87 	       &smc->cs[3].setup);
88 	writel(AT91_SMC_PULSE_NWE(4) | AT91_SMC_PULSE_NCS_WR(4) |
89 	       AT91_SMC_PULSE_NRD(4) | AT91_SMC_PULSE_NCS_RD(4),
90 	       &smc->cs[3].pulse);
91 	writel(AT91_SMC_CYCLE_NWE(7) | AT91_SMC_CYCLE_NRD(7),
92 	       &smc->cs[3].cycle);
93 #ifdef CONFIG_SYS_NAND_DBW_16
94 	flags = AT91_SMC_MODE_DBW_16;
95 #else
96 	flags = AT91_SMC_MODE_DBW_8;
97 #endif
98 	writel(AT91_SMC_MODE_RM_NRD | AT91_SMC_MODE_WM_NWE |
99 	       AT91_SMC_MODE_EXNW_DISABLE |
100 	       flags |
101 	       AT91_SMC_MODE_TDF_CYCLE(3),
102 	       &smc->cs[3].mode);
103 
104 	ret = gpio_request(CONFIG_SYS_NAND_READY_PIN, "nand_rdy");
105 	if (ret)
106 		return ret;
107 	gpio_direction_input(CONFIG_SYS_NAND_READY_PIN);
108 
109 	/* Enable NandFlash */
110 	ret = gpio_request(CONFIG_SYS_NAND_ENABLE_PIN, "nand_ce");
111 	if (ret)
112 		return ret;
113 	gpio_direction_output(CONFIG_SYS_NAND_ENABLE_PIN, 1);
114 
115 	return 0;
116 }
117 #endif
118 
119 #ifdef CONFIG_GURNARD_SPLASH
lcd_splash(int width,int height)120 static void lcd_splash(int width, int height)
121 {
122 	u16 colour;
123 	int x, y;
124 	u16 *base_addr = (u16 *)gd->video_bottom;
125 
126 	memset(base_addr, 0xff, width * height * 2);
127 	/*
128 	 * Blit the logo to the center of the screen
129 	 */
130 	for (y = 0; y < BMP_LOGO_HEIGHT; y++) {
131 		for (x = 0; x < BMP_LOGO_WIDTH; x++) {
132 			int posx, posy;
133 			colour = bmp_logo_palette[bmp_logo_bitmap[
134 			    y * BMP_LOGO_WIDTH + x]];
135 			posx = x + (width - BMP_LOGO_WIDTH) / 2;
136 			posy = y;
137 			base_addr[posy * width + posx] = colour;
138 		}
139 	}
140 }
141 #endif
142 
143 #ifdef CONFIG_DM_VIDEO
at91sam9g45_lcd_hw_init(void)144 static void at91sam9g45_lcd_hw_init(void)
145 {
146 	at91_set_A_periph(AT91_PIN_PE0, 0);	/* LCDDPWR */
147 	at91_set_A_periph(AT91_PIN_PE2, 0);	/* LCDCC */
148 	at91_set_A_periph(AT91_PIN_PE3, 0);	/* LCDVSYNC */
149 	at91_set_A_periph(AT91_PIN_PE4, 0);	/* LCDHSYNC */
150 	at91_set_A_periph(AT91_PIN_PE5, 0);	/* LCDDOTCK */
151 
152 	at91_set_A_periph(AT91_PIN_PE7, 0);	/* LCDD0 */
153 	at91_set_A_periph(AT91_PIN_PE8, 0);	/* LCDD1 */
154 	at91_set_A_periph(AT91_PIN_PE9, 0);	/* LCDD2 */
155 	at91_set_A_periph(AT91_PIN_PE10, 0);	/* LCDD3 */
156 	at91_set_A_periph(AT91_PIN_PE11, 0);	/* LCDD4 */
157 	at91_set_A_periph(AT91_PIN_PE12, 0);	/* LCDD5 */
158 	at91_set_A_periph(AT91_PIN_PE13, 0);	/* LCDD6 */
159 	at91_set_A_periph(AT91_PIN_PE14, 0);	/* LCDD7 */
160 	at91_set_A_periph(AT91_PIN_PE15, 0);	/* LCDD8 */
161 	at91_set_A_periph(AT91_PIN_PE16, 0);	/* LCDD9 */
162 	at91_set_A_periph(AT91_PIN_PE17, 0);	/* LCDD10 */
163 	at91_set_A_periph(AT91_PIN_PE18, 0);	/* LCDD11 */
164 	at91_set_A_periph(AT91_PIN_PE19, 0);	/* LCDD12 */
165 	at91_set_B_periph(AT91_PIN_PE20, 0);	/* LCDD13 */
166 	at91_set_A_periph(AT91_PIN_PE21, 0);	/* LCDD14 */
167 	at91_set_A_periph(AT91_PIN_PE22, 0);	/* LCDD15 */
168 	at91_set_A_periph(AT91_PIN_PE23, 0);	/* LCDD16 */
169 	at91_set_A_periph(AT91_PIN_PE24, 0);	/* LCDD17 */
170 	at91_set_A_periph(AT91_PIN_PE25, 0);	/* LCDD18 */
171 	at91_set_A_periph(AT91_PIN_PE26, 0);	/* LCDD19 */
172 	at91_set_A_periph(AT91_PIN_PE27, 0);	/* LCDD20 */
173 	at91_set_B_periph(AT91_PIN_PE28, 0);	/* LCDD21 */
174 	at91_set_A_periph(AT91_PIN_PE29, 0);	/* LCDD22 */
175 	at91_set_A_periph(AT91_PIN_PE30, 0);	/* LCDD23 */
176 
177 	at91_periph_clk_enable(ATMEL_ID_LCDC);
178 }
179 #endif
180 
181 #ifdef CONFIG_GURNARD_FPGA
182 /**
183  * Initialise the memory bus settings so that we can talk to the
184  * memory mapped FPGA
185  */
fpga_hw_init(void)186 static int fpga_hw_init(void)
187 {
188 	struct at91_matrix *matrix = (struct at91_matrix *)ATMEL_BASE_MATRIX;
189 	struct at91_smc *smc = (struct at91_smc *)ATMEL_BASE_SMC;
190 	int i;
191 
192 	setbits_le32(&matrix->ebicsa, AT91_MATRIX_EBI_CS1A_SDRAMC);
193 
194 	at91_set_a_periph(2, 4, 0); /* EBIA21 */
195 	at91_set_a_periph(2, 5, 0); /* EBIA22 */
196 	at91_set_a_periph(2, 6, 0); /* EBIA23 */
197 	at91_set_a_periph(2, 7, 0); /* EBIA24 */
198 	at91_set_a_periph(2, 12, 0); /* EBIA25 */
199 	for (i = 15; i <= 31; i++) /* EBINWAIT & EBID16 - 31 */
200 		at91_set_a_periph(2, i, 0);
201 
202 	/* configure SMC cs0 for FPGA access timing */
203 	writel(AT91_SMC_SETUP_NWE(1) | AT91_SMC_SETUP_NCS_WR(2) |
204 	       AT91_SMC_SETUP_NRD(0) | AT91_SMC_SETUP_NCS_RD(2),
205 	       &smc->cs[0].setup);
206 	writel(AT91_SMC_PULSE_NWE(5) | AT91_SMC_PULSE_NCS_WR(4) |
207 	       AT91_SMC_PULSE_NRD(6) | AT91_SMC_PULSE_NCS_RD(4),
208 	       &smc->cs[0].pulse);
209 	writel(AT91_SMC_CYCLE_NWE(6) | AT91_SMC_CYCLE_NRD(6),
210 	       &smc->cs[0].cycle);
211 	writel(AT91_SMC_MODE_BAT |
212 	       AT91_SMC_MODE_EXNW_DISABLE |
213 	       AT91_SMC_MODE_DBW_32 |
214 	       AT91_SMC_MODE_TDF |
215 	       AT91_SMC_MODE_TDF_CYCLE(2),
216 	       &smc->cs[0].mode);
217 
218 	/* Do a write to within EBI_CS1 to enable the SDCK */
219 	writel(0, ATMEL_BASE_CS1);
220 
221 	return 0;
222 }
223 #endif
224 
225 #ifdef CONFIG_CMD_USB
226 
227 #define USB0_ENABLE_PIN		AT91_PIN_PB22
228 #define USB1_ENABLE_PIN		AT91_PIN_PB23
229 
gurnard_usb_init(void)230 void gurnard_usb_init(void)
231 {
232 	at91_set_gpio_output(USB0_ENABLE_PIN, 1);
233 	at91_set_gpio_value(USB0_ENABLE_PIN, 0);
234 	at91_set_gpio_output(USB1_ENABLE_PIN, 1);
235 	at91_set_gpio_value(USB1_ENABLE_PIN, 0);
236 }
237 #endif
238 
239 #ifdef CONFIG_GENERIC_ATMEL_MCI
cpu_mmc_init(struct bd_info * bis)240 int cpu_mmc_init(struct bd_info *bis)
241 {
242 	return atmel_mci_init((void *)ATMEL_BASE_MCI0);
243 }
244 #endif
245 
gurnard_enable_console(int enable)246 static void gurnard_enable_console(int enable)
247 {
248 	at91_set_gpio_output(AT91_PIN_PB14, 1);
249 	at91_set_gpio_value(AT91_PIN_PB14, enable ? 0 : 1);
250 }
251 
at91sam9g45_slowclock_init(void)252 void at91sam9g45_slowclock_init(void)
253 {
254 	/*
255 	 * On AT91SAM9G45 revC CPUs, the slow clock can be based on an
256 	 * internal impreciseRC oscillator or an external 32kHz oscillator.
257 	 * Switch to the latter.
258 	 */
259 	unsigned i, tmp;
260 	ulong *reg = (ulong *)ATMEL_BASE_SCKCR;
261 
262 	tmp = readl(reg);
263 	if ((tmp & AT91SAM9G45_SCKCR_OSCSEL) == AT91SAM9G45_SCKCR_OSCSEL_RC) {
264 		timer_init();
265 		tmp |= AT91SAM9G45_SCKCR_OSC32EN;
266 		writel(tmp, reg);
267 		for (i = 0; i < 1200; i++)
268 			udelay(1000);
269 		tmp |= AT91SAM9G45_SCKCR_OSCSEL_32;
270 		writel(tmp, reg);
271 		udelay(200);
272 		tmp &= ~AT91SAM9G45_SCKCR_RCEN;
273 		writel(tmp, reg);
274 	}
275 }
276 
board_early_init_f(void)277 int board_early_init_f(void)
278 {
279 	at91_seriald_hw_init();
280 	gurnard_enable_console(1);
281 
282 	return 0;
283 }
284 
board_init(void)285 int board_init(void)
286 {
287 	const char *rev_str;
288 #ifdef CONFIG_CMD_NAND
289 	int ret;
290 #endif
291 
292 	at91_periph_clk_enable(ATMEL_ID_PIOA);
293 	at91_periph_clk_enable(ATMEL_ID_PIOB);
294 	at91_periph_clk_enable(ATMEL_ID_PIOC);
295 	at91_periph_clk_enable(ATMEL_ID_PIODE);
296 
297 	at91sam9g45_slowclock_init();
298 
299 	/*
300 	 * Clear the RTC IDR to disable all IRQs. Avoid issues when Linux
301 	 * boots with spurious IRQs.
302 	 */
303 	writel(0xffffffff, AT91_RTC_IDR);
304 
305 	/* Make sure that the reset signal is attached properly */
306 	setbits_le32(AT91_ASM_RSTC_MR, AT91_RSTC_KEY | AT91_RSTC_MR_URSTEN);
307 
308 	gd->bd->bi_arch_number = MACH_TYPE_SNAPPER_9260;
309 
310 	/* Address of boot parameters */
311 	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
312 
313 #ifdef CONFIG_CMD_NAND
314 	ret = gurnard_nand_hw_init();
315 	if (ret)
316 		return ret;
317 #endif
318 #ifdef CONFIG_ATMEL_SPI
319 	at91_spi0_hw_init(1 << 4);
320 #endif
321 
322 #ifdef CONFIG_MACB
323 	gurnard_macb_hw_init();
324 #endif
325 
326 #ifdef CONFIG_GURNARD_FPGA
327 	fpga_hw_init();
328 #endif
329 
330 #ifdef CONFIG_CMD_USB
331 	gurnard_usb_init();
332 #endif
333 
334 #ifdef CONFIG_CMD_MMC
335 	at91_set_A_periph(AT91_PIN_PA12, 0);
336 	at91_set_gpio_output(AT91_PIN_PA8, 1);
337 	at91_set_gpio_value(AT91_PIN_PA8, 0);
338 	at91_mci_hw_init();
339 #endif
340 
341 #ifdef CONFIG_DM_VIDEO
342 	at91sam9g45_lcd_hw_init();
343 	at91_set_A_periph(AT91_PIN_PE6, 1);	/* power up */
344 
345 	/* Select the second timing index for board rev 2 */
346 	rev_str = env_get("board_rev");
347 	if (rev_str && !strncmp(rev_str, "2", 1)) {
348 		struct udevice *dev;
349 
350 		uclass_find_first_device(UCLASS_VIDEO, &dev);
351 		if (dev) {
352 			struct atmel_lcd_plat *plat = dev_get_plat(dev);
353 
354 			plat->timing_index = 1;
355 		}
356 	}
357 #endif
358 
359 	return 0;
360 }
361 
board_late_init(void)362 int board_late_init(void)
363 {
364 	u_int8_t env_enetaddr[8];
365 	char *env_str;
366 	char *end;
367 	int i;
368 
369 	/*
370 	 * Set MAC address so we do not need to init Ethernet before Linux
371 	 * boot
372 	 */
373 	env_str = env_get("ethaddr");
374 	if (env_str) {
375 		struct at91_emac *emac = (struct at91_emac *)ATMEL_BASE_EMAC;
376 		/* Parse MAC address */
377 		for (i = 0; i < 6; i++) {
378 			env_enetaddr[i] = env_str ?
379 				simple_strtoul(env_str, &end, 16) : 0;
380 			if (env_str)
381 				env_str = (*end) ? end+1 : end;
382 		}
383 
384 		/* Set hardware address */
385 		writel(env_enetaddr[0] | env_enetaddr[1] << 8 |
386 		       env_enetaddr[2] << 16 | env_enetaddr[3] << 24,
387 		       &emac->sa2l);
388 		writel((env_enetaddr[4] | env_enetaddr[5] << 8), &emac->sa2h);
389 
390 		printf("MAC:   %s\n", env_get("ethaddr"));
391 	} else {
392 		/* Not set in environment */
393 		printf("MAC:   not set\n");
394 	}
395 #ifdef CONFIG_GURNARD_SPLASH
396 	lcd_splash(480, 272);
397 #endif
398 
399 	return 0;
400 }
401 
402 #ifndef CONFIG_DM_ETH
board_eth_init(struct bd_info * bis)403 int board_eth_init(struct bd_info *bis)
404 {
405 	return macb_eth_initialize(0, (void *)ATMEL_BASE_EMAC, 0);
406 }
407 #endif
408 
dram_init(void)409 int dram_init(void)
410 {
411 	gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
412 				    CONFIG_SYS_SDRAM_SIZE);
413 	return 0;
414 }
415 
reset_phy(void)416 void reset_phy(void)
417 {
418 }
419 
420 static struct atmel_serial_plat at91sam9260_serial_plat = {
421 	.base_addr = ATMEL_BASE_DBGU,
422 };
423 
424 U_BOOT_DRVINFO(at91sam9260_serial) = {
425 	.name	= "serial_atmel",
426 	.plat = &at91sam9260_serial_plat,
427 };
428