xref: /openbmc/linux/arch/m68k/coldfire/m53xx.c (revision 968f0e1c)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2f86b9e03SGreg Ungerer /***************************************************************************/
3f86b9e03SGreg Ungerer 
4f86b9e03SGreg Ungerer /*
5f86b9e03SGreg Ungerer  *	m53xx.c -- platform support for ColdFire 53xx based boards
6f86b9e03SGreg Ungerer  *
7f86b9e03SGreg Ungerer  *	Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
8f86b9e03SGreg Ungerer  *	Copyright (C) 2000, Lineo (www.lineo.com)
9f86b9e03SGreg Ungerer  *	Yaroslav Vinogradov yaroslav.vinogradov@freescale.com
10f86b9e03SGreg Ungerer  *	Copyright Freescale Semiconductor, Inc 2006
11f86b9e03SGreg Ungerer  *	Copyright (c) 2006, emlix, Sebastian Hess <shess@hessware.de>
12f86b9e03SGreg Ungerer  */
13f86b9e03SGreg Ungerer 
14f86b9e03SGreg Ungerer /***************************************************************************/
15f86b9e03SGreg Ungerer 
16007f84edSArnd Bergmann #include <linux/clkdev.h>
17f86b9e03SGreg Ungerer #include <linux/kernel.h>
18f86b9e03SGreg Ungerer #include <linux/param.h>
19f86b9e03SGreg Ungerer #include <linux/init.h>
20f86b9e03SGreg Ungerer #include <linux/io.h>
21f86b9e03SGreg Ungerer #include <asm/machdep.h>
22f86b9e03SGreg Ungerer #include <asm/coldfire.h>
23f86b9e03SGreg Ungerer #include <asm/mcfsim.h>
24f86b9e03SGreg Ungerer #include <asm/mcfuart.h>
25f86b9e03SGreg Ungerer #include <asm/mcfdma.h>
26f86b9e03SGreg Ungerer #include <asm/mcfwdebug.h>
27f86b9e03SGreg Ungerer #include <asm/mcfclk.h>
28f86b9e03SGreg Ungerer 
29f86b9e03SGreg Ungerer /***************************************************************************/
30f86b9e03SGreg Ungerer 
31f86b9e03SGreg Ungerer DEFINE_CLK(0, "flexbus", 2, MCF_CLK);
32f86b9e03SGreg Ungerer DEFINE_CLK(0, "mcfcan.0", 8, MCF_CLK);
33f86b9e03SGreg Ungerer DEFINE_CLK(0, "fec.0", 12, MCF_CLK);
34f86b9e03SGreg Ungerer DEFINE_CLK(0, "edma", 17, MCF_CLK);
35f86b9e03SGreg Ungerer DEFINE_CLK(0, "intc.0", 18, MCF_CLK);
36f86b9e03SGreg Ungerer DEFINE_CLK(0, "intc.1", 19, MCF_CLK);
37f86b9e03SGreg Ungerer DEFINE_CLK(0, "iack.0", 21, MCF_CLK);
382d24b532SSteven King DEFINE_CLK(0, "imx1-i2c.0", 22, MCF_CLK);
39f86b9e03SGreg Ungerer DEFINE_CLK(0, "mcfqspi.0", 23, MCF_CLK);
40f86b9e03SGreg Ungerer DEFINE_CLK(0, "mcfuart.0", 24, MCF_BUSCLK);
41f86b9e03SGreg Ungerer DEFINE_CLK(0, "mcfuart.1", 25, MCF_BUSCLK);
42f86b9e03SGreg Ungerer DEFINE_CLK(0, "mcfuart.2", 26, MCF_BUSCLK);
43f86b9e03SGreg Ungerer DEFINE_CLK(0, "mcftmr.0", 28, MCF_CLK);
44f86b9e03SGreg Ungerer DEFINE_CLK(0, "mcftmr.1", 29, MCF_CLK);
45f86b9e03SGreg Ungerer DEFINE_CLK(0, "mcftmr.2", 30, MCF_CLK);
46f86b9e03SGreg Ungerer DEFINE_CLK(0, "mcftmr.3", 31, MCF_CLK);
47f86b9e03SGreg Ungerer 
48f86b9e03SGreg Ungerer DEFINE_CLK(0, "mcfpit.0", 32, MCF_CLK);
49f86b9e03SGreg Ungerer DEFINE_CLK(0, "mcfpit.1", 33, MCF_CLK);
50f86b9e03SGreg Ungerer DEFINE_CLK(0, "mcfpit.2", 34, MCF_CLK);
51f86b9e03SGreg Ungerer DEFINE_CLK(0, "mcfpit.3", 35, MCF_CLK);
52f86b9e03SGreg Ungerer DEFINE_CLK(0, "mcfpwm.0", 36, MCF_CLK);
53f86b9e03SGreg Ungerer DEFINE_CLK(0, "mcfeport.0", 37, MCF_CLK);
54f86b9e03SGreg Ungerer DEFINE_CLK(0, "mcfwdt.0", 38, MCF_CLK);
55f86b9e03SGreg Ungerer DEFINE_CLK(0, "sys.0", 40, MCF_BUSCLK);
56f86b9e03SGreg Ungerer DEFINE_CLK(0, "gpio.0", 41, MCF_BUSCLK);
57f86b9e03SGreg Ungerer DEFINE_CLK(0, "mcfrtc.0", 42, MCF_CLK);
58f86b9e03SGreg Ungerer DEFINE_CLK(0, "mcflcd.0", 43, MCF_CLK);
59f86b9e03SGreg Ungerer DEFINE_CLK(0, "mcfusb-otg.0", 44, MCF_CLK);
60f86b9e03SGreg Ungerer DEFINE_CLK(0, "mcfusb-host.0", 45, MCF_CLK);
61f86b9e03SGreg Ungerer DEFINE_CLK(0, "sdram.0", 46, MCF_CLK);
62f86b9e03SGreg Ungerer DEFINE_CLK(0, "ssi.0", 47, MCF_CLK);
63f86b9e03SGreg Ungerer DEFINE_CLK(0, "pll.0", 48, MCF_CLK);
64f86b9e03SGreg Ungerer 
65f86b9e03SGreg Ungerer DEFINE_CLK(1, "mdha.0", 32, MCF_CLK);
66f86b9e03SGreg Ungerer DEFINE_CLK(1, "skha.0", 33, MCF_CLK);
67f86b9e03SGreg Ungerer DEFINE_CLK(1, "rng.0", 34, MCF_CLK);
68f86b9e03SGreg Ungerer 
69007f84edSArnd Bergmann static struct clk_lookup m53xx_clk_lookup[] = {
70007f84edSArnd Bergmann 	CLKDEV_INIT("flexbus", NULL, &__clk_0_2),
71007f84edSArnd Bergmann 	CLKDEV_INIT("mcfcan.0", NULL, &__clk_0_8),
72007f84edSArnd Bergmann 	CLKDEV_INIT("fec.0", NULL, &__clk_0_12),
73007f84edSArnd Bergmann 	CLKDEV_INIT("edma", NULL, &__clk_0_17),
74007f84edSArnd Bergmann 	CLKDEV_INIT("intc.0", NULL, &__clk_0_18),
75007f84edSArnd Bergmann 	CLKDEV_INIT("intc.1", NULL, &__clk_0_19),
76007f84edSArnd Bergmann 	CLKDEV_INIT("iack.0", NULL, &__clk_0_21),
77007f84edSArnd Bergmann 	CLKDEV_INIT("imx1-i2c.0", NULL, &__clk_0_22),
78007f84edSArnd Bergmann 	CLKDEV_INIT("mcfqspi.0", NULL, &__clk_0_23),
79007f84edSArnd Bergmann 	CLKDEV_INIT("mcfuart.0", NULL, &__clk_0_24),
80007f84edSArnd Bergmann 	CLKDEV_INIT("mcfuart.1", NULL, &__clk_0_25),
81007f84edSArnd Bergmann 	CLKDEV_INIT("mcfuart.2", NULL, &__clk_0_26),
82007f84edSArnd Bergmann 	CLKDEV_INIT("mcftmr.0", NULL, &__clk_0_28),
83007f84edSArnd Bergmann 	CLKDEV_INIT("mcftmr.1", NULL, &__clk_0_29),
84007f84edSArnd Bergmann 	CLKDEV_INIT("mcftmr.2", NULL, &__clk_0_30),
85007f84edSArnd Bergmann 	CLKDEV_INIT("mcftmr.3", NULL, &__clk_0_31),
86007f84edSArnd Bergmann 	CLKDEV_INIT("mcfpit.0", NULL, &__clk_0_32),
87007f84edSArnd Bergmann 	CLKDEV_INIT("mcfpit.1", NULL, &__clk_0_33),
88007f84edSArnd Bergmann 	CLKDEV_INIT("mcfpit.2", NULL, &__clk_0_34),
89007f84edSArnd Bergmann 	CLKDEV_INIT("mcfpit.3", NULL, &__clk_0_35),
90007f84edSArnd Bergmann 	CLKDEV_INIT("mcfpwm.0", NULL, &__clk_0_36),
91007f84edSArnd Bergmann 	CLKDEV_INIT("mcfeport.0", NULL, &__clk_0_37),
92007f84edSArnd Bergmann 	CLKDEV_INIT("mcfwdt.0", NULL, &__clk_0_38),
93007f84edSArnd Bergmann 	CLKDEV_INIT(NULL, "sys.0", &__clk_0_40),
94007f84edSArnd Bergmann 	CLKDEV_INIT("gpio.0", NULL, &__clk_0_41),
95007f84edSArnd Bergmann 	CLKDEV_INIT("mcfrtc.0", NULL, &__clk_0_42),
96007f84edSArnd Bergmann 	CLKDEV_INIT("mcflcd.0", NULL, &__clk_0_43),
97007f84edSArnd Bergmann 	CLKDEV_INIT("mcfusb-otg.0", NULL, &__clk_0_44),
98007f84edSArnd Bergmann 	CLKDEV_INIT("mcfusb-host.0", NULL, &__clk_0_45),
99007f84edSArnd Bergmann 	CLKDEV_INIT("sdram.0", NULL, &__clk_0_46),
100007f84edSArnd Bergmann 	CLKDEV_INIT("ssi.0", NULL, &__clk_0_47),
101007f84edSArnd Bergmann 	CLKDEV_INIT(NULL, "pll.0", &__clk_0_48),
102007f84edSArnd Bergmann 	CLKDEV_INIT("mdha.0", NULL, &__clk_1_32),
103007f84edSArnd Bergmann 	CLKDEV_INIT("skha.0", NULL, &__clk_1_33),
104007f84edSArnd Bergmann 	CLKDEV_INIT("rng.0", NULL, &__clk_1_34),
105f86b9e03SGreg Ungerer };
106f86b9e03SGreg Ungerer 
107f86b9e03SGreg Ungerer static struct clk * const enable_clks[] __initconst = {
108f86b9e03SGreg Ungerer 	&__clk_0_2,	/* flexbus */
109f86b9e03SGreg Ungerer 	&__clk_0_18,	/* intc.0 */
110f86b9e03SGreg Ungerer 	&__clk_0_19,	/* intc.1 */
111f86b9e03SGreg Ungerer 	&__clk_0_21,	/* iack.0 */
112f86b9e03SGreg Ungerer 	&__clk_0_24,	/* mcfuart.0 */
113f86b9e03SGreg Ungerer 	&__clk_0_25,	/* mcfuart.1 */
114f86b9e03SGreg Ungerer 	&__clk_0_26,	/* mcfuart.2 */
115f86b9e03SGreg Ungerer 	&__clk_0_28,	/* mcftmr.0 */
116f86b9e03SGreg Ungerer 	&__clk_0_29,	/* mcftmr.1 */
117f86b9e03SGreg Ungerer 	&__clk_0_32,	/* mcfpit.0 */
118f86b9e03SGreg Ungerer 	&__clk_0_33,	/* mcfpit.1 */
119f86b9e03SGreg Ungerer 	&__clk_0_37,	/* mcfeport.0 */
120f86b9e03SGreg Ungerer 	&__clk_0_40,	/* sys.0 */
121f86b9e03SGreg Ungerer 	&__clk_0_41,	/* gpio.0 */
122f86b9e03SGreg Ungerer 	&__clk_0_46,	/* sdram.0 */
123f86b9e03SGreg Ungerer 	&__clk_0_48,	/* pll.0 */
124f86b9e03SGreg Ungerer };
125f86b9e03SGreg Ungerer 
126f86b9e03SGreg Ungerer static struct clk * const disable_clks[] __initconst = {
127f86b9e03SGreg Ungerer 	&__clk_0_8,	/* mcfcan.0 */
128f86b9e03SGreg Ungerer 	&__clk_0_12,	/* fec.0 */
129f86b9e03SGreg Ungerer 	&__clk_0_17,	/* edma */
1302d24b532SSteven King 	&__clk_0_22,	/* imx1-i2c.0 */
131f86b9e03SGreg Ungerer 	&__clk_0_23,	/* mcfqspi.0 */
132f86b9e03SGreg Ungerer 	&__clk_0_30,	/* mcftmr.2 */
133f86b9e03SGreg Ungerer 	&__clk_0_31,	/* mcftmr.3 */
134f86b9e03SGreg Ungerer 	&__clk_0_34,	/* mcfpit.2 */
135f86b9e03SGreg Ungerer 	&__clk_0_35,	/* mcfpit.3 */
136f86b9e03SGreg Ungerer 	&__clk_0_36,	/* mcfpwm.0 */
137f86b9e03SGreg Ungerer 	&__clk_0_38,	/* mcfwdt.0 */
138f86b9e03SGreg Ungerer 	&__clk_0_42,	/* mcfrtc.0 */
139f86b9e03SGreg Ungerer 	&__clk_0_43,	/* mcflcd.0 */
140f86b9e03SGreg Ungerer 	&__clk_0_44,	/* mcfusb-otg.0 */
141f86b9e03SGreg Ungerer 	&__clk_0_45,	/* mcfusb-host.0 */
142f86b9e03SGreg Ungerer 	&__clk_0_47,	/* ssi.0 */
143f86b9e03SGreg Ungerer 	&__clk_1_32,	/* mdha.0 */
144f86b9e03SGreg Ungerer 	&__clk_1_33,	/* skha.0 */
145f86b9e03SGreg Ungerer 	&__clk_1_34,	/* rng.0 */
146f86b9e03SGreg Ungerer };
147f86b9e03SGreg Ungerer 
148f86b9e03SGreg Ungerer 
m53xx_clk_init(void)149f86b9e03SGreg Ungerer static void __init m53xx_clk_init(void)
150f86b9e03SGreg Ungerer {
151f86b9e03SGreg Ungerer 	unsigned i;
152f86b9e03SGreg Ungerer 
153f86b9e03SGreg Ungerer 	/* make sure these clocks are enabled */
154f86b9e03SGreg Ungerer 	for (i = 0; i < ARRAY_SIZE(enable_clks); ++i)
155f86b9e03SGreg Ungerer 		__clk_init_enabled(enable_clks[i]);
156f86b9e03SGreg Ungerer 	/* make sure these clocks are disabled */
157f86b9e03SGreg Ungerer 	for (i = 0; i < ARRAY_SIZE(disable_clks); ++i)
158f86b9e03SGreg Ungerer 		__clk_init_disabled(disable_clks[i]);
159007f84edSArnd Bergmann 
160007f84edSArnd Bergmann 	clkdev_add_table(m53xx_clk_lookup, ARRAY_SIZE(m53xx_clk_lookup));
161f86b9e03SGreg Ungerer }
162f86b9e03SGreg Ungerer 
163f86b9e03SGreg Ungerer /***************************************************************************/
164f86b9e03SGreg Ungerer 
m53xx_qspi_init(void)165f86b9e03SGreg Ungerer static void __init m53xx_qspi_init(void)
166f86b9e03SGreg Ungerer {
167f86b9e03SGreg Ungerer #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
168f86b9e03SGreg Ungerer 	/* setup QSPS pins for QSPI with gpio CS control */
169f86b9e03SGreg Ungerer 	writew(0x01f0, MCFGPIO_PAR_QSPI);
170f86b9e03SGreg Ungerer #endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
171f86b9e03SGreg Ungerer }
172f86b9e03SGreg Ungerer 
173f86b9e03SGreg Ungerer /***************************************************************************/
174f86b9e03SGreg Ungerer 
m53xx_i2c_init(void)1752d24b532SSteven King static void __init m53xx_i2c_init(void)
1762d24b532SSteven King {
1772d24b532SSteven King #if IS_ENABLED(CONFIG_I2C_IMX)
1782d24b532SSteven King 	/* setup Port AS Pin Assignment Register for I2C */
1792d24b532SSteven King 	/*  set PASPA0 to SCL and PASPA1 to SDA */
1802d24b532SSteven King 	u8 r = readb(MCFGPIO_PAR_FECI2C);
1812d24b532SSteven King 	r |= 0x0f;
1822d24b532SSteven King 	writeb(r, MCFGPIO_PAR_FECI2C);
1832d24b532SSteven King #endif /* IS_ENABLED(CONFIG_I2C_IMX) */
1842d24b532SSteven King }
1852d24b532SSteven King 
1862d24b532SSteven King /***************************************************************************/
1872d24b532SSteven King 
m53xx_uarts_init(void)188f86b9e03SGreg Ungerer static void __init m53xx_uarts_init(void)
189f86b9e03SGreg Ungerer {
190f86b9e03SGreg Ungerer 	/* UART GPIO initialization */
191f86b9e03SGreg Ungerer 	writew(readw(MCFGPIO_PAR_UART) | 0x0FFF, MCFGPIO_PAR_UART);
192f86b9e03SGreg Ungerer }
193f86b9e03SGreg Ungerer 
194f86b9e03SGreg Ungerer /***************************************************************************/
195f86b9e03SGreg Ungerer 
m53xx_fec_init(void)196f86b9e03SGreg Ungerer static void __init m53xx_fec_init(void)
197f86b9e03SGreg Ungerer {
198f86b9e03SGreg Ungerer 	u8 v;
199f86b9e03SGreg Ungerer 
200f86b9e03SGreg Ungerer 	/* Set multi-function pins to ethernet mode for fec0 */
201f86b9e03SGreg Ungerer 	v = readb(MCFGPIO_PAR_FECI2C);
202f86b9e03SGreg Ungerer 	v |= MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
203f86b9e03SGreg Ungerer 		MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO;
204f86b9e03SGreg Ungerer 	writeb(v, MCFGPIO_PAR_FECI2C);
205f86b9e03SGreg Ungerer 
206f86b9e03SGreg Ungerer 	v = readb(MCFGPIO_PAR_FEC);
207f86b9e03SGreg Ungerer 	v = MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC | MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC;
208f86b9e03SGreg Ungerer 	writeb(v, MCFGPIO_PAR_FEC);
209f86b9e03SGreg Ungerer }
210f86b9e03SGreg Ungerer 
211f86b9e03SGreg Ungerer /***************************************************************************/
212f86b9e03SGreg Ungerer 
config_BSP(char * commandp,int size)213f86b9e03SGreg Ungerer void __init config_BSP(char *commandp, int size)
214f86b9e03SGreg Ungerer {
215f86b9e03SGreg Ungerer #if !defined(CONFIG_BOOTPARAM)
216f86b9e03SGreg Ungerer 	/* Copy command line from FLASH to local buffer... */
217f86b9e03SGreg Ungerer 	memcpy(commandp, (char *) 0x4000, 4);
218f86b9e03SGreg Ungerer 	if(strncmp(commandp, "kcl ", 4) == 0){
219f86b9e03SGreg Ungerer 		memcpy(commandp, (char *) 0x4004, size);
220f86b9e03SGreg Ungerer 		commandp[size-1] = 0;
221f86b9e03SGreg Ungerer 	} else {
222f86b9e03SGreg Ungerer 		memset(commandp, 0, size);
223f86b9e03SGreg Ungerer 	}
224f86b9e03SGreg Ungerer #endif
225f86b9e03SGreg Ungerer 	mach_sched_init = hw_timer_init;
226f86b9e03SGreg Ungerer 	m53xx_clk_init();
227f86b9e03SGreg Ungerer 	m53xx_uarts_init();
228f86b9e03SGreg Ungerer 	m53xx_fec_init();
229f86b9e03SGreg Ungerer 	m53xx_qspi_init();
2302d24b532SSteven King 	m53xx_i2c_init();
231f86b9e03SGreg Ungerer 
232f86b9e03SGreg Ungerer #ifdef CONFIG_BDM_DISABLE
233f86b9e03SGreg Ungerer 	/*
234f86b9e03SGreg Ungerer 	 * Disable the BDM clocking.  This also turns off most of the rest of
235f86b9e03SGreg Ungerer 	 * the BDM device.  This is good for EMC reasons. This option is not
236f86b9e03SGreg Ungerer 	 * incompatible with the memory protection option.
237f86b9e03SGreg Ungerer 	 */
238f86b9e03SGreg Ungerer 	wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK);
239f86b9e03SGreg Ungerer #endif
240f86b9e03SGreg Ungerer }
241f86b9e03SGreg Ungerer 
242f86b9e03SGreg Ungerer /***************************************************************************/
243f86b9e03SGreg Ungerer /* Board initialization */
244f86b9e03SGreg Ungerer /***************************************************************************/
245f86b9e03SGreg Ungerer /*
246f86b9e03SGreg Ungerer  * PLL min/max specifications
247f86b9e03SGreg Ungerer  */
248f86b9e03SGreg Ungerer #define MAX_FVCO	500000	/* KHz */
249f86b9e03SGreg Ungerer #define MAX_FSYS	80000 	/* KHz */
250f86b9e03SGreg Ungerer #define MIN_FSYS	58333 	/* KHz */
251f86b9e03SGreg Ungerer #define FREF		16000   /* KHz */
252f86b9e03SGreg Ungerer 
253f86b9e03SGreg Ungerer 
254f86b9e03SGreg Ungerer #define MAX_MFD		135     /* Multiplier */
255f86b9e03SGreg Ungerer #define MIN_MFD		88      /* Multiplier */
256f86b9e03SGreg Ungerer #define BUSDIV		6       /* Divider */
257f86b9e03SGreg Ungerer 
258f86b9e03SGreg Ungerer /*
259f86b9e03SGreg Ungerer  * Low Power Divider specifications
260f86b9e03SGreg Ungerer  */
261f86b9e03SGreg Ungerer #define MIN_LPD		(1 << 0)    /* Divider (not encoded) */
262f86b9e03SGreg Ungerer #define MAX_LPD		(1 << 15)   /* Divider (not encoded) */
263f86b9e03SGreg Ungerer #define DEFAULT_LPD	(1 << 1)	/* Divider (not encoded) */
264f86b9e03SGreg Ungerer 
265f86b9e03SGreg Ungerer #define SYS_CLK_KHZ	80000
266f86b9e03SGreg Ungerer #define SYSTEM_PERIOD	12.5
267f86b9e03SGreg Ungerer /*
268f86b9e03SGreg Ungerer  *  SDRAM Timing Parameters
269f86b9e03SGreg Ungerer  */
270f86b9e03SGreg Ungerer #define SDRAM_BL	8	/* # of beats in a burst */
271f86b9e03SGreg Ungerer #define SDRAM_TWR	2	/* in clocks */
272f86b9e03SGreg Ungerer #define SDRAM_CASL	2.5	/* CASL in clocks */
273f86b9e03SGreg Ungerer #define SDRAM_TRCD	2	/* in clocks */
274f86b9e03SGreg Ungerer #define SDRAM_TRP	2	/* in clocks */
275f86b9e03SGreg Ungerer #define SDRAM_TRFC	7	/* in clocks */
276f86b9e03SGreg Ungerer #define SDRAM_TREFI	7800	/* in ns */
277f86b9e03SGreg Ungerer 
278f86b9e03SGreg Ungerer #define EXT_SRAM_ADDRESS	(0xC0000000)
279f86b9e03SGreg Ungerer #define FLASH_ADDRESS		(0x00000000)
280f86b9e03SGreg Ungerer #define SDRAM_ADDRESS		(0x40000000)
281f86b9e03SGreg Ungerer 
282f86b9e03SGreg Ungerer #define NAND_FLASH_ADDRESS	(0xD0000000)
283f86b9e03SGreg Ungerer 
284f86b9e03SGreg Ungerer void wtm_init(void);
285f86b9e03SGreg Ungerer void scm_init(void);
286f86b9e03SGreg Ungerer void gpio_init(void);
287f86b9e03SGreg Ungerer void fbcs_init(void);
288f86b9e03SGreg Ungerer void sdramc_init(void);
289f86b9e03SGreg Ungerer int  clock_pll (int fsys, int flags);
290f86b9e03SGreg Ungerer int  clock_limp (int);
291f86b9e03SGreg Ungerer int  clock_exit_limp (void);
292f86b9e03SGreg Ungerer int  get_sys_clock (void);
293f86b9e03SGreg Ungerer 
sysinit(void)294f86b9e03SGreg Ungerer asmlinkage void __init sysinit(void)
295f86b9e03SGreg Ungerer {
296bc065e47SGreg Ungerer 	clock_pll(0, 0);
297f86b9e03SGreg Ungerer 
298f86b9e03SGreg Ungerer 	wtm_init();
299f86b9e03SGreg Ungerer 	scm_init();
300f86b9e03SGreg Ungerer 	gpio_init();
301f86b9e03SGreg Ungerer 	fbcs_init();
302f86b9e03SGreg Ungerer 	sdramc_init();
303f86b9e03SGreg Ungerer }
304f86b9e03SGreg Ungerer 
wtm_init(void)305f86b9e03SGreg Ungerer void wtm_init(void)
306f86b9e03SGreg Ungerer {
307f86b9e03SGreg Ungerer 	/* Disable watchdog timer */
308f86b9e03SGreg Ungerer 	writew(0, MCF_WTM_WCR);
309f86b9e03SGreg Ungerer }
310f86b9e03SGreg Ungerer 
311f86b9e03SGreg Ungerer #define MCF_SCM_BCR_GBW		(0x00000100)
312f86b9e03SGreg Ungerer #define MCF_SCM_BCR_GBR		(0x00000200)
313f86b9e03SGreg Ungerer 
scm_init(void)314f86b9e03SGreg Ungerer void scm_init(void)
315f86b9e03SGreg Ungerer {
316f86b9e03SGreg Ungerer 	/* All masters are trusted */
317f86b9e03SGreg Ungerer 	writel(0x77777777, MCF_SCM_MPR);
318f86b9e03SGreg Ungerer 
319f86b9e03SGreg Ungerer 	/* Allow supervisor/user, read/write, and trusted/untrusted
320f86b9e03SGreg Ungerer 	   access to all slaves */
321f86b9e03SGreg Ungerer 	writel(0, MCF_SCM_PACRA);
322f86b9e03SGreg Ungerer 	writel(0, MCF_SCM_PACRB);
323f86b9e03SGreg Ungerer 	writel(0, MCF_SCM_PACRC);
324f86b9e03SGreg Ungerer 	writel(0, MCF_SCM_PACRD);
325f86b9e03SGreg Ungerer 	writel(0, MCF_SCM_PACRE);
326f86b9e03SGreg Ungerer 	writel(0, MCF_SCM_PACRF);
327f86b9e03SGreg Ungerer 
328f86b9e03SGreg Ungerer 	/* Enable bursts */
329f86b9e03SGreg Ungerer 	writel(MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW, MCF_SCM_BCR);
330f86b9e03SGreg Ungerer }
331f86b9e03SGreg Ungerer 
332f86b9e03SGreg Ungerer 
fbcs_init(void)333f86b9e03SGreg Ungerer void fbcs_init(void)
334f86b9e03SGreg Ungerer {
335f86b9e03SGreg Ungerer 	writeb(0x3E, MCFGPIO_PAR_CS);
336f86b9e03SGreg Ungerer 
337f86b9e03SGreg Ungerer 	/* Latch chip select */
338f86b9e03SGreg Ungerer 	writel(0x10080000, MCF_FBCS1_CSAR);
339f86b9e03SGreg Ungerer 
340f86b9e03SGreg Ungerer 	writel(0x002A3780, MCF_FBCS1_CSCR);
341f86b9e03SGreg Ungerer 	writel(MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
342f86b9e03SGreg Ungerer 
343f86b9e03SGreg Ungerer 	/* Initialize latch to drive signals to inactive states */
344f86b9e03SGreg Ungerer 	writew(0xffff, 0x10080000);
345f86b9e03SGreg Ungerer 
346f86b9e03SGreg Ungerer 	/* External SRAM */
347f86b9e03SGreg Ungerer 	writel(EXT_SRAM_ADDRESS, MCF_FBCS1_CSAR);
348f86b9e03SGreg Ungerer 	writel(MCF_FBCS_CSCR_PS_16 |
349f86b9e03SGreg Ungerer 		MCF_FBCS_CSCR_AA |
350f86b9e03SGreg Ungerer 		MCF_FBCS_CSCR_SBM |
351f86b9e03SGreg Ungerer 		MCF_FBCS_CSCR_WS(1),
352f86b9e03SGreg Ungerer 		MCF_FBCS1_CSCR);
353f86b9e03SGreg Ungerer 	writel(MCF_FBCS_CSMR_BAM_512K | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
354f86b9e03SGreg Ungerer 
355f86b9e03SGreg Ungerer 	/* Boot Flash connected to FBCS0 */
356f86b9e03SGreg Ungerer 	writel(FLASH_ADDRESS, MCF_FBCS0_CSAR);
357f86b9e03SGreg Ungerer 	writel(MCF_FBCS_CSCR_PS_16 |
358f86b9e03SGreg Ungerer 		MCF_FBCS_CSCR_BEM |
359f86b9e03SGreg Ungerer 		MCF_FBCS_CSCR_AA |
360f86b9e03SGreg Ungerer 		MCF_FBCS_CSCR_SBM |
361f86b9e03SGreg Ungerer 		MCF_FBCS_CSCR_WS(7),
362f86b9e03SGreg Ungerer 		MCF_FBCS0_CSCR);
363f86b9e03SGreg Ungerer 	writel(MCF_FBCS_CSMR_BAM_32M | MCF_FBCS_CSMR_V, MCF_FBCS0_CSMR);
364f86b9e03SGreg Ungerer }
365f86b9e03SGreg Ungerer 
sdramc_init(void)366f86b9e03SGreg Ungerer void sdramc_init(void)
367f86b9e03SGreg Ungerer {
368f86b9e03SGreg Ungerer 	/*
369f86b9e03SGreg Ungerer 	 * Check to see if the SDRAM has already been initialized
370f86b9e03SGreg Ungerer 	 * by a run control tool
371f86b9e03SGreg Ungerer 	 */
372f86b9e03SGreg Ungerer 	if (!(readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)) {
373f86b9e03SGreg Ungerer 		/* SDRAM chip select initialization */
374f86b9e03SGreg Ungerer 
375f86b9e03SGreg Ungerer 		/* Initialize SDRAM chip select */
376f86b9e03SGreg Ungerer 		writel(MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS) |
377f86b9e03SGreg Ungerer 			MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE),
378f86b9e03SGreg Ungerer 			MCF_SDRAMC_SDCS0);
379f86b9e03SGreg Ungerer 
380f86b9e03SGreg Ungerer 	/*
381f86b9e03SGreg Ungerer 	 * Basic configuration and initialization
382f86b9e03SGreg Ungerer 	 */
383f86b9e03SGreg Ungerer 	writel(MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5)) |
384f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1) |
385f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL * 2) + 2)) |
386f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDCFG1_ACT2RW((int)(SDRAM_TRCD + 0.5)) |
387f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDCFG1_PRE2ACT((int)(SDRAM_TRP + 0.5)) |
388f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDCFG1_REF2ACT((int)(SDRAM_TRFC + 0.5)) |
389f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDCFG1_WTLAT(3),
390f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDCFG1);
391f86b9e03SGreg Ungerer 	writel(MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL / 2 + 1) |
392f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL / 2 + SDRAM_TWR) |
393f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL + SDRAM_BL / 2 - 1.0) + 0.5)) |
394f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDCFG2_BL(SDRAM_BL - 1),
395f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDCFG2);
396f86b9e03SGreg Ungerer 
397f86b9e03SGreg Ungerer 
398f86b9e03SGreg Ungerer 	/*
399f86b9e03SGreg Ungerer 	 * Precharge and enable write to SDMR
400f86b9e03SGreg Ungerer 	 */
401f86b9e03SGreg Ungerer 	writel(MCF_SDRAMC_SDCR_MODE_EN |
402f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDCR_CKE |
403f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDCR_DDR |
404f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDCR_MUX(1) |
405f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI / (SYSTEM_PERIOD * 64)) - 1) + 0.5)) |
406f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDCR_PS_16 |
407f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDCR_IPALL,
408f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDCR);
409f86b9e03SGreg Ungerer 
410f86b9e03SGreg Ungerer 	/*
411f86b9e03SGreg Ungerer 	 * Write extended mode register
412f86b9e03SGreg Ungerer 	 */
413f86b9e03SGreg Ungerer 	writel(MCF_SDRAMC_SDMR_BNKAD_LEMR |
414f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDMR_AD(0x0) |
415f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDMR_CMD,
416f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDMR);
417f86b9e03SGreg Ungerer 
418f86b9e03SGreg Ungerer 	/*
419f86b9e03SGreg Ungerer 	 * Write mode register and reset DLL
420f86b9e03SGreg Ungerer 	 */
421f86b9e03SGreg Ungerer 	writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
422f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDMR_AD(0x163) |
423f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDMR_CMD,
424f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDMR);
425f86b9e03SGreg Ungerer 
426f86b9e03SGreg Ungerer 	/*
427f86b9e03SGreg Ungerer 	 * Execute a PALL command
428f86b9e03SGreg Ungerer 	 */
429f86b9e03SGreg Ungerer 	writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IPALL, MCF_SDRAMC_SDCR);
430f86b9e03SGreg Ungerer 
431f86b9e03SGreg Ungerer 	/*
432f86b9e03SGreg Ungerer 	 * Perform two REF cycles
433f86b9e03SGreg Ungerer 	 */
434f86b9e03SGreg Ungerer 	writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IREF, MCF_SDRAMC_SDCR);
435f86b9e03SGreg Ungerer 	writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IREF, MCF_SDRAMC_SDCR);
436f86b9e03SGreg Ungerer 
437f86b9e03SGreg Ungerer 	/*
438f86b9e03SGreg Ungerer 	 * Write mode register and clear reset DLL
439f86b9e03SGreg Ungerer 	 */
440f86b9e03SGreg Ungerer 	writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
441f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDMR_AD(0x063) |
442f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDMR_CMD,
443f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDMR);
444f86b9e03SGreg Ungerer 
445f86b9e03SGreg Ungerer 	/*
446f86b9e03SGreg Ungerer 	 * Enable auto refresh and lock SDMR
447f86b9e03SGreg Ungerer 	 */
448f86b9e03SGreg Ungerer 	writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_MODE_EN,
449f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDCR);
450f86b9e03SGreg Ungerer 	writel(MCF_SDRAMC_SDCR_REF | MCF_SDRAMC_SDCR_DQS_OE(0xC),
451f86b9e03SGreg Ungerer 		MCF_SDRAMC_SDCR);
452f86b9e03SGreg Ungerer 	}
453f86b9e03SGreg Ungerer }
454f86b9e03SGreg Ungerer 
gpio_init(void)455f86b9e03SGreg Ungerer void gpio_init(void)
456f86b9e03SGreg Ungerer {
457f86b9e03SGreg Ungerer 	/* Enable UART0 pins */
458f86b9e03SGreg Ungerer 	writew(MCF_GPIO_PAR_UART_PAR_URXD0 | MCF_GPIO_PAR_UART_PAR_UTXD0,
459f86b9e03SGreg Ungerer 		MCFGPIO_PAR_UART);
460f86b9e03SGreg Ungerer 
461f86b9e03SGreg Ungerer 	/*
462f86b9e03SGreg Ungerer 	 * Initialize TIN3 as a GPIO output to enable the write
463f86b9e03SGreg Ungerer 	 * half of the latch.
464f86b9e03SGreg Ungerer 	 */
465f86b9e03SGreg Ungerer 	writeb(0x00, MCFGPIO_PAR_TIMER);
466f86b9e03SGreg Ungerer 	writeb(0x08, MCFGPIO_PDDR_TIMER);
467f86b9e03SGreg Ungerer 	writeb(0x00, MCFGPIO_PCLRR_TIMER);
468f86b9e03SGreg Ungerer }
469f86b9e03SGreg Ungerer 
clock_pll(int fsys,int flags)470f86b9e03SGreg Ungerer int clock_pll(int fsys, int flags)
471f86b9e03SGreg Ungerer {
472f86b9e03SGreg Ungerer 	int fref, temp, fout, mfd;
473f86b9e03SGreg Ungerer 	u32 i;
474f86b9e03SGreg Ungerer 
475f86b9e03SGreg Ungerer 	fref = FREF;
476f86b9e03SGreg Ungerer 
477f86b9e03SGreg Ungerer 	if (fsys == 0) {
478f86b9e03SGreg Ungerer 		/* Return current PLL output */
479f86b9e03SGreg Ungerer 		mfd = readb(MCF_PLL_PFDR);
480f86b9e03SGreg Ungerer 
481f86b9e03SGreg Ungerer 		return (fref * mfd / (BUSDIV * 4));
482f86b9e03SGreg Ungerer 	}
483f86b9e03SGreg Ungerer 
484f86b9e03SGreg Ungerer 	/* Check bounds of requested system clock */
485f86b9e03SGreg Ungerer 	if (fsys > MAX_FSYS)
486f86b9e03SGreg Ungerer 		fsys = MAX_FSYS;
487f86b9e03SGreg Ungerer 	if (fsys < MIN_FSYS)
488f86b9e03SGreg Ungerer 		fsys = MIN_FSYS;
489f86b9e03SGreg Ungerer 
490f86b9e03SGreg Ungerer 	/* Multiplying by 100 when calculating the temp value,
491f86b9e03SGreg Ungerer 	   and then dividing by 100 to calculate the mfd allows
492f86b9e03SGreg Ungerer 	   for exact values without needing to include floating
493f86b9e03SGreg Ungerer 	   point libraries. */
494f86b9e03SGreg Ungerer 	temp = 100 * fsys / fref;
495f86b9e03SGreg Ungerer 	mfd = 4 * BUSDIV * temp / 100;
496f86b9e03SGreg Ungerer 
497f86b9e03SGreg Ungerer 	/* Determine the output frequency for selected values */
498f86b9e03SGreg Ungerer 	fout = (fref * mfd / (BUSDIV * 4));
499f86b9e03SGreg Ungerer 
500f86b9e03SGreg Ungerer 	/*
501f86b9e03SGreg Ungerer 	 * Check to see if the SDRAM has already been initialized.
502f86b9e03SGreg Ungerer 	 * If it has then the SDRAM needs to be put into self refresh
503f86b9e03SGreg Ungerer 	 * mode before reprogramming the PLL.
504f86b9e03SGreg Ungerer 	 */
505f86b9e03SGreg Ungerer 	if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
506f86b9e03SGreg Ungerer 		/* Put SDRAM into self refresh mode */
507f86b9e03SGreg Ungerer 		writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_CKE,
508f86b9e03SGreg Ungerer 			MCF_SDRAMC_SDCR);
509f86b9e03SGreg Ungerer 
510f86b9e03SGreg Ungerer 	/*
511f86b9e03SGreg Ungerer 	 * Initialize the PLL to generate the new system clock frequency.
512f86b9e03SGreg Ungerer 	 * The device must be put into LIMP mode to reprogram the PLL.
513f86b9e03SGreg Ungerer 	 */
514f86b9e03SGreg Ungerer 
515f86b9e03SGreg Ungerer 	/* Enter LIMP mode */
516f86b9e03SGreg Ungerer 	clock_limp(DEFAULT_LPD);
517f86b9e03SGreg Ungerer 
518f86b9e03SGreg Ungerer 	/* Reprogram PLL for desired fsys */
519f86b9e03SGreg Ungerer 	writeb(MCF_PLL_PODR_CPUDIV(BUSDIV/3) | MCF_PLL_PODR_BUSDIV(BUSDIV),
520f86b9e03SGreg Ungerer 		MCF_PLL_PODR);
521f86b9e03SGreg Ungerer 
522f86b9e03SGreg Ungerer 	writeb(mfd, MCF_PLL_PFDR);
523f86b9e03SGreg Ungerer 
524f86b9e03SGreg Ungerer 	/* Exit LIMP mode */
525f86b9e03SGreg Ungerer 	clock_exit_limp();
526f86b9e03SGreg Ungerer 
527f86b9e03SGreg Ungerer 	/*
528f86b9e03SGreg Ungerer 	 * Return the SDRAM to normal operation if it is in use.
529f86b9e03SGreg Ungerer 	 */
530f86b9e03SGreg Ungerer 	if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
531f86b9e03SGreg Ungerer 		/* Exit self refresh mode */
532f86b9e03SGreg Ungerer 		writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_CKE,
533f86b9e03SGreg Ungerer 			MCF_SDRAMC_SDCR);
534f86b9e03SGreg Ungerer 
535*968f0e1cSJulia Lawall 	/* Errata - workaround for SDRAM operation after exiting LIMP mode */
536f86b9e03SGreg Ungerer 	writel(MCF_SDRAMC_REFRESH, MCF_SDRAMC_LIMP_FIX);
537f86b9e03SGreg Ungerer 
538f86b9e03SGreg Ungerer 	/* wait for DQS logic to relock */
539f86b9e03SGreg Ungerer 	for (i = 0; i < 0x200; i++)
540f86b9e03SGreg Ungerer 		;
541f86b9e03SGreg Ungerer 
542f86b9e03SGreg Ungerer 	return fout;
543f86b9e03SGreg Ungerer }
544f86b9e03SGreg Ungerer 
clock_limp(int div)545f86b9e03SGreg Ungerer int clock_limp(int div)
546f86b9e03SGreg Ungerer {
547f86b9e03SGreg Ungerer 	u32 temp;
548f86b9e03SGreg Ungerer 
549f86b9e03SGreg Ungerer 	/* Check bounds of divider */
550f86b9e03SGreg Ungerer 	if (div < MIN_LPD)
551f86b9e03SGreg Ungerer 		div = MIN_LPD;
552f86b9e03SGreg Ungerer 	if (div > MAX_LPD)
553f86b9e03SGreg Ungerer 		div = MAX_LPD;
554f86b9e03SGreg Ungerer 
555f86b9e03SGreg Ungerer 	/* Save of the current value of the SSIDIV so we don't
556f86b9e03SGreg Ungerer 	   overwrite the value*/
557f86b9e03SGreg Ungerer 	temp = readw(MCF_CCM_CDR) & MCF_CCM_CDR_SSIDIV(0xF);
558f86b9e03SGreg Ungerer 
559f86b9e03SGreg Ungerer 	/* Apply the divider to the system clock */
560f86b9e03SGreg Ungerer 	writew(MCF_CCM_CDR_LPDIV(div) | MCF_CCM_CDR_SSIDIV(temp), MCF_CCM_CDR);
561f86b9e03SGreg Ungerer 
562f86b9e03SGreg Ungerer 	writew(readw(MCF_CCM_MISCCR) | MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
563f86b9e03SGreg Ungerer 
564f86b9e03SGreg Ungerer 	return (FREF/(3*(1 << div)));
565f86b9e03SGreg Ungerer }
566f86b9e03SGreg Ungerer 
clock_exit_limp(void)567f86b9e03SGreg Ungerer int clock_exit_limp(void)
568f86b9e03SGreg Ungerer {
569f86b9e03SGreg Ungerer 	int fout;
570f86b9e03SGreg Ungerer 
571f86b9e03SGreg Ungerer 	/* Exit LIMP mode */
572f86b9e03SGreg Ungerer 	writew(readw(MCF_CCM_MISCCR) & ~MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
573f86b9e03SGreg Ungerer 
574f86b9e03SGreg Ungerer 	/* Wait for PLL to lock */
575f86b9e03SGreg Ungerer 	while (!(readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_PLL_LOCK))
576f86b9e03SGreg Ungerer 		;
577f86b9e03SGreg Ungerer 
578f86b9e03SGreg Ungerer 	fout = get_sys_clock();
579f86b9e03SGreg Ungerer 
580f86b9e03SGreg Ungerer 	return fout;
581f86b9e03SGreg Ungerer }
582f86b9e03SGreg Ungerer 
get_sys_clock(void)583f86b9e03SGreg Ungerer int get_sys_clock(void)
584f86b9e03SGreg Ungerer {
585f86b9e03SGreg Ungerer 	int divider;
586f86b9e03SGreg Ungerer 
587f86b9e03SGreg Ungerer 	/* Test to see if device is in LIMP mode */
588f86b9e03SGreg Ungerer 	if (readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_LIMP) {
589f86b9e03SGreg Ungerer 		divider = readw(MCF_CCM_CDR) & MCF_CCM_CDR_LPDIV(0xF);
590f86b9e03SGreg Ungerer 		return (FREF/(2 << divider));
591f86b9e03SGreg Ungerer 	}
592f86b9e03SGreg Ungerer 	else
593f86b9e03SGreg Ungerer 		return (FREF * readb(MCF_PLL_PFDR)) / (BUSDIV * 4);
594f86b9e03SGreg Ungerer }
595