generic.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  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. #if defined(CONFIG_DISPLAY_CPUINFO)
  92. int print_cpuinfo (void)
  93. {
  94. char buf[32];
  95. printf ("CPU: Freescale i.MX25 at %s MHz\n\n",
  96. strmhz (buf, imx_get_armclk ()));
  97. return 0;
  98. }
  99. #endif
  100. int cpu_eth_init (bd_t * bis)
  101. {
  102. #if defined(CONFIG_FEC_MXC)
  103. struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
  104. ulong val;
  105. val = readl (&ccm->cgr0);
  106. val |= (1 << 23);
  107. writel (val, &ccm->cgr0);
  108. return fecmxc_initialize (bis);
  109. #else
  110. return 0;
  111. #endif
  112. }
  113. /*
  114. * Initializes on-chip MMC controllers.
  115. * to override, implement board_mmc_init()
  116. */
  117. int cpu_mmc_init (bd_t * bis)
  118. {
  119. #ifdef CONFIG_MXC_MMC
  120. return mxc_mmc_init (bis);
  121. #else
  122. return 0;
  123. #endif
  124. }
  125. #ifdef CONFIG_MXC_UART
  126. void mx25_uart_init_pins (void)
  127. {
  128. struct iomuxc_mux_ctl *muxctl;
  129. struct iomuxc_pad_ctl *padctl;
  130. u32 inpadctl;
  131. u32 outpadctl;
  132. u32 muxmode0;
  133. muxctl = (struct iomuxc_mux_ctl *)IMX_IOPADMUX_BASE;
  134. padctl = (struct iomuxc_pad_ctl *)IMX_IOPADCTL_BASE;
  135. muxmode0 = MX25_PIN_MUX_MODE (0);
  136. /*
  137. * set up input pins with hysteresis and 100K pull-ups
  138. */
  139. inpadctl = MX25_PIN_PAD_CTL_HYS
  140. | MX25_PIN_PAD_CTL_PKE
  141. | MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_100K_PU;
  142. /*
  143. * set up output pins with 100K pull-downs
  144. * FIXME: need to revisit this
  145. * PUE is ignored if PKE is not set
  146. * so the right value here is likely
  147. * 0x0 for no pull up/down
  148. * or
  149. * 0xc0 for 100k pull down
  150. */
  151. outpadctl = MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_100K_PD;
  152. /* UART1 */
  153. /* rxd */
  154. writel (muxmode0, &muxctl->pad_uart1_rxd);
  155. writel (inpadctl, &padctl->pad_uart1_rxd);
  156. /* txd */
  157. writel (muxmode0, &muxctl->pad_uart1_txd);
  158. writel (outpadctl, &padctl->pad_uart1_txd);
  159. /* rts */
  160. writel (muxmode0, &muxctl->pad_uart1_rts);
  161. writel (outpadctl, &padctl->pad_uart1_rts);
  162. /* cts */
  163. writel (muxmode0, &muxctl->pad_uart1_cts);
  164. writel (inpadctl, &padctl->pad_uart1_cts);
  165. }
  166. #endif /* CONFIG_MXC_UART */
  167. #ifdef CONFIG_FEC_MXC
  168. void mx25_fec_init_pins (void)
  169. {
  170. struct iomuxc_mux_ctl *muxctl;
  171. struct iomuxc_pad_ctl *padctl;
  172. u32 inpadctl_100kpd;
  173. u32 inpadctl_22kpu;
  174. u32 outpadctl;
  175. u32 muxmode0;
  176. muxctl = (struct iomuxc_mux_ctl *)IMX_IOPADMUX_BASE;
  177. padctl = (struct iomuxc_pad_ctl *)IMX_IOPADCTL_BASE;
  178. muxmode0 = MX25_PIN_MUX_MODE (0);
  179. inpadctl_100kpd = MX25_PIN_PAD_CTL_HYS
  180. | MX25_PIN_PAD_CTL_PKE
  181. | MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_100K_PD;
  182. inpadctl_22kpu = MX25_PIN_PAD_CTL_HYS
  183. | MX25_PIN_PAD_CTL_PKE
  184. | MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_22K_PU;
  185. /*
  186. * set up output pins with 100K pull-downs
  187. * FIXME: need to revisit this
  188. * PUE is ignored if PKE is not set
  189. * so the right value here is likely
  190. * 0x0 for no pull
  191. * or
  192. * 0xc0 for 100k pull down
  193. */
  194. outpadctl = MX25_PIN_PAD_CTL_PUE | MX25_PIN_PAD_CTL_100K_PD;
  195. /* FEC_TX_CLK */
  196. writel (muxmode0, &muxctl->pad_fec_tx_clk);
  197. writel (inpadctl_100kpd, &padctl->pad_fec_tx_clk);
  198. /* FEC_RX_DV */
  199. writel (muxmode0, &muxctl->pad_fec_rx_dv);
  200. writel (inpadctl_100kpd, &padctl->pad_fec_rx_dv);
  201. /* FEC_RDATA0 */
  202. writel (muxmode0, &muxctl->pad_fec_rdata0);
  203. writel (inpadctl_100kpd, &padctl->pad_fec_rdata0);
  204. /* FEC_TDATA0 */
  205. writel (muxmode0, &muxctl->pad_fec_tdata0);
  206. writel (outpadctl, &padctl->pad_fec_tdata0);
  207. /* FEC_TX_EN */
  208. writel (muxmode0, &muxctl->pad_fec_tx_en);
  209. writel (outpadctl, &padctl->pad_fec_tx_en);
  210. /* FEC_MDC */
  211. writel (muxmode0, &muxctl->pad_fec_mdc);
  212. writel (outpadctl, &padctl->pad_fec_mdc);
  213. /* FEC_MDIO */
  214. writel (muxmode0, &muxctl->pad_fec_mdio);
  215. writel (inpadctl_22kpu, &padctl->pad_fec_mdio);
  216. /* FEC_RDATA1 */
  217. writel (muxmode0, &muxctl->pad_fec_rdata1);
  218. writel (inpadctl_100kpd, &padctl->pad_fec_rdata1);
  219. /* FEC_TDATA1 */
  220. writel (muxmode0, &muxctl->pad_fec_tdata1);
  221. writel (outpadctl, &padctl->pad_fec_tdata1);
  222. }
  223. #endif /* CONFIG_FEC_MXC */