generic.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. /*
  2. * Copyright 2013 Freescale Semiconductor, Inc.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of
  7. * the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  17. * MA 02111-1307 USA
  18. */
  19. #include <common.h>
  20. #include <asm/io.h>
  21. #include <asm/arch/imx-regs.h>
  22. #include <asm/arch/clock.h>
  23. #include <asm/arch/crm_regs.h>
  24. #include <usb/regs-usbphy-mx6.h>
  25. #include <netdev.h>
  26. #include <asm/arch/sys_proto.h>
  27. #ifdef CONFIG_FSL_ESDHC
  28. #include <fsl_esdhc.h>
  29. #endif
  30. #ifdef CONFIG_FSL_ESDHC
  31. DECLARE_GLOBAL_DATA_PTR;
  32. #endif
  33. #ifdef CONFIG_MXC_OCOTP
  34. void enable_ocotp_clk(unsigned char enable)
  35. {
  36. struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
  37. u32 reg;
  38. reg = readl(&ccm->ccgr6);
  39. if (enable)
  40. reg |= CCM_CCGR6_OCOTP_CTRL_MASK;
  41. else
  42. reg &= ~CCM_CCGR6_OCOTP_CTRL_MASK;
  43. writel(reg, &ccm->ccgr6);
  44. }
  45. #endif
  46. static u32 get_mcu_main_clk(void)
  47. {
  48. struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
  49. u32 ccm_ccsr, ccm_cacrr, armclk_div;
  50. u32 sysclk_sel, pll_pfd_sel = 0;
  51. u32 freq = 0;
  52. ccm_ccsr = readl(&ccm->ccsr);
  53. sysclk_sel = ccm_ccsr & CCM_CCSR_SYS_CLK_SEL_MASK;
  54. sysclk_sel >>= CCM_CCSR_SYS_CLK_SEL_OFFSET;
  55. ccm_cacrr = readl(&ccm->cacrr);
  56. armclk_div = ccm_cacrr & CCM_CACRR_ARM_CLK_DIV_MASK;
  57. armclk_div >>= CCM_CACRR_ARM_CLK_DIV_OFFSET;
  58. armclk_div += 1;
  59. switch (sysclk_sel) {
  60. case 0:
  61. freq = FASE_CLK_FREQ;
  62. break;
  63. case 1:
  64. freq = SLOW_CLK_FREQ;
  65. break;
  66. case 2:
  67. pll_pfd_sel = ccm_ccsr & CCM_CCSR_PLL2_PFD_CLK_SEL_MASK;
  68. pll_pfd_sel >>= CCM_CCSR_PLL2_PFD_CLK_SEL_OFFSET;
  69. if (pll_pfd_sel == 0)
  70. freq = PLL2_MAIN_FREQ;
  71. else if (pll_pfd_sel == 1)
  72. freq = PLL2_PFD1_FREQ;
  73. else if (pll_pfd_sel == 2)
  74. freq = PLL2_PFD2_FREQ;
  75. else if (pll_pfd_sel == 3)
  76. freq = PLL2_PFD3_FREQ;
  77. else if (pll_pfd_sel == 4)
  78. freq = PLL2_PFD4_FREQ;
  79. break;
  80. case 3:
  81. freq = PLL2_MAIN_FREQ;
  82. break;
  83. case 4:
  84. pll_pfd_sel = ccm_ccsr & CCM_CCSR_PLL1_PFD_CLK_SEL_MASK;
  85. pll_pfd_sel >>= CCM_CCSR_PLL1_PFD_CLK_SEL_OFFSET;
  86. if (pll_pfd_sel == 0)
  87. freq = PLL1_MAIN_FREQ;
  88. else if (pll_pfd_sel == 1)
  89. freq = PLL1_PFD1_FREQ;
  90. else if (pll_pfd_sel == 2)
  91. freq = PLL1_PFD2_FREQ;
  92. else if (pll_pfd_sel == 3)
  93. freq = PLL1_PFD3_FREQ;
  94. else if (pll_pfd_sel == 4)
  95. freq = PLL1_PFD4_FREQ;
  96. break;
  97. case 5:
  98. freq = PLL3_MAIN_FREQ;
  99. break;
  100. default:
  101. printf("unsupported system clock select\n");
  102. }
  103. return freq / armclk_div;
  104. }
  105. static u32 get_bus_clk(void)
  106. {
  107. struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
  108. u32 ccm_cacrr, busclk_div;
  109. ccm_cacrr = readl(&ccm->cacrr);
  110. busclk_div = ccm_cacrr & CCM_CACRR_BUS_CLK_DIV_MASK;
  111. busclk_div >>= CCM_CACRR_BUS_CLK_DIV_OFFSET;
  112. busclk_div += 1;
  113. return get_mcu_main_clk() / busclk_div;
  114. }
  115. static u32 get_ipg_clk(void)
  116. {
  117. struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
  118. u32 ccm_cacrr, ipgclk_div;
  119. ccm_cacrr = readl(&ccm->cacrr);
  120. ipgclk_div = ccm_cacrr & CCM_CACRR_IPG_CLK_DIV_MASK;
  121. ipgclk_div >>= CCM_CACRR_IPG_CLK_DIV_OFFSET;
  122. ipgclk_div += 1;
  123. return get_bus_clk() / ipgclk_div;
  124. }
  125. static u32 get_uart_clk(void)
  126. {
  127. return get_ipg_clk();
  128. }
  129. static u32 get_sdhc_clk(void)
  130. {
  131. struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
  132. u32 ccm_cscmr1, ccm_cscdr2, sdhc_clk_sel, sdhc_clk_div;
  133. u32 freq = 0;
  134. ccm_cscmr1 = readl(&ccm->cscmr1);
  135. sdhc_clk_sel = ccm_cscmr1 & CCM_CSCMR1_ESDHC1_CLK_SEL_MASK;
  136. sdhc_clk_sel >>= CCM_CSCMR1_ESDHC1_CLK_SEL_OFFSET;
  137. ccm_cscdr2 = readl(&ccm->cscdr2);
  138. sdhc_clk_div = ccm_cscdr2 & CCM_CSCDR2_ESDHC1_CLK_DIV_MASK;
  139. sdhc_clk_div >>= CCM_CSCDR2_ESDHC1_CLK_DIV_OFFSET;
  140. sdhc_clk_div += 1;
  141. switch (sdhc_clk_sel) {
  142. case 0:
  143. freq = PLL3_MAIN_FREQ;
  144. break;
  145. case 1:
  146. freq = PLL3_PFD3_FREQ;
  147. break;
  148. case 2:
  149. freq = PLL1_PFD3_FREQ;
  150. break;
  151. case 3:
  152. freq = get_bus_clk();
  153. break;
  154. }
  155. return freq / sdhc_clk_div;
  156. }
  157. u32 get_fec_clk(void)
  158. {
  159. struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
  160. u32 ccm_cscmr2, rmii_clk_sel;
  161. u32 freq = 0;
  162. ccm_cscmr2 = readl(&ccm->cscmr2);
  163. rmii_clk_sel = ccm_cscmr2 & CCM_CSCMR2_RMII_CLK_SEL_MASK;
  164. rmii_clk_sel >>= CCM_CSCMR2_RMII_CLK_SEL_OFFSET;
  165. switch (rmii_clk_sel) {
  166. case 0:
  167. freq = ENET_EXTERNAL_CLK;
  168. break;
  169. case 1:
  170. freq = AUDIO_EXTERNAL_CLK;
  171. break;
  172. case 2:
  173. freq = PLL5_MAIN_FREQ;
  174. break;
  175. case 3:
  176. freq = PLL5_MAIN_FREQ / 2;
  177. break;
  178. }
  179. return freq;
  180. }
  181. unsigned int mxc_get_clock(enum mxc_clock clk)
  182. {
  183. switch (clk) {
  184. case MXC_ARM_CLK:
  185. return get_mcu_main_clk();
  186. case MXC_BUS_CLK:
  187. return get_bus_clk();
  188. case MXC_IPG_CLK:
  189. return get_ipg_clk();
  190. case MXC_UART_CLK:
  191. return get_uart_clk();
  192. case MXC_ESDHC_CLK:
  193. return get_sdhc_clk();
  194. case MXC_FEC_CLK:
  195. return get_fec_clk();
  196. default:
  197. break;
  198. }
  199. return -1;
  200. }
  201. /* Dump some core clocks */
  202. int do_vf610_showclocks(cmd_tbl_t *cmdtp, int flag, int argc,
  203. char * const argv[])
  204. {
  205. printf("\n");
  206. printf("cpu clock : %8d MHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000000);
  207. printf("bus clock : %8d MHz\n", mxc_get_clock(MXC_BUS_CLK) / 1000000);
  208. printf("ipg clock : %8d MHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000000);
  209. return 0;
  210. }
  211. U_BOOT_CMD(
  212. clocks, CONFIG_SYS_MAXARGS, 1, do_vf610_showclocks,
  213. "display clocks",
  214. ""
  215. );
  216. #ifdef CONFIG_FEC_MXC
  217. void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
  218. {
  219. struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
  220. struct fuse_bank *bank = &ocotp->bank[4];
  221. struct fuse_bank4_regs *fuse =
  222. (struct fuse_bank4_regs *)bank->fuse_regs;
  223. u32 value = readl(&fuse->mac_addr0);
  224. mac[0] = (value >> 8);
  225. mac[1] = value;
  226. value = readl(&fuse->mac_addr1);
  227. mac[2] = value >> 24;
  228. mac[3] = value >> 16;
  229. mac[4] = value >> 8;
  230. mac[5] = value;
  231. }
  232. #endif
  233. #if defined(CONFIG_DISPLAY_CPUINFO)
  234. static char *get_reset_cause(void)
  235. {
  236. u32 cause;
  237. struct src *src_regs = (struct src *)SRC_BASE_ADDR;
  238. cause = readl(&src_regs->srsr);
  239. writel(cause, &src_regs->srsr);
  240. cause &= 0xff;
  241. if (cause & 0x01)
  242. cause = 0x01;
  243. switch (cause) {
  244. case 0x01:
  245. return "POR";
  246. case 0x08:
  247. return "CA5 WDOG RESET";
  248. case 0x10:
  249. return "CM4 WDOG RESET";
  250. case 0x20:
  251. return "JTAG HIGH-Z";
  252. case 0x80:
  253. return "EXTERNAL RESET";
  254. default:
  255. return "unknown reset";
  256. }
  257. }
  258. int print_cpuinfo(void)
  259. {
  260. u32 cpurev;
  261. cpurev = get_cpu_rev();
  262. printf("CPU: Freescale Vybrid %x family rev%d.%d at %d MHz\n",
  263. (cpurev & 0xFFF000) >> 12,
  264. (cpurev & 0x000F0) >> 4,
  265. (cpurev & 0x0000F) >> 0,
  266. mxc_get_clock(MXC_ARM_CLK) / 1000000);
  267. printf("Reset cause: %s\n", get_reset_cause());
  268. return 0;
  269. }
  270. #endif
  271. int cpu_eth_init(bd_t *bis)
  272. {
  273. int rc = -ENODEV;
  274. #if defined(CONFIG_FEC_MXC)
  275. rc = fecmxc_initialize(bis);
  276. #endif
  277. return rc;
  278. }
  279. #ifdef CONFIG_FSL_ESDHC
  280. int cpu_mmc_init(bd_t *bis)
  281. {
  282. return fsl_esdhc_mmc_init(bis);
  283. }
  284. #endif
  285. int get_clocks(void)
  286. {
  287. #ifdef CONFIG_FSL_ESDHC
  288. gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
  289. #endif
  290. return 0;
  291. }
  292. void set_usboh3_clk(void)
  293. {
  294. udc_pins_setting();
  295. }
  296. void set_usb_phy1_clk(void)
  297. {
  298. struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
  299. struct anadig_reg *anadig = (struct anadig_reg *)ANADIG_BASE_ADDR;
  300. u32 reg;
  301. /*setup clocking and PLL*/
  302. reg = readl(&ccm->clpcr);
  303. reg &= ~CCM_CLPCR_SBYOS_MASK;
  304. writel(reg, &ccm->clpcr);
  305. /*setup 3v0 regulator*/
  306. reg = readl(&anadig->reg_3p0);
  307. reg |= ANADIG_3P0_EN_BO_MASK;
  308. reg |= ANADIG_3P0_EN_LINREG_MASK;
  309. writel(reg, &anadig->reg_3p0);
  310. while(!(readl(&anadig->reg_3p0)& ANADIG_3P0_OK_VDD3P0_MASK));
  311. reg = readl(&anadig->pll3_ctrl);
  312. reg &= ~ANADIG_PLL3_CTRL_BYPASS_CLK_SRC;
  313. reg &= ~ANADIG_PLL3_CTRL_BYPASS;
  314. reg |= ANADIG_PLL3_CTRL_POWERDOWN;
  315. reg |= ANADIG_PLL3_CTRL_ENUSBCLK;
  316. writel(reg, &anadig->pll3_ctrl);
  317. }
  318. void enable_usboh3_clk(unsigned char enable)
  319. {
  320. struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR;
  321. struct anadig_reg *anadig = (struct anadig_reg *)ANADIG_BASE_ADDR;
  322. u32 reg;
  323. reg = readl(&ccm->ccgr1);
  324. if (enable)
  325. reg |= CCM_CCGR1_USBC0_CTRL_MASK ;
  326. else
  327. reg &= ~CCM_CCGR1_USBC0_CTRL_MASK;
  328. writel(reg, &ccm->ccgr1);
  329. reg = readl(&anadig->pll3_ctrl);
  330. reg &= ~ANADIG_PLL3_CTRL_BYPASS_CLK_SRC;
  331. reg &= ~ANADIG_PLL3_CTRL_BYPASS;
  332. reg |= ANADIG_PLL3_CTRL_POWERDOWN;
  333. reg |= ANADIG_PLL3_CTRL_ENUSBCLK;
  334. writel(reg, &anadig->pll3_ctrl);
  335. }
  336. void enable_usb_phy1_clk(unsigned char enable)
  337. {
  338. u32 reg;
  339. void* usb_reg = (void *)0x40035800;
  340. if (enable) {
  341. writel(BM_USBPHY_CTRL_SFTRST | BM_USBPHY_CTRL_CLKGATE, USB_PHY0_BASE_ADDR + HW_USBPHY_CTRL_CLR);
  342. writel(BM_USBPHY_DEBUG_CLKGATE, USB_PHY0_BASE_ADDR + HW_USBPHY_DEBUG_CLR);
  343. writel(BM_USBPHY_CTRL_ENUTMILEVEL3 | BM_USBPHY_CTRL_ENUTMILEVEL2, USB_PHY0_BASE_ADDR + HW_USBPHY_CTRL_SET);
  344. writel(0, USB_PHY0_BASE_ADDR + HW_USBPHY_PWD);
  345. reg = readl(&usb_reg);
  346. reg |= 1<<9;
  347. writel(reg, &usb_reg);
  348. } else {
  349. writel(BM_USBPHY_CTRL_CLKGATE, USB_PHY0_BASE_ADDR + HW_USBPHY_CTRL_SET);
  350. }
  351. }
  352. #define USB_USBCMD (OTG_BASE_ADDR + 0x0140)
  353. #define USB_CMD_RUN_STOP (0x00000001)
  354. #define USB_CMD_CTRL_RESET (0x00000002)
  355. #define PORTSC_PHCD (1 << 23)
  356. #define USB_PORTSC1 (OTG_BASE_ADDR + 0x0184)
  357. void usb_phy_enable(void)
  358. {
  359. u32 tmp;
  360. void *phy_reg = USB_PHY0_BASE_ADDR;
  361. void *phy_ctrl;
  362. /* Stop then Reset */
  363. writel(readl(USB_USBCMD) & ~USB_CMD_RUN_STOP, USB_USBCMD);
  364. writel(readl(USB_USBCMD) | USB_CMD_CTRL_RESET, USB_USBCMD);
  365. /* Reset USBPHY module */
  366. phy_ctrl = HW_USBPHY_CTRL;
  367. writel(readl(phy_ctrl) | BM_USBPHY_CTRL_SFTRST, phy_ctrl);
  368. udelay(10);
  369. /* Remove CLKGATE and SFTRST */
  370. tmp = readl(phy_ctrl);
  371. tmp &= ~(BM_USBPHY_CTRL_CLKGATE | BM_USBPHY_CTRL_SFTRST);
  372. writel(tmp, phy_ctrl);
  373. udelay(10);
  374. /* Power up the PHY */
  375. writel(0, phy_reg + HW_USBPHY_PWD);
  376. /* enable FS/LS device */
  377. tmp = readl(phy_reg + HW_USBPHY_CTRL);
  378. tmp |= (BM_USBPHY_CTRL_ENUTMILEVEL2 | BM_USBPHY_CTRL_ENUTMILEVEL3);
  379. writel(tmp, phy_reg + HW_USBPHY_CTRL);
  380. if(readl(USB_PORTSC1) & PORTSC_PHCD) {
  381. writel(readl(USB_PORTSC1) & ~PORTSC_PHCD, USB_PORTSC1);
  382. mdelay(1);
  383. }
  384. writel(BM_USBPHY_CTRL_CLKGATE, phy_reg + HW_USBPHY_CTRL_CLR);
  385. tmp = (BM_USBPHY_PWD_TXPWDFS
  386. | BM_USBPHY_PWD_TXPWDIBIAS
  387. | BM_USBPHY_PWD_TXPWDV2I
  388. | BM_USBPHY_PWD_RXPWDENV
  389. | BM_USBPHY_PWD_RXPWD1PT1
  390. | BM_USBPHY_PWD_RXPWDDIFF
  391. | BM_USBPHY_PWD_RXPWDRX);
  392. writel(tmp, phy_reg + HW_USBPHY_PWD_CLR);
  393. mdelay(3);
  394. }