am1808_lowlevel.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. /*
  2. * SoC-specific lowlevel code for AM1808 and similar chips
  3. *
  4. * Copyright (C) 2011
  5. * Heiko Schocher, DENX Software Engineering, hs@denx.de.
  6. *
  7. * See file CREDITS for list of people who contributed to this
  8. * project.
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23. */
  24. #include <common.h>
  25. #include <nand.h>
  26. #include <ns16550.h>
  27. #include <post.h>
  28. #include <asm/arch/am1808_lowlevel.h>
  29. #include <asm/arch/hardware.h>
  30. #include <asm/arch/ddr2_defs.h>
  31. #include <asm/arch/emif_defs.h>
  32. void am1808_waitloop(unsigned long loopcnt)
  33. {
  34. unsigned long i;
  35. for (i = 0; i < loopcnt; i++)
  36. asm(" NOP");
  37. }
  38. int am1808_pll_init(struct davinci_pllc_regs *reg, unsigned long pllmult)
  39. {
  40. if (reg == davinci_pllc0_regs)
  41. /* Unlock PLL registers. */
  42. clrbits_le32(&davinci_syscfg_regs->cfgchip0, 0x00000010);
  43. /*
  44. * Set PLLENSRC '0',bit 5, PLL Enable(PLLEN) selection is controlled
  45. * through MMR
  46. */
  47. clrbits_le32(&reg->pllctl, 0x00000020);
  48. /* PLLCTL.EXTCLKSRC bit 9 should be left at 0 for Freon */
  49. clrbits_le32(&reg->pllctl, 0x00000200);
  50. /* Set PLLEN=0 => PLL BYPASS MODE */
  51. clrbits_le32(&reg->pllctl, 0x00000001);
  52. am1808_waitloop(150);
  53. if (reg == davinci_pllc0_regs) {
  54. /*
  55. * Select the Clock Mode bit 8 as External Clock or On Chip
  56. * Oscilator
  57. */
  58. dv_maskbits(&reg->pllctl, 0xFFFFFEFF);
  59. setbits_le32(&reg->pllctl, (CONFIG_SYS_DV_CLKMODE << 8));
  60. }
  61. /* Clear PLLRST bit to reset the PLL */
  62. clrbits_le32(&reg->pllctl, 0x00000008);
  63. /* Disable the PLL output */
  64. setbits_le32(&reg->pllctl, 0x00000010);
  65. /* PLL initialization sequence */
  66. /*
  67. * Power up the PLL- PWRDN bit set to 0 to bring the PLL out of
  68. * power down bit
  69. */
  70. clrbits_le32(&reg->pllctl, 0x00000002);
  71. /* Enable the PLL from Disable Mode PLLDIS bit to 0 */
  72. clrbits_le32(&reg->pllctl, 0x00000010);
  73. /* Program the required multiplier value in PLLM */
  74. writel(pllmult, &reg->pllm);
  75. /* program the postdiv */
  76. if (reg == davinci_pllc0_regs)
  77. writel((0x8000 | CONFIG_SYS_AM1808_PLL0_POSTDIV),
  78. &reg->postdiv);
  79. else
  80. writel((0x8000 | CONFIG_SYS_AM1808_PLL1_POSTDIV),
  81. &reg->postdiv);
  82. /*
  83. * Check for the GOSTAT bit in PLLSTAT to clear to 0 to indicate that
  84. * no GO operation is currently in progress
  85. */
  86. while ((readl(&reg->pllstat) & 0x1) == 1)
  87. ;
  88. if (reg == davinci_pllc0_regs) {
  89. writel(CONFIG_SYS_AM1808_PLL0_PLLDIV1, &reg->plldiv1);
  90. writel(CONFIG_SYS_AM1808_PLL0_PLLDIV2, &reg->plldiv2);
  91. writel(CONFIG_SYS_AM1808_PLL0_PLLDIV3, &reg->plldiv3);
  92. writel(CONFIG_SYS_AM1808_PLL0_PLLDIV4, &reg->plldiv4);
  93. writel(CONFIG_SYS_AM1808_PLL0_PLLDIV5, &reg->plldiv5);
  94. writel(CONFIG_SYS_AM1808_PLL0_PLLDIV6, &reg->plldiv6);
  95. writel(CONFIG_SYS_AM1808_PLL0_PLLDIV7, &reg->plldiv7);
  96. } else {
  97. writel(CONFIG_SYS_AM1808_PLL1_PLLDIV1, &reg->plldiv1);
  98. writel(CONFIG_SYS_AM1808_PLL1_PLLDIV2, &reg->plldiv2);
  99. writel(CONFIG_SYS_AM1808_PLL1_PLLDIV3, &reg->plldiv3);
  100. }
  101. /*
  102. * Set the GOSET bit in PLLCMD to 1 to initiate a new divider
  103. * transition.
  104. */
  105. setbits_le32(&reg->pllcmd, 0x01);
  106. /*
  107. * Wait for the GOSTAT bit in PLLSTAT to clear to 0
  108. * (completion of phase alignment).
  109. */
  110. while ((readl(&reg->pllstat) & 0x1) == 1)
  111. ;
  112. /* Wait for PLL to reset properly. See PLL spec for PLL reset time */
  113. am1808_waitloop(200);
  114. /* Set the PLLRST bit in PLLCTL to 1 to bring the PLL out of reset */
  115. setbits_le32(&reg->pllctl, 0x00000008);
  116. /* Wait for PLL to lock. See PLL spec for PLL lock time */
  117. am1808_waitloop(2400);
  118. /*
  119. * Set the PLLEN bit in PLLCTL to 1 to remove the PLL from bypass
  120. * mode
  121. */
  122. setbits_le32(&reg->pllctl, 0x00000001);
  123. /*
  124. * clear EMIFA and EMIFB clock source settings, let them
  125. * run off SYSCLK
  126. */
  127. if (reg == davinci_pllc0_regs)
  128. dv_maskbits(&davinci_syscfg_regs->cfgchip3, 0xFFFFFFF8);
  129. return 0;
  130. }
  131. void am1808_lpc_transition(unsigned char pscnum, unsigned char module,
  132. unsigned char domain, unsigned char state)
  133. {
  134. struct davinci_psc_regs *reg;
  135. dv_reg_p mdstat, mdctl;
  136. if (pscnum == 0) {
  137. reg = davinci_psc0_regs;
  138. mdstat = &reg->psc0.mdstat[module];
  139. mdctl = &reg->psc0.mdctl[module];
  140. } else {
  141. reg = davinci_psc1_regs;
  142. mdstat = &reg->psc1.mdstat[module];
  143. mdctl = &reg->psc1.mdctl[module];
  144. }
  145. /* Wait for any outstanding transition to complete */
  146. while ((readl(&reg->ptstat) & (0x00000001 << domain)))
  147. ;
  148. /* If we are already in that state, just return */
  149. if ((readl(mdstat) & 0x1F) == state)
  150. return;
  151. /* Perform transition */
  152. writel((readl(mdctl) & 0xFFFFFFE0) | state, mdctl);
  153. setbits_le32(&reg->ptcmd, (0x00000001 << domain));
  154. /* Wait for transition to complete */
  155. while (readl(&reg->ptstat) & (0x00000001 << domain))
  156. ;
  157. /* Wait and verify the state */
  158. while ((readl(mdstat) & 0x1F) != state)
  159. ;
  160. }
  161. int am1808_ddr_setup(unsigned int freq)
  162. {
  163. unsigned long tmp;
  164. /* Enable the Clock to DDR2/mDDR */
  165. am1808_lpc_transition(1, 6, 0, PSC_ENABLE);
  166. tmp = readl(&davinci_syscfg1_regs->vtpio_ctl);
  167. if ((tmp & VTP_POWERDWN) == VTP_POWERDWN) {
  168. /* Begin VTP Calibration */
  169. clrbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_POWERDWN);
  170. clrbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_LOCK);
  171. setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_CLKRZ);
  172. clrbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_CLKRZ);
  173. setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_CLKRZ);
  174. /* Polling READY bit to see when VTP calibration is done */
  175. tmp = readl(&davinci_syscfg1_regs->vtpio_ctl);
  176. while ((tmp & VTP_READY) != VTP_READY)
  177. tmp = readl(&davinci_syscfg1_regs->vtpio_ctl);
  178. setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_LOCK);
  179. setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_POWERDWN);
  180. setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_IOPWRDWN);
  181. }
  182. writel(CONFIG_SYS_AM1808_DDR2_DDRPHYCR, &dv_ddr2_regs_ctrl->ddrphycr);
  183. clrbits_le32(&davinci_syscfg1_regs->ddr_slew,
  184. (1 << DDR_SLEW_CMOSEN_BIT));
  185. setbits_le32(&dv_ddr2_regs_ctrl->sdbcr, DV_DDR_BOOTUNLOCK);
  186. writel((CONFIG_SYS_AM1808_DDR2_SDBCR & ~0xf0000000) |
  187. (readl(&dv_ddr2_regs_ctrl->sdbcr) & 0xf0000000), /*rsv Bytes*/
  188. &dv_ddr2_regs_ctrl->sdbcr);
  189. writel(CONFIG_SYS_AM1808_DDR2_SDBCR2, &dv_ddr2_regs_ctrl->sdbcr2);
  190. writel(CONFIG_SYS_AM1808_DDR2_SDTIMR, &dv_ddr2_regs_ctrl->sdtimr);
  191. writel(CONFIG_SYS_AM1808_DDR2_SDTIMR2, &dv_ddr2_regs_ctrl->sdtimr2);
  192. clrbits_le32(&dv_ddr2_regs_ctrl->sdbcr,
  193. (1 << DV_DDR_SDCR_TIMUNLOCK_SHIFT));
  194. /*
  195. * LPMODEN and MCLKSTOPEN must be set!
  196. * Without this bits set, PSC don;t switch states !!
  197. */
  198. writel(CONFIG_SYS_AM1808_DDR2_SDRCR |
  199. (1 << DV_DDR_SRCR_LPMODEN_SHIFT) |
  200. (1 << DV_DDR_SRCR_MCLKSTOPEN_SHIFT),
  201. &dv_ddr2_regs_ctrl->sdrcr);
  202. /* SyncReset the Clock to EMIF3A SDRAM */
  203. am1808_lpc_transition(1, 6, 0, PSC_SYNCRESET);
  204. /* Enable the Clock to EMIF3A SDRAM */
  205. am1808_lpc_transition(1, 6, 0, PSC_ENABLE);
  206. /* disable self refresh */
  207. clrbits_le32(&dv_ddr2_regs_ctrl->sdrcr, 0xc0000000);
  208. writel(0x30, &dv_ddr2_regs_ctrl->pbbpr);
  209. return 0;
  210. }
  211. static void am1808_set_mdctl(dv_reg_p mdctl)
  212. {
  213. if ((readl(mdctl) & 0x1F) != PSC_ENABLE)
  214. writel(((readl(mdctl) & 0xFFFFFFE0) | PSC_ENABLE), mdctl);
  215. }
  216. void am1808_psc_init(void)
  217. {
  218. struct davinci_psc_regs *reg;
  219. int i;
  220. /* PSC 0 domain 0 init */
  221. reg = davinci_psc0_regs;
  222. while ((readl(&reg->ptstat) & 0x00000001))
  223. ;
  224. for (i = 3; i <= 4 ; i++)
  225. am1808_set_mdctl(&reg->psc0.mdctl[i]);
  226. for (i = 7; i <= 12 ; i++)
  227. am1808_set_mdctl(&reg->psc0.mdctl[i]);
  228. /* Do Always-On Power Domain Transitions */
  229. setbits_le32(&reg->ptcmd, 0x00000001);
  230. while (readl(&reg->ptstat) & 0x00000001)
  231. ;
  232. /* PSC1, domain 1 init */
  233. reg = davinci_psc1_regs;
  234. while ((readl(&reg->ptstat) & 0x00000001))
  235. ;
  236. am1808_set_mdctl(&reg->psc1.mdctl[3]);
  237. am1808_set_mdctl(&reg->psc1.mdctl[6]);
  238. /* UART1 + UART2 */
  239. for (i = 12 ; i <= 13 ; i++)
  240. am1808_set_mdctl(&reg->psc1.mdctl[i]);
  241. am1808_set_mdctl(&reg->psc1.mdctl[26]);
  242. am1808_set_mdctl(&reg->psc1.mdctl[31]);
  243. /* Do Always-On Power Domain Transitions */
  244. setbits_le32(&reg->ptcmd, 0x00000001);
  245. while (readl(&reg->ptstat) & 0x00000001)
  246. ;
  247. }
  248. void am1808_pinmux_ctl(unsigned long offset, unsigned long mask,
  249. unsigned long value)
  250. {
  251. clrbits_le32(&davinci_syscfg_regs->pinmux[offset], mask);
  252. setbits_le32(&davinci_syscfg_regs->pinmux[offset], (mask & value));
  253. }
  254. __attribute__((weak))
  255. void board_gpio_init(void)
  256. {
  257. return;
  258. }
  259. #if defined(CONFIG_NAND_SPL)
  260. void nand_boot(void)
  261. {
  262. __attribute__((noreturn)) void (*uboot)(void);
  263. /* copy image from NOR to RAM */
  264. memcpy((void *)CONFIG_SYS_NAND_U_BOOT_DST,
  265. (void *)CONFIG_SYS_NAND_U_BOOT_OFFS,
  266. CONFIG_SYS_NAND_U_BOOT_SIZE);
  267. /* and jump to it ... */
  268. uboot = (void *)CONFIG_SYS_NAND_U_BOOT_START;
  269. (*uboot)();
  270. }
  271. #endif
  272. #if defined(CONFIG_NAND_SPL)
  273. void board_init_f(ulong bootflag)
  274. #else
  275. int arch_cpu_init(void)
  276. #endif
  277. {
  278. /*
  279. * copied from arch/arm/cpu/arm926ejs/start.S
  280. *
  281. * flush v4 I/D caches
  282. */
  283. asm("mov r0, #0");
  284. asm("mcr p15, 0, r0, c7, c7, 0"); /* flush v3/v4 cache */
  285. asm("mcr p15, 0, r0, c8, c7, 0"); /* flush v4 TLB */
  286. /*
  287. * disable MMU stuff and caches
  288. */
  289. asm("mrc p15, 0, r0, c1, c0, 0");
  290. /* clear bits 13, 9:8 (--V- --RS) */
  291. asm("bic r0, r0, #0x00002300");
  292. /* clear bits 7, 2:0 (B--- -CAM) */
  293. asm("bic r0, r0, #0x00000087");
  294. /* set bit 2 (A) Align */
  295. asm("orr r0, r0, #0x00000002");
  296. /* set bit 12 (I) I-Cache */
  297. asm("orr r0, r0, #0x00001000");
  298. asm("mcr p15, 0, r0, c1, c0, 0");
  299. /* Unlock kick registers */
  300. writel(0x83e70b13, &davinci_syscfg_regs->kick0);
  301. writel(0x95a4f1e0, &davinci_syscfg_regs->kick1);
  302. dv_maskbits(&davinci_syscfg_regs->suspsrc,
  303. ((1 << 27) | (1 << 22) | (1 << 20) | (1 << 5) | (1 << 16)));
  304. /* System PSC setup - enable all */
  305. am1808_psc_init();
  306. /* Setup Pinmux */
  307. am1808_pinmux_ctl(0, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX0);
  308. am1808_pinmux_ctl(1, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX1);
  309. am1808_pinmux_ctl(2, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX2);
  310. am1808_pinmux_ctl(3, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX3);
  311. am1808_pinmux_ctl(4, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX4);
  312. am1808_pinmux_ctl(5, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX5);
  313. am1808_pinmux_ctl(6, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX6);
  314. am1808_pinmux_ctl(7, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX7);
  315. am1808_pinmux_ctl(8, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX8);
  316. am1808_pinmux_ctl(9, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX9);
  317. am1808_pinmux_ctl(10, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX10);
  318. am1808_pinmux_ctl(11, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX11);
  319. am1808_pinmux_ctl(12, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX12);
  320. am1808_pinmux_ctl(13, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX13);
  321. am1808_pinmux_ctl(14, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX14);
  322. am1808_pinmux_ctl(15, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX15);
  323. am1808_pinmux_ctl(16, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX16);
  324. am1808_pinmux_ctl(17, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX17);
  325. am1808_pinmux_ctl(18, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX18);
  326. am1808_pinmux_ctl(19, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX19);
  327. /* PLL setup */
  328. am1808_pll_init(davinci_pllc0_regs, CONFIG_SYS_AM1808_PLL0_PLLM);
  329. am1808_pll_init(davinci_pllc1_regs, CONFIG_SYS_AM1808_PLL1_PLLM);
  330. /* GPIO setup */
  331. board_gpio_init();
  332. /* setup CSn config */
  333. writel(CONFIG_SYS_AM1808_CS2CFG, &davinci_emif_regs->ab1cr);
  334. writel(CONFIG_SYS_AM1808_CS3CFG, &davinci_emif_regs->ab2cr);
  335. am1808_lpc_transition(1, 13, 0, PSC_ENABLE);
  336. NS16550_init((NS16550_t)(CONFIG_SYS_NS16550_COM1),
  337. CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE);
  338. /*
  339. * Fix Power and Emulation Management Register
  340. * see sprufw3a.pdf page 37 Table 24
  341. */
  342. writel(readl((CONFIG_SYS_NS16550_COM1 + 0x30)) | 0x00006001,
  343. (CONFIG_SYS_NS16550_COM1 + 0x30));
  344. #if defined(CONFIG_NAND_SPL)
  345. puts("ddr init\n");
  346. am1808_ddr_setup(132);
  347. puts("boot u-boot ...\n");
  348. nand_boot();
  349. #else
  350. am1808_ddr_setup(132);
  351. return 0;
  352. #endif
  353. }