diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/cpu/mpc512x/cpu_init.c | 120 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc512x/fixed_sdram.c | 17 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc512x/iopin.c | 54 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc5xxx/spl_boot.c | 20 | ||||
-rw-r--r-- | arch/powerpc/include/asm/immap_512x.h | 22 |
5 files changed, 226 insertions, 7 deletions
diff --git a/arch/powerpc/cpu/mpc512x/cpu_init.c b/arch/powerpc/cpu/mpc512x/cpu_init.c index 32ade1b0b9..b308cb4be3 100644 --- a/arch/powerpc/cpu/mpc512x/cpu_init.c +++ b/arch/powerpc/cpu/mpc512x/cpu_init.c @@ -26,6 +26,7 @@ #include <common.h> #include <asm/io.h> +#include <asm/mpc512x.h> #include <asm/processor.h> DECLARE_GLOBAL_DATA_PTR; @@ -43,6 +44,101 @@ void cpu_init_f (volatile immap_t * im) /* Clear initial global data */ memset ((void *) gd, 0, sizeof (gd_t)); + /* Local Window and chip select configuration */ +#if defined(CONFIG_SYS_CS0_START) && defined(CONFIG_SYS_CS0_SIZE) + out_be32(&im->sysconf.lpcs0aw, + CSAW_START(CONFIG_SYS_CS0_START) | + CSAW_STOP(CONFIG_SYS_CS0_START, CONFIG_SYS_CS0_SIZE)); + sync_law(&im->sysconf.lpcs0aw); +#endif +#if defined(CONFIG_SYS_CS0_CFG) + out_be32(&im->lpc.cs_cfg[0], CONFIG_SYS_CS0_CFG); +#endif + +#if defined(CONFIG_SYS_CS1_START) && defined(CONFIG_SYS_CS1_SIZE) + out_be32(&im->sysconf.lpcs1aw, + CSAW_START(CONFIG_SYS_CS1_START) | + CSAW_STOP(CONFIG_SYS_CS1_START, CONFIG_SYS_CS1_SIZE)); + sync_law(&im->sysconf.lpcs1aw); +#endif +#if defined(CONFIG_SYS_CS1_CFG) + out_be32(&im->lpc.cs_cfg[1], CONFIG_SYS_CS1_CFG); +#endif + +#if defined(CONFIG_SYS_CS2_START) && (defined CONFIG_SYS_CS2_SIZE) + out_be32(&im->sysconf.lpcs2aw, + CSAW_START(CONFIG_SYS_CS2_START) | + CSAW_STOP(CONFIG_SYS_CS2_START, CONFIG_SYS_CS2_SIZE)); + sync_law(&im->sysconf.lpcs2aw); +#endif +#if defined(CONFIG_SYS_CS2_CFG) + out_be32(&im->lpc.cs_cfg[2], CONFIG_SYS_CS2_CFG); +#endif + +#if defined(CONFIG_SYS_CS3_START) && defined(CONFIG_SYS_CS3_SIZE) + out_be32(&im->sysconf.lpcs3aw, + CSAW_START(CONFIG_SYS_CS3_START) | + CSAW_STOP(CONFIG_SYS_CS3_START, CONFIG_SYS_CS3_SIZE)); + sync_law(&im->sysconf.lpcs3aw); +#endif +#if defined(CONFIG_SYS_CS3_CFG) + out_be32(&im->lpc.cs_cfg[3], CONFIG_SYS_CS3_CFG); +#endif + +#if defined(CONFIG_SYS_CS4_START) && defined(CONFIG_SYS_CS4_SIZE) + out_be32(&im->sysconf.lpcs4aw, + CSAW_START(CONFIG_SYS_CS4_START) | + CSAW_STOP(CONFIG_SYS_CS4_START, CONFIG_SYS_CS4_SIZE)); + sync_law(&im->sysconf.lpcs4aw); +#endif +#if defined(CONFIG_SYS_CS4_CFG) + out_be32(&im->lpc.cs_cfg[4], CONFIG_SYS_CS4_CFG); +#endif + +#if defined(CONFIG_SYS_CS5_START) && defined(CONFIG_SYS_CS5_SIZE) + out_be32(&im->sysconf.lpcs5aw, + CSAW_START(CONFIG_SYS_CS5_START) | + CSAW_STOP(CONFIG_SYS_CS5_START, CONFIG_SYS_CS5_SIZE)); + sync_law(&im->sysconf.lpcs5aw); +#endif +#if defined(CONFIG_SYS_CS5_CFG) + out_be32(&im->lpc.cs_cfg[5], CONFIG_SYS_CS5_CFG); +#endif + +#if defined(CONFIG_SYS_CS6_START) && defined(CONFIG_SYS_CS6_SIZE) + out_be32(&im->sysconf.lpcs6aw, + CSAW_START(CONFIG_SYS_CS6_START) | + CSAW_STOP(CONFIG_SYS_CS6_START, CONFIG_SYS_CS6_SIZE)); + sync_law(&im->sysconf.lpcs6aw); +#endif +#if defined(CONFIG_SYS_CS6_CFG) + out_be32(&im->lpc.cs_cfg[6], CONFIG_SYS_CS6_CFG); +#endif + +#if defined(CONFIG_SYS_CS7_START) && defined(CONFIG_SYS_CS7_SIZE) + out_be32(&im->sysconf.lpcs7aw, + CSAW_START(CONFIG_SYS_CS7_START) | + CSAW_STOP(CONFIG_SYS_CS7_START, CONFIG_SYS_CS7_SIZE)); + sync_law(&im->sysconf.lpcs7aw); +#endif +#if defined(CONFIG_SYS_CS7_CFG) + out_be32(&im->lpc.cs_cfg[7], CONFIG_SYS_CS7_CFG); +#endif + +#if defined CONFIG_SYS_CS_ALETIMING + if (SVR_MJREV(in_be32(&im->sysconf.spridr)) >= 2) + out_be32(&im->lpc.altr, CONFIG_SYS_CS_ALETIMING); +#endif +#if defined CONFIG_SYS_CS_BURST + out_be32(&im->lpc.cs_bcr, CONFIG_SYS_CS_BURST); +#endif +#if defined CONFIG_SYS_CS_DEADCYCLE + out_be32(&im->lpc.cs_dccr, CONFIG_SYS_CS_DEADCYCLE); +#endif +#if defined CONFIG_SYS_CS_HOLDCYCLE + out_be32(&im->lpc.cs_hccr, CONFIG_SYS_CS_HOLDCYCLE); +#endif + /* system performance tweaking */ #ifdef CONFIG_SYS_ACR_PIPE_DEP @@ -76,6 +172,21 @@ void cpu_init_f (volatile immap_t * im) ips_div |= SCFR1_IPS_DIV << SCFR1_IPS_DIV_SHIFT; out_be32(&im->clk.scfr[0], ips_div); +#ifdef SCFR1_LPC_DIV + clrsetbits_be32(&im->clk.scfr[0], SCFR1_LPC_DIV_MASK, + SCFR1_LPC_DIV << SCFR1_LPC_DIV_SHIFT); +#endif + +#ifdef SCFR1_NFC_DIV + clrsetbits_be32(&im->clk.scfr[0], SCFR1_NFC_DIV_MASK, + SCFR1_NFC_DIV << SCFR1_NFC_DIV_SHIFT); +#endif + +#ifdef SCFR1_DIU_DIV + clrsetbits_be32(&im->clk.scfr[0], SCFR1_DIU_DIV_MASK, + SCFR1_DIU_DIV << SCFR1_DIU_DIV_SHIFT); +#endif + /* * Enable Time Base/Decrementer * @@ -84,6 +195,15 @@ void cpu_init_f (volatile immap_t * im) * during FLASH chip identification etc. */ setbits_be32(&im->sysconf.spcr, SPCR_TBEN); + + /* + * Enable clocks + */ + out_be32(&im->clk.sccr[0], SCCR1_CLOCKS_EN); + out_be32(&im->clk.sccr[1], SCCR2_CLOCKS_EN); +#if defined(CONFIG_IIM) || defined(CONFIG_CMD_FUSE) + setbits_be32(&im->clk.sccr[1], CLOCK_SCCR2_IIM_EN); +#endif } int cpu_init_r (void) diff --git a/arch/powerpc/cpu/mpc512x/fixed_sdram.c b/arch/powerpc/cpu/mpc512x/fixed_sdram.c index 550cbd0bd6..6635fb036e 100644 --- a/arch/powerpc/cpu/mpc512x/fixed_sdram.c +++ b/arch/powerpc/cpu/mpc512x/fixed_sdram.c @@ -99,7 +99,19 @@ long int fixed_sdram(ddr512x_config_t *mddrc_config, sync_law(&im->sysconf.ddrlaw.ar); /* DDR Enable */ - out_be32(&im->mddrc.ddr_sys_config, MDDRC_SYS_CFG_EN); + /* + * the "enable" combination: DRAM controller out of reset, + * clock enabled, command mode -- BUT leave CKE low for now + */ + i = MDDRC_SYS_CFG_EN & ~MDDRC_SYS_CFG_CKE_MASK; + out_be32(&im->mddrc.ddr_sys_config, i); + /* maintain 200 microseconds of stable power and clock */ + udelay(200); + /* apply a NOP, it shouldn't harm */ + out_be32(&im->mddrc.ddr_command, CONFIG_SYS_DDRCMD_NOP); + /* now assert CKE (high) */ + i |= MDDRC_SYS_CFG_CKE_MASK; + out_be32(&im->mddrc.ddr_sys_config, i); /* Initialize DDR Priority Manager */ out_be32(&im->mddrc.prioman_config1, CONFIG_SYS_MDDRCGRP_PM_CFG1); @@ -148,6 +160,9 @@ long int fixed_sdram(ddr512x_config_t *mddrc_config, out_be32(&im->mddrc.ddr_time_config0, mddrc_config->ddr_time_config0); out_be32(&im->mddrc.ddr_sys_config, mddrc_config->ddr_sys_config); + /* Allow for the DLL to startup before accessing data */ + udelay(10); + msize = get_ram_size(CONFIG_SYS_DDR_BASE, CONFIG_SYS_MAX_RAM_SIZE); /* Fix DDR Local Window for new size */ out_be32(&im->sysconf.ddrlaw.ar, __ilog2(msize) - 1); diff --git a/arch/powerpc/cpu/mpc512x/iopin.c b/arch/powerpc/cpu/mpc512x/iopin.c index be20947623..1a39101622 100644 --- a/arch/powerpc/cpu/mpc512x/iopin.c +++ b/arch/powerpc/cpu/mpc512x/iopin.c @@ -47,3 +47,57 @@ void iopin_initialize(iopin_t *ioregs_init, int len) } return; } + +void iopin_initialize_bits(iopin_t *ioregs_init, int len) +{ + short i, j, p; + u32 *reg, mask; + immap_t *im = (immap_t *)CONFIG_SYS_IMMR; + + reg = (u32 *)&(im->io_ctrl); + + /* iterate over table entries */ + for (i = 0; i < len; i++) { + /* iterate over pins within a table entry */ + for (p = 0, j = ioregs_init[i].p_offset / sizeof(u_long); + p < ioregs_init[i].nr_pins; p++, j++) { + if (ioregs_init[i].bit_or & IO_PIN_OVER_EACH) { + /* replace all settings at once */ + out_be32(reg + j, ioregs_init[i].val); + } else { + /* + * only replace individual parts, but + * REPLACE them instead of just ORing + * them in and "inheriting" previously + * set bits which we don't want + */ + mask = 0; + if (ioregs_init[i].bit_or & IO_PIN_OVER_FMUX) + mask |= IO_PIN_FMUX(3); + + if (ioregs_init[i].bit_or & IO_PIN_OVER_HOLD) + mask |= IO_PIN_HOLD(3); + + if (ioregs_init[i].bit_or & IO_PIN_OVER_PULL) + mask |= IO_PIN_PUD(1) | IO_PIN_PUE(1); + + if (ioregs_init[i].bit_or & IO_PIN_OVER_STRIG) + mask |= IO_PIN_ST(1); + + if (ioregs_init[i].bit_or & IO_PIN_OVER_DRVSTR) + mask |= IO_PIN_DS(3); + /* + * DON'T do the "mask, then insert" + * in place on the register, it may + * break access to external hardware + * (like boot ROMs) when configuring + * LPB related pins, while the code to + * configure the pin is read from this + * very address region + */ + clrsetbits_be32(reg + j, mask, + ioregs_init[i].val & mask); + } + } + } +} diff --git a/arch/powerpc/cpu/mpc5xxx/spl_boot.c b/arch/powerpc/cpu/mpc5xxx/spl_boot.c index 9f14127dca..080bd580d9 100644 --- a/arch/powerpc/cpu/mpc5xxx/spl_boot.c +++ b/arch/powerpc/cpu/mpc5xxx/spl_boot.c @@ -41,13 +41,12 @@ void board_init_f(ulong bootflag) end_align = (u32)__spl_flash_end; /* - * First we need to initialize the SDRAM, so that the real - * U-Boot or the OS (Linux) can be loaded + * On MPC5200, the initial RAM (and gd) is located in the internal + * SRAM. So we can actually call the preloader console init code + * before calling initdram(). This makes serial output (printf) + * available very early, even before SDRAM init, which has been + * an U-Boot priciple from day 1. */ - initdram(0); - - /* Clear bss */ - memset(__bss_start, '\0', __bss_end__ - __bss_start); /* * Init global_data pointer. Has to be done before calling @@ -71,6 +70,15 @@ void board_init_f(ulong bootflag) preloader_console_init(); /* + * First we need to initialize the SDRAM, so that the real + * U-Boot or the OS (Linux) can be loaded + */ + initdram(0); + + /* Clear bss */ + memset(__bss_start, '\0', __bss_end__ - __bss_start); + + /* * Call board_init_r() (SPL framework version) to load and boot * real U-Boot or OS */ diff --git a/arch/powerpc/include/asm/immap_512x.h b/arch/powerpc/include/asm/immap_512x.h index f763a5413e..d96e53646a 100644 --- a/arch/powerpc/include/asm/immap_512x.h +++ b/arch/powerpc/include/asm/immap_512x.h @@ -227,7 +227,9 @@ typedef struct clk512x { #define CLOCK_SCCR2_IIM_EN 0x00080000 /* SCFR1 System Clock Frequency Register 1 */ +#ifndef SCFR1_IPS_DIV #define SCFR1_IPS_DIV 0x3 +#endif #define SCFR1_IPS_DIV_MASK 0x03800000 #define SCFR1_IPS_DIV_SHIFT 23 @@ -238,6 +240,12 @@ typedef struct clk512x { #define SCFR1_LPC_DIV_MASK 0x00003800 #define SCFR1_LPC_DIV_SHIFT 11 +#define SCFR1_NFC_DIV_MASK 0x00000700 +#define SCFR1_NFC_DIV_SHIFT 8 + +#define SCFR1_DIU_DIV_MASK 0x000000FF +#define SCFR1_DIU_DIV_SHIFT 0 + /* SCFR2 System Clock Frequency Register 2 */ #define SCFR2_SYS_DIV 0xFC000000 #define SCFR2_SYS_DIV_SHIFT 26 @@ -343,6 +351,7 @@ typedef struct ddr512x { /* MDDRC SYS CFG and Timing CFG0 Registers */ #define MDDRC_SYS_CFG_EN 0xF0000000 +#define MDDRC_SYS_CFG_CKE_MASK 0x40000000 #define MDDRC_SYS_CFG_CMD_MASK 0x10000000 #define MDDRC_REFRESH_ZERO_MASK 0x0000FFFF @@ -871,6 +880,19 @@ typedef struct iopin_t { void iopin_initialize(iopin_t *,int); /* + * support to adjust individual parts of the IO pin setup + */ + +#define IO_PIN_OVER_EACH (1 << 0) /* for compatibility */ +#define IO_PIN_OVER_FMUX (1 << 1) +#define IO_PIN_OVER_HOLD (1 << 2) +#define IO_PIN_OVER_PULL (1 << 3) +#define IO_PIN_OVER_STRIG (1 << 4) +#define IO_PIN_OVER_DRVSTR (1 << 5) + +void iopin_initialize_bits(iopin_t *, int); + +/* * IIM */ typedef struct iim512x { |