gurnard.c 10 KB

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