summaryrefslogtreecommitdiff
path: root/cpu
diff options
context:
space:
mode:
authorWolfgang Denk <wd@denx.de>2008-06-11 22:13:07 +0200
committerWolfgang Denk <wd@denx.de>2008-06-11 22:13:07 +0200
commit1730edf76c54381475e2da11f75b1ce563c4e62c (patch)
tree1f2a9fb7a7cd9b547374d9cc3715a7f18001e1ee /cpu
parent5ea67393b8b554b8165c38912d753a8df043020d (diff)
parentb2815f79288d4da7a3ba18bdbd05120ce09d5622 (diff)
Merge branch 'master' of git://www.denx.de/git/u-boot-ppc4xx
Diffstat (limited to 'cpu')
-rw-r--r--cpu/ppc4xx/44x_spd_ddr.c200
-rw-r--r--cpu/ppc4xx/44x_spd_ddr2.c131
-rw-r--r--cpu/ppc4xx/4xx_uart.c10
-rw-r--r--cpu/ppc4xx/Makefile1
-rw-r--r--cpu/ppc4xx/cpu_init.c85
-rw-r--r--cpu/ppc4xx/ecc.c122
-rw-r--r--cpu/ppc4xx/ecc.h69
-rw-r--r--cpu/ppc4xx/sdram.c54
-rw-r--r--cpu/ppc4xx/start.S522
-rw-r--r--cpu/ppc4xx/traps.c9
10 files changed, 656 insertions, 547 deletions
diff --git a/cpu/ppc4xx/44x_spd_ddr.c b/cpu/ppc4xx/44x_spd_ddr.c
index b9cf5cbfcca..9efcedefed0 100644
--- a/cpu/ppc4xx/44x_spd_ddr.c
+++ b/cpu/ppc4xx/44x_spd_ddr.c
@@ -53,6 +53,8 @@
#include <ppc4xx.h>
#include <asm/mmu.h>
+#include "ecc.h"
+
#if defined(CONFIG_SPD_EEPROM) && \
(defined(CONFIG_440GP) || defined(CONFIG_440GX) || \
defined(CONFIG_440EP) || defined(CONFIG_440GR))
@@ -79,157 +81,6 @@ void __spd_ddr_init_hang (void)
}
void spd_ddr_init_hang (void) __attribute__((weak, alias("__spd_ddr_init_hang")));
-/*-----------------------------------------------------------------------------
- | Memory Controller Options 0
- +-----------------------------------------------------------------------------*/
-#define SDRAM_CFG0_DCEN 0x80000000 /* SDRAM Controller Enable */
-#define SDRAM_CFG0_MCHK_MASK 0x30000000 /* Memory data errchecking mask */
-#define SDRAM_CFG0_MCHK_NON 0x00000000 /* No ECC generation */
-#define SDRAM_CFG0_MCHK_GEN 0x20000000 /* ECC generation */
-#define SDRAM_CFG0_MCHK_CHK 0x30000000 /* ECC generation and checking */
-#define SDRAM_CFG0_RDEN 0x08000000 /* Registered DIMM enable */
-#define SDRAM_CFG0_PMUD 0x04000000 /* Page management unit */
-#define SDRAM_CFG0_DMWD_MASK 0x02000000 /* DRAM width mask */
-#define SDRAM_CFG0_DMWD_32 0x00000000 /* 32 bits */
-#define SDRAM_CFG0_DMWD_64 0x02000000 /* 64 bits */
-#define SDRAM_CFG0_UIOS_MASK 0x00C00000 /* Unused IO State */
-#define SDRAM_CFG0_PDP 0x00200000 /* Page deallocation policy */
-
-/*-----------------------------------------------------------------------------
- | Memory Controller Options 1
- +-----------------------------------------------------------------------------*/
-#define SDRAM_CFG1_SRE 0x80000000 /* Self-Refresh Entry */
-#define SDRAM_CFG1_PMEN 0x40000000 /* Power Management Enable */
-
-/*-----------------------------------------------------------------------------+
- | SDRAM DEVPOT Options
- +-----------------------------------------------------------------------------*/
-#define SDRAM_DEVOPT_DLL 0x80000000
-#define SDRAM_DEVOPT_DS 0x40000000
-
-/*-----------------------------------------------------------------------------+
- | SDRAM MCSTS Options
- +-----------------------------------------------------------------------------*/
-#define SDRAM_MCSTS_MRSC 0x80000000
-#define SDRAM_MCSTS_SRMS 0x40000000
-#define SDRAM_MCSTS_CIS 0x20000000
-
-/*-----------------------------------------------------------------------------
- | SDRAM Refresh Timer Register
- +-----------------------------------------------------------------------------*/
-#define SDRAM_RTR_RINT_MASK 0xFFFF0000
-#define SDRAM_RTR_RINT_ENCODE(n) (((n) << 16) & SDRAM_RTR_RINT_MASK)
-#define sdram_HZ_to_ns(hertz) (1000000000/(hertz))
-
-/*-----------------------------------------------------------------------------+
- | SDRAM UABus Base Address Reg
- +-----------------------------------------------------------------------------*/
-#define SDRAM_UABBA_UBBA_MASK 0x0000000F
-
-/*-----------------------------------------------------------------------------+
- | Memory Bank 0-7 configuration
- +-----------------------------------------------------------------------------*/
-#define SDRAM_BXCR_SDBA_MASK 0xff800000 /* Base address */
-#define SDRAM_BXCR_SDSZ_MASK 0x000e0000 /* Size */
-#define SDRAM_BXCR_SDSZ_8 0x00020000 /* 8M */
-#define SDRAM_BXCR_SDSZ_16 0x00040000 /* 16M */
-#define SDRAM_BXCR_SDSZ_32 0x00060000 /* 32M */
-#define SDRAM_BXCR_SDSZ_64 0x00080000 /* 64M */
-#define SDRAM_BXCR_SDSZ_128 0x000a0000 /* 128M */
-#define SDRAM_BXCR_SDSZ_256 0x000c0000 /* 256M */
-#define SDRAM_BXCR_SDSZ_512 0x000e0000 /* 512M */
-#define SDRAM_BXCR_SDAM_MASK 0x0000e000 /* Addressing mode */
-#define SDRAM_BXCR_SDAM_1 0x00000000 /* Mode 1 */
-#define SDRAM_BXCR_SDAM_2 0x00002000 /* Mode 2 */
-#define SDRAM_BXCR_SDAM_3 0x00004000 /* Mode 3 */
-#define SDRAM_BXCR_SDAM_4 0x00006000 /* Mode 4 */
-#define SDRAM_BXCR_SDBE 0x00000001 /* Memory Bank Enable */
-
-/*-----------------------------------------------------------------------------+
- | SDRAM TR0 Options
- +-----------------------------------------------------------------------------*/
-#define SDRAM_TR0_SDWR_MASK 0x80000000
-#define SDRAM_TR0_SDWR_2_CLK 0x00000000
-#define SDRAM_TR0_SDWR_3_CLK 0x80000000
-#define SDRAM_TR0_SDWD_MASK 0x40000000
-#define SDRAM_TR0_SDWD_0_CLK 0x00000000
-#define SDRAM_TR0_SDWD_1_CLK 0x40000000
-#define SDRAM_TR0_SDCL_MASK 0x01800000
-#define SDRAM_TR0_SDCL_2_0_CLK 0x00800000
-#define SDRAM_TR0_SDCL_2_5_CLK 0x01000000
-#define SDRAM_TR0_SDCL_3_0_CLK 0x01800000
-#define SDRAM_TR0_SDPA_MASK 0x000C0000
-#define SDRAM_TR0_SDPA_2_CLK 0x00040000
-#define SDRAM_TR0_SDPA_3_CLK 0x00080000
-#define SDRAM_TR0_SDPA_4_CLK 0x000C0000
-#define SDRAM_TR0_SDCP_MASK 0x00030000
-#define SDRAM_TR0_SDCP_2_CLK 0x00000000
-#define SDRAM_TR0_SDCP_3_CLK 0x00010000
-#define SDRAM_TR0_SDCP_4_CLK 0x00020000
-#define SDRAM_TR0_SDCP_5_CLK 0x00030000
-#define SDRAM_TR0_SDLD_MASK 0x0000C000
-#define SDRAM_TR0_SDLD_1_CLK 0x00000000
-#define SDRAM_TR0_SDLD_2_CLK 0x00004000
-#define SDRAM_TR0_SDRA_MASK 0x0000001C
-#define SDRAM_TR0_SDRA_6_CLK 0x00000000
-#define SDRAM_TR0_SDRA_7_CLK 0x00000004
-#define SDRAM_TR0_SDRA_8_CLK 0x00000008
-#define SDRAM_TR0_SDRA_9_CLK 0x0000000C
-#define SDRAM_TR0_SDRA_10_CLK 0x00000010
-#define SDRAM_TR0_SDRA_11_CLK 0x00000014
-#define SDRAM_TR0_SDRA_12_CLK 0x00000018
-#define SDRAM_TR0_SDRA_13_CLK 0x0000001C
-#define SDRAM_TR0_SDRD_MASK 0x00000003
-#define SDRAM_TR0_SDRD_2_CLK 0x00000001
-#define SDRAM_TR0_SDRD_3_CLK 0x00000002
-#define SDRAM_TR0_SDRD_4_CLK 0x00000003
-
-/*-----------------------------------------------------------------------------+
- | SDRAM TR1 Options
- +-----------------------------------------------------------------------------*/
-#define SDRAM_TR1_RDSS_MASK 0xC0000000
-#define SDRAM_TR1_RDSS_TR0 0x00000000
-#define SDRAM_TR1_RDSS_TR1 0x40000000
-#define SDRAM_TR1_RDSS_TR2 0x80000000
-#define SDRAM_TR1_RDSS_TR3 0xC0000000
-#define SDRAM_TR1_RDSL_MASK 0x00C00000
-#define SDRAM_TR1_RDSL_STAGE1 0x00000000
-#define SDRAM_TR1_RDSL_STAGE2 0x00400000
-#define SDRAM_TR1_RDSL_STAGE3 0x00800000
-#define SDRAM_TR1_RDCD_MASK 0x00000800
-#define SDRAM_TR1_RDCD_RCD_0_0 0x00000000
-#define SDRAM_TR1_RDCD_RCD_1_2 0x00000800
-#define SDRAM_TR1_RDCT_MASK 0x000001FF
-#define SDRAM_TR1_RDCT_ENCODE(x) (((x) << 0) & SDRAM_TR1_RDCT_MASK)
-#define SDRAM_TR1_RDCT_DECODE(x) (((x) & SDRAM_TR1_RDCT_MASK) >> 0)
-#define SDRAM_TR1_RDCT_MIN 0x00000000
-#define SDRAM_TR1_RDCT_MAX 0x000001FF
-
-/*-----------------------------------------------------------------------------+
- | SDRAM WDDCTR Options
- +-----------------------------------------------------------------------------*/
-#define SDRAM_WDDCTR_WRCP_MASK 0xC0000000
-#define SDRAM_WDDCTR_WRCP_0DEG 0x00000000
-#define SDRAM_WDDCTR_WRCP_90DEG 0x40000000
-#define SDRAM_WDDCTR_WRCP_180DEG 0x80000000
-#define SDRAM_WDDCTR_DCD_MASK 0x000001FF
-
-/*-----------------------------------------------------------------------------+
- | SDRAM CLKTR Options
- +-----------------------------------------------------------------------------*/
-#define SDRAM_CLKTR_CLKP_MASK 0xC0000000
-#define SDRAM_CLKTR_CLKP_0DEG 0x00000000
-#define SDRAM_CLKTR_CLKP_90DEG 0x40000000
-#define SDRAM_CLKTR_CLKP_180DEG 0x80000000
-#define SDRAM_CLKTR_DCDT_MASK 0x000001FF
-
-/*-----------------------------------------------------------------------------+
- | SDRAM DLYCAL Options
- +-----------------------------------------------------------------------------*/
-#define SDRAM_DLYCAL_DLCV_MASK 0x000003FC
-#define SDRAM_DLYCAL_DLCV_ENCODE(x) (((x)<<2) & SDRAM_DLYCAL_DLCV_MASK)
-#define SDRAM_DLYCAL_DLCV_DECODE(x) (((x) & SDRAM_DLYCAL_DLCV_MASK)>>2)
-
/*-----------------------------------------------------------------------------+
| General Definition
+-----------------------------------------------------------------------------*/
@@ -296,10 +147,6 @@ static void program_tr0(unsigned long *dimm_populated,
unsigned long num_dimm_banks);
static void program_tr1(void);
-#ifdef CONFIG_DDR_ECC
-static void program_ecc(unsigned long num_bytes);
-#endif
-
static unsigned long program_bxcr(unsigned long *dimm_populated,
unsigned char *iic0_dimm_addr,
unsigned long num_dimm_banks);
@@ -418,7 +265,7 @@ long int spd_sdram(void) {
/*
* If ecc is enabled, initialize the parity bits.
*/
- program_ecc(total_size);
+ ecc_init(CFG_SDRAM_BASE, total_size);
#endif
return total_size;
@@ -1402,45 +1249,4 @@ static unsigned long program_bxcr(unsigned long *dimm_populated,
return(bank_base_addr);
}
-
-#ifdef CONFIG_DDR_ECC
-static void program_ecc(unsigned long num_bytes)
-{
- unsigned long bank_base_addr;
- unsigned long current_address;
- unsigned long end_address;
- unsigned long address_increment;
- unsigned long cfg0;
-
- /*
- * get Memory Controller Options 0 data
- */
- mfsdram(mem_cfg0, cfg0);
-
- /*
- * reset the bank_base address
- */
- bank_base_addr = CFG_SDRAM_BASE;
-
- if ((cfg0 & SDRAM_CFG0_MCHK_MASK) != SDRAM_CFG0_MCHK_NON) {
- mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | SDRAM_CFG0_MCHK_GEN);
-
- if ((cfg0 & SDRAM_CFG0_DMWD_MASK) == SDRAM_CFG0_DMWD_32)
- address_increment = 4;
- else
- address_increment = 8;
-
- current_address = (unsigned long)(bank_base_addr);
- end_address = (unsigned long)(bank_base_addr) + num_bytes;
-
- while (current_address < end_address) {
- *((unsigned long*)current_address) = 0x00000000;
- current_address += address_increment;
- }
-
- mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) |
- SDRAM_CFG0_MCHK_CHK);
- }
-}
-#endif /* CONFIG_DDR_ECC */
#endif /* CONFIG_SPD_EEPROM */
diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c
index ec76b718bcc..521491820d7 100644
--- a/cpu/ppc4xx/44x_spd_ddr2.c
+++ b/cpu/ppc4xx/44x_spd_ddr2.c
@@ -3,9 +3,12 @@
* This SPD SDRAM detection code supports AMCC PPC44x cpu's with a
* DDR2 controller (non Denali Core). Those currently are:
*
- * 405: 405EX
+ * 405: 405EX(r)
* 440/460: 440SP/440SPe/460EX/460GT
*
+ * Copyright (c) 2008 Nuovation System Designs, LLC
+ * Grant Erickson <gerickson@nuovations.com>
+
* (C) Copyright 2007-2008
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
@@ -45,6 +48,8 @@
#include <asm/mmu.h>
#include <asm/cache.h>
+#include "ecc.h"
+
#if defined(CONFIG_SPD_EEPROM) && \
(defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
defined(CONFIG_460EX) || defined(CONFIG_460GT))
@@ -3064,9 +3069,127 @@ static void ppc440sp_sdram_register_dump(void)
dcr_data = mfdcr(SDRAM_R3BAS);
printf(" MQ3_B0BAS = 0x%08X\n", dcr_data);
}
-#else
+#else /* !defined(DEBUG) */
static void ppc440sp_sdram_register_dump(void)
{
}
-#endif
-#endif /* CONFIG_SPD_EEPROM */
+#endif /* defined(DEBUG) */
+#elif defined(CONFIG_405EX)
+/*-----------------------------------------------------------------------------
+ * Function: initdram
+ * Description: Configures the PPC405EX(r) DDR1/DDR2 SDRAM memory
+ * banks. The configuration is performed using static, compile-
+ * time parameters.
+ *---------------------------------------------------------------------------*/
+long initdram(int board_type)
+{
+ /*
+ * Only run this SDRAM init code once. For NAND booting
+ * targets like Kilauea, we call initdram() early from the
+ * 4k NAND booting image (CONFIG_NAND_SPL) from nand_boot().
+ * Later on the NAND U-Boot image runs (CONFIG_NAND_U_BOOT)
+ * which calls initdram() again. This time the controller
+ * mustn't be reconfigured again since we're already running
+ * from SDRAM.
+ */
+#if !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL)
+ unsigned long val;
+
+ /* Set Memory Bank Configuration Registers */
+
+ mtsdram(SDRAM_MB0CF, CFG_SDRAM0_MB0CF);
+ mtsdram(SDRAM_MB1CF, CFG_SDRAM0_MB1CF);
+ mtsdram(SDRAM_MB2CF, CFG_SDRAM0_MB2CF);
+ mtsdram(SDRAM_MB3CF, CFG_SDRAM0_MB3CF);
+
+ /* Set Memory Clock Timing Register */
+
+ mtsdram(SDRAM_CLKTR, CFG_SDRAM0_CLKTR);
+
+ /* Set Refresh Time Register */
+
+ mtsdram(SDRAM_RTR, CFG_SDRAM0_RTR);
+
+ /* Set SDRAM Timing Registers */
+
+ mtsdram(SDRAM_SDTR1, CFG_SDRAM0_SDTR1);
+ mtsdram(SDRAM_SDTR2, CFG_SDRAM0_SDTR2);
+ mtsdram(SDRAM_SDTR3, CFG_SDRAM0_SDTR3);
+
+ /* Set Mode and Extended Mode Registers */
+
+ mtsdram(SDRAM_MMODE, CFG_SDRAM0_MMODE);
+ mtsdram(SDRAM_MEMODE, CFG_SDRAM0_MEMODE);
+
+ /* Set Memory Controller Options 1 Register */
+
+ mtsdram(SDRAM_MCOPT1, CFG_SDRAM0_MCOPT1);
+
+ /* Set Manual Initialization Control Registers */
+
+ mtsdram(SDRAM_INITPLR0, CFG_SDRAM0_INITPLR0);
+ mtsdram(SDRAM_INITPLR1, CFG_SDRAM0_INITPLR1);
+ mtsdram(SDRAM_INITPLR2, CFG_SDRAM0_INITPLR2);
+ mtsdram(SDRAM_INITPLR3, CFG_SDRAM0_INITPLR3);
+ mtsdram(SDRAM_INITPLR4, CFG_SDRAM0_INITPLR4);
+ mtsdram(SDRAM_INITPLR5, CFG_SDRAM0_INITPLR5);
+ mtsdram(SDRAM_INITPLR6, CFG_SDRAM0_INITPLR6);
+ mtsdram(SDRAM_INITPLR7, CFG_SDRAM0_INITPLR7);
+ mtsdram(SDRAM_INITPLR8, CFG_SDRAM0_INITPLR8);
+ mtsdram(SDRAM_INITPLR9, CFG_SDRAM0_INITPLR9);
+ mtsdram(SDRAM_INITPLR10, CFG_SDRAM0_INITPLR10);
+ mtsdram(SDRAM_INITPLR11, CFG_SDRAM0_INITPLR11);
+ mtsdram(SDRAM_INITPLR12, CFG_SDRAM0_INITPLR12);
+ mtsdram(SDRAM_INITPLR13, CFG_SDRAM0_INITPLR13);
+ mtsdram(SDRAM_INITPLR14, CFG_SDRAM0_INITPLR14);
+ mtsdram(SDRAM_INITPLR15, CFG_SDRAM0_INITPLR15);
+
+ /* Set On-Die Termination Registers */
+
+ mtsdram(SDRAM_CODT, CFG_SDRAM0_CODT);
+ mtsdram(SDRAM_MODT0, CFG_SDRAM0_MODT0);
+ mtsdram(SDRAM_MODT1, CFG_SDRAM0_MODT1);
+
+ /* Set Write Timing Register */
+
+ mtsdram(SDRAM_WRDTR, CFG_SDRAM0_WRDTR);
+
+ /*
+ * Start Initialization by SDRAM0_MCOPT2[SREN] = 0 and
+ * SDRAM0_MCOPT2[IPTR] = 1
+ */
+
+ mtsdram(SDRAM_MCOPT2, (SDRAM_MCOPT2_SREN_EXIT |
+ SDRAM_MCOPT2_IPTR_EXECUTE));
+
+ /*
+ * Poll SDRAM0_MCSTAT[MIC] for assertion to indicate the
+ * completion of initialization.
+ */
+
+ do {
+ mfsdram(SDRAM_MCSTAT, val);
+ } while ((val & SDRAM_MCSTAT_MIC_MASK) != SDRAM_MCSTAT_MIC_COMP);
+
+ /* Set Delay Control Registers */
+
+ mtsdram(SDRAM_DLCR, CFG_SDRAM0_DLCR);
+ mtsdram(SDRAM_RDCC, CFG_SDRAM0_RDCC);
+ mtsdram(SDRAM_RQDC, CFG_SDRAM0_RQDC);
+ mtsdram(SDRAM_RFDC, CFG_SDRAM0_RFDC);
+
+ /*
+ * Enable Controller by SDRAM0_MCOPT2[DCEN] = 1:
+ */
+
+ mfsdram(SDRAM_MCOPT2, val);
+ mtsdram(SDRAM_MCOPT2, val | SDRAM_MCOPT2_DCEN_ENABLE);
+
+#if defined(CONFIG_DDR_ECC)
+ ecc_init(CFG_SDRAM_BASE, CFG_MBYTES_SDRAM << 20);
+#endif /* defined(CONFIG_DDR_ECC) */
+#endif /* !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL) */
+
+ return (CFG_MBYTES_SDRAM << 20);
+}
+#endif /* defined(CONFIG_SPD_EEPROM) && defined(CONFIG_440SP) || ... */
diff --git a/cpu/ppc4xx/4xx_uart.c b/cpu/ppc4xx/4xx_uart.c
index ffbc222e7a9..a7587d4351f 100644
--- a/cpu/ppc4xx/4xx_uart.c
+++ b/cpu/ppc4xx/4xx_uart.c
@@ -98,14 +98,14 @@ DECLARE_GLOBAL_DATA_PTR;
#define UDIV_SUBTRACT 0
#define UART0_SDR sdr_uart0
#define UART1_SDR sdr_uart1
-#if defined(CONFIG_440EP) || defined(CONFIG_440EPx) || \
- defined(CONFIG_440GR) || defined(CONFIG_440GRx) || \
- defined(CONFIG_440SP) || defined(CONFIG_440SPe) || \
+#if defined(CONFIG_440EP) || defined(CONFIG_440EPX) || \
+ defined(CONFIG_440GR) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
defined(CONFIG_460EX) || defined(CONFIG_460GT)
#define UART2_SDR sdr_uart2
#endif
-#if defined(CONFIG_440EP) || defined(CONFIG_440EPx) || \
- defined(CONFIG_440GR) || defined(CONFIG_440GRx) || \
+#if defined(CONFIG_440EP) || defined(CONFIG_440EPX) || \
+ defined(CONFIG_440GR) || defined(CONFIG_440GRX) || \
defined(CONFIG_460EX) || defined(CONFIG_460GT)
#define UART3_SDR sdr_uart3
#endif
diff --git a/cpu/ppc4xx/Makefile b/cpu/ppc4xx/Makefile
index 178c5c67425..800bb41d014 100644
--- a/cpu/ppc4xx/Makefile
+++ b/cpu/ppc4xx/Makefile
@@ -45,6 +45,7 @@ COBJS += cpu.o
COBJS += cpu_init.o
COBJS += denali_data_eye.o
COBJS += denali_spd_ddr2.o
+COBJS += ecc.o
COBJS += fdt.o
COBJS += gpio.o
COBJS += i2c.o
diff --git a/cpu/ppc4xx/cpu_init.c b/cpu/ppc4xx/cpu_init.c
index 42eabfe568a..1e9423a89bf 100644
--- a/cpu/ppc4xx/cpu_init.c
+++ b/cpu/ppc4xx/cpu_init.c
@@ -32,73 +32,6 @@
DECLARE_GLOBAL_DATA_PTR;
#endif
-#ifdef CFG_INIT_DCACHE_CS
-# if (CFG_INIT_DCACHE_CS == 0)
-# define PBxAP pb0ap
-# define PBxCR pb0cr
-# if (defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
-# define PBxAP_VAL CFG_EBC_PB0AP
-# define PBxCR_VAL CFG_EBC_PB0CR
-# endif
-# endif
-# if (CFG_INIT_DCACHE_CS == 1)
-# define PBxAP pb1ap
-# define PBxCR pb1cr
-# if (defined(CFG_EBC_PB1AP) && defined(CFG_EBC_PB1CR))
-# define PBxAP_VAL CFG_EBC_PB1AP
-# define PBxCR_VAL CFG_EBC_PB1CR
-# endif
-# endif
-# if (CFG_INIT_DCACHE_CS == 2)
-# define PBxAP pb2ap
-# define PBxCR pb2cr
-# if (defined(CFG_EBC_PB2AP) && defined(CFG_EBC_PB2CR))
-# define PBxAP_VAL CFG_EBC_PB2AP
-# define PBxCR_VAL CFG_EBC_PB2CR
-# endif
-# endif
-# if (CFG_INIT_DCACHE_CS == 3)
-# define PBxAP pb3ap
-# define PBxCR pb3cr
-# if (defined(CFG_EBC_PB3AP) && defined(CFG_EBC_PB3CR))
-# define PBxAP_VAL CFG_EBC_PB3AP
-# define PBxCR_VAL CFG_EBC_PB3CR
-# endif
-# endif
-# if (CFG_INIT_DCACHE_CS == 4)
-# define PBxAP pb4ap
-# define PBxCR pb4cr
-# if (defined(CFG_EBC_PB4AP) && defined(CFG_EBC_PB4CR))
-# define PBxAP_VAL CFG_EBC_PB4AP
-# define PBxCR_VAL CFG_EBC_PB4CR
-# endif
-# endif
-# if (CFG_INIT_DCACHE_CS == 5)
-# define PBxAP pb5ap
-# define PBxCR pb5cr
-# if (defined(CFG_EBC_PB5AP) && defined(CFG_EBC_PB5CR))
-# define PBxAP_VAL CFG_EBC_PB5AP
-# define PBxCR_VAL CFG_EBC_PB5CR
-# endif
-# endif
-# if (CFG_INIT_DCACHE_CS == 6)
-# define PBxAP pb6ap
-# define PBxCR pb6cr
-# if (defined(CFG_EBC_PB6AP) && defined(CFG_EBC_PB6CR))
-# define PBxAP_VAL CFG_EBC_PB6AP
-# define PBxCR_VAL CFG_EBC_PB6CR
-# endif
-# endif
-# if (CFG_INIT_DCACHE_CS == 7)
-# define PBxAP pb7ap
-# define PBxCR pb7cr
-# if (defined(CFG_EBC_PB7AP) && defined(CFG_EBC_PB7CR))
-# define PBxAP_VAL CFG_EBC_PB7AP
-# define PBxCR_VAL CFG_EBC_PB7CR
-# endif
-# endif
-#endif /* CFG_INIT_DCACHE_CS */
-
#ifndef CFG_PLL_RECONFIG
#define CFG_PLL_RECONFIG 0
#endif
@@ -353,24 +286,6 @@ int cpu_init_r (void)
uint pvr = get_pvr();
#endif
-#ifdef CFG_INIT_DCACHE_CS
- /*
- * Flush and invalidate dcache, then disable CS for temporary stack.
- * Afterwards, this CS can be used for other purposes
- */
- dcache_disable(); /* flush and invalidate dcache */
- mtebc(PBxAP, 0);
- mtebc(PBxCR, 0); /* disable CS for temporary stack */
-
-#if (defined(PBxAP_VAL) && defined(PBxCR_VAL))
- /*
- * Write new value into CS register
- */
- mtebc(PBxAP, PBxAP_VAL);
- mtebc(PBxCR, PBxCR_VAL);
-#endif
-#endif /* CFG_INIT_DCACHE_CS */
-
/*
* Write Ethernetaddress into on-chip register
*/
diff --git a/cpu/ppc4xx/ecc.c b/cpu/ppc4xx/ecc.c
new file mode 100644
index 00000000000..a2eb07bd755
--- /dev/null
+++ b/cpu/ppc4xx/ecc.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2008 Nuovation System Designs, LLC
+ * Grant Erickson <gerickson@nuovations.com>
+ *
+ * (C) Copyright 2005-2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * (C) Copyright 2002
+ * Jun Gu, Artesyn Technology, jung@artesyncp.com
+ *
+ * (C) Copyright 2001
+ * Bill Hunter, Wave 7 Optics, williamhunter@attbi.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will abe useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Description:
+ * This file implements generic DRAM ECC initialization for
+ * PowerPC processors using a SDRAM DDR/DDR2 controller,
+ * including the 405EX(r), 440GP/GX/EP/GR, 440SP(E), and
+ * 460EX/GT.
+ */
+
+#include <common.h>
+#include <ppc4xx.h>
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+
+#include "ecc.h"
+
+#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR) || \
+ defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2)
+#if defined(CONFIG_DDR_ECC) || defined(CONFIG_SDRAM_ECC)
+/*
+ * void ecc_init()
+ *
+ * Description:
+ * This routine initializes a range of DRAM ECC memory with known
+ * data and enables ECC checking.
+ *
+ * TO DO:
+ * - Improve performance by utilizing cache.
+ * - Further generalize to make usable by other 4xx variants (e.g.
+ * 440EPx, et al).
+ *
+ * Input(s):
+ * start - A pointer to the start of memory covered by ECC requiring
+ * initialization.
+ * size - The size, in bytes, of the memory covered by ECC requiring
+ * initialization.
+ *
+ * Output(s):
+ * start - A pointer to the start of memory covered by ECC with
+ * CFG_ECC_PATTERN written to all locations and ECC data
+ * primed.
+ *
+ * Returns:
+ * N/A
+ */
+void ecc_init(unsigned long * const start, unsigned long size)
+{
+ const unsigned long pattern = CFG_ECC_PATTERN;
+ unsigned long * const end = (unsigned long * const)((long)start + size);
+ unsigned long * current = start;
+ unsigned long mcopt1;
+ long increment;
+
+ if (start >= end)
+ return;
+
+ mfsdram(SDRAM_ECC_CFG, mcopt1);
+
+ /* Enable ECC generation without checking or reporting */
+
+ mtsdram(SDRAM_ECC_CFG, ((mcopt1 & ~SDRAM_ECC_CFG_MCHK_MASK) |
+ SDRAM_ECC_CFG_MCHK_GEN));
+
+ increment = sizeof(u32);
+
+#if defined(CONFIG_440)
+ /*
+ * Look at the geometry of SDRAM (data width) to determine whether we
+ * can skip words when writing.
+ */
+
+ if ((mcopt1 & SDRAM_ECC_CFG_DMWD_MASK) != SDRAM_ECC_CFG_DMWD_32)
+ increment = sizeof(u64);
+#endif /* defined(CONFIG_440) */
+
+ while (current < end) {
+ *current = pattern;
+ current = (unsigned long *)((long)current + increment);
+ }
+
+ /* Wait until the writes are finished. */
+
+ sync();
+
+ /* Enable ECC generation with checking and no reporting */
+
+ mtsdram(SDRAM_ECC_CFG, ((mcopt1 & ~SDRAM_ECC_CFG_MCHK_MASK) |
+ SDRAM_ECC_CFG_MCHK_CHK));
+}
+#endif /* defined(CONFIG_DDR_ECC) || defined(CONFIG_SDRAM_ECC) */
+#endif /* defined(CONFIG_SDRAM_PPC4xx_IBM_DDR)... */
diff --git a/cpu/ppc4xx/ecc.h b/cpu/ppc4xx/ecc.h
new file mode 100644
index 00000000000..aecf291a8b6
--- /dev/null
+++ b/cpu/ppc4xx/ecc.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2008 Nuovation System Designs, LLC
+ * Grant Erickson <gerickson@nuovations.com>
+ *
+ * Copyright (c) 2007 DENX Software Engineering, GmbH
+ * Stefan Roese <sr@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will abe useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Description:
+ * This file implements ECC initialization for PowerPC processors
+ * using the SDRAM DDR2 controller, including the 405EX(r),
+ * 440SP(E), 460EX and 460GT.
+ *
+ */
+
+#ifndef _ECC_H_
+#define _ECC_H_
+
+#if !defined(CFG_ECC_PATTERN)
+#define CFG_ECC_PATTERN 0x00000000
+#endif /* !defined(CFG_ECC_PATTERN) */
+
+/*
+ * Since the IBM DDR controller used on 440GP/GX/EP/GR is not register
+ * compatible to the IBM DDR/2 controller used on 405EX/440SP/SPe/460EX/GT
+ * we need to make some processor dependant defines used later on by the
+ * driver.
+ */
+
+/* For 440GP/GX/EP/GR */
+#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR)
+#define SDRAM_ECC_CFG SDRAM_CFG0
+#define SDRAM_ECC_CFG_MCHK_MASK SDRAM_CFG0_MCHK_MASK
+#define SDRAM_ECC_CFG_MCHK_GEN SDRAM_CFG0_MCHK_GEN
+#define SDRAM_ECC_CFG_MCHK_CHK SDRAM_CFG0_MCHK_CHK
+#define SDRAM_ECC_CFG_DMWD_MASK SDRAM_CFG0_DMWD_MASK
+#define SDRAM_ECC_CFG_DMWD_32 SDRAM_CFG0_DMWD_32
+#endif
+
+/* For 405EX/440SP/SPe/460EX/GT */
+#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2)
+#define SDRAM_ECC_CFG SDRAM_MCOPT1
+#define SDRAM_ECC_CFG_MCHK_MASK SDRAM_MCOPT1_MCHK_MASK
+#define SDRAM_ECC_CFG_MCHK_GEN SDRAM_MCOPT1_MCHK_GEN
+#define SDRAM_ECC_CFG_MCHK_CHK SDRAM_MCOPT1_MCHK_CHK
+#define SDRAM_ECC_CFG_DMWD_MASK SDRAM_MCOPT1_DMWD_MASK
+#define SDRAM_ECC_CFG_DMWD_32 SDRAM_MCOPT1_DMWD_32
+#endif
+
+extern void ecc_init(unsigned long * const start, unsigned long size);
+
+#endif /* _ECC_H_ */
diff --git a/cpu/ppc4xx/sdram.c b/cpu/ppc4xx/sdram.c
index 2724d91f0f1..c7771addaac 100644
--- a/cpu/ppc4xx/sdram.c
+++ b/cpu/ppc4xx/sdram.c
@@ -31,6 +31,7 @@
#include <ppc4xx.h>
#include <asm/processor.h>
#include "sdram.h"
+#include "ecc.h"
#ifdef CONFIG_SDRAM_BANK0
@@ -163,7 +164,7 @@ static ulong compute_rtr(ulong speed, ulong rows, ulong refresh)
/*
* Autodetect onboard SDRAM on 405 platforms
*/
-void sdram_init(void)
+long int initdram(int board_type)
{
ulong speed;
ulong sdtr1;
@@ -231,9 +232,15 @@ void sdram_init(void)
mtsdram(mem_mcopt1, 0);
}
#endif
- return;
+
+ /*
+ * OK, size detected -> all done
+ */
+ return mb0cf[i].size;
}
}
+
+ return 0;
}
#else /* CONFIG_440 */
@@ -332,49 +339,6 @@ static void sdram_tr1_set(int ram_address, int* tr1_value)
*tr1_value = (first_good + last_bad) / 2;
}
-#ifdef CONFIG_SDRAM_ECC
-static void ecc_init(ulong start, ulong size)
-{
- ulong current_addr; /* current byte address */
- ulong end_addr; /* end of memory region */
- ulong addr_inc; /* address skip between writes */
- ulong cfg0_reg; /* for restoring ECC state */
-
- /*
- * TODO: Enable dcache before running this test (speedup)
- */
-
- mfsdram(mem_cfg0, cfg0_reg);
- mtsdram(mem_cfg0, (cfg0_reg & ~SDRAM_CFG0_MEMCHK) | SDRAM_CFG0_MEMCHK_GEN);
-
- /*
- * look at geometry of SDRAM (data width) to determine whether we
- * can skip words when writing
- */
- if ((cfg0_reg & SDRAM_CFG0_DRAMWDTH) == SDRAM_CFG0_DRAMWDTH_32)
- addr_inc = 4;
- else
- addr_inc = 8;
-
- current_addr = start;
- end_addr = start + size;
-
- while (current_addr < end_addr) {
- *((ulong *)current_addr) = 0x00000000;
- current_addr += addr_inc;
- }
-
- /*
- * TODO: Flush dcache and disable it again
- */
-
- /*
- * Enable ecc checking and parity errors
- */
- mtsdram(mem_cfg0, (cfg0_reg & ~SDRAM_CFG0_MEMCHK) | SDRAM_CFG0_MEMCHK_CHK);
-}
-#endif
-
/*
* Autodetect onboard DDR SDRAM on 440 platforms
*
diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S
index 0008170128a..426bf3c6f9a 100644
--- a/cpu/ppc4xx/start.S
+++ b/cpu/ppc4xx/start.S
@@ -3,6 +3,8 @@
* Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
* Copyright (C) 2000,2001,2002 Wolfgang Denk <wd@denx.de>
* Copyright (C) 2007 Stefan Roese <sr@denx.de>, DENX Software Engineering
+ * Copyright (c) 2008 Nuovation System Designs, LLC
+ * Grant Erickson <gerickson@nuovations.com>
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -79,34 +81,100 @@
# if (CFG_INIT_DCACHE_CS == 0)
# define PBxAP pb0ap
# define PBxCR pb0cr
+# if (defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
+# define PBxAP_VAL CFG_EBC_PB0AP
+# define PBxCR_VAL CFG_EBC_PB0CR
+# endif
# endif
# if (CFG_INIT_DCACHE_CS == 1)
# define PBxAP pb1ap
# define PBxCR pb1cr
+# if (defined(CFG_EBC_PB1AP) && defined(CFG_EBC_PB1CR))
+# define PBxAP_VAL CFG_EBC_PB1AP
+# define PBxCR_VAL CFG_EBC_PB1CR
+# endif
# endif
# if (CFG_INIT_DCACHE_CS == 2)
# define PBxAP pb2ap
# define PBxCR pb2cr
+# if (defined(CFG_EBC_PB2AP) && defined(CFG_EBC_PB2CR))
+# define PBxAP_VAL CFG_EBC_PB2AP
+# define PBxCR_VAL CFG_EBC_PB2CR
+# endif
# endif
# if (CFG_INIT_DCACHE_CS == 3)
# define PBxAP pb3ap
# define PBxCR pb3cr
+# if (defined(CFG_EBC_PB3AP) && defined(CFG_EBC_PB3CR))
+# define PBxAP_VAL CFG_EBC_PB3AP
+# define PBxCR_VAL CFG_EBC_PB3CR
+# endif
# endif
# if (CFG_INIT_DCACHE_CS == 4)
# define PBxAP pb4ap
# define PBxCR pb4cr
+# if (defined(CFG_EBC_PB4AP) && defined(CFG_EBC_PB4CR))
+# define PBxAP_VAL CFG_EBC_PB4AP
+# define PBxCR_VAL CFG_EBC_PB4CR
+# endif
# endif
# if (CFG_INIT_DCACHE_CS == 5)
# define PBxAP pb5ap
# define PBxCR pb5cr
+# if (defined(CFG_EBC_PB5AP) && defined(CFG_EBC_PB5CR))
+# define PBxAP_VAL CFG_EBC_PB5AP
+# define PBxCR_VAL CFG_EBC_PB5CR
+# endif
# endif
# if (CFG_INIT_DCACHE_CS == 6)
# define PBxAP pb6ap
# define PBxCR pb6cr
+# if (defined(CFG_EBC_PB6AP) && defined(CFG_EBC_PB6CR))
+# define PBxAP_VAL CFG_EBC_PB6AP
+# define PBxCR_VAL CFG_EBC_PB6CR
+# endif
# endif
# if (CFG_INIT_DCACHE_CS == 7)
# define PBxAP pb7ap
# define PBxCR pb7cr
+# if (defined(CFG_EBC_PB7AP) && defined(CFG_EBC_PB7CR))
+# define PBxAP_VAL CFG_EBC_PB7AP
+# define PBxCR_VAL CFG_EBC_PB7CR
+# endif
+# endif
+# ifndef PBxAP_VAL
+# define PBxAP_VAL 0
+# endif
+# ifndef PBxCR_VAL
+# define PBxCR_VAL 0
+# endif
+/*
+ * Memory Bank x (nothingness) initialization CFG_INIT_RAM_ADDR + 64 MiB
+ * used as temporary stack pointer for the primordial stack
+ */
+# ifndef CFG_INIT_DCACHE_PBxAR
+# define CFG_INIT_DCACHE_PBxAR (EBC_BXAP_BME_DISABLED | \
+ EBC_BXAP_TWT_ENCODE(7) | \
+ EBC_BXAP_BCE_DISABLE | \
+ EBC_BXAP_BCT_2TRANS | \
+ EBC_BXAP_CSN_ENCODE(0) | \
+ EBC_BXAP_OEN_ENCODE(0) | \
+ EBC_BXAP_WBN_ENCODE(0) | \
+ EBC_BXAP_WBF_ENCODE(0) | \
+ EBC_BXAP_TH_ENCODE(2) | \
+ EBC_BXAP_RE_DISABLED | \
+ EBC_BXAP_SOR_NONDELAYED | \
+ EBC_BXAP_BEM_WRITEONLY | \
+ EBC_BXAP_PEN_DISABLED)
+# endif /* CFG_INIT_DCACHE_PBxAR */
+# ifndef CFG_INIT_DCACHE_PBxCR
+# define CFG_INIT_DCACHE_PBxCR (EBC_BXCR_BAS_ENCODE(CFG_INIT_RAM_ADDR) | \
+ EBC_BXCR_BS_64MB | \
+ EBC_BXCR_BU_RW | \
+ EBC_BXCR_BW_16BIT)
+# endif /* CFG_INIT_DCACHE_PBxCR */
+# ifndef CFG_INIT_RAM_PATTERN
+# define CFG_INIT_RAM_PATTERN 0xDEADDEAD
# endif
#endif /* CFG_INIT_DCACHE_CS */
@@ -114,6 +182,27 @@
#error Only 4k of init-ram is supported - please adjust CFG_INIT_RAM_END!
#endif
+/*
+ * Unless otherwise overriden, enable two 128MB cachable instruction regions
+ * at CFG_SDRAM_BASE and another 128MB cacheable instruction region covering
+ * NOR flash at CFG_FLASH_BASE. Disable all cacheable data regions.
+ */
+#if !defined(CFG_FLASH_BASE)
+/* If not already defined, set it to the "last" 128MByte region */
+# define CFG_FLASH_BASE 0xf8000000
+#endif
+#if !defined(CFG_ICACHE_SACR_VALUE)
+# define CFG_ICACHE_SACR_VALUE \
+ (PPC_128MB_SACR_VALUE(CFG_SDRAM_BASE + ( 0 << 20)) | \
+ PPC_128MB_SACR_VALUE(CFG_SDRAM_BASE + (128 << 20)) | \
+ PPC_128MB_SACR_VALUE(CFG_FLASH_BASE))
+#endif /* !defined(CFG_ICACHE_SACR_VALUE) */
+
+#if !defined(CFG_DCACHE_SACR_VALUE)
+# define CFG_DCACHE_SACR_VALUE \
+ (0x00000000)
+#endif /* !defined(CFG_DCACHE_SACR_VALUE) */
+
#define function_prolog(func_name) .text; \
.align 2; \
.globl func_name; \
@@ -128,7 +217,6 @@
.extern ext_bus_cntlr_init
- .extern sdram_init
#ifdef CONFIG_NAND_U_BOOT
.extern reconfig_tlb0
#endif
@@ -401,97 +489,6 @@ rsttlb: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/
/* Continue from 'normal' start */
/*----------------------------------------------------------------*/
2:
-
-#if defined(CONFIG_NAND_SPL)
-#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
- defined(CONFIG_460EX) || defined(CONFIG_460GT)
- /*
- * Enable internal SRAM (only on 440EPx/GRx, 440EP/GR have no OCM)
- */
- lis r2,0x7fff
- ori r2,r2,0xffff
- mfdcr r1,isram0_dpc
- and r1,r1,r2 /* Disable parity check */
- mtdcr isram0_dpc,r1
- mfdcr r1,isram0_pmeg
- and r1,r1,r2 /* Disable pwr mgmt */
- mtdcr isram0_pmeg,r1
-#if defined(CONFIG_460EX) || defined(CONFIG_460GT)
- lis r1,0x4000 /* BAS = 8000_0000 */
- ori r1,r1,0x4580 /* 16k */
- mtdcr isram0_sb0cr,r1
-#endif
-#endif
-#if defined(CONFIG_440EP)
- /*
- * On 440EP with no internal SRAM, we setup SDRAM very early
- * and copy the NAND_SPL to SDRAM and jump to it
- */
- /* Clear Dcache to use as RAM */
- addis r3,r0,CFG_INIT_RAM_ADDR@h
- ori r3,r3,CFG_INIT_RAM_ADDR@l
- addis r4,r0,CFG_INIT_RAM_END@h
- ori r4,r4,CFG_INIT_RAM_END@l
- rlwinm. r5,r4,0,27,31
- rlwinm r5,r4,27,5,31
- beq ..d_ran3
- addi r5,r5,0x0001
-..d_ran3:
- mtctr r5
-..d_ag3:
- dcbz r0,r3
- addi r3,r3,32
- bdnz ..d_ag3
- /*----------------------------------------------------------------*/
- /* Setup the stack in internal SRAM */
- /*----------------------------------------------------------------*/
- lis r1,CFG_INIT_RAM_ADDR@h
- ori r1,r1,CFG_INIT_SP_OFFSET@l
- li r0,0
- stwu r0,-4(r1)
- stwu r0,-4(r1) /* Terminate call chain */
-
- stwu r1,-8(r1) /* Save back chain and move SP */
- lis r0,RESET_VECTOR@h /* Address of reset vector */
- ori r0,r0, RESET_VECTOR@l
- stwu r1,-8(r1) /* Save back chain and move SP */
- stw r0,+12(r1) /* Save return addr (underflow vect) */
- sync
- bl early_sdram_init
- sync
-#endif /* CONFIG_440EP */
-
- /*
- * Copy SPL from cache into internal SRAM
- */
- li r4,(CFG_NAND_BOOT_SPL_SIZE >> 2) - 1
- mtctr r4
- lis r2,CFG_NAND_BOOT_SPL_SRC@h
- ori r2,r2,CFG_NAND_BOOT_SPL_SRC@l
- lis r3,CFG_NAND_BOOT_SPL_DST@h
- ori r3,r3,CFG_NAND_BOOT_SPL_DST@l
-spl_loop:
- lwzu r4,4(r2)
- stwu r4,4(r3)
- bdnz spl_loop
-
- /*
- * Jump to code in RAM
- */
- bl 00f
-00: mflr r10
- lis r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@h
- ori r3,r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@l
- sub r10,r10,r3
- addi r10,r10,28
- mtlr r10
- blr
-
-start_ram:
- sync
- isync
-#endif /* CONFIG_NAND_SPL */
-
bl 3f
b _start
@@ -746,7 +743,7 @@ _start:
stw r0,+12(r1) /* Save return addr (underflow vect) */
#ifdef CONFIG_NAND_SPL
- bl nand_boot /* will not return */
+ bl nand_boot_common /* will not return */
#else
GET_GOT
@@ -840,16 +837,16 @@ _start:
/* make sure above stores all comlete before going on */
sync
- /*----------------------------------------------------------------------- */
- /* Enable two 128MB cachable regions. */
- /*----------------------------------------------------------------------- */
- addis r1,r0,0xc000
- addi r1,r1,0x0001
- mticcr r1 /* instruction cache */
+ /* Set-up icache cacheability. */
+ lis r1, CFG_ICACHE_SACR_VALUE@h
+ ori r1, r1, CFG_ICACHE_SACR_VALUE@l
+ mticcr r1
+ isync
- addis r1,r0,0x0000
- addi r1,r1,0x0000
- mtdccr r1 /* data cache */
+ /* Set-up dcache cacheability. */
+ lis r1, CFG_DCACHE_SACR_VALUE@h
+ ori r1, r1, CFG_DCACHE_SACR_VALUE@l
+ mtdccr r1
addis r1,r0,CFG_INIT_RAM_ADDR@h
ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack to SDRAM */
@@ -892,39 +889,33 @@ _start:
/* dbsr is cleared by setting bits to 1) */
mtdbsr r4 /* clear/reset the dbsr */
- /*----------------------------------------------------------------------- */
- /* Invalidate I and D caches. Enable I cache for defined memory regions */
- /* to speed things up. Leave the D cache disabled for now. It will be */
- /* enabled/left disabled later based on user selected menu options. */
- /* Be aware that the I cache may be disabled later based on the menu */
- /* options as well. See miscLib/main.c. */
- /*----------------------------------------------------------------------- */
+ /* Invalidate the i- and d-caches. */
bl invalidate_icache
bl invalidate_dcache
- /*----------------------------------------------------------------------- */
- /* Enable two 128MB cachable regions. */
- /*----------------------------------------------------------------------- */
- lis r4,0xc000
- ori r4,r4,0x0001
- mticcr r4 /* instruction cache */
+ /* Set-up icache cacheability. */
+ lis r4, CFG_ICACHE_SACR_VALUE@h
+ ori r4, r4, CFG_ICACHE_SACR_VALUE@l
+ mticcr r4
isync
- lis r4,0x0000
- ori r4,r4,0x0000
- mtdccr r4 /* data cache */
+ /* Set-up dcache cacheability. */
+ lis r4, CFG_DCACHE_SACR_VALUE@h
+ ori r4, r4, CFG_DCACHE_SACR_VALUE@l
+ mtdccr r4
-#if !(defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR)) || defined(CONFIG_405EX)
+#if !(defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
/*----------------------------------------------------------------------- */
/* Tune the speed and size for flash CS0 */
/*----------------------------------------------------------------------- */
bl ext_bus_cntlr_init
#endif
+
#if !(defined(CFG_INIT_DCACHE_CS) || defined(CFG_TEMP_STACK_OCM))
/*
- * Boards like the Kilauea (405EX) don't have OCM and can't use
- * DCache for init-ram. So setup stack here directly after the
- * SDRAM is initialized.
+ * For boards that don't have OCM and can't use the data cache
+ * for their primordial stack, setup stack here directly after the
+ * SDRAM is initialized in ext_bus_cntlr_init.
*/
lis r1, CFG_INIT_RAM_ADDR@h
ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack in SDRAM */
@@ -1007,83 +998,90 @@ _start:
#endif /* CONFIG_405EZ */
#endif
-#ifdef CONFIG_NAND_SPL
+ /*----------------------------------------------------------------------- */
+ /* Setup temporary stack in DCACHE or OCM if needed for SDRAM SPD. */
+ /*----------------------------------------------------------------------- */
+#ifdef CFG_INIT_DCACHE_CS
+ li r4, PBxAP
+ mtdcr ebccfga, r4
+ lis r4, CFG_INIT_DCACHE_PBxAR@h
+ ori r4, r4, CFG_INIT_DCACHE_PBxAR@l
+ mtdcr ebccfgd, r4
+
+ addi r4, 0, PBxCR
+ mtdcr ebccfga, r4
+ lis r4, CFG_INIT_DCACHE_PBxCR@h
+ ori r4, r4, CFG_INIT_DCACHE_PBxCR@l
+ mtdcr ebccfgd, r4
+
/*
- * Copy SPL from cache into internal SRAM
+ * Enable the data cache for the 128MB storage access control region
+ * at CFG_INIT_RAM_ADDR.
*/
- li r4,(CFG_NAND_BOOT_SPL_SIZE >> 2) - 1
- mtctr r4
- lis r2,CFG_NAND_BOOT_SPL_SRC@h
- ori r2,r2,CFG_NAND_BOOT_SPL_SRC@l
- lis r3,CFG_NAND_BOOT_SPL_DST@h
- ori r3,r3,CFG_NAND_BOOT_SPL_DST@l
-spl_loop:
- lwzu r4,4(r2)
- stwu r4,4(r3)
- bdnz spl_loop
+ mfdccr r4
+ oris r4, r4, PPC_128MB_SACR_VALUE(CFG_INIT_RAM_ADDR)@h
+ ori r4, r4, PPC_128MB_SACR_VALUE(CFG_INIT_RAM_ADDR)@l
+ mtdccr r4
/*
- * Jump to code in RAM
+ * Preallocate data cache lines to be used to avoid a subsequent
+ * cache miss and an ensuing machine check exception when exceptions
+ * are enabled.
*/
- bl 00f
-00: mflr r10
- lis r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@h
- ori r3,r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@l
- sub r10,r10,r3
- addi r10,r10,28
- mtlr r10
- blr
+ li r0, 0
-start_ram:
- sync
- isync
-#endif /* CONFIG_NAND_SPL */
+ lis r3, CFG_INIT_RAM_ADDR@h
+ ori r3, r3, CFG_INIT_RAM_ADDR@l
- /*----------------------------------------------------------------------- */
- /* Setup temporary stack in DCACHE or OCM if needed for SDRAM SPD. */
- /*----------------------------------------------------------------------- */
-#ifdef CFG_INIT_DCACHE_CS
- /*----------------------------------------------------------------------- */
- /* Memory Bank x (nothingness) initialization 1GB+64MEG */
- /* used as temporary stack pointer for stage0 */
- /*----------------------------------------------------------------------- */
- li r4,PBxAP
- mtdcr ebccfga,r4
- lis r4,0x0380
- ori r4,r4,0x0480
- mtdcr ebccfgd,r4
-
- addi r4,0,PBxCR
- mtdcr ebccfga,r4
- lis r4,0x400D
- ori r4,r4,0xa000
- mtdcr ebccfgd,r4
-
- /* turn on data cache for this region */
- lis r4,0x0080
- mtdccr r4
+ lis r4, CFG_INIT_RAM_END@h
+ ori r4, r4, CFG_INIT_RAM_END@l
+
+ /*
+ * Convert the size, in bytes, to the number of cache lines/blocks
+ * to preallocate.
+ */
+ clrlwi. r5, r4, (32 - L1_CACHE_SHIFT)
+ srwi r5, r4, L1_CACHE_SHIFT
+ beq ..load_counter
+ addi r5, r5, 0x0001
+..load_counter:
+ mtctr r5
- /* set stack pointer and clear stack to known value */
+ /* Preallocate the computed number of cache blocks. */
+..alloc_dcache_block:
+ dcba r0, r3
+ addi r3, r3, L1_CACHE_BYTES
+ bdnz ..alloc_dcache_block
+ sync
- lis r1,CFG_INIT_RAM_ADDR@h
- ori r1,r1,CFG_INIT_SP_OFFSET@l
+ /*
+ * Load the initial stack pointer and data area and convert the size,
+ * in bytes, to the number of words to initialize to a known value.
+ */
+ lis r1, CFG_INIT_RAM_ADDR@h
+ ori r1, r1, CFG_INIT_SP_OFFSET@l
- li r4,2048 /* we store 2048 words to stack */
+ lis r4, (CFG_INIT_RAM_END >> 2)@h
+ ori r4, r4, (CFG_INIT_RAM_END >> 2)@l
mtctr r4
- lis r2,CFG_INIT_RAM_ADDR@h /* we also clear data area */
- ori r2,r2,CFG_INIT_RAM_END@l /* so cant copy value from r1 */
+ lis r2, CFG_INIT_RAM_ADDR@h
+ ori r2, r2, CFG_INIT_RAM_END@l
- lis r4,0xdead /* we store 0xdeaddead in the stack */
- ori r4,r4,0xdead
+ lis r4, CFG_INIT_RAM_PATTERN@h
+ ori r4, r4, CFG_INIT_RAM_PATTERN@l
..stackloop:
- stwu r4,-4(r2)
+ stwu r4, -4(r2)
bdnz ..stackloop
- li r0, 0 /* Make room for stack frame header and */
- stwu r0, -4(r1) /* clear final stack frame so that */
- stwu r0, -4(r1) /* stack backtraces terminate cleanly */
+ /*
+ * Make room for stack frame header and clear final stack frame so
+ * that stack backtraces terminate cleanly.
+ */
+ stwu r0, -4(r1)
+ stwu r0, -4(r1)
+
/*
* Set up a dummy frame to store reset vector as return address.
* this causes stack underflow to reset board.
@@ -1120,13 +1118,8 @@ start_ram:
stw r0, +12(r1) /* Save return addr (underflow vect) */
#endif /* CFG_INIT_DCACHE_CS */
- /*----------------------------------------------------------------------- */
- /* Initialize SDRAM Controller */
- /*----------------------------------------------------------------------- */
- bl sdram_init
-
#ifdef CONFIG_NAND_SPL
- bl nand_boot /* will not return */
+ bl nand_boot_common /* will not return */
#else
GET_GOT /* initialize GOT access */
@@ -1328,33 +1321,72 @@ in32r:
* This "function" does not return, instead it continues in RAM
* after relocating the monitor code.
*
- * r3 = dest
- * r4 = src
- * r5 = length in bytes
- * r6 = cachelinesize
+ * r3 = Relocated stack pointer
+ * r4 = Relocated global data pointer
+ * r5 = Relocated text pointer
*/
.globl relocate_code
relocate_code:
-#ifdef CONFIG_4xx_DCACHE
+#if defined(CONFIG_4xx_DCACHE) || defined(CFG_INIT_DCACHE_CS)
/*
- * We need to flush the Init Data before the dcache will be
- * invalidated
+ * We need to flush the initial global data (gd_t) before the dcache
+ * will be invalidated.
*/
- /* save regs */
- mr r9,r3
- mr r10,r4
- mr r11,r5
+ /* Save registers */
+ mr r9, r3
+ mr r10, r4
+ mr r11, r5
- mr r3,r4
- addi r4,r4,0x200 /* should be enough for init data */
+ /* Flush initial global data range */
+ mr r3, r4
+ addi r4, r4, CFG_GBL_DATA_SIZE@l
bl flush_dcache_range
- /* restore regs */
- mr r3,r9
- mr r4,r10
- mr r5,r11
-#endif
+#if defined(CFG_INIT_DCACHE_CS)
+ /*
+ * Undo the earlier data cache set-up for the primordial stack and
+ * data area. First, invalidate the data cache and then disable data
+ * cacheability for that area. Finally, restore the EBC values, if
+ * any.
+ */
+
+ /* Invalidate the primordial stack and data area in cache */
+ lis r3, CFG_INIT_RAM_ADDR@h
+ ori r3, r3, CFG_INIT_RAM_ADDR@l
+
+ lis r4, CFG_INIT_RAM_END@h
+ ori r4, r4, CFG_INIT_RAM_END@l
+ add r4, r4, r3
+
+ bl invalidate_dcache_range
+
+ /* Disable cacheability for the region */
+ mfdccr r3
+ lis r4, ~PPC_128MB_SACR_VALUE(CFG_INIT_RAM_ADDR)@h
+ ori r4, r4, ~PPC_128MB_SACR_VALUE(CFG_INIT_RAM_ADDR)@l
+ and r3, r3, r4
+ mtdccr r3
+
+ /* Restore the EBC parameters */
+ li r3, PBxAP
+ mtdcr ebccfga, r3
+ lis r3, PBxAP_VAL@h
+ ori r3, r3, PBxAP_VAL@l
+ mtdcr ebccfgd, r3
+
+ li r3, PBxCR
+ mtdcr ebccfga, r3
+ lis r3, PBxCR_VAL@h
+ ori r3, r3, PBxCR_VAL@l
+ mtdcr ebccfgd, r3
+#endif /* defined(CFG_INIT_DCACHE_CS) */
+
+ /* Restore registers */
+ mr r3, r9
+ mr r4, r10
+ mr r5, r11
+#endif /* defined(CONFIG_4xx_DCACHE) || defined(CFG_INIT_DCACHE_CS) */
#ifdef CFG_INIT_RAM_DCACHE
/*
@@ -1396,13 +1428,13 @@ relocate_code:
addi r1,r0,CFG_TLB_FOR_BOOT_FLASH /* Use defined TLB */
#else
addi r1,r0,0x0000 /* Default TLB entry is #0 */
-#endif
+#endif /* CFG_TLB_FOR_BOOT_FLASH */
tlbre r0,r1,0x0002 /* Read contents */
ori r0,r0,0x0c00 /* Or in the inhibit, write through bit */
tlbwe r0,r1,0x0002 /* Save it out */
sync
isync
-#endif
+#endif /* defined(CONFIG_440EP) || ... || defined(CONFIG_460GT) */
mr r1, r3 /* Set new stack pointer */
mr r9, r4 /* Save copy of Init Data pointer */
mr r10, r5 /* Save copy of Destination Address */
@@ -1425,7 +1457,7 @@ relocate_code:
/* First our own GOT */
add r14, r14, r15
- /* the the one used by the C code */
+ /* then the one used by the C code */
add r30, r30, r15
/*
@@ -2024,3 +2056,75 @@ pll_wait:
blr
function_epilog(mftlb1)
#endif /* CONFIG_440 */
+
+#if defined(CONFIG_NAND_SPL)
+/*
+ * void nand_boot_relocate(dst, src, bytes)
+ *
+ * r3 = Destination address to copy code to (in SDRAM)
+ * r4 = Source address to copy code from
+ * r5 = size to copy in bytes
+ */
+nand_boot_relocate:
+ mr r6,r3
+ mr r7,r4
+ mflr r8
+
+ /*
+ * Copy SPL from icache into SDRAM
+ */
+ subi r3,r3,4
+ subi r4,r4,4
+ srwi r5,r5,2
+ mtctr r5
+..spl_loop:
+ lwzu r0,4(r4)
+ stwu r0,4(r3)
+ bdnz ..spl_loop
+
+ /*
+ * Calculate "corrected" link register, so that we "continue"
+ * in execution in destination range
+ */
+ sub r3,r7,r6 /* r3 = src - dst */
+ sub r8,r8,r3 /* r8 = link-reg - (src - dst) */
+ mtlr r8
+ blr
+
+nand_boot_common:
+ /*
+ * First initialize SDRAM. It has to be available *before* calling
+ * nand_boot().
+ */
+ lis r3,CFG_SDRAM_BASE@h
+ ori r3,r3,CFG_SDRAM_BASE@l
+ bl initdram
+
+ /*
+ * Now copy the 4k SPL code into SDRAM and continue execution
+ * from there.
+ */
+ lis r3,CFG_NAND_BOOT_SPL_DST@h
+ ori r3,r3,CFG_NAND_BOOT_SPL_DST@l
+ lis r4,CFG_NAND_BOOT_SPL_SRC@h
+ ori r4,r4,CFG_NAND_BOOT_SPL_SRC@l
+ lis r5,CFG_NAND_BOOT_SPL_SIZE@h
+ ori r5,r5,CFG_NAND_BOOT_SPL_SIZE@l
+ bl nand_boot_relocate
+
+ /*
+ * We're running from SDRAM now!!!
+ *
+ * It is necessary for 4xx systems to relocate from running at
+ * the original location (0xfffffxxx) to somewhere else (SDRAM
+ * preferably). This is because CS0 needs to be reconfigured for
+ * NAND access. And we can't reconfigure this CS when currently
+ * "running" from it.
+ */
+
+ /*
+ * Finally call nand_boot() to load main NAND U-Boot image from
+ * NAND and jump to it.
+ */
+ bl nand_boot /* will not return */
+#endif /* CONFIG_NAND_SPL */
diff --git a/cpu/ppc4xx/traps.c b/cpu/ppc4xx/traps.c
index 38b6f895550..8b7e32a17bc 100644
--- a/cpu/ppc4xx/traps.c
+++ b/cpu/ppc4xx/traps.c
@@ -170,7 +170,7 @@ MachineCheckException(struct pt_regs *regs)
val = get_esr();
-#if !defined(CONFIG_440)
+#if !defined(CONFIG_440) && !defined(CONFIG_405EX)
if (val& ESR_IMCP) {
printf("Instruction");
mtspr(ESR, val & ~ESR_IMCP);
@@ -179,7 +179,7 @@ MachineCheckException(struct pt_regs *regs)
}
printf(" machine check.\n");
-#elif defined(CONFIG_440)
+#elif defined(CONFIG_440) || defined(CONFIG_405EX)
if (val& ESR_IMCP){
printf("Instruction Synchronous Machine Check exception\n");
mtspr(SPRN_ESR, val & ~ESR_IMCP);
@@ -187,10 +187,15 @@ MachineCheckException(struct pt_regs *regs)
val = mfspr(MCSR);
if (val & MCSR_IB)
printf("Instruction Read PLB Error\n");
+#if defined(CONFIG_440)
if (val & MCSR_DRB)
printf("Data Read PLB Error\n");
if (val & MCSR_DWB)
printf("Data Write PLB Error\n");
+#else
+ if (val & MCSR_DB)
+ printf("Data PLB Error\n");
+#endif
if (val & MCSR_TLBP)
printf("TLB Parity Error\n");
if (val & MCSR_ICP){