]>
git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/cpu/arm926ejs/mx27/generic.c
222a8e95eaf51997fee397a0407da4e5d9ff442d
2 * Copyright (c) 2008 Eric Jarrige <eric.jarrige@armadeus.org>
3 * Copyright (c) 2009 Ilya Yanok <yanok@emcraft.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25 #include <asm/arch/imx-regs.h>
27 #include <asm/arch/mxcmmc.h>
31 * get the system pll clock in Hz
33 * mfi + mfn / (mfd +1)
34 * f = 2 * f_ref * --------------------
37 unsigned int imx_decode_pll(unsigned int pll
, unsigned int f_ref
)
39 unsigned int mfi
= (pll
>> 10) & 0xf;
40 unsigned int mfn
= pll
& 0x3ff;
41 unsigned int mfd
= (pll
>> 16) & 0x3ff;
42 unsigned int pd
= (pll
>> 26) & 0xf;
44 mfi
= mfi
<= 5 ? 5 : mfi
;
46 return lldiv(2 * (u64
)f_ref
* (mfi
* (mfd
+ 1) + mfn
),
47 (mfd
+ 1) * (pd
+ 1));
50 static ulong
clk_in_32k(void)
52 return 1024 * CONFIG_MX27_CLK32
;
55 static ulong
clk_in_26m(void)
57 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
59 if (readl(&pll
->cscr
) & CSCR_OSC26M_DIV1P5
) {
61 return 26000000 * 2 / 3;
67 ulong
imx_get_mpllclk(void)
69 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
70 ulong cscr
= readl(&pll
->cscr
);
73 if (cscr
& CSCR_MCU_SEL
)
78 return imx_decode_pll(readl(&pll
->mpctl0
), fref
);
81 ulong
imx_get_armclk(void)
83 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
84 ulong cscr
= readl(&pll
->cscr
);
85 ulong fref
= imx_get_mpllclk();
88 if (!(cscr
& CSCR_ARM_SRC_MPLL
))
89 fref
= lldiv((fref
* 2), 3);
91 div
= ((cscr
>> 12) & 0x3) + 1;
93 return lldiv(fref
, div
);
96 ulong
imx_get_ahbclk(void)
98 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
99 ulong cscr
= readl(&pll
->cscr
);
100 ulong fref
= imx_get_mpllclk();
103 div
= ((cscr
>> 8) & 0x3) + 1;
105 return lldiv(fref
* 2, 3 * div
);
108 ulong
imx_get_spllclk(void)
110 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
111 ulong cscr
= readl(&pll
->cscr
);
114 if (cscr
& CSCR_SP_SEL
)
119 return imx_decode_pll(readl(&pll
->spctl0
), fref
);
122 static ulong
imx_decode_perclk(ulong div
)
124 return lldiv((imx_get_mpllclk() * 2), (div
* 3));
127 ulong
imx_get_perclk1(void)
129 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
131 return imx_decode_perclk((readl(&pll
->pcdr1
) & 0x3f) + 1);
134 ulong
imx_get_perclk2(void)
136 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
138 return imx_decode_perclk(((readl(&pll
->pcdr1
) >> 8) & 0x3f) + 1);
141 ulong
imx_get_perclk3(void)
143 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
145 return imx_decode_perclk(((readl(&pll
->pcdr1
) >> 16) & 0x3f) + 1);
148 ulong
imx_get_perclk4(void)
150 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
152 return imx_decode_perclk(((readl(&pll
->pcdr1
) >> 24) & 0x3f) + 1);
155 #if defined(CONFIG_DISPLAY_CPUINFO)
156 int print_cpuinfo (void)
160 printf("CPU: Freescale i.MX27 at %s MHz\n\n",
161 strmhz(buf
, imx_get_mpllclk()));
166 int cpu_eth_init(bd_t
*bis
)
168 #if defined(CONFIG_FEC_MXC)
169 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
171 /* enable FEC clock */
172 writel(readl(&pll
->pccr1
) | PCCR1_HCLK_FEC
, &pll
->pccr1
);
173 writel(readl(&pll
->pccr0
) | PCCR0_FEC_EN
, &pll
->pccr0
);
174 return fecmxc_initialize(bis
);
181 * Initializes on-chip MMC controllers.
182 * to override, implement board_mmc_init()
184 int cpu_mmc_init(bd_t
*bis
)
186 #ifdef CONFIG_MXC_MMC
187 return mxc_mmc_init(bis
);
193 void imx_gpio_mode(int gpio_mode
)
195 struct gpio_regs
*regs
= (struct gpio_regs
*)IMX_GPIO_BASE
;
196 unsigned int pin
= gpio_mode
& GPIO_PIN_MASK
;
197 unsigned int port
= (gpio_mode
& GPIO_PORT_MASK
) >> GPIO_PORT_SHIFT
;
198 unsigned int ocr
= (gpio_mode
& GPIO_OCR_MASK
) >> GPIO_OCR_SHIFT
;
199 unsigned int aout
= (gpio_mode
& GPIO_AOUT_MASK
) >> GPIO_AOUT_SHIFT
;
200 unsigned int bout
= (gpio_mode
& GPIO_BOUT_MASK
) >> GPIO_BOUT_SHIFT
;
204 if (gpio_mode
& GPIO_PUEN
) {
205 writel(readl(®s
->port
[port
].puen
) | (1 << pin
),
206 ®s
->port
[port
].puen
);
208 writel(readl(®s
->port
[port
].puen
) & ~(1 << pin
),
209 ®s
->port
[port
].puen
);
213 if (gpio_mode
& GPIO_OUT
) {
214 writel(readl(®s
->port
[port
].ddir
) | 1 << pin
,
215 ®s
->port
[port
].ddir
);
217 writel(readl(®s
->port
[port
].ddir
) & ~(1 << pin
),
218 ®s
->port
[port
].ddir
);
221 /* Primary / alternate function */
222 if (gpio_mode
& GPIO_AF
) {
223 writel(readl(®s
->port
[port
].gpr
) | (1 << pin
),
224 ®s
->port
[port
].gpr
);
226 writel(readl(®s
->port
[port
].gpr
) & ~(1 << pin
),
227 ®s
->port
[port
].gpr
);
231 if (!(gpio_mode
& (GPIO_PF
| GPIO_AF
))) {
232 writel(readl(®s
->port
[port
].gius
) | (1 << pin
),
233 ®s
->port
[port
].gius
);
235 writel(readl(®s
->port
[port
].gius
) & ~(1 << pin
),
236 ®s
->port
[port
].gius
);
239 /* Output / input configuration */
241 tmp
= readl(®s
->port
[port
].ocr1
);
242 tmp
&= ~(3 << (pin
* 2));
243 tmp
|= (ocr
<< (pin
* 2));
244 writel(tmp
, ®s
->port
[port
].ocr1
);
246 writel(readl(®s
->port
[port
].iconfa1
) & ~(3 << (pin
* 2)),
247 ®s
->port
[port
].iconfa1
);
248 writel(readl(®s
->port
[port
].iconfa1
) | aout
<< (pin
* 2),
249 ®s
->port
[port
].iconfa1
);
250 writel(readl(®s
->port
[port
].iconfb1
) & ~(3 << (pin
* 2)),
251 ®s
->port
[port
].iconfb1
);
252 writel(readl(®s
->port
[port
].iconfb1
) | bout
<< (pin
* 2),
253 ®s
->port
[port
].iconfb1
);
257 tmp
= readl(®s
->port
[port
].ocr2
);
258 tmp
&= ~(3 << (pin
* 2));
259 tmp
|= (ocr
<< (pin
* 2));
260 writel(tmp
, ®s
->port
[port
].ocr2
);
262 writel(readl(®s
->port
[port
].iconfa2
) & ~(3 << (pin
* 2)),
263 ®s
->port
[port
].iconfa2
);
264 writel(readl(®s
->port
[port
].iconfa2
) | aout
<< (pin
* 2),
265 ®s
->port
[port
].iconfa2
);
266 writel(readl(®s
->port
[port
].iconfb2
) & ~(3 << (pin
* 2)),
267 ®s
->port
[port
].iconfb2
);
268 writel(readl(®s
->port
[port
].iconfb2
) | bout
<< (pin
* 2),
269 ®s
->port
[port
].iconfb2
);
273 #ifdef CONFIG_MXC_UART
274 void mx27_uart1_init_pins(void)
277 unsigned int mode
[] = {
282 for (i
= 0; i
< ARRAY_SIZE(mode
); i
++)
283 imx_gpio_mode(mode
[i
]);
286 #endif /* CONFIG_MXC_UART */
288 #ifdef CONFIG_FEC_MXC
289 void mx27_fec_init_pins(void)
292 unsigned int mode
[] = {
302 PD9_AIN_FEC_MDC
| GPIO_PUEN
,
304 PD11_AOUT_FEC_TX_CLK
,
313 for (i
= 0; i
< ARRAY_SIZE(mode
); i
++)
314 imx_gpio_mode(mode
[i
]);
317 void imx_get_mac_from_fuse(unsigned char *mac
)
320 struct iim_regs
*iim
= (struct iim_regs
*)IMX_IIM_BASE
;
321 struct fuse_bank
*bank
= &iim
->bank
[0];
322 struct fuse_bank0_regs
*fuse
=
323 (struct fuse_bank0_regs
*)bank
->fuse_regs
;
325 for (i
= 0; i
< 6; i
++)
326 mac
[6 - 1 - i
] = readl(&fuse
->mac_addr
[i
]) & 0xff;
328 #endif /* CONFIG_FEC_MXC */
330 #ifdef CONFIG_MXC_MMC
331 void mx27_sd1_init_pins(void)
334 unsigned int mode
[] = {
343 for (i
= 0; i
< ARRAY_SIZE(mode
); i
++)
344 imx_gpio_mode(mode
[i
]);
348 void mx27_sd2_init_pins(void)
351 unsigned int mode
[] = {
360 for (i
= 0; i
< ARRAY_SIZE(mode
); i
++)
361 imx_gpio_mode(mode
[i
]);
364 #endif /* CONFIG_MXC_MMC */