gurnard.c 10 KB

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