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