From d2d432760d2199d0e8558fdd9d1789b8131abcf7 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 1 Jun 2007 15:09:50 +0200 Subject: ppc4xx: 44x DDR driver code cleanup and small fix for Bamboo Signed-off-by: Stefan Roese --- cpu/ppc4xx/44x_spd_ddr.c | 341 +++++++++++++++++++++++------------------------ 1 file changed, 166 insertions(+), 175 deletions(-) (limited to 'cpu') diff --git a/cpu/ppc4xx/44x_spd_ddr.c b/cpu/ppc4xx/44x_spd_ddr.c index 10b4c189789..c500d3f2421 100644 --- a/cpu/ppc4xx/44x_spd_ddr.c +++ b/cpu/ppc4xx/44x_spd_ddr.c @@ -20,7 +20,7 @@ * Jun Gu, Artesyn Technology, jung@artesyncp.com * Support for AMCC 440 based on OpenBIOS draminit.c from IBM. * - * (C) Copyright 2005 + * (C) Copyright 2005-2007 * Stefan Roese, DENX Software Engineering, sr@denx.de. * * See file CREDITS for list of people who contributed to this @@ -42,6 +42,11 @@ * MA 02111-1307 USA */ +/* define DEBUG for debugging output (obviously ;-)) */ +#if 0 +#define DEBUG +#endif + #include #include #include @@ -246,25 +251,6 @@ #define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE /* disable caching on SDRAM */ #endif -const unsigned long test[NUMMEMTESTS][NUMMEMWORDS] = { - {0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, - 0xFFFFFFFF, 0xFFFFFFFF}, - {0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, - 0x00000000, 0x00000000}, - {0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, - 0x55555555, 0x55555555}, - {0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, - 0xAAAAAAAA, 0xAAAAAAAA}, - {0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5, - 0x5A5A5A5A, 0x5A5A5A5A}, - {0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A, - 0xA5A5A5A5, 0xA5A5A5A5}, - {0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55, - 0x55AA55AA, 0x55AA55AA}, - {0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, - 0xAA55AA55, 0xAA55AA55} -}; - /* bank_parms is used to sort the bank sizes by descending order */ struct bank_param { unsigned long cr; @@ -278,46 +264,37 @@ extern unsigned char cfg_simulate_spd_eeprom[128]; #endif void program_tlb(u32 start, u32 size, u32 tlb_word2_i_value); -unsigned char spd_read(uchar chip, uint addr); - -void get_spd_info(unsigned long* dimm_populated, - unsigned char* iic0_dimm_addr, - unsigned long num_dimm_banks); - -void check_mem_type -(unsigned long* dimm_populated, - unsigned char* iic0_dimm_addr, - unsigned long num_dimm_banks); - -void check_volt_type -(unsigned long* dimm_populated, - unsigned char* iic0_dimm_addr, - unsigned long num_dimm_banks); - -void program_cfg0(unsigned long* dimm_populated, - unsigned char* iic0_dimm_addr, - unsigned long num_dimm_banks); - -void program_cfg1(unsigned long* dimm_populated, - unsigned char* iic0_dimm_addr, - unsigned long num_dimm_banks); - -void program_rtr (unsigned long* dimm_populated, - unsigned char* iic0_dimm_addr, - unsigned long num_dimm_banks); - -void program_tr0 (unsigned long* dimm_populated, - unsigned char* iic0_dimm_addr, - unsigned long num_dimm_banks); - -void program_tr1 (void); - -void program_ecc (unsigned long num_bytes); +static unsigned char spd_read(uchar chip, uint addr); +static void get_spd_info(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); +static void check_mem_type(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); +static void check_volt_type(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); +static void program_cfg0(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); +static void program_cfg1(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); +static void program_rtr(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); +static void program_tr0(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); +static void program_tr1(void); + +#ifdef CONFIG_DDR_ECC +static void program_ecc(unsigned long num_bytes); +#endif -unsigned -long program_bxcr(unsigned long* dimm_populated, - unsigned char* iic0_dimm_addr, - unsigned long num_dimm_banks); +static unsigned long program_bxcr(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); /* * This function is reading data from the DIMM module EEPROM over the SPD bus @@ -328,7 +305,6 @@ long program_bxcr(unsigned long* dimm_populated, * BUG: Don't handle ECC memory * BUG: A few values in the TR register is currently hardcoded */ - long int spd_sdram(void) { unsigned char iic0_dimm_addr[] = SPD_EEPROM_ADDRESS; unsigned long dimm_populated[sizeof(iic0_dimm_addr)]; @@ -421,9 +397,8 @@ long int spd_sdram(void) { */ while (1) { mfsdram(mem_mcsts, mcsts); - if ((mcsts & SDRAM_MCSTS_MRSC) != 0) { + if ((mcsts & SDRAM_MCSTS_MRSC) != 0) break; - } } /* @@ -431,14 +406,17 @@ long int spd_sdram(void) { */ program_tr1(); +#ifdef CONFIG_DDR_ECC /* - * if ECC is enabled, initialize parity bits + * If ecc is enabled, initialize the parity bits. */ + program_ecc(total_size); +#endif return total_size; } -unsigned char spd_read(uchar chip, uint addr) +static unsigned char spd_read(uchar chip, uint addr) { unsigned char data[2]; @@ -460,9 +438,9 @@ unsigned char spd_read(uchar chip, uint addr) return 0; } -void get_spd_info(unsigned long* dimm_populated, - unsigned char* iic0_dimm_addr, - unsigned long num_dimm_banks) +static void get_spd_info(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks) { unsigned long dimm_num; unsigned long dimm_found; @@ -480,14 +458,10 @@ void get_spd_info(unsigned long* dimm_populated, if ((num_of_bytes != 0) && (total_size != 0)) { dimm_populated[dimm_num] = TRUE; dimm_found = TRUE; -#if 0 - printf("DIMM slot %lu: populated\n", dimm_num); -#endif + debug("DIMM slot %lu: populated\n", dimm_num); } else { dimm_populated[dimm_num] = FALSE; -#if 0 - printf("DIMM slot %lu: Not populated\n", dimm_num); -#endif + debug("DIMM slot %lu: Not populated\n", dimm_num); } } @@ -497,9 +471,9 @@ void get_spd_info(unsigned long* dimm_populated, } } -void check_mem_type(unsigned long* dimm_populated, - unsigned char* iic0_dimm_addr, - unsigned long num_dimm_banks) +static void check_mem_type(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks) { unsigned long dimm_num; unsigned char dimm_type; @@ -509,9 +483,7 @@ void check_mem_type(unsigned long* dimm_populated, dimm_type = spd_read(iic0_dimm_addr[dimm_num], 2); switch (dimm_type) { case 7: -#if 0 - printf("DIMM slot %lu: DDR SDRAM detected\n", dimm_num); -#endif + debug("DIMM slot %lu: DDR SDRAM detected\n", dimm_num); break; default: printf("ERROR: Unsupported DIMM detected in slot %lu.\n", @@ -525,10 +497,9 @@ void check_mem_type(unsigned long* dimm_populated, } } - -void check_volt_type(unsigned long* dimm_populated, - unsigned char* iic0_dimm_addr, - unsigned long num_dimm_banks) +static void check_volt_type(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks) { unsigned long dimm_num; unsigned long voltage_type; @@ -541,18 +512,16 @@ void check_volt_type(unsigned long* dimm_populated, dimm_num); hang(); } else { -#if 0 - printf("DIMM %lu voltage level supported.\n", dimm_num); -#endif + debug("DIMM %lu voltage level supported.\n", dimm_num); } break; } } } -void program_cfg0(unsigned long* dimm_populated, - unsigned char* iic0_dimm_addr, - unsigned long num_dimm_banks) +static void program_cfg0(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks) { unsigned long dimm_num; unsigned long cfg0; @@ -640,9 +609,9 @@ void program_cfg0(unsigned long* dimm_populated, mtsdram(mem_cfg0, cfg0); } -void program_cfg1(unsigned long* dimm_populated, - unsigned char* iic0_dimm_addr, - unsigned long num_dimm_banks) +static void program_cfg1(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks) { unsigned long cfg1; mfsdram(mem_cfg1, cfg1); @@ -658,9 +627,9 @@ void program_cfg1(unsigned long* dimm_populated, mtsdram(mem_cfg1, cfg1); } -void program_rtr (unsigned long* dimm_populated, - unsigned char* iic0_dimm_addr, - unsigned long num_dimm_banks) +static void program_rtr(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks) { unsigned long dimm_num; unsigned long bus_period_x_10; @@ -676,7 +645,6 @@ void program_rtr (unsigned long* dimm_populated, get_sys_info(&sys_info); bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10); - for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { if (dimm_populated[dimm_num] == TRUE) { refresh_rate_type = 0x7F & spd_read(iic0_dimm_addr[dimm_num], 12); @@ -719,9 +687,9 @@ void program_rtr (unsigned long* dimm_populated, mtsdram(mem_rtr, sdram_rtr); } -void program_tr0 (unsigned long* dimm_populated, - unsigned char* iic0_dimm_addr, - unsigned long num_dimm_banks) +static void program_tr0(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks) { unsigned long dimm_num; unsigned long tr0; @@ -1001,13 +969,73 @@ void program_tr0 (unsigned long* dimm_populated, break; } -#if 0 - printf("tr0: %x\n", tr0); -#endif + debug("tr0: %x\n", tr0); mtsdram(mem_tr0, tr0); } -void program_tr1 (void) +static int short_mem_test(void) +{ + unsigned long i, j; + unsigned long bxcr_num; + unsigned long *membase; + const unsigned long test[NUMMEMTESTS][NUMMEMWORDS] = { + {0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000}, + {0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, + 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555}, + {0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, + 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA}, + {0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A, + 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A}, + {0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5, + 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5}, + {0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, + 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA}, + {0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55, + 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55}}; + + for (bxcr_num = 0; bxcr_num < MAXBXCR; bxcr_num++) { + mtdcr(memcfga, mem_b0cr + (bxcr_num << 2)); + if ((mfdcr(memcfgd) & SDRAM_BXCR_SDBE) == SDRAM_BXCR_SDBE) { + /* Bank is enabled */ + membase = (unsigned long*) + (mfdcr(memcfgd) & SDRAM_BXCR_SDBA_MASK); + + /* + * Run the short memory test + */ + for (i = 0; i < NUMMEMTESTS; i++) { + for (j = 0; j < NUMMEMWORDS; j++) { + membase[j] = test[i][j]; + ppcDcbf((unsigned long)&(membase[j])); + } + + for (j = 0; j < NUMMEMWORDS; j++) { + if (membase[j] != test[i][j]) { + ppcDcbf((unsigned long)&(membase[j])); + return 0; + } + ppcDcbf((unsigned long)&(membase[j])); + } + + if (j < NUMMEMWORDS) + return 0; + } + + /* + * see if the rdclt value passed + */ + if (i < NUMMEMTESTS) + return 0; + } + } + + return 1; +} + +static void program_tr1(void) { unsigned long tr0; unsigned long tr1; @@ -1015,8 +1043,7 @@ void program_tr1 (void) unsigned long ecc_temp; unsigned long dlycal; unsigned long dly_val; - unsigned long i, j, k; - unsigned long bxcr_num; + unsigned long k; unsigned long max_pass_length; unsigned long current_pass_length; unsigned long current_fail_length; @@ -1029,7 +1056,6 @@ void program_tr1 (void) unsigned char window_found; unsigned char fail_found; unsigned char pass_found; - unsigned long * membase; PPC440_SYS_INFO sys_info; /* @@ -1079,55 +1105,16 @@ void program_tr1 (void) window_found = FALSE; fail_found = FALSE; pass_found = FALSE; -#ifdef DEBUG - printf("Starting memory test "); -#endif + debug("Starting memory test "); + for (k = 0; k < NUMHALFCYCLES; k++) { - for (rdclt = 0; rdclt < dly_val; rdclt++) { + for (rdclt = 0; rdclt < dly_val; rdclt++) { /* * Set the timing reg for the test. */ mtsdram(mem_tr1, (tr1 | SDRAM_TR1_RDCT_ENCODE(rdclt))); - for (bxcr_num = 0; bxcr_num < MAXBXCR; bxcr_num++) { - mtdcr(memcfga, mem_b0cr + (bxcr_num<<2)); - if ((mfdcr(memcfgd) & SDRAM_BXCR_SDBE) == SDRAM_BXCR_SDBE) { - /* Bank is enabled */ - membase = (unsigned long*) - (mfdcr(memcfgd) & SDRAM_BXCR_SDBA_MASK); - - /* - * Run the short memory test - */ - for (i = 0; i < NUMMEMTESTS; i++) { - for (j = 0; j < NUMMEMWORDS; j++) { - membase[j] = test[i][j]; - ppcDcbf((unsigned long)&(membase[j])); - } - - for (j = 0; j < NUMMEMWORDS; j++) { - if (membase[j] != test[i][j]) { - ppcDcbf((unsigned long)&(membase[j])); - break; - } - ppcDcbf((unsigned long)&(membase[j])); - } - - if (j < NUMMEMWORDS) { - break; - } - } - - /* - * see if the rdclt value passed - */ - if (i < NUMMEMTESTS) { - break; - } - } - } - - if (bxcr_num == MAXBXCR) { + if (short_mem_test()) { if (fail_found == TRUE) { pass_found = TRUE; if (current_pass_length == 0) { @@ -1157,9 +1144,8 @@ void program_tr1 (void) } } } -#ifdef DEBUG - printf("."); -#endif + debug("."); + if (window_found == TRUE) { break; } @@ -1167,9 +1153,7 @@ void program_tr1 (void) tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK; rdclt_offset += dly_val; } -#ifdef DEBUG - printf("\n"); -#endif + debug("\n"); /* * make sure we find the window @@ -1218,18 +1202,17 @@ void program_tr1 (void) } tr1 |= SDRAM_TR1_RDCT_ENCODE(rdclt_average); -#if 0 - printf("tr1: %x\n", tr1); -#endif + debug("tr1: %x\n", tr1); + /* * program SDRAM Timing Register 1 TR1 */ mtsdram(mem_tr1, tr1); } -unsigned long program_bxcr(unsigned long* dimm_populated, - unsigned char* iic0_dimm_addr, - unsigned long num_dimm_banks) +static unsigned long program_bxcr(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks) { unsigned long dimm_num; unsigned long bank_base_addr; @@ -1262,8 +1245,8 @@ unsigned long program_bxcr(unsigned long* dimm_populated, #ifdef CONFIG_BAMBOO /* * This next section is hardware dependent and must be programmed - * to match the hardware. For bammboo, the following holds... - * 1. SDRAM0_B0CR: Bank 0 of dimm 0 ctrl_bank_num : 0 + * to match the hardware. For bamboo, the following holds... + * 1. SDRAM0_B0CR: Bank 0 of dimm 0 ctrl_bank_num : 0 (soldered onboard) * 2. SDRAM0_B1CR: Bank 0 of dimm 1 ctrl_bank_num : 1 * 3. SDRAM0_B2CR: Bank 1 of dimm 1 ctrl_bank_num : 1 * 4. SDRAM0_B3CR: Bank 0 of dimm 2 ctrl_bank_num : 3 @@ -1273,10 +1256,12 @@ unsigned long program_bxcr(unsigned long* dimm_populated, ctrl_bank_num[1] = 1; ctrl_bank_num[2] = 3; #else + /* + * Ocotea, Ebony and the other IBM/AMCC eval boards have + * 2 DIMM slots with each max 2 banks + */ ctrl_bank_num[0] = 0; - ctrl_bank_num[1] = 1; - ctrl_bank_num[2] = 2; - ctrl_bank_num[3] = 3; + ctrl_bank_num[1] = 2; #endif /* @@ -1290,6 +1275,8 @@ unsigned long program_bxcr(unsigned long* dimm_populated, num_col_addr = spd_read(iic0_dimm_addr[dimm_num], 4); num_banks = spd_read(iic0_dimm_addr[dimm_num], 5); bank_size_id = spd_read(iic0_dimm_addr[dimm_num], 31); + debug("DIMM%d: row=%d col=%d banks=%d\n", dimm_num, + num_row_addr, num_col_addr, num_banks); /* * Set the SDRAM0_BxCR regs @@ -1354,9 +1341,12 @@ unsigned long program_bxcr(unsigned long* dimm_populated, cr |= SDRAM_BXCR_SDBE; for (i = 0; i < num_banks; i++) { - bank_parms[ctrl_bank_num[dimm_num]+i+dimm_num].bank_size_bytes = - (4 * 1024 * 1024) * bank_size_id; - bank_parms[ctrl_bank_num[dimm_num]+i+dimm_num].cr = cr; + bank_parms[ctrl_bank_num[dimm_num]+i].bank_size_bytes = + (4 << 20) * bank_size_id; + bank_parms[ctrl_bank_num[dimm_num]+i].cr = cr; + debug("DIMM%d-bank %d (SDRAM0_B%dCR): bank_size_bytes=%d\n", + dimm_num, i, ctrl_bank_num[dimm_num]+i, + bank_parms[ctrl_bank_num[dimm_num]+i].bank_size_bytes); } } } @@ -1400,13 +1390,15 @@ unsigned long program_bxcr(unsigned long* dimm_populated, bank_parms[sorted_bank_num[bx_cr_num]].cr; mtdcr(memcfgd, temp); bank_base_addr += bank_parms[sorted_bank_num[bx_cr_num]].bank_size_bytes; + debug("SDRAM0_B%dCR=0x%08lx\n", sorted_bank_num[bx_cr_num], temp); } } return(bank_base_addr); } -void program_ecc (unsigned long num_bytes) +#ifdef CONFIG_DDR_ECC +static void program_ecc(unsigned long num_bytes) { unsigned long bank_base_addr; unsigned long current_address; @@ -1425,14 +1417,12 @@ void program_ecc (unsigned long num_bytes) 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); + mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | SDRAM_CFG0_MCHK_GEN); - if ((cfg0 & SDRAM_CFG0_DMWD_MASK) == SDRAM_CFG0_DMWD_32) { + if ((cfg0 & SDRAM_CFG0_DMWD_MASK) == SDRAM_CFG0_DMWD_32) address_increment = 4; - } else { + else address_increment = 8; - } current_address = (unsigned long)(bank_base_addr); end_address = (unsigned long)(bank_base_addr) + num_bytes; @@ -1446,4 +1436,5 @@ void program_ecc (unsigned long num_bytes) SDRAM_CFG0_MCHK_CHK); } } +#endif /* CONFIG_DDR_ECC */ #endif /* CONFIG_SPD_EEPROM */ -- cgit v1.3.1 From 91da09cfbce0c1de05d6d84aa8363d666fa7ea3c Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 1 Jun 2007 15:15:12 +0200 Subject: NAND: Add hardware ECC support to the PPC4xx NAND driver ndfc.c This patch adds hardware ECC support to the NDFC driver. It also changes the register access from using the "simple" in32/out32 functions to the in_be32/out_be32 functions, which make sure that the access is correctly synced. This is the only recommended access to SoC registers in the current Linux kernel. Signed-off-by: Stefan Roese --- cpu/ppc4xx/ndfc.c | 74 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 20 deletions(-) (limited to 'cpu') diff --git a/cpu/ppc4xx/ndfc.c b/cpu/ppc4xx/ndfc.c index b198ff46ceb..09aac38f488 100644 --- a/cpu/ppc4xx/ndfc.c +++ b/cpu/ppc4xx/ndfc.c @@ -3,7 +3,7 @@ * Platform independend driver for NDFC (NanD Flash Controller) * integrated into EP440 cores * - * (C) Copyright 2006 + * (C) Copyright 2006-2007 * Stefan Roese, DENX Software Engineering, sr@denx.de. * * Based on original work by @@ -37,7 +37,9 @@ #include #include +#include #include +#include #include static u8 hwctl = 0; @@ -69,11 +71,11 @@ static void ndfc_write_byte(struct mtd_info *mtdinfo, u_char byte) ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc; if (hwctl & 0x1) - out8(base + NDFC_CMD, byte); + out_8((u8 *)(base + NDFC_CMD), byte); else if (hwctl & 0x2) - out8(base + NDFC_ALE, byte); + out_8((u8 *)(base + NDFC_ALE), byte); else - out8(base + NDFC_DATA, byte); + out_8((u8 *)(base + NDFC_DATA), byte); } static u_char ndfc_read_byte(struct mtd_info *mtdinfo) @@ -81,7 +83,7 @@ static u_char ndfc_read_byte(struct mtd_info *mtdinfo) struct nand_chip *this = mtdinfo->priv; ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc; - return (in8(base + NDFC_DATA)); + return (in_8((u8 *)(base + NDFC_DATA))); } static int ndfc_dev_ready(struct mtd_info *mtdinfo) @@ -89,17 +91,41 @@ static int ndfc_dev_ready(struct mtd_info *mtdinfo) struct nand_chip *this = mtdinfo->priv; ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc; - while (!(in32(base + NDFC_STAT) & NDFC_STAT_IS_READY)) + while (!(in_be32((u32 *)(base + NDFC_STAT)) & NDFC_STAT_IS_READY)) ; return 1; } -#ifndef CONFIG_NAND_SPL -/* - * Don't use these speedup functions in NAND boot image, since the image - * has to fit into 4kByte. - */ +static void ndfc_enable_hwecc(struct mtd_info *mtdinfo, int mode) +{ + struct nand_chip *this = mtdinfo->priv; + ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc; + u32 ccr; + + ccr = in_be32((u32 *)(base + NDFC_CCR)); + ccr |= NDFC_CCR_RESET_ECC; + out_be32((u32 *)(base + NDFC_CCR), ccr); +} + +static int ndfc_calculate_ecc(struct mtd_info *mtdinfo, + const u_char *dat, u_char *ecc_code) +{ + struct nand_chip *this = mtdinfo->priv; + ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc; + u32 ecc; + u8 *p = (u8 *)&ecc; + + ecc = in_be32((u32 *)(base + NDFC_ECC)); + + /* The NDFC uses Smart Media (SMC) bytes order + */ + ecc_code[0] = p[2]; + ecc_code[1] = p[1]; + ecc_code[2] = p[3]; + + return 0; +} /* * Speedups for buffer read/write/verify @@ -115,9 +141,14 @@ static void ndfc_read_buf(struct mtd_info *mtdinfo, uint8_t *buf, int len) uint32_t *p = (uint32_t *) buf; for (;len > 0; len -= 4) - *p++ = in32(base + NDFC_DATA); + *p++ = in_be32((u32 *)(base + NDFC_DATA)); } +#ifndef CONFIG_NAND_SPL +/* + * Don't use these speedup functions in NAND boot image, since the image + * has to fit into 4kByte. + */ static void ndfc_write_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len) { struct nand_chip *this = mtdinfo->priv; @@ -125,7 +156,7 @@ static void ndfc_write_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len uint32_t *p = (uint32_t *) buf; for (; len > 0; len -= 4) - out32(base + NDFC_DATA, *p++); + out_be32((u32 *)(base + NDFC_DATA), *p++); } static int ndfc_verify_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len) @@ -135,7 +166,7 @@ static int ndfc_verify_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len uint32_t *p = (uint32_t *) buf; for (; len > 0; len -= 4) - if (*p++ != in32(base + NDFC_DATA)) + if (*p++ != in_be32((u32 *)(base + NDFC_DATA))) return -1; return 0; @@ -152,8 +183,8 @@ void board_nand_select_device(struct nand_chip *nand, int chip) ulong base = (ulong)nand->IO_ADDR_W & 0xfffffffc; /* Set NandFlash Core Configuration Register */ - /* 1col x 2 rows */ - out32(base + NDFC_CCR, 0x00000000 | (cs << 24)); + /* 1 col x 2 rows */ + out_be32((u32 *)(base + NDFC_CCR), 0x00000000 | (cs << 24)); } int board_nand_init(struct nand_chip *nand) @@ -161,16 +192,19 @@ int board_nand_init(struct nand_chip *nand) int cs = (ulong)nand->IO_ADDR_W & 0x00000003; ulong base = (ulong)nand->IO_ADDR_W & 0xfffffffc; - nand->eccmode = NAND_ECC_SOFT; - nand->hwcontrol = ndfc_hwcontrol; nand->read_byte = ndfc_read_byte; + nand->read_buf = ndfc_read_buf; nand->write_byte = ndfc_write_byte; nand->dev_ready = ndfc_dev_ready; + nand->eccmode = NAND_ECC_HW3_256; + nand->enable_hwecc = ndfc_enable_hwecc; + nand->calculate_ecc = ndfc_calculate_ecc; + nand->correct_data = nand_correct_data; + #ifndef CONFIG_NAND_SPL nand->write_buf = ndfc_write_buf; - nand->read_buf = ndfc_read_buf; nand->verify_buf = ndfc_verify_buf; #else /* @@ -187,7 +221,7 @@ int board_nand_init(struct nand_chip *nand) * Select required NAND chip in NDFC */ board_nand_select_device(nand, cs); - out32(base + NDFC_BCFG0 + (cs << 2), 0x80002222); + out_be32((u32 *)(base + NDFC_BCFG0 + (cs << 2)), 0x80002222); return 0; } -- cgit v1.3.1 From cf959c7d6687567c308e366e9581e1a5aff5cc5b Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 1 Jun 2007 15:27:11 +0200 Subject: ppc4xx: Add NAND booting support for AMCC Bamboo (440EP) eval board This patch adds NAND booting support for the AMCC Bamboo eval board. Since the NAND-SPL boot image is limited to 4kbytes, this version only supports the onboard 64MBytes of DDR. The DIMM modules can't be supported, since the setup code for I2C DIMM autodetection and configuration is too big for this NAND bootloader. Signed-off-by: Stefan Roese --- MAKEALL | 30 ++--- Makefile | 10 ++ cpu/ppc4xx/start.S | 221 ++++++++++++++++++++-------------- include/configs/bamboo.h | 88 ++++++++++++-- nand_spl/board/amcc/bamboo/Makefile | 100 +++++++++++++++ nand_spl/board/amcc/bamboo/config.mk | 49 ++++++++ nand_spl/board/amcc/bamboo/sdram.c | 92 ++++++++++++++ nand_spl/board/amcc/bamboo/u-boot.lds | 65 ++++++++++ 8 files changed, 536 insertions(+), 119 deletions(-) create mode 100644 nand_spl/board/amcc/bamboo/Makefile create mode 100644 nand_spl/board/amcc/bamboo/config.mk create mode 100644 nand_spl/board/amcc/bamboo/sdram.c create mode 100644 nand_spl/board/amcc/bamboo/u-boot.lds (limited to 'cpu') diff --git a/MAKEALL b/MAKEALL index 47f20307064..23402a298de 100755 --- a/MAKEALL +++ b/MAKEALL @@ -76,21 +76,21 @@ LIST_8xx=" \ LIST_4xx=" \ acadia ADCIOP alpr AP1000 \ - AR405 ASH405 bamboo bubinga \ - CANBT CMS700 CPCI2DP CPCI405 \ - CPCI4052 CPCI405AB CPCI405DT CPCI440 \ - CPCIISER4 CRAYL1 csb272 csb472 \ - DASA_SIM DP405 DU405 ebony \ - ERIC EXBITGEN G2000 HH405 \ - HUB405 JSE KAREF katmai \ - luan METROBOX MIP405 MIP405T \ - ML2 ml300 ocotea OCRTC \ - ORSG p3p440 PCI405 pcs440ep \ - PIP405 PLU405 PMC405 PPChameleonEVB \ - sbc405 sc3 sequoia sequoia_nand \ - taishan VOH405 VOM405 W7OLMC \ - W7OLMG walnut WUH405 XPEDITE1K \ - yellowstone yosemite yucca \ + AR405 ASH405 bamboo bamboo_nand \ + bubinga CANBT CMS700 CPCI2DP \ + CPCI405 CPCI4052 CPCI405AB CPCI405DT \ + CPCI440 CPCIISER4 CRAYL1 csb272 \ + csb472 DASA_SIM DP405 DU405 \ + ebony ERIC EXBITGEN G2000 \ + HH405 HUB405 JSE KAREF \ + katmai luan METROBOX MIP405 \ + MIP405T ML2 ml300 ocotea \ + OCRTC ORSG p3p440 PCI405 \ + pcs440ep PIP405 PLU405 PMC405 \ + PPChameleonEVB sbc405 sc3 sequoia \ + sequoia_nand taishan VOH405 VOM405 \ + W7OLMC W7OLMG walnut WUH405 \ + XPEDITE1K yellowstone yosemite yucca \ " ######################################################################### diff --git a/Makefile b/Makefile index 8e551eb555d..99f38afb6f7 100644 --- a/Makefile +++ b/Makefile @@ -1035,6 +1035,16 @@ ASH405_config: unconfig bamboo_config: unconfig @$(MKCONFIG) $(@:_config=) ppc ppc4xx bamboo amcc +bamboo_nand_config: unconfig + @mkdir -p $(obj)include + @mkdir -p $(obj)nand_spl + @mkdir -p $(obj)board/amcc/bamboo + @echo "#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h + @echo "Compile NAND boot image for bamboo" + @$(MKCONFIG) -a bamboo ppc ppc4xx bamboo amcc + @echo "TEXT_BASE = 0x01000000" > $(obj)board/amcc/bamboo/config.tmp + @echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk + bubinga_config: unconfig @$(MKCONFIG) $(@:_config=) ppc ppc4xx bubinga amcc diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index 3b1586c0ae3..fe14ecd7bfe 100644 --- a/cpu/ppc4xx/start.S +++ b/cpu/ppc4xx/start.S @@ -110,6 +110,13 @@ # endif #endif /* CFG_INIT_DCACHE_CS */ +#define function_prolog(func_name) .text; \ + .align 2; \ + .globl func_name; \ + func_name: +#define function_epilog(func_name) .type func_name,@function; \ + .size func_name,.-func_name + /* We don't want the MMU yet. */ #undef MSR_KERNEL @@ -388,8 +395,9 @@ rsttlb: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/ 2: #if defined(CONFIG_NAND_SPL) +#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) /* - * Enable internal SRAM + * Enable internal SRAM (only on 440EPx/GRx, 440EP/GR have no OCM) */ lis r2,0x7fff ori r2,r2,0xffff @@ -399,6 +407,45 @@ rsttlb: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/ mfdcr r1,isram0_pmeg and r1,r1,r2 /* Disable pwr mgmt */ mtdcr isram0_pmeg,r1 +#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 @@ -429,7 +476,7 @@ spl_loop: start_ram: sync isync -#endif +#endif /* CONFIG_NAND_SPL */ bl 3f b _start @@ -1137,7 +1184,6 @@ crit_return: lwz r1,GPR1(r1) SYNC rfci -#endif /* CONFIG_NAND_SPL */ /* Cache functions. */ @@ -1254,24 +1300,6 @@ wr_tcr: mtspr tcr, r3 blr -/*------------------------------------------------------------------------------- */ -/* Function: in8 */ -/* Description: Input 8 bits */ -/*------------------------------------------------------------------------------- */ - .globl in8 -in8: - lbz r3,0x0000(r3) - blr - -/*------------------------------------------------------------------------------- */ -/* Function: out8 */ -/* Description: Output 8 bits */ -/*------------------------------------------------------------------------------- */ - .globl out8 -out8: - stb r4,0x0000(r3) - blr - /*------------------------------------------------------------------------------- */ /* Function: out16 */ /* Description: Output 16 bits */ @@ -1290,15 +1318,6 @@ out16r: sthbrx r4,r0,r3 blr -/*------------------------------------------------------------------------------- */ -/* Function: out32 */ -/* Description: Output 32 bits */ -/*------------------------------------------------------------------------------- */ - .globl out32 -out32: - stw r4,0x0000(r3) - blr - /*------------------------------------------------------------------------------- */ /* Function: out32r */ /* Description: Byte reverse and output 32 bits */ @@ -1326,15 +1345,6 @@ in16r: lhbrx r3,r0,r3 blr -/*------------------------------------------------------------------------------- */ -/* Function: in32 */ -/* Description: Input 32 bits */ -/*------------------------------------------------------------------------------- */ - .globl in32 -in32: - lwz 3,0x0000(3) - blr - /*------------------------------------------------------------------------------- */ /* Function: in32r */ /* Description: Input 32 bits and byte reverse */ @@ -1377,9 +1387,6 @@ ppcSync: sync blr -/*------------------------------------------------------------------------------*/ - -#ifndef CONFIG_NAND_SPL /* * void relocate_code (addr_sp, gd, addr_moni) * @@ -1644,8 +1651,88 @@ trap_reloc: stw r0, 4(r7) blr + +#if defined(CONFIG_440) +/*----------------------------------------------------------------------------+ +| dcbz_area. ++----------------------------------------------------------------------------*/ + function_prolog(dcbz_area) + rlwinm. r5,r4,0,27,31 + rlwinm r5,r4,27,5,31 + beq ..d_ra2 + addi r5,r5,0x0001 +..d_ra2:mtctr r5 +..d_ag2:dcbz r0,r3 + addi r3,r3,32 + bdnz ..d_ag2 + sync + blr + function_epilog(dcbz_area) + +/*----------------------------------------------------------------------------+ +| dflush. Assume 32K at vector address is cachable. ++----------------------------------------------------------------------------*/ + function_prolog(dflush) + mfmsr r9 + rlwinm r8,r9,0,15,13 + rlwinm r8,r8,0,17,15 + mtmsr r8 + addi r3,r0,0x0000 + mtspr dvlim,r3 + mfspr r3,ivpr + addi r4,r0,1024 + mtctr r4 +..dflush_loop: + lwz r6,0x0(r3) + addi r3,r3,32 + bdnz ..dflush_loop + addi r3,r3,-32 + mtctr r4 +..ag: dcbf r0,r3 + addi r3,r3,-32 + bdnz ..ag + sync + mtmsr r9 + blr + function_epilog(dflush) +#endif /* CONFIG_440 */ #endif /* CONFIG_NAND_SPL */ +/*------------------------------------------------------------------------------- */ +/* Function: in8 */ +/* Description: Input 8 bits */ +/*------------------------------------------------------------------------------- */ + .globl in8 +in8: + lbz r3,0x0000(r3) + blr + +/*------------------------------------------------------------------------------- */ +/* Function: out8 */ +/* Description: Output 8 bits */ +/*------------------------------------------------------------------------------- */ + .globl out8 +out8: + stb r4,0x0000(r3) + blr + +/*------------------------------------------------------------------------------- */ +/* Function: out32 */ +/* Description: Output 32 bits */ +/*------------------------------------------------------------------------------- */ + .globl out32 +out32: + stw r4,0x0000(r3) + blr + +/*------------------------------------------------------------------------------- */ +/* Function: in32 */ +/* Description: Input 32 bits */ +/*------------------------------------------------------------------------------- */ + .globl in32 +in32: + lwz 3,0x0000(3) + blr /**************************************************************************/ /* PPC405EP specific stuff */ @@ -1892,13 +1979,6 @@ pll_wait: #endif /* CONFIG_405EP */ #if defined(CONFIG_440) -#define function_prolog(func_name) .text; \ - .align 2; \ - .globl func_name; \ - func_name: -#define function_epilog(func_name) .type func_name,@function; \ - .size func_name,.-func_name - /*----------------------------------------------------------------------------+ | mttlb3. +----------------------------------------------------------------------------*/ @@ -1946,47 +2026,4 @@ pll_wait: TLBRE(3,3,0) blr function_epilog(mftlb1) - -/*----------------------------------------------------------------------------+ -| dcbz_area. -+----------------------------------------------------------------------------*/ - function_prolog(dcbz_area) - rlwinm. r5,r4,0,27,31 - rlwinm r5,r4,27,5,31 - beq ..d_ra2 - addi r5,r5,0x0001 -..d_ra2:mtctr r5 -..d_ag2:dcbz r0,r3 - addi r3,r3,32 - bdnz ..d_ag2 - sync - blr - function_epilog(dcbz_area) - -/*----------------------------------------------------------------------------+ -| dflush. Assume 32K at vector address is cachable. -+----------------------------------------------------------------------------*/ - function_prolog(dflush) - mfmsr r9 - rlwinm r8,r9,0,15,13 - rlwinm r8,r8,0,17,15 - mtmsr r8 - addi r3,r0,0x0000 - mtspr dvlim,r3 - mfspr r3,ivpr - addi r4,r0,1024 - mtctr r4 -..dflush_loop: - lwz r6,0x0(r3) - addi r3,r3,32 - bdnz ..dflush_loop - addi r3,r3,-32 - mtctr r4 -..ag: dcbf r0,r3 - addi r3,r3,-32 - bdnz ..ag - sync - mtmsr r9 - blr - function_epilog(dflush) #endif /* CONFIG_440 */ diff --git a/include/configs/bamboo.h b/include/configs/bamboo.h index db58a9fa74a..763d1c7a8b4 100644 --- a/include/configs/bamboo.h +++ b/include/configs/bamboo.h @@ -50,7 +50,7 @@ *----------------------------------------------------------------------*/ #define CFG_MONITOR_LEN (384 * 1024) /* Reserve 384 kB for Monitor */ #define CFG_MALLOC_LEN (256 * 1024) /* Reserve 256 kB for malloc() */ -#define CFG_MONITOR_BASE (-CFG_MONITOR_LEN) +#define CFG_MONITOR_BASE TEXT_BASE #define CFG_SDRAM_BASE 0x00000000 /* _must_ be 0 */ #define CFG_FLASH_BASE 0xfff00000 /* start of FLASH */ #define CFG_PCI_MEMBASE 0xa0000000 /* mapped pci memory*/ @@ -104,14 +104,11 @@ /*----------------------------------------------------------------------- * Environment *----------------------------------------------------------------------*/ -/* - * Define here the location of the environment variables (FLASH or EEPROM). - * Note: DENX encourages to use redundant environment in FLASH. - */ -#if 1 +#if !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) #define CFG_ENV_IS_IN_FLASH 1 /* use FLASH for environment vars */ #else -#define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */ +#define CFG_ENV_IS_IN_NAND 1 /* use NAND for environment vars */ +#define CFG_ENV_IS_EMBEDDED 1 /* use embedded environment */ #endif /*----------------------------------------------------------------------- @@ -133,7 +130,7 @@ #ifdef CFG_ENV_IS_IN_FLASH #define CFG_ENV_SECT_SIZE 0x10000 /* size of one complete sector */ -#define CFG_ENV_ADDR (CFG_MONITOR_BASE-CFG_ENV_SECT_SIZE) +#define CFG_ENV_ADDR ((-CFG_MONITOR_LEN)-CFG_ENV_SECT_SIZE) #define CFG_ENV_SIZE 0x2000 /* Total Size of Environment Sector */ /* Address and size of Redundant Environment Sector */ @@ -141,22 +138,89 @@ #define CFG_ENV_SIZE_REDUND (CFG_ENV_SIZE) #endif /* CFG_ENV_IS_IN_FLASH */ +/* + * IPL (Initial Program Loader, integrated inside CPU) + * Will load first 4k from NAND (SPL) into cache and execute it from there. + * + * SPL (Secondary Program Loader) + * Will load special U-Boot version (NUB) from NAND and execute it. This SPL + * has to fit into 4kByte. It sets up the CPU and configures the SDRAM + * controller and the NAND controller so that the special U-Boot image can be + * loaded from NAND to SDRAM. + * + * NUB (NAND U-Boot) + * This NAND U-Boot (NUB) is a special U-Boot version which can be started + * from RAM. Therefore it mustn't (re-)configure the SDRAM controller. + * + * On 440EPx the SPL is copied to SDRAM before the NAND controller is + * set up. While still running from cache, I experienced problems accessing + * the NAND controller. sr - 2006-08-25 + */ +#define CFG_NAND_BOOT_SPL_SRC 0xfffff000 /* SPL location */ +#define CFG_NAND_BOOT_SPL_SIZE (4 << 10) /* SPL size */ +#define CFG_NAND_BOOT_SPL_DST 0x00800000 /* Copy SPL here */ +#define CFG_NAND_U_BOOT_DST 0x01000000 /* Load NUB to this addr */ +#define CFG_NAND_U_BOOT_START CFG_NAND_U_BOOT_DST /* Start NUB from this addr */ +#define CFG_NAND_BOOT_SPL_DELTA (CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST) + +/* + * Define the partitioning of the NAND chip (only RAM U-Boot is needed here) + */ +#define CFG_NAND_U_BOOT_OFFS (16 << 10) /* Offset to RAM U-Boot image */ +#define CFG_NAND_U_BOOT_SIZE (384 << 10) /* Size of RAM U-Boot image */ + +/* + * Now the NAND chip has to be defined (no autodetection used!) + */ +#define CFG_NAND_PAGE_SIZE 512 /* NAND chip page size */ +#define CFG_NAND_BLOCK_SIZE (16 << 10) /* NAND chip block size */ +#define CFG_NAND_PAGE_COUNT 32 /* NAND chip page count */ +#define CFG_NAND_BAD_BLOCK_POS 5 /* Location of bad block marker */ +#define CFG_NAND_4_ADDR_CYCLE 1 /* Fourth addr used (>32MB) */ + +#define CFG_NAND_ECCSIZE 256 +#define CFG_NAND_ECCBYTES 3 +#define CFG_NAND_ECCSTEPS (CFG_NAND_PAGE_SIZE / CFG_NAND_ECCSIZE) +#define CFG_NAND_OOBSIZE 16 +#define CFG_NAND_ECCTOTAL (CFG_NAND_ECCBYTES * CFG_NAND_ECCSTEPS) +#define CFG_NAND_ECCPOS {0, 1, 2, 3, 6, 7} + +#ifdef CFG_ENV_IS_IN_NAND +/* + * For NAND booting the environment is embedded in the U-Boot image. Please take + * look at the file board/amcc/sequoia/u-boot-nand.lds for details. + */ +#define CFG_ENV_SIZE CFG_NAND_BLOCK_SIZE +#define CFG_ENV_OFFSET (CFG_NAND_U_BOOT_OFFS + CFG_ENV_SIZE) +#define CFG_ENV_OFFSET_REDUND (CFG_ENV_OFFSET + CFG_ENV_SIZE) +#endif + /*----------------------------------------------------------------------- * NAND FLASH *----------------------------------------------------------------------*/ -#define CFG_MAX_NAND_DEVICE 1 -#define NAND_MAX_CHIPS 1 -#define CFG_NAND_CS 1 +#define CFG_MAX_NAND_DEVICE 2 +#define NAND_MAX_CHIPS CFG_MAX_NAND_DEVICE #define CFG_NAND_BASE (CFG_NAND_ADDR + CFG_NAND_CS) +#define CFG_NAND_BASE_LIST { CFG_NAND_BASE, CFG_NAND_ADDR + 2 } #define CFG_NAND_SELECT_DEVICE 1 /* nand driver supports mutipl. chips */ +#if !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) +#define CFG_NAND_CS 1 +#else +#define CFG_NAND_CS 0 /* NAND chip connected to CSx */ +/* Memory Bank 0 (NAND-FLASH) initialization */ +#define CFG_EBC_PB0AP 0x018003c0 +#define CFG_EBC_PB0CR (CFG_NAND_ADDR | 0x1c000) +#endif + /*----------------------------------------------------------------------- * DDR SDRAM *----------------------------------------------------------------------------- */ #define CONFIG_SPD_EEPROM /* Use SPD EEPROM for setup */ #undef CONFIG_DDR_ECC /* don't use ECC */ #define CFG_SIMULATE_SPD_EEPROM 0xff /* simulate spd eeprom on this address */ -#define SPD_EEPROM_ADDRESS {CFG_SIMULATE_SPD_EEPROM, 0x50, 0x51} +#define SPD_EEPROM_ADDRESS {CFG_SIMULATE_SPD_EEPROM, 0x50, 0x51} +#define CFG_MBYTES_SDRAM (64) /* 64MB fixed size for early-sdram-init */ /*----------------------------------------------------------------------- * I2C diff --git a/nand_spl/board/amcc/bamboo/Makefile b/nand_spl/board/amcc/bamboo/Makefile new file mode 100644 index 00000000000..0df86f99d45 --- /dev/null +++ b/nand_spl/board/amcc/bamboo/Makefile @@ -0,0 +1,100 @@ +# +# (C) Copyright 2007 +# Stefan Roese, DENX Software Engineering, 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 be 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 +# + +include $(TOPDIR)/config.mk +include $(TOPDIR)/nand_spl/board/$(BOARDDIR)/config.mk + +LDSCRIPT= $(TOPDIR)/nand_spl/board/$(BOARDDIR)/u-boot.lds +LDFLAGS = -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS) +AFLAGS += -DCONFIG_NAND_SPL +CFLAGS += -DCONFIG_NAND_SPL + +SOBJS = start.o init.o resetvec.o +COBJS = nand_boot.o nand_ecc.o ndfc.o sdram.o + +SRCS := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c)) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +__OBJS := $(SOBJS) $(COBJS) +LNDIR := $(OBJTREE)/nand_spl/board/$(BOARDDIR) + +nandobj := $(OBJTREE)/nand_spl/ + +ALL = $(nandobj)u-boot-spl $(nandobj)u-boot-spl.bin $(nandobj)u-boot-spl-16k.bin + +all: $(obj).depend $(ALL) + +$(nandobj)u-boot-spl-16k.bin: $(nandobj)u-boot-spl + $(OBJCOPY) ${OBJCFLAGS} --pad-to=$(PAD_TO) -O binary $< $@ + +$(nandobj)u-boot-spl.bin: $(nandobj)u-boot-spl + $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@ + +$(nandobj)u-boot-spl: $(OBJS) + cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \ + -Map $(nandobj)u-boot-spl.map \ + -o $(nandobj)u-boot-spl + +# create symbolic links for common files + +# from cpu directory +$(obj)ndfc.c: + @rm -f $(obj)ndfc.c + ln -s $(SRCTREE)/cpu/ppc4xx/ndfc.c $(obj)ndfc.c + +$(obj)resetvec.S: + @rm -f $(obj)resetvec.S + ln -s $(SRCTREE)/cpu/ppc4xx/resetvec.S $(obj)resetvec.S + +$(obj)start.S: + @rm -f $(obj)start.S + ln -s $(SRCTREE)/cpu/ppc4xx/start.S $(obj)start.S + +# from board directory +$(obj)init.S: + @rm -f $(obj)init.S + ln -s $(SRCTREE)/board/amcc/bamboo/init.S $(obj)init.S + +# from nand_spl directory +$(obj)nand_boot.c: + @rm -f $(obj)nand_boot.c + ln -s $(SRCTREE)/nand_spl/nand_boot.c $(obj)nand_boot.c + +# from drivers/nand directory +$(obj)nand_ecc.c: + @rm -f $(obj)nand_ecc.c + ln -s $(SRCTREE)/drivers/nand/nand_ecc.c $(obj)nand_ecc.c + +######################################################################### + +$(obj)%.o: $(obj)%.S + $(CC) $(AFLAGS) -c -o $@ $< + +$(obj)%.o: $(obj)%.c + $(CC) $(CFLAGS) -c -o $@ $< + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/nand_spl/board/amcc/bamboo/config.mk b/nand_spl/board/amcc/bamboo/config.mk new file mode 100644 index 00000000000..f7ec7514f00 --- /dev/null +++ b/nand_spl/board/amcc/bamboo/config.mk @@ -0,0 +1,49 @@ +# +# (C) Copyright 2007 +# Stefan Roese, DENX Software Engineering, 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 be 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 +# +# +# AMCC 440EP Reference Platform (Bamboo) board +# + +# +# TEXT_BASE for SPL: +# +# On 440EP(x) platforms the SPL is located at 0xfffff000...0xffffffff, +# in the last 4kBytes of memory space in cache. +# We will copy this SPL into instruction-cache in start.S. So we set +# TEXT_BASE to starting address in i-cache here. +# +TEXT_BASE = 0x00800000 + +# PAD_TO used to generate a 16kByte binary needed for the combined image +# -> PAD_TO = TEXT_BASE + 0x4000 +PAD_TO = 0x00804000 + +PLATFORM_CPPFLAGS += -DCONFIG_440=1 + +ifeq ($(debug),1) +PLATFORM_CPPFLAGS += -DDEBUG +endif + +ifeq ($(dbcr),1) +PLATFORM_CPPFLAGS += -DCFG_INIT_DBCR=0x8cff0000 +endif diff --git a/nand_spl/board/amcc/bamboo/sdram.c b/nand_spl/board/amcc/bamboo/sdram.c new file mode 100644 index 00000000000..4f09072df08 --- /dev/null +++ b/nand_spl/board/amcc/bamboo/sdram.c @@ -0,0 +1,92 @@ +/* + * (C) Copyright 2007 + * Stefan Roese, DENX Software Engineering, 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 be 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 + */ + +#include +#include +#include +#include + +static void wait_init_complete(void) +{ + u32 val; + + do { + mfsdram(mem_mcsts, val); + } while (!(val & 0x80000000)); +} + +/* + * early_sdram_init() + * + * As the name already indicates, this function is called very early + * from start.S and configures the SDRAM with fixed values. This is needed, + * since the 440EP has no internal SRAM and the 4kB NAND_SPL loader has + * not enough free space to implement the complete I2C SPD DDR autodetection + * routines. Therefore the Bamboo only supports the onboard 64MBytes of SDRAM + * when booting from NAND flash. + */ +void early_sdram_init(void) +{ + /* + * Soft-reset SDRAM controller. + */ + mtsdr(sdr_srst, SDR0_SRST_DMC); + mtsdr(sdr_srst, 0x00000000); + + /* + * Disable memory controller. + */ + mtsdram(mem_cfg0, 0x00000000); + + /* + * Setup some default + */ + mtsdram(mem_uabba, 0x00000000); /* ubba=0 (default) */ + mtsdram(mem_slio, 0x00000000); /* rdre=0 wrre=0 rarw=0 */ + mtsdram(mem_devopt, 0x00000000); /* dll=0 ds=0 (normal) */ + mtsdram(mem_wddctr, 0x00000000); /* wrcp=0 dcd=0 */ + mtsdram(mem_clktr, 0x40000000); /* clkp=1 (90 deg wr) dcdt=0 */ + + /* + * Following for CAS Latency = 2.5 @ 133 MHz PLB + */ + mtsdram(mem_b0cr, 0x00082001); + mtsdram(mem_tr0, 0x41094012); + mtsdram(mem_tr1, 0x8080083d); /* SS=T2 SL=STAGE 3 CD=1 CT=0x00*/ + mtsdram(mem_rtr, 0x04100000); /* Interval 7.8µs @ 133MHz PLB */ + mtsdram(mem_cfg1, 0x00000000); /* Self-refresh exit, disable PM*/ + + /* + * Enable the controller, then wait for DCEN to complete + */ + mtsdram(mem_cfg0, 0x80000000); /* DCEN=1, PMUD=0*/ + wait_init_complete(); +} + +long int initdram(int board_type) +{ + /* + * Nothing to do here, just return size of fixed SDRAM setup + */ + return CFG_MBYTES_SDRAM << 20; +} diff --git a/nand_spl/board/amcc/bamboo/u-boot.lds b/nand_spl/board/amcc/bamboo/u-boot.lds new file mode 100644 index 00000000000..28228f84ddc --- /dev/null +++ b/nand_spl/board/amcc/bamboo/u-boot.lds @@ -0,0 +1,65 @@ +/* + * (C) Copyright 2007 + * Stefan Roese, DENX Software Engineering, 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 be 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 + */ + +OUTPUT_ARCH(powerpc:common) +SECTIONS +{ + .resetvec 0x00800FFC : + { + *(.resetvec) + } = 0xffff + + .text : + { + start.o (.text) + init.o (.text) + nand_boot.o (.text) + sdram.o (.text) + ndfc.o (.text) + + *(.text) + *(.fixup) + } + _etext = .; + + .data : + { + *(.rodata*) + *(.data*) + *(.sdata*) + __got2_start = .; + *(.got2) + __got2_end = .; + } + + _edata = .; + + __bss_start = .; + .bss : + { + *(.sbss) + *(.bss) + } + + _end = . ; +} -- cgit v1.3.1