]>
git.ipfire.org Git - thirdparty/u-boot.git/blob - arch/arm/cpu/arm926ejs/mx27/generic.c
9bed0e91bea670b085a007e2807ff7b9aac0a900
1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2008 Eric Jarrige <eric.jarrige@armadeus.org>
4 * Copyright (c) 2009 Ilya Yanok <yanok@emcraft.com>
12 #include <asm/arch/imx-regs.h>
13 #include <asm/arch/clock.h>
14 #include <asm/arch/gpio.h>
15 #include <asm/mach-imx/sys_proto.h>
17 #include <asm/arch/mxcmmc.h>
21 * get the system pll clock in Hz
23 * mfi + mfn / (mfd +1)
24 * f = 2 * f_ref * --------------------
27 static unsigned int imx_decode_pll(unsigned int pll
, unsigned int f_ref
)
29 unsigned int mfi
= (pll
>> 10) & 0xf;
30 unsigned int mfn
= pll
& 0x3ff;
31 unsigned int mfd
= (pll
>> 16) & 0x3ff;
32 unsigned int pd
= (pll
>> 26) & 0xf;
34 mfi
= mfi
<= 5 ? 5 : mfi
;
36 return lldiv(2 * (u64
)f_ref
* (mfi
* (mfd
+ 1) + mfn
),
37 (mfd
+ 1) * (pd
+ 1));
40 static ulong
clk_in_32k(void)
42 return 1024 * CONFIG_MX27_CLK32
;
45 static ulong
clk_in_26m(void)
47 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
49 if (readl(&pll
->cscr
) & CSCR_OSC26M_DIV1P5
) {
51 return 26000000 * 2 / 3;
57 static ulong
imx_get_mpllclk(void)
59 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
60 ulong cscr
= readl(&pll
->cscr
);
63 if (cscr
& CSCR_MCU_SEL
)
68 return imx_decode_pll(readl(&pll
->mpctl0
), fref
);
71 static ulong
imx_get_armclk(void)
73 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
74 ulong cscr
= readl(&pll
->cscr
);
75 ulong fref
= imx_get_mpllclk();
78 if (!(cscr
& CSCR_ARM_SRC_MPLL
))
79 fref
= lldiv((fref
* 2), 3);
81 div
= ((cscr
>> 12) & 0x3) + 1;
83 return lldiv(fref
, div
);
86 static ulong
imx_get_ahbclk(void)
88 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
89 ulong cscr
= readl(&pll
->cscr
);
90 ulong fref
= imx_get_mpllclk();
93 div
= ((cscr
>> 8) & 0x3) + 1;
95 return lldiv(fref
* 2, 3 * div
);
98 static __attribute__((unused
)) ulong
imx_get_spllclk(void)
100 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
101 ulong cscr
= readl(&pll
->cscr
);
104 if (cscr
& CSCR_SP_SEL
)
109 return imx_decode_pll(readl(&pll
->spctl0
), fref
);
112 static ulong
imx_decode_perclk(ulong div
)
114 return lldiv((imx_get_mpllclk() * 2), (div
* 3));
117 static ulong
imx_get_perclk1(void)
119 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
121 return imx_decode_perclk((readl(&pll
->pcdr1
) & 0x3f) + 1);
124 static ulong
imx_get_perclk2(void)
126 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
128 return imx_decode_perclk(((readl(&pll
->pcdr1
) >> 8) & 0x3f) + 1);
131 static __attribute__((unused
)) ulong
imx_get_perclk3(void)
133 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
135 return imx_decode_perclk(((readl(&pll
->pcdr1
) >> 16) & 0x3f) + 1);
138 static __attribute__((unused
)) ulong
imx_get_perclk4(void)
140 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
142 return imx_decode_perclk(((readl(&pll
->pcdr1
) >> 24) & 0x3f) + 1);
145 unsigned int mxc_get_clock(enum mxc_clock clk
)
149 return imx_get_armclk();
151 return imx_get_ahbclk()/2;
153 return imx_get_perclk1();
155 return imx_get_ahbclk();
157 return imx_get_perclk2();
163 u32
get_cpu_rev(void)
165 return MXC_CPU_MX27
<< 12;
168 #if defined(CONFIG_DISPLAY_CPUINFO)
169 int print_cpuinfo (void)
173 printf("CPU: Freescale i.MX27 at %s MHz\n\n",
174 strmhz(buf
, imx_get_mpllclk()));
179 int cpu_eth_init(bd_t
*bis
)
181 #if defined(CONFIG_FEC_MXC)
182 struct pll_regs
*pll
= (struct pll_regs
*)IMX_PLL_BASE
;
184 /* enable FEC clock */
185 writel(readl(&pll
->pccr1
) | PCCR1_HCLK_FEC
, &pll
->pccr1
);
186 writel(readl(&pll
->pccr0
) | PCCR0_FEC_EN
, &pll
->pccr0
);
187 return fecmxc_initialize(bis
);
194 * Initializes on-chip MMC controllers.
195 * to override, implement board_mmc_init()
197 int cpu_mmc_init(bd_t
*bis
)
199 #ifdef CONFIG_MMC_MXC
200 return mxc_mmc_init(bis
);
206 void imx_gpio_mode(int gpio_mode
)
208 struct gpio_port_regs
*regs
= (struct gpio_port_regs
*)IMX_GPIO_BASE
;
209 unsigned int pin
= gpio_mode
& GPIO_PIN_MASK
;
210 unsigned int port
= (gpio_mode
& GPIO_PORT_MASK
) >> GPIO_PORT_SHIFT
;
211 unsigned int ocr
= (gpio_mode
& GPIO_OCR_MASK
) >> GPIO_OCR_SHIFT
;
212 unsigned int aout
= (gpio_mode
& GPIO_AOUT_MASK
) >> GPIO_AOUT_SHIFT
;
213 unsigned int bout
= (gpio_mode
& GPIO_BOUT_MASK
) >> GPIO_BOUT_SHIFT
;
217 if (gpio_mode
& GPIO_PUEN
) {
218 writel(readl(®s
->port
[port
].puen
) | (1 << pin
),
219 ®s
->port
[port
].puen
);
221 writel(readl(®s
->port
[port
].puen
) & ~(1 << pin
),
222 ®s
->port
[port
].puen
);
226 if (gpio_mode
& GPIO_OUT
) {
227 writel(readl(®s
->port
[port
].gpio_dir
) | 1 << pin
,
228 ®s
->port
[port
].gpio_dir
);
230 writel(readl(®s
->port
[port
].gpio_dir
) & ~(1 << pin
),
231 ®s
->port
[port
].gpio_dir
);
234 /* Primary / alternate function */
235 if (gpio_mode
& GPIO_AF
) {
236 writel(readl(®s
->port
[port
].gpr
) | (1 << pin
),
237 ®s
->port
[port
].gpr
);
239 writel(readl(®s
->port
[port
].gpr
) & ~(1 << pin
),
240 ®s
->port
[port
].gpr
);
244 if (!(gpio_mode
& (GPIO_PF
| GPIO_AF
))) {
245 writel(readl(®s
->port
[port
].gius
) | (1 << pin
),
246 ®s
->port
[port
].gius
);
248 writel(readl(®s
->port
[port
].gius
) & ~(1 << pin
),
249 ®s
->port
[port
].gius
);
252 /* Output / input configuration */
254 tmp
= readl(®s
->port
[port
].ocr1
);
255 tmp
&= ~(3 << (pin
* 2));
256 tmp
|= (ocr
<< (pin
* 2));
257 writel(tmp
, ®s
->port
[port
].ocr1
);
259 writel(readl(®s
->port
[port
].iconfa1
) & ~(3 << (pin
* 2)),
260 ®s
->port
[port
].iconfa1
);
261 writel(readl(®s
->port
[port
].iconfa1
) | aout
<< (pin
* 2),
262 ®s
->port
[port
].iconfa1
);
263 writel(readl(®s
->port
[port
].iconfb1
) & ~(3 << (pin
* 2)),
264 ®s
->port
[port
].iconfb1
);
265 writel(readl(®s
->port
[port
].iconfb1
) | bout
<< (pin
* 2),
266 ®s
->port
[port
].iconfb1
);
270 tmp
= readl(®s
->port
[port
].ocr2
);
271 tmp
&= ~(3 << (pin
* 2));
272 tmp
|= (ocr
<< (pin
* 2));
273 writel(tmp
, ®s
->port
[port
].ocr2
);
275 writel(readl(®s
->port
[port
].iconfa2
) & ~(3 << (pin
* 2)),
276 ®s
->port
[port
].iconfa2
);
277 writel(readl(®s
->port
[port
].iconfa2
) | aout
<< (pin
* 2),
278 ®s
->port
[port
].iconfa2
);
279 writel(readl(®s
->port
[port
].iconfb2
) & ~(3 << (pin
* 2)),
280 ®s
->port
[port
].iconfb2
);
281 writel(readl(®s
->port
[port
].iconfb2
) | bout
<< (pin
* 2),
282 ®s
->port
[port
].iconfb2
);
286 #ifdef CONFIG_MXC_UART
287 void mx27_uart1_init_pins(void)
290 unsigned int mode
[] = {
295 for (i
= 0; i
< ARRAY_SIZE(mode
); i
++)
296 imx_gpio_mode(mode
[i
]);
299 #endif /* CONFIG_MXC_UART */
301 #ifdef CONFIG_FEC_MXC
302 void mx27_fec_init_pins(void)
305 unsigned int mode
[] = {
315 PD9_AIN_FEC_MDC
| GPIO_PUEN
,
317 PD11_AOUT_FEC_TX_CLK
,
326 for (i
= 0; i
< ARRAY_SIZE(mode
); i
++)
327 imx_gpio_mode(mode
[i
]);
330 void imx_get_mac_from_fuse(int dev_id
, unsigned char *mac
)
333 struct iim_regs
*iim
= (struct iim_regs
*)IMX_IIM_BASE
;
334 struct fuse_bank
*bank
= &iim
->bank
[0];
335 struct fuse_bank0_regs
*fuse
=
336 (struct fuse_bank0_regs
*)bank
->fuse_regs
;
338 for (i
= 0; i
< 6; i
++)
339 mac
[6 - 1 - i
] = readl(&fuse
->mac_addr
[i
]) & 0xff;
341 #endif /* CONFIG_FEC_MXC */
343 #ifdef CONFIG_MMC_MXC
344 void mx27_sd1_init_pins(void)
347 unsigned int mode
[] = {
356 for (i
= 0; i
< ARRAY_SIZE(mode
); i
++)
357 imx_gpio_mode(mode
[i
]);
361 void mx27_sd2_init_pins(void)
364 unsigned int mode
[] = {
373 for (i
= 0; i
< ARRAY_SIZE(mode
); i
++)
374 imx_gpio_mode(mode
[i
]);
377 #endif /* CONFIG_MMC_MXC */