generic.c 10 KB

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