gurnard.c 11 KB

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