generic.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /*
  2. * (C) Copyright 2009 DENX Software Engineering
  3. * Author: John Rigby <jrigby@gmail.com>
  4. *
  5. * Based on mx27/generic.c:
  6. * Copyright (c) 2008 Eric Jarrige <eric.jarrige@armadeus.org>
  7. * Copyright (c) 2009 Ilya Yanok <yanok@emcraft.com>
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License as
  11. * published by the Free Software Foundation; either version 2 of
  12. * the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  22. * MA 02111-1307 USA
  23. */
  24. #include <common.h>
  25. #include <div64.h>
  26. #include <netdev.h>
  27. #include <asm/io.h>
  28. #include <asm/arch/imx-regs.h>
  29. #include <asm/arch/imx25-pinmux.h>
  30. #ifdef CONFIG_MXC_MMC
  31. #include <asm/arch/mxcmmc.h>
  32. #endif
  33. /*
  34. * get the system pll clock in Hz
  35. *
  36. * mfi + mfn / (mfd +1)
  37. * f = 2 * f_ref * --------------------
  38. * pd + 1
  39. */
  40. static unsigned int imx_decode_pll (unsigned int pll, unsigned int f_ref)
  41. {
  42. unsigned int mfi = (pll >> CCM_PLL_MFI_SHIFT)
  43. & CCM_PLL_MFI_MASK;
  44. unsigned int mfn = (pll >> CCM_PLL_MFN_SHIFT)
  45. & CCM_PLL_MFN_MASK;
  46. unsigned int mfd = (pll >> CCM_PLL_MFD_SHIFT)
  47. & CCM_PLL_MFD_MASK;
  48. unsigned int pd = (pll >> CCM_PLL_PD_SHIFT)
  49. & CCM_PLL_PD_MASK;
  50. mfi = mfi <= 5 ? 5 : mfi;
  51. return lldiv (2 * (u64) f_ref * (mfi * (mfd + 1) + mfn),
  52. (mfd + 1) * (pd + 1));
  53. }
  54. static ulong imx_get_mpllclk (void)
  55. {
  56. struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
  57. ulong fref = 24000000;
  58. return imx_decode_pll (readl (&ccm->mpctl), fref);
  59. }
  60. ulong imx_get_armclk (void)
  61. {
  62. struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
  63. ulong cctl = readl (&ccm->cctl);
  64. ulong fref = imx_get_mpllclk ();
  65. ulong div;
  66. if (cctl & CCM_CCTL_ARM_SRC)
  67. fref = lldiv ((fref * 3), 4);
  68. div = ((cctl >> CCM_CCTL_ARM_DIV_SHIFT)
  69. & CCM_CCTL_ARM_DIV_MASK) + 1;
  70. return lldiv (fref, div);
  71. }
  72. ulong imx_get_ahbclk (void)
  73. {
  74. struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
  75. ulong cctl = readl (&ccm->cctl);
  76. ulong fref = imx_get_armclk ();
  77. ulong div;
  78. div = ((cctl >> CCM_CCTL_AHB_DIV_SHIFT)
  79. & CCM_CCTL_AHB_DIV_MASK) + 1;
  80. return lldiv (fref, div);
  81. }
  82. ulong imx_get_perclk (int clk)
  83. {
  84. struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
  85. ulong fref = imx_get_ahbclk ();
  86. ulong div;
  87. div = readl (&ccm->pcdr[CCM_PERCLK_REG (clk)]);
  88. div = ((div >> CCM_PERCLK_SHIFT (clk)) & CCM_PERCLK_MASK) + 1;
  89. return lldiv (fref, div);
  90. }
  91. u32 get_cpu_rev(void)
  92. {
  93. u32 srev;
  94. u32 system_rev = 0x25000;
  95. /* read SREV register from IIM module */
  96. struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
  97. srev = readl(&iim->iim_srev);
  98. switch (srev) {
  99. case 0x00:
  100. system_rev |= CHIP_REV_1_0;
  101. break;
  102. case 0x01:
  103. system_rev |= CHIP_REV_1_1;
  104. break;
  105. default:
  106. system_rev |= 0x8000;
  107. break;
  108. }
  109. return system_rev;
  110. }
  111. #if defined(CONFIG_DISPLAY_CPUINFO)
  112. int print_cpuinfo (void)
  113. {
  114. char buf[32];
  115. u32 cpurev = get_cpu_rev();
  116. printf("CPU: Freescale i.MX25 rev%d.%d%s at %s MHz\n\n",
  117. (cpurev & 0xF0) >> 4, (cpurev & 0x0F),
  118. ((cpurev & 0x8000) ? " unknown" : ""),
  119. strmhz (buf, imx_get_armclk ()));
  120. return 0;
  121. }
  122. #endif
  123. int cpu_eth_init (bd_t * bis)
  124. {
  125. #if defined(CONFIG_FEC_MXC)
  126. struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
  127. ulong val;
  128. val = readl (&ccm->cgr0);
  129. val |= (1 << 23);
  130. writel (val, &ccm->cgr0);
  131. return fecmxc_initialize (bis);
  132. #else
  133. return 0;
  134. #endif
  135. }
  136. /*
  137. * Initializes on-chip MMC controllers.
  138. * to override, implement board_mmc_init()
  139. */
  140. int cpu_mmc_init (bd_t * bis)
  141. {
  142. #ifdef CONFIG_MXC_MMC
  143. return mxc_mmc_init (bis);
  144. #else
  145. return 0;
  146. #endif
  147. }
  148. #ifdef CONFIG_MXC_UART
  149. void mx25_uart1_init_pins(void)
  150. {
  151. struct iomuxc_mux_ctl *muxctl;
  152. struct iomuxc_pad_ctl *padctl;
  153. u32 inpadctl;
  154. u32 outpadctl;
  155. u32 muxmode0;
  156. muxctl = (struct iomuxc_mux_ctl *)IMX_IOPADMUX_BASE;
  157. padctl = (struct iomuxc_pad_ctl *)IMX_IOPADCTL_BASE;
  158. muxmode0 = MX25_PIN_MUX_MODE (0);
  159. /*
  160. * set up input pins with hysteresis and 100K pull-ups
  161. */
  162. inpadctl = MX25_PIN_PAD_CTL_HYS
  163. | MX25_PIN_PAD_CTL_PKE
  164. | MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_100K_PU;
  165. /*
  166. * set up output pins with 100K pull-downs
  167. * FIXME: need to revisit this
  168. * PUE is ignored if PKE is not set
  169. * so the right value here is likely
  170. * 0x0 for no pull up/down
  171. * or
  172. * 0xc0 for 100k pull down
  173. */
  174. outpadctl = MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_100K_PD;
  175. /* UART1 */
  176. /* rxd */
  177. writel (muxmode0, &muxctl->pad_uart1_rxd);
  178. writel (inpadctl, &padctl->pad_uart1_rxd);
  179. /* txd */
  180. writel (muxmode0, &muxctl->pad_uart1_txd);
  181. writel (outpadctl, &padctl->pad_uart1_txd);
  182. /* rts */
  183. writel (muxmode0, &muxctl->pad_uart1_rts);
  184. writel (outpadctl, &padctl->pad_uart1_rts);
  185. /* cts */
  186. writel (muxmode0, &muxctl->pad_uart1_cts);
  187. writel (inpadctl, &padctl->pad_uart1_cts);
  188. }
  189. #endif /* CONFIG_MXC_UART */
  190. #ifdef CONFIG_FEC_MXC
  191. void mx25_fec_init_pins (void)
  192. {
  193. struct iomuxc_mux_ctl *muxctl;
  194. struct iomuxc_pad_ctl *padctl;
  195. u32 inpadctl_100kpd;
  196. u32 inpadctl_22kpu;
  197. u32 outpadctl;
  198. u32 muxmode0;
  199. muxctl = (struct iomuxc_mux_ctl *)IMX_IOPADMUX_BASE;
  200. padctl = (struct iomuxc_pad_ctl *)IMX_IOPADCTL_BASE;
  201. muxmode0 = MX25_PIN_MUX_MODE (0);
  202. inpadctl_100kpd = MX25_PIN_PAD_CTL_HYS
  203. | MX25_PIN_PAD_CTL_PKE
  204. | MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_100K_PD;
  205. inpadctl_22kpu = MX25_PIN_PAD_CTL_HYS
  206. | MX25_PIN_PAD_CTL_PKE
  207. | MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_22K_PU;
  208. /*
  209. * set up output pins with 100K pull-downs
  210. * FIXME: need to revisit this
  211. * PUE is ignored if PKE is not set
  212. * so the right value here is likely
  213. * 0x0 for no pull
  214. * or
  215. * 0xc0 for 100k pull down
  216. */
  217. outpadctl = MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_100K_PD;
  218. /* FEC_TX_CLK */
  219. writel (muxmode0, &muxctl->pad_fec_tx_clk);
  220. writel (inpadctl_100kpd, &padctl->pad_fec_tx_clk);
  221. /* FEC_RX_DV */
  222. writel (muxmode0, &muxctl->pad_fec_rx_dv);
  223. writel (inpadctl_100kpd, &padctl->pad_fec_rx_dv);
  224. /* FEC_RDATA0 */
  225. writel (muxmode0, &muxctl->pad_fec_rdata0);
  226. writel (inpadctl_100kpd, &padctl->pad_fec_rdata0);
  227. /* FEC_TDATA0 */
  228. writel (muxmode0, &muxctl->pad_fec_tdata0);
  229. writel (outpadctl, &padctl->pad_fec_tdata0);
  230. /* FEC_TX_EN */
  231. writel (muxmode0, &muxctl->pad_fec_tx_en);
  232. writel (outpadctl, &padctl->pad_fec_tx_en);
  233. /* FEC_MDC */
  234. writel (muxmode0, &muxctl->pad_fec_mdc);
  235. writel (outpadctl, &padctl->pad_fec_mdc);
  236. /* FEC_MDIO */
  237. writel (muxmode0, &muxctl->pad_fec_mdio);
  238. writel (inpadctl_22kpu, &padctl->pad_fec_mdio);
  239. /* FEC_RDATA1 */
  240. writel (muxmode0, &muxctl->pad_fec_rdata1);
  241. writel (inpadctl_100kpd, &padctl->pad_fec_rdata1);
  242. /* FEC_TDATA1 */
  243. writel (muxmode0, &muxctl->pad_fec_tdata1);
  244. writel (outpadctl, &padctl->pad_fec_tdata1);
  245. }
  246. void imx_get_mac_from_fuse(unsigned char *mac)
  247. {
  248. int i;
  249. struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
  250. struct fuse_bank *bank = &iim->bank[0];
  251. struct fuse_bank0_regs *fuse =
  252. (struct fuse_bank0_regs *)bank->fuse_regs;
  253. for (i = 0; i < 6; i++)
  254. mac[i] = readl(&fuse->mac_addr[i]) & 0xff;
  255. }
  256. #endif /* CONFIG_FEC_MXC */