]>
git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/cpu/arm926ejs/mx27/generic.c
2 * Copyright (c) 2008 Eric Jarrige <eric.jarrige@armadeus.org>
3 * Copyright (c) 2009 Ilya Yanok <yanok@emcraft.com>
5 * SPDX-License-Identifier: GPL-2.0+
12 #include <asm/arch/imx-regs.h>
13 #include <asm/arch/clock.h>
14 #include <asm/arch/gpio.h>
16 #include <asm/arch/mxcmmc.h>
20 * get the system pll clock in Hz
22 * mfi + mfn / (mfd +1)
23 * f = 2 * f_ref * --------------------
26 static unsigned int imx_decode_pll(unsigned int pll
, unsigned int f_ref
)
28 unsigned int mfi
= (pll
>> 10) & 0xf;
29 unsigned int mfn
= pll
& 0x3ff;
30 unsigned int mfd
= (pll
>> 16) & 0x3ff;
31 unsigned int pd
= (pll
>> 26) & 0xf;
33 mfi
= mfi
<= 5 ? 5 : mfi
;
35 return lldiv(2 * (u64
)f_ref
* (mfi
* (mfd
+ 1) + mfn
),
36 (mfd
+ 1) * (pd
+ 1));
39 static ulong
clk_in_32k(void)
41 return 1024 * CONFIG_MX27_CLK32
;
44 static ulong
clk_in_26m(void)
46 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
48 if (readl(&pll
->cscr
) & CSCR_OSC26M_DIV1P5
) {
50 return 26000000 * 2 / 3;
56 static ulong
imx_get_mpllclk(void)
58 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
59 ulong cscr
= readl(&pll
->cscr
);
62 if (cscr
& CSCR_MCU_SEL
)
67 return imx_decode_pll(readl(&pll
->mpctl0
), fref
);
70 static ulong
imx_get_armclk(void)
72 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
73 ulong cscr
= readl(&pll
->cscr
);
74 ulong fref
= imx_get_mpllclk();
77 if (!(cscr
& CSCR_ARM_SRC_MPLL
))
78 fref
= lldiv((fref
* 2), 3);
80 div
= ((cscr
>> 12) & 0x3) + 1;
82 return lldiv(fref
, div
);
85 static ulong
imx_get_ahbclk(void)
87 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
88 ulong cscr
= readl(&pll
->cscr
);
89 ulong fref
= imx_get_mpllclk();
92 div
= ((cscr
>> 8) & 0x3) + 1;
94 return lldiv(fref
* 2, 3 * div
);
97 static __attribute__((unused
)) ulong
imx_get_spllclk(void)
99 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
100 ulong cscr
= readl(&pll
->cscr
);
103 if (cscr
& CSCR_SP_SEL
)
108 return imx_decode_pll(readl(&pll
->spctl0
), fref
);
111 static ulong
imx_decode_perclk(ulong div
)
113 return lldiv((imx_get_mpllclk() * 2), (div
* 3));
116 static ulong
imx_get_perclk1(void)
118 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
120 return imx_decode_perclk((readl(&pll
->pcdr1
) & 0x3f) + 1);
123 static ulong
imx_get_perclk2(void)
125 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
127 return imx_decode_perclk(((readl(&pll
->pcdr1
) >> 8) & 0x3f) + 1);
130 static __attribute__((unused
)) ulong
imx_get_perclk3(void)
132 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
134 return imx_decode_perclk(((readl(&pll
->pcdr1
) >> 16) & 0x3f) + 1);
137 static __attribute__((unused
)) ulong
imx_get_perclk4(void)
139 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
141 return imx_decode_perclk(((readl(&pll
->pcdr1
) >> 24) & 0x3f) + 1);
144 unsigned int mxc_get_clock(enum mxc_clock clk
)
148 return imx_get_armclk();
150 return imx_get_ahbclk()/2;
152 return imx_get_perclk1();
154 return imx_get_ahbclk();
156 return imx_get_perclk2();
162 #if defined(CONFIG_DISPLAY_CPUINFO)
163 int print_cpuinfo (void)
167 printf("CPU: Freescale i.MX27 at %s MHz\n\n",
168 strmhz(buf
, imx_get_mpllclk()));
173 int cpu_eth_init(bd_t
*bis
)
175 #if defined(CONFIG_FEC_MXC)
176 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
178 /* enable FEC clock */
179 writel(readl(&pll
->pccr1
) | PCCR1_HCLK_FEC
, &pll
->pccr1
);
180 writel(readl(&pll
->pccr0
) | PCCR0_FEC_EN
, &pll
->pccr0
);
181 return fecmxc_initialize(bis
);
188 * Initializes on-chip MMC controllers.
189 * to override, implement board_mmc_init()
191 int cpu_mmc_init(bd_t
*bis
)
193 #ifdef CONFIG_MXC_MMC
194 return mxc_mmc_init(bis
);
200 void imx_gpio_mode(int gpio_mode
)
202 struct gpio_port_regs
*regs
= (struct gpio_port_regs
*)IMX_GPIO_BASE
;
203 unsigned int pin
= gpio_mode
& GPIO_PIN_MASK
;
204 unsigned int port
= (gpio_mode
& GPIO_PORT_MASK
) >> GPIO_PORT_SHIFT
;
205 unsigned int ocr
= (gpio_mode
& GPIO_OCR_MASK
) >> GPIO_OCR_SHIFT
;
206 unsigned int aout
= (gpio_mode
& GPIO_AOUT_MASK
) >> GPIO_AOUT_SHIFT
;
207 unsigned int bout
= (gpio_mode
& GPIO_BOUT_MASK
) >> GPIO_BOUT_SHIFT
;
211 if (gpio_mode
& GPIO_PUEN
) {
212 writel(readl(®s
->port
[port
].puen
) | (1 << pin
),
213 ®s
->port
[port
].puen
);
215 writel(readl(®s
->port
[port
].puen
) & ~(1 << pin
),
216 ®s
->port
[port
].puen
);
220 if (gpio_mode
& GPIO_OUT
) {
221 writel(readl(®s
->port
[port
].gpio_dir
) | 1 << pin
,
222 ®s
->port
[port
].gpio_dir
);
224 writel(readl(®s
->port
[port
].gpio_dir
) & ~(1 << pin
),
225 ®s
->port
[port
].gpio_dir
);
228 /* Primary / alternate function */
229 if (gpio_mode
& GPIO_AF
) {
230 writel(readl(®s
->port
[port
].gpr
) | (1 << pin
),
231 ®s
->port
[port
].gpr
);
233 writel(readl(®s
->port
[port
].gpr
) & ~(1 << pin
),
234 ®s
->port
[port
].gpr
);
238 if (!(gpio_mode
& (GPIO_PF
| GPIO_AF
))) {
239 writel(readl(®s
->port
[port
].gius
) | (1 << pin
),
240 ®s
->port
[port
].gius
);
242 writel(readl(®s
->port
[port
].gius
) & ~(1 << pin
),
243 ®s
->port
[port
].gius
);
246 /* Output / input configuration */
248 tmp
= readl(®s
->port
[port
].ocr1
);
249 tmp
&= ~(3 << (pin
* 2));
250 tmp
|= (ocr
<< (pin
* 2));
251 writel(tmp
, ®s
->port
[port
].ocr1
);
253 writel(readl(®s
->port
[port
].iconfa1
) & ~(3 << (pin
* 2)),
254 ®s
->port
[port
].iconfa1
);
255 writel(readl(®s
->port
[port
].iconfa1
) | aout
<< (pin
* 2),
256 ®s
->port
[port
].iconfa1
);
257 writel(readl(®s
->port
[port
].iconfb1
) & ~(3 << (pin
* 2)),
258 ®s
->port
[port
].iconfb1
);
259 writel(readl(®s
->port
[port
].iconfb1
) | bout
<< (pin
* 2),
260 ®s
->port
[port
].iconfb1
);
264 tmp
= readl(®s
->port
[port
].ocr2
);
265 tmp
&= ~(3 << (pin
* 2));
266 tmp
|= (ocr
<< (pin
* 2));
267 writel(tmp
, ®s
->port
[port
].ocr2
);
269 writel(readl(®s
->port
[port
].iconfa2
) & ~(3 << (pin
* 2)),
270 ®s
->port
[port
].iconfa2
);
271 writel(readl(®s
->port
[port
].iconfa2
) | aout
<< (pin
* 2),
272 ®s
->port
[port
].iconfa2
);
273 writel(readl(®s
->port
[port
].iconfb2
) & ~(3 << (pin
* 2)),
274 ®s
->port
[port
].iconfb2
);
275 writel(readl(®s
->port
[port
].iconfb2
) | bout
<< (pin
* 2),
276 ®s
->port
[port
].iconfb2
);
280 #ifdef CONFIG_MXC_UART
281 void mx27_uart1_init_pins(void)
284 unsigned int mode
[] = {
289 for (i
= 0; i
< ARRAY_SIZE(mode
); i
++)
290 imx_gpio_mode(mode
[i
]);
293 #endif /* CONFIG_MXC_UART */
295 #ifdef CONFIG_FEC_MXC
296 void mx27_fec_init_pins(void)
299 unsigned int mode
[] = {
309 PD9_AIN_FEC_MDC
| GPIO_PUEN
,
311 PD11_AOUT_FEC_TX_CLK
,
320 for (i
= 0; i
< ARRAY_SIZE(mode
); i
++)
321 imx_gpio_mode(mode
[i
]);
324 void imx_get_mac_from_fuse(int dev_id
, unsigned char *mac
)
327 struct iim_regs
*iim
= (struct iim_regs
*)IMX_IIM_BASE
;
328 struct fuse_bank
*bank
= &iim
->bank
[0];
329 struct fuse_bank0_regs
*fuse
=
330 (struct fuse_bank0_regs
*)bank
->fuse_regs
;
332 for (i
= 0; i
< 6; i
++)
333 mac
[6 - 1 - i
] = readl(&fuse
->mac_addr
[i
]) & 0xff;
335 #endif /* CONFIG_FEC_MXC */
337 #ifdef CONFIG_MXC_MMC
338 void mx27_sd1_init_pins(void)
341 unsigned int mode
[] = {
350 for (i
= 0; i
< ARRAY_SIZE(mode
); i
++)
351 imx_gpio_mode(mode
[i
]);
355 void mx27_sd2_init_pins(void)
358 unsigned int mode
[] = {
367 for (i
= 0; i
< ARRAY_SIZE(mode
); i
++)
368 imx_gpio_mode(mode
[i
]);
371 #endif /* CONFIG_MXC_MMC */
373 #ifndef CONFIG_SYS_DCACHE_OFF
374 void enable_caches(void)
376 /* Enable D-cache. I-cache is already enabled in start.S */
379 #endif /* CONFIG_SYS_DCACHE_OFF */