apf27.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2008-2013 Eric Jarrige <eric.jarrige@armadeus.org>
  4. *
  5. * based on the files by
  6. * Sascha Hauer, Pengutronix
  7. */
  8. #include <common.h>
  9. #include <hang.h>
  10. #include <init.h>
  11. #include <asm/global_data.h>
  12. #include <jffs2/jffs2.h>
  13. #include <nand.h>
  14. #include <netdev.h>
  15. #include <asm/io.h>
  16. #include <asm/arch/imx-regs.h>
  17. #include <asm/arch/gpio.h>
  18. #include <asm/gpio.h>
  19. #include <linux/errno.h>
  20. #include <u-boot/crc.h>
  21. #include "apf27.h"
  22. #include "fpga.h"
  23. DECLARE_GLOBAL_DATA_PTR;
  24. /*
  25. * Fuse bank 1 row 8 is "reserved for future use" and therefore available for
  26. * customer use. The APF27 board uses this fuse to store the board revision:
  27. * 0: initial board revision
  28. * 1: first revision - Presence of the second RAM chip on the board is blown in
  29. * fuse bank 1 row 9 bit 0 - No hardware change
  30. * N: to be defined
  31. */
  32. static u32 get_board_rev(void)
  33. {
  34. struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
  35. return readl(&iim->bank[1].fuse_regs[8]);
  36. }
  37. /*
  38. * Fuse bank 1 row 9 is "reserved for future use" and therefore available for
  39. * customer use. The APF27 board revision 1 uses the bit 0 to permanently store
  40. * the presence of the second RAM chip
  41. * 0: AFP27 with 1 RAM of 64 MiB
  42. * 1: AFP27 with 2 RAM chips of 64 MiB each (128MB)
  43. */
  44. static int get_num_ram_bank(void)
  45. {
  46. struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
  47. int nr_dram_banks = 1;
  48. if ((get_board_rev() > 0) && (CONFIG_NR_DRAM_BANKS > 1))
  49. nr_dram_banks += readl(&iim->bank[1].fuse_regs[9]) & 0x01;
  50. else
  51. nr_dram_banks = CONFIG_NR_DRAM_POPULATED;
  52. return nr_dram_banks;
  53. }
  54. static void apf27_port_init(int port, u32 gpio_dr, u32 ocr1, u32 ocr2,
  55. u32 iconfa1, u32 iconfa2, u32 iconfb1, u32 iconfb2,
  56. u32 icr1, u32 icr2, u32 imr, u32 gpio_dir, u32 gpr,
  57. u32 puen, u32 gius)
  58. {
  59. struct gpio_port_regs *regs = (struct gpio_port_regs *)IMX_GPIO_BASE;
  60. writel(gpio_dr, &regs->port[port].gpio_dr);
  61. writel(ocr1, &regs->port[port].ocr1);
  62. writel(ocr2, &regs->port[port].ocr2);
  63. writel(iconfa1, &regs->port[port].iconfa1);
  64. writel(iconfa2, &regs->port[port].iconfa2);
  65. writel(iconfb1, &regs->port[port].iconfb1);
  66. writel(iconfb2, &regs->port[port].iconfb2);
  67. writel(icr1, &regs->port[port].icr1);
  68. writel(icr2, &regs->port[port].icr2);
  69. writel(imr, &regs->port[port].imr);
  70. writel(gpio_dir, &regs->port[port].gpio_dir);
  71. writel(gpr, &regs->port[port].gpr);
  72. writel(puen, &regs->port[port].puen);
  73. writel(gius, &regs->port[port].gius);
  74. }
  75. #define APF27_PORT_INIT(n) apf27_port_init(PORT##n, ACFG_DR_##n##_VAL, \
  76. ACFG_OCR1_##n##_VAL, ACFG_OCR2_##n##_VAL, ACFG_ICFA1_##n##_VAL, \
  77. ACFG_ICFA2_##n##_VAL, ACFG_ICFB1_##n##_VAL, ACFG_ICFB2_##n##_VAL, \
  78. ACFG_ICR1_##n##_VAL, ACFG_ICR2_##n##_VAL, ACFG_IMR_##n##_VAL, \
  79. ACFG_DDIR_##n##_VAL, ACFG_GPR_##n##_VAL, ACFG_PUEN_##n##_VAL, \
  80. ACFG_GIUS_##n##_VAL)
  81. static void apf27_iomux_init(void)
  82. {
  83. APF27_PORT_INIT(A);
  84. APF27_PORT_INIT(B);
  85. APF27_PORT_INIT(C);
  86. APF27_PORT_INIT(D);
  87. APF27_PORT_INIT(E);
  88. APF27_PORT_INIT(F);
  89. }
  90. static int apf27_devices_init(void)
  91. {
  92. int i;
  93. unsigned int mode[] = {
  94. PC5_PF_I2C2_DATA,
  95. PC6_PF_I2C2_CLK,
  96. PD17_PF_I2C_DATA,
  97. PD18_PF_I2C_CLK,
  98. };
  99. for (i = 0; i < ARRAY_SIZE(mode); i++)
  100. imx_gpio_mode(mode[i]);
  101. #ifdef CONFIG_MXC_UART
  102. mx27_uart1_init_pins();
  103. #endif
  104. #ifdef CONFIG_FEC_MXC
  105. mx27_fec_init_pins();
  106. #endif
  107. #ifdef CONFIG_MMC_MXC
  108. mx27_sd2_init_pins();
  109. imx_gpio_mode((GPIO_PORTF | GPIO_OUT | GPIO_PUEN | GPIO_GPIO | 16));
  110. gpio_request(PC_PWRON, "pc_pwron");
  111. gpio_set_value(PC_PWRON, 1);
  112. #endif
  113. return 0;
  114. }
  115. static void apf27_setup_csx(void)
  116. {
  117. struct weim_regs *weim = (struct weim_regs *)IMX_WEIM_BASE;
  118. writel(ACFG_CS0U_VAL, &weim->cs0u);
  119. writel(ACFG_CS0L_VAL, &weim->cs0l);
  120. writel(ACFG_CS0A_VAL, &weim->cs0a);
  121. writel(ACFG_CS1U_VAL, &weim->cs1u);
  122. writel(ACFG_CS1L_VAL, &weim->cs1l);
  123. writel(ACFG_CS1A_VAL, &weim->cs1a);
  124. writel(ACFG_CS2U_VAL, &weim->cs2u);
  125. writel(ACFG_CS2L_VAL, &weim->cs2l);
  126. writel(ACFG_CS2A_VAL, &weim->cs2a);
  127. writel(ACFG_CS3U_VAL, &weim->cs3u);
  128. writel(ACFG_CS3L_VAL, &weim->cs3l);
  129. writel(ACFG_CS3A_VAL, &weim->cs3a);
  130. writel(ACFG_CS4U_VAL, &weim->cs4u);
  131. writel(ACFG_CS4L_VAL, &weim->cs4l);
  132. writel(ACFG_CS4A_VAL, &weim->cs4a);
  133. writel(ACFG_CS5U_VAL, &weim->cs5u);
  134. writel(ACFG_CS5L_VAL, &weim->cs5l);
  135. writel(ACFG_CS5A_VAL, &weim->cs5a);
  136. writel(ACFG_EIM_VAL, &weim->eim);
  137. }
  138. static void apf27_setup_port(void)
  139. {
  140. struct system_control_regs *system =
  141. (struct system_control_regs *)IMX_SYSTEM_CTL_BASE;
  142. writel(ACFG_FMCR_VAL, &system->fmcr);
  143. }
  144. int board_init(void)
  145. {
  146. gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
  147. apf27_setup_csx();
  148. apf27_setup_port();
  149. apf27_iomux_init();
  150. apf27_devices_init();
  151. #if defined(CONFIG_FPGA)
  152. APF27_init_fpga();
  153. #endif
  154. return 0;
  155. }
  156. int dram_init(void)
  157. {
  158. gd->ram_size = get_ram_size((void *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
  159. if (get_num_ram_bank() > 1)
  160. gd->ram_size += get_ram_size((void *)PHYS_SDRAM_2,
  161. PHYS_SDRAM_2_SIZE);
  162. return 0;
  163. }
  164. int dram_init_banksize(void)
  165. {
  166. gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
  167. gd->bd->bi_dram[0].size = get_ram_size((void *)PHYS_SDRAM_1,
  168. PHYS_SDRAM_1_SIZE);
  169. gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
  170. if (get_num_ram_bank() > 1)
  171. gd->bd->bi_dram[1].size = get_ram_size((void *)PHYS_SDRAM_2,
  172. PHYS_SDRAM_2_SIZE);
  173. else
  174. gd->bd->bi_dram[1].size = 0;
  175. return 0;
  176. }
  177. ulong board_get_usable_ram_top(ulong total_size)
  178. {
  179. ulong ramtop;
  180. if (get_num_ram_bank() > 1)
  181. ramtop = PHYS_SDRAM_2 + get_ram_size((void *)PHYS_SDRAM_2,
  182. PHYS_SDRAM_2_SIZE);
  183. else
  184. ramtop = PHYS_SDRAM_1 + get_ram_size((void *)PHYS_SDRAM_1,
  185. PHYS_SDRAM_1_SIZE);
  186. return ramtop;
  187. }
  188. int checkboard(void)
  189. {
  190. printf("Board: Armadeus APF27 revision %d\n", get_board_rev());
  191. return 0;
  192. }
  193. #ifdef CONFIG_SPL_BUILD
  194. inline void hang(void)
  195. {
  196. for (;;)
  197. ;
  198. }
  199. void board_init_f(ulong bootflag)
  200. {
  201. /*
  202. * copy ourselves from where we are running to where we were
  203. * linked at. Use ulong pointers as all addresses involved
  204. * are 4-byte-aligned.
  205. */
  206. ulong *start_ptr, *end_ptr, *link_ptr, *run_ptr, *dst;
  207. asm volatile ("ldr %0, =_start" : "=r"(start_ptr));
  208. asm volatile ("ldr %0, =_end" : "=r"(end_ptr));
  209. asm volatile ("ldr %0, =board_init_f" : "=r"(link_ptr));
  210. asm volatile ("adr %0, board_init_f" : "=r"(run_ptr));
  211. for (dst = start_ptr; dst < end_ptr; dst++)
  212. *dst = *(dst+(run_ptr-link_ptr));
  213. /*
  214. * branch to nand_boot's link-time address.
  215. */
  216. asm volatile("ldr pc, =nand_boot");
  217. }
  218. #endif /* CONFIG_SPL_BUILD */