gurnard.c 10 KB

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