diff options
Diffstat (limited to 'cpu/ppc4xx')
-rw-r--r-- | cpu/ppc4xx/405gp_pci.c | 15 | ||||
-rw-r--r-- | cpu/ppc4xx/cpu.c | 15 | ||||
-rw-r--r-- | cpu/ppc4xx/cpu_init.c | 126 | ||||
-rw-r--r-- | cpu/ppc4xx/i2c.c | 3 | ||||
-rw-r--r-- | cpu/ppc4xx/interrupts.c | 4 | ||||
-rw-r--r-- | cpu/ppc4xx/sdram.c | 306 | ||||
-rw-r--r-- | cpu/ppc4xx/sdram.h | 78 | ||||
-rw-r--r-- | cpu/ppc4xx/serial.c | 14 | ||||
-rw-r--r-- | cpu/ppc4xx/spd_sdram.c | 2 | ||||
-rw-r--r-- | cpu/ppc4xx/speed.c | 6 | ||||
-rw-r--r-- | cpu/ppc4xx/start.S | 50 |
11 files changed, 524 insertions, 95 deletions
diff --git a/cpu/ppc4xx/405gp_pci.c b/cpu/ppc4xx/405gp_pci.c index 2fda60e..0ccb3d8 100644 --- a/cpu/ppc4xx/405gp_pci.c +++ b/cpu/ppc4xx/405gp_pci.c @@ -77,10 +77,16 @@ #include <asm/processor.h> #include <pci.h> +DECLARE_GLOBAL_DATA_PTR; + #if defined(CONFIG_405GP) || defined(CONFIG_405EP) #ifdef CONFIG_PCI +#if defined(CONFIG_PMC405) +ushort pmc405_pci_subsys_deviceid(void); +#endif + /*#define DEBUG*/ /*-----------------------------------------------------------------------------+ @@ -88,21 +94,16 @@ *-----------------------------------------------------------------------------*/ void pci_405gp_init(struct pci_controller *hose) { - DECLARE_GLOBAL_DATA_PTR; - int i, reg_num = 0; bd_t *bd = gd->bd; unsigned short temp_short; unsigned long ptmpcila[2] = {CFG_PCI_PTM1PCI, CFG_PCI_PTM2PCI}; #if defined(CONFIG_CPCI405) || defined(CONFIG_PMC405) - unsigned long ptmla[2] = {bd->bi_memstart, bd->bi_flashstart}; - unsigned long ptmms[2] = {~(bd->bi_memsize - 1) | 1, ~(bd->bi_flashsize - 1) | 1}; char *ptmla_str, *ptmms_str; -#else +#endif unsigned long ptmla[2] = {CFG_PCI_PTM1LA, CFG_PCI_PTM2LA}; unsigned long ptmms[2] = {CFG_PCI_PTM1MS, CFG_PCI_PTM2MS}; -#endif #if defined(CONFIG_PIP405) || defined (CONFIG_MIP405) unsigned long pmmla[3] = {0x80000000, 0xA0000000, 0}; unsigned long pmmma[3] = {0xE0000001, 0xE0000001, 0}; @@ -372,7 +373,7 @@ void pci_405gp_setup_vga(struct pci_controller *hose, pci_dev_t dev, { unsigned int cmdstat = 0; - pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_io); + pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_prefetch, hose->pci_io); /* always enable io space on vga boards */ pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat); diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c index 3e85a88..6a84b09 100644 --- a/cpu/ppc4xx/cpu.c +++ b/cpu/ppc4xx/cpu.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2003 + * (C) Copyright 2000-2006 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * See file CREDITS for list of people who contributed to this @@ -37,6 +37,10 @@ #include <asm/cache.h> #include <ppc4xx.h> +#if !defined(CONFIG_405) +DECLARE_GLOBAL_DATA_PTR; +#endif + #if defined(CONFIG_440) #define FREQ_EBC (sys_info.freqEPB) @@ -120,7 +124,6 @@ static int do_chip_reset(unsigned long sys0, unsigned long sys1); int checkcpu (void) { #if !defined(CONFIG_405) /* not used on Xilinx 405 FPGA implementations */ - DECLARE_GLOBAL_DATA_PTR; uint pvr = get_pvr(); ulong clock = gd->cpu_clk; char buf[32]; @@ -224,12 +227,20 @@ int checkcpu (void) case PVR_440EP_RB: /* 440EP rev B and 440GR rev A have same PVR */ puts("EP Rev. B"); break; + + case PVR_440EP_RC: /* 440EP rev C and 440GR rev B have same PVR */ + puts("EP Rev. C"); + break; #endif /* CONFIG_440EP */ #ifdef CONFIG_440GR case PVR_440GR_RA: /* 440EP rev B and 440GR rev A have same PVR */ puts("GR Rev. A"); break; + + case PVR_440GR_RB: /* 440EP rev C and 440GR rev B have same PVR */ + puts("GR Rev. B"); + break; #endif /* CONFIG_440GR */ #endif /* CONFIG_440 */ diff --git a/cpu/ppc4xx/cpu_init.c b/cpu/ppc4xx/cpu_init.c index 79cfba3..b27567f 100644 --- a/cpu/ppc4xx/cpu_init.c +++ b/cpu/ppc4xx/cpu_init.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000 + * (C) Copyright 2000-2006 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * See file CREDITS for list of people who contributed to this @@ -27,6 +27,10 @@ #include <asm/processor.h> #include <ppc4xx.h> +#if defined(CONFIG_405GP) || defined(CONFIG_405EP) +DECLARE_GLOBAL_DATA_PTR; +#endif + #define mtebc(reg, data) mtdcr(ebccfga,reg);mtdcr(ebccfgd,data) @@ -97,6 +101,117 @@ # endif #endif /* CFG_INIT_DCACHE_CS */ +#if defined(CFG_440_GPIO_TABLE) +gpio_param_s gpio_tab[GPIO_GROUP_MAX][GPIO_MAX] = CFG_440_GPIO_TABLE; + +void set_chip_gpio_configuration(gpio_param_s (*gpio_tab)[GPIO_GROUP_MAX][GPIO_MAX]) +{ + unsigned char i=0, j=0, reg_offset = 0, gpio_core; + unsigned long gpio_reg, gpio_core_add; + + for (gpio_core=0; gpio_core<GPIO_GROUP_MAX; gpio_core++) { + j = 0; + reg_offset = 0; + /* GPIO config of the GPIOs 0 to 31 */ + for (i=0; i<GPIO_MAX; i++, j++) { + if (i == GPIO_MAX/2) { + reg_offset = 4; + j = i-16; + } + + gpio_core_add = (*gpio_tab)[gpio_core][i].add; + + if (((*gpio_tab)[gpio_core][i].in_out == GPIO_IN) || + ((*gpio_tab)[gpio_core][i].in_out == GPIO_BI)) { + + switch ((*gpio_tab)[gpio_core][i].alt_nb) { + case GPIO_SEL: + break; + + case GPIO_ALT1: + gpio_reg = in32(GPIO_IS1(gpio_core_add+reg_offset)) + & ~(GPIO_MASK >> (j*2)); + gpio_reg = gpio_reg | (GPIO_IN_SEL >> (j*2)); + out32(GPIO_IS1(gpio_core_add+reg_offset), gpio_reg); + break; + + case GPIO_ALT2: + gpio_reg = in32(GPIO_IS2(gpio_core_add+reg_offset)) + & ~(GPIO_MASK >> (j*2)); + gpio_reg = gpio_reg | (GPIO_IN_SEL >> (j*2)); + out32(GPIO_IS2(gpio_core_add+reg_offset), gpio_reg); + break; + + case GPIO_ALT3: + gpio_reg = in32(GPIO_IS3(gpio_core_add+reg_offset)) + & ~(GPIO_MASK >> (j*2)); + gpio_reg = gpio_reg | (GPIO_IN_SEL >> (j*2)); + out32(GPIO_IS3(gpio_core_add+reg_offset), gpio_reg); + break; + } + } + + if (((*gpio_tab)[gpio_core][i].in_out == GPIO_OUT) || + ((*gpio_tab)[gpio_core][i].in_out == GPIO_BI)) { + + switch ((*gpio_tab)[gpio_core][i].alt_nb) { + case GPIO_SEL: + if (gpio_core == GPIO0) { + gpio_reg = in32(GPIO0_TCR) | (0x80000000 >> (j)); + out32(GPIO0_TCR, gpio_reg); + } + + if (gpio_core == GPIO1) { + gpio_reg = in32(GPIO1_TCR) | (0x80000000 >> (j)); + out32(GPIO1_TCR, gpio_reg); + } + + gpio_reg = in32(GPIO_OS(gpio_core_add+reg_offset)) + & ~(GPIO_MASK >> (j*2)); + out32(GPIO_OS(gpio_core_add+reg_offset), gpio_reg); + gpio_reg = in32(GPIO_TS(gpio_core_add+reg_offset)) + & ~(GPIO_MASK >> (j*2)); + out32(GPIO_TS(gpio_core_add+reg_offset), gpio_reg); + break; + + case GPIO_ALT1: + gpio_reg = in32(GPIO_OS(gpio_core_add+reg_offset)) + & ~(GPIO_MASK >> (j*2)); + gpio_reg = gpio_reg | (GPIO_ALT1_SEL >> (j*2)); + out32(GPIO_OS(gpio_core_add+reg_offset), gpio_reg); + gpio_reg = in32(GPIO_TS(gpio_core_add+reg_offset)) + & ~(GPIO_MASK >> (j*2)); + gpio_reg = gpio_reg | (GPIO_ALT1_SEL >> (j*2)); + out32(GPIO_TS(gpio_core_add+reg_offset), gpio_reg); + break; + + case GPIO_ALT2: + gpio_reg = in32(GPIO_OS(gpio_core_add+reg_offset)) + & ~(GPIO_MASK >> (j*2)); + gpio_reg = gpio_reg | (GPIO_ALT2_SEL >> (j*2)); + out32(GPIO_OS(gpio_core_add+reg_offset), gpio_reg); + gpio_reg = in32(GPIO_TS(gpio_core_add+reg_offset)) + & ~(GPIO_MASK >> (j*2)); + gpio_reg = gpio_reg | (GPIO_ALT2_SEL >> (j*2)); + out32(GPIO_TS(gpio_core_add+reg_offset), gpio_reg); + break; + + case GPIO_ALT3: + gpio_reg = in32(GPIO_OS(gpio_core_add+reg_offset)) + & ~(GPIO_MASK >> (j*2)); + gpio_reg = gpio_reg | (GPIO_ALT3_SEL >> (j*2)); + out32(GPIO_OS(gpio_core_add+reg_offset), gpio_reg); + gpio_reg = in32(GPIO_TS(gpio_core_add+reg_offset)) + & ~(GPIO_MASK >> (j*2)); + gpio_reg = gpio_reg | (GPIO_ALT3_SEL >> (j*2)); + out32(GPIO_TS(gpio_core_add+reg_offset), gpio_reg); + break; + } + } + } + } +} +#endif /* CFG_440_GPIO_TABLE */ /* * Breath some life into the CPU... @@ -125,10 +240,16 @@ cpu_init_f (void) mtdcr(cpc0_epctl, CPC0_EPRCSR_E0NFE | CPC0_EPRCSR_E1NFE); #endif /* CONFIG_405EP */ +#if defined(CFG_440_GPIO_TABLE) + set_chip_gpio_configuration(&gpio_tab); +#endif /* CFG_440_GPIO_TABLE */ + /* * External Bus Controller (EBC) Setup */ #if (defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR)) +#if (defined(CONFIG_405GP) || defined(CONFIG_405CR) || \ + defined(CONFIG_405EP) || defined(CONFIG_405)) /* * Move the next instructions into icache, since these modify the flash * we are running from! @@ -144,6 +265,7 @@ cpu_init_f (void) asm volatile(" ori 3, 3, 0xA000" ::: "r3"); asm volatile(" mtctr 3" ::: "ctr"); asm volatile("2: bdnz 2b" ::: "ctr", "cr0"); +#endif mtebc(pb0ap, CFG_EBC_PB0AP); mtebc(pb0cr, CFG_EBC_PB0CR); @@ -209,8 +331,6 @@ cpu_init_f (void) int cpu_init_r (void) { #if defined(CONFIG_405GP) || defined(CONFIG_405EP) - DECLARE_GLOBAL_DATA_PTR; - bd_t *bd = gd->bd; unsigned long reg; #if defined(CONFIG_405GP) diff --git a/cpu/ppc4xx/i2c.c b/cpu/ppc4xx/i2c.c index be94b57..7db1cd8 100644 --- a/cpu/ppc4xx/i2c.c +++ b/cpu/ppc4xx/i2c.c @@ -16,6 +16,8 @@ #ifdef CONFIG_HARD_I2C +DECLARE_GLOBAL_DATA_PTR; + #define IIC_OK 0 #define IIC_NOK 1 #define IIC_NOK_LA 2 /* Lost arbitration */ @@ -350,7 +352,6 @@ int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len) { uchar xaddr[4]; int ret; - DECLARE_GLOBAL_DATA_PTR; if ( alen > 4 ) { printf ("I2C read: addr len %d not supported\n", alen); diff --git a/cpu/ppc4xx/interrupts.c b/cpu/ppc4xx/interrupts.c index fdae846..886f405 100644 --- a/cpu/ppc4xx/interrupts.c +++ b/cpu/ppc4xx/interrupts.c @@ -36,6 +36,8 @@ #include <commproc.h> #include "vecnum.h" +DECLARE_GLOBAL_DATA_PTR; + /****************************************************************************/ /* @@ -100,8 +102,6 @@ static __inline__ void set_evpr(unsigned long val) int interrupt_init_cpu (unsigned *decrementer_count) { - DECLARE_GLOBAL_DATA_PTR; - int vec; unsigned long val; diff --git a/cpu/ppc4xx/sdram.c b/cpu/ppc4xx/sdram.c index e9548cd..e31d59d 100644 --- a/cpu/ppc4xx/sdram.c +++ b/cpu/ppc4xx/sdram.c @@ -1,7 +1,10 @@ /* - * (C) Copyright 2005 + * (C) Copyright 2005-2006 * Stefan Roese, DENX Software Engineering, sr@denx.de. * + * (C) Copyright 2006 + * DAVE Srl <www.dave-tech.it> + * * (C) Copyright 2002-2004 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com * @@ -15,7 +18,7 @@ * * 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 + * 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 @@ -27,63 +30,161 @@ #include <common.h> #include <ppc4xx.h> #include <asm/processor.h> +#include "sdram.h" #ifdef CONFIG_SDRAM_BANK0 -#define mtsdram0(reg, data) mtdcr(memcfga,reg);mtdcr(memcfgd,data) - - -struct sdram_conf_s { - unsigned long size; - unsigned long reg; -}; - -typedef struct sdram_conf_s sdram_conf_t; - #ifndef CFG_SDRAM_TABLE sdram_conf_t mb0cf[] = { - {(128 << 20), 0x000A4001}, /* (0-128MB) Address Mode 3, 13x10(4) */ - {(64 << 20), 0x00084001}, /* (0-64MB) Address Mode 3, 13x9(4) */ - {(32 << 20), 0x00062001}, /* (0-32MB) Address Mode 2, 12x9(4) */ - {(16 << 20), 0x00046001}, /* (0-16MB) Address Mode 4, 12x8(4) */ - {(4 << 20), 0x00008001}, /* (0-4MB) Address Mode 5, 11x8(2) */ + {(128 << 20), 13, 0x000A4001}, /* (0-128MB) Address Mode 3, 13x10(4) */ + {(64 << 20), 13, 0x00084001}, /* (0-64MB) Address Mode 3, 13x9(4) */ + {(32 << 20), 12, 0x00062001}, /* (0-32MB) Address Mode 2, 12x9(4) */ + {(16 << 20), 12, 0x00046001}, /* (0-16MB) Address Mode 4, 12x8(4) */ + {(4 << 20), 11, 0x00008001}, /* (0-4MB) Address Mode 5, 11x8(2) */ }; #else sdram_conf_t mb0cf[] = CFG_SDRAM_TABLE; #endif -#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0])) +#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0])) #ifndef CONFIG_440 -/* - * Autodetect onboard SDRAM on 405 platforms - */ -void sdram_init(void) +#ifdef CFG_SDRAM_CASL +static ulong ns2clks(ulong ns) { - ulong sdtr1; - ulong rtr; - int i; + ulong bus_period_x_10 = ONE_BILLION / (get_bus_freq(0) / 10); + return ((ns * 10) + bus_period_x_10) / bus_period_x_10; +} +#endif /* CFG_SDRAM_CASL */ + +static ulong compute_sdtr1(ulong speed) +{ +#ifdef CFG_SDRAM_CASL + ulong tmp; + ulong sdtr1 = 0; + + /* CASL */ + if (CFG_SDRAM_CASL < 2) + sdtr1 |= (1 << SDRAM0_TR_CASL); + else + if (CFG_SDRAM_CASL > 4) + sdtr1 |= (3 << SDRAM0_TR_CASL); + else + sdtr1 |= ((CFG_SDRAM_CASL-1) << SDRAM0_TR_CASL); + + /* PTA */ + tmp = ns2clks(CFG_SDRAM_PTA); + if ((tmp >= 2) && (tmp <= 4)) + sdtr1 |= ((tmp-1) << SDRAM0_TR_PTA); + else + sdtr1 |= ((4-1) << SDRAM0_TR_PTA); + + /* CTP */ + tmp = ns2clks(CFG_SDRAM_CTP); + if ((tmp >= 2) && (tmp <= 4)) + sdtr1 |= ((tmp-1) << SDRAM0_TR_CTP); + else + sdtr1 |= ((4-1) << SDRAM0_TR_CTP); + + /* LDF */ + tmp = ns2clks(CFG_SDRAM_LDF); + if ((tmp >= 2) && (tmp <= 4)) + sdtr1 |= ((tmp-1) << SDRAM0_TR_LDF); + else + sdtr1 |= ((2-1) << SDRAM0_TR_LDF); + + /* RFTA */ + tmp = ns2clks(CFG_SDRAM_RFTA); + if ((tmp >= 4) && (tmp <= 10)) + sdtr1 |= ((tmp-4) << SDRAM0_TR_RFTA); + else + sdtr1 |= ((10-4) << SDRAM0_TR_RFTA); + + /* RCD */ + tmp = ns2clks(CFG_SDRAM_RCD); + if ((tmp >= 2) && (tmp <= 4)) + sdtr1 |= ((tmp-1) << SDRAM0_TR_RCD); + else + sdtr1 |= ((4-1) << SDRAM0_TR_RCD); + + return sdtr1; +#else /* CFG_SDRAM_CASL */ /* - * Support for 100MHz and 133MHz SDRAM + * If no values are configured in the board config file + * use the default values, which seem to be ok for most + * boards. + * + * REMARK: + * For new board ports we strongly recommend to define the + * correct values for the used SDRAM chips in your board + * config file (see PPChameleonEVB.h) */ - if (get_bus_freq(0) > 100000000) { + if (speed > 100000000) { /* * 133 MHz SDRAM */ - sdtr1 = 0x01074015; - rtr = 0x07f00000; + return 0x01074015; } else { /* * default: 100 MHz SDRAM */ - sdtr1 = 0x0086400d; - rtr = 0x05f00000; + return 0x0086400d; } +#endif /* CFG_SDRAM_CASL */ +} + +/* refresh is expressed in ms */ +static ulong compute_rtr(ulong speed, ulong rows, ulong refresh) +{ +#ifdef CFG_SDRAM_CASL + ulong tmp; + + tmp = ((refresh*1000*1000) / (1 << rows)) * (speed / 1000); + tmp /= 1000000; + + return ((tmp & 0x00003FF8) << 16); +#else /* CFG_SDRAM_CASL */ + if (speed > 100000000) { + /* + * 133 MHz SDRAM + */ + return 0x07f00000; + } else { + /* + * default: 100 MHz SDRAM + */ + return 0x05f00000; + } +#endif /* CFG_SDRAM_CASL */ +} + +/* + * Autodetect onboard SDRAM on 405 platforms + */ +void sdram_init(void) +{ + ulong speed; + ulong sdtr1; + int i; + + /* + * Determine SDRAM speed + */ + speed = get_bus_freq(0); /* parameter not used on ppc4xx */ + + /* + * sdtr1 (register SDRAM0_TR) must take into account timings listed + * in SDRAM chip datasheet. rtr (register SDRAM0_RTR) must take into + * account actual SDRAM size. So we can set up sdtr1 according to what + * is specified in board configuration file while rtr dependds on SDRAM + * size we are assuming before detection. + */ + sdtr1 = compute_sdtr1(speed); for (i=0; i<N_MB0CF; i++) { /* @@ -96,7 +197,7 @@ void sdram_init(void) */ mtsdram0(mem_mb0cf, mb0cf[i].reg); mtsdram0(mem_sdtr1, sdtr1); - mtsdram0(mem_rtr, rtr); + mtsdram0(mem_rtr, compute_rtr(speed, mb0cf[i].rows, 64)); udelay(200); @@ -120,16 +221,135 @@ void sdram_init(void) #else /* CONFIG_440 */ +#define NUM_TRIES 64 +#define NUM_READS 10 + +static void sdram_tr1_set(int ram_address, int* tr1_value) +{ + int i; + int j, k; + volatile unsigned int* ram_pointer = (unsigned int *)ram_address; + int first_good = -1, last_bad = 0x1ff; + + unsigned long test[NUM_TRIES] = { + 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 }; + + /* go through all possible SDRAM0_TR1[RDCT] values */ + for (i=0; i<=0x1ff; i++) { + /* set the current value for TR1 */ + mtsdram(mem_tr1, (0x80800800 | i)); + + /* write values */ + for (j=0; j<NUM_TRIES; j++) { + ram_pointer[j] = test[j]; + + /* clear any cache at ram location */ + __asm__("dcbf 0,%0": :"r" (&ram_pointer[j])); + } + + /* read values back */ + for (j=0; j<NUM_TRIES; j++) { + for (k=0; k<NUM_READS; k++) { + /* clear any cache at ram location */ + __asm__("dcbf 0,%0": :"r" (&ram_pointer[j])); + + if (ram_pointer[j] != test[j]) + break; + } + + /* read error */ + if (k != NUM_READS) + break; + } + + /* we have a SDRAM0_TR1[RDCT] that is part of the window */ + if (j == NUM_TRIES) { + if (first_good == -1) + first_good = i; /* found beginning of window */ + } else { /* bad read */ + /* if we have not had a good read then don't care */ + if (first_good != -1) { + /* first failure after a good read */ + last_bad = i-1; + break; + } + } + } + + /* return the current value for TR1 */ + *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 * * NOTE: Some of the hardcoded values are hardware dependant, - * so this should be extended for other future boards - * using this routine! + * so this should be extended for other future boards + * using this routine! */ long int initdram(int board_type) { int i; + int tr1_bank1; for (i=0; i<N_MB0CF; i++) { /* @@ -140,11 +360,11 @@ long int initdram(int board_type) /* * Setup some default */ - mtsdram(mem_uabba, 0x00000000); /* ubba=0 (default) */ - mtsdram(mem_slio, 0x00000000); /* rdre=0 wrre=0 rarw=0 */ + 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 */ + mtsdram(mem_clktr, 0x40000000); /* clkp=1 (90 deg wr) dcdt=0 */ /* * Following for CAS Latency = 2.5 @ 133 MHz PLB @@ -159,11 +379,21 @@ long int initdram(int board_type) /* * Enable the controller, then wait for DCEN to complete */ - mtsdram(mem_cfg0, 0x86000000); /* DCEN=1, PMUD=1, 64-bit */ + mtsdram(mem_cfg0, 0x86000000); /* DCEN=1, PMUD=1, 64-bit */ udelay(10000); if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) { /* + * Optimize TR1 to current hardware environment + */ + sdram_tr1_set(0x00000000, &tr1_bank1); + mtsdram(mem_tr1, (tr1_bank1 | 0x80800800)); + +#ifdef CONFIG_SDRAM_ECC + ecc_init(0, mb0cf[i].size); +#endif + + /* * OK, size detected -> all done */ return mb0cf[i].size; diff --git a/cpu/ppc4xx/sdram.h b/cpu/ppc4xx/sdram.h new file mode 100644 index 0000000..62b5442 --- /dev/null +++ b/cpu/ppc4xx/sdram.h @@ -0,0 +1,78 @@ +/* + * (C) Copyright 2006 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * (C) Copyright 2006 + * DAVE Srl <www.dave-tech.it> + * + * 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 + */ + +#ifndef _SDRAM_H_ +#define _SDRAM_H_ + +#include <config.h> + +#define mtsdram0(reg, data) mtdcr(memcfga,reg);mtdcr(memcfgd,data) + +#define ONE_BILLION 1000000000 + +struct sdram_conf_s { + unsigned long size; + int rows; + unsigned long reg; +}; + +typedef struct sdram_conf_s sdram_conf_t; + +/* Bitfields offsets */ +#define SDRAM0_TR_CASL (31 - 8) +#define SDRAM0_TR_PTA (31 - 13) +#define SDRAM0_TR_CTP (31 - 15) +#define SDRAM0_TR_LDF (31 - 17) +#define SDRAM0_TR_RFTA (31 - 29) +#define SDRAM0_TR_RCD (31 - 31) + +#ifdef CFG_SDRAM_CL +/* SDRAM timings [ns] according to AMCC/IBM names (see SDRAM_faq.doc) */ +#define CFG_SDRAM_CASL CFG_SDRAM_CL +#define CFG_SDRAM_PTA CFG_SDRAM_tRP +#define CFG_SDRAM_CTP (CFG_SDRAM_tRC - CFG_SDRAM_tRCD - CFG_SDRAM_tRP) +#define CFG_SDRAM_LDF 0 +#ifdef CFG_SDRAM_tRFC +#define CFG_SDRAM_RFTA CFG_SDRAM_tRFC +#else +#define CFG_SDRAM_RFTA CFG_SDRAM_tRC +#endif +#define CFG_SDRAM_RCD CFG_SDRAM_tRCD +#endif /* #ifdef CFG_SDRAM_CL */ + +/* + * Some defines for the 440 DDR controller + */ +#define SDRAM_CFG0_DC_EN 0x80000000 /* SDRAM Controller Enable */ +#define SDRAM_CFG0_MEMCHK 0x30000000 /* Memory data error checking mask*/ +#define SDRAM_CFG0_MEMCHK_NON 0x00000000 /* No ECC generation */ +#define SDRAM_CFG0_MEMCHK_GEN 0x20000000 /* ECC generation */ +#define SDRAM_CFG0_MEMCHK_CHK 0x30000000 /* ECC generation and checking */ +#define SDRAM_CFG0_DRAMWDTH 0x02000000 /* DRAM width mask */ +#define SDRAM_CFG0_DRAMWDTH_32 0x00000000 /* 32 bits */ +#define SDRAM_CFG0_DRAMWDTH_64 0x02000000 /* 64 bits */ + +#endif diff --git a/cpu/ppc4xx/serial.c b/cpu/ppc4xx/serial.c index 2734520..3749811 100644 --- a/cpu/ppc4xx/serial.c +++ b/cpu/ppc4xx/serial.c @@ -59,6 +59,8 @@ #include <malloc.h> #endif +DECLARE_GLOBAL_DATA_PTR; + /*****************************************************************************/ #ifdef CONFIG_IOP480 @@ -161,8 +163,6 @@ int serial_init (void) { - DECLARE_GLOBAL_DATA_PTR; - volatile char val; unsigned short br_reg; @@ -185,8 +185,6 @@ int serial_init (void) void serial_setbrg (void) { - DECLARE_GLOBAL_DATA_PTR; - unsigned short br_reg; br_reg = ((((CONFIG_CPUCLOCK * 1000000) / 16) / gd->baudrate) - 1); @@ -435,8 +433,6 @@ int serial_init_dev (unsigned long dev_base) int serial_init(void) #endif { - DECLARE_GLOBAL_DATA_PTR; - unsigned long reg; unsigned long udiv; unsigned short bdiv; @@ -527,8 +523,6 @@ int serial_init_dev (unsigned long dev_base) int serial_init (void) #endif { - DECLARE_GLOBAL_DATA_PTR; - unsigned long reg; unsigned long tmp; unsigned long clk; @@ -604,8 +598,6 @@ void serial_setbrg_dev (unsigned long dev_base) void serial_setbrg (void) #endif { - DECLARE_GLOBAL_DATA_PTR; - unsigned long tmp; unsigned long clk; unsigned long udiv; @@ -907,8 +899,6 @@ int serial_buffered_tstc (void) #if (CONFIG_KGDB_SER_INDEX & 2) void kgdb_serial_init (void) { - DECLARE_GLOBAL_DATA_PTR; - volatile char val; unsigned short br_reg; diff --git a/cpu/ppc4xx/spd_sdram.c b/cpu/ppc4xx/spd_sdram.c index ebd5f39..c0a6933 100644 --- a/cpu/ppc4xx/spd_sdram.c +++ b/cpu/ppc4xx/spd_sdram.c @@ -745,7 +745,7 @@ long int spd_sdram(void) { */ check_volt_type(dimm_populated, iic0_dimm_addr, num_dimm_banks); -#if defined(CONFIG_440GX) +#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP) /* * Soft-reset SDRAM controller. */ diff --git a/cpu/ppc4xx/speed.c b/cpu/ppc4xx/speed.c index 7778271..e552c03 100644 --- a/cpu/ppc4xx/speed.c +++ b/cpu/ppc4xx/speed.c @@ -26,7 +26,7 @@ #include <ppc4xx.h> #include <asm/processor.h> -/* ------------------------------------------------------------------------- */ +DECLARE_GLOBAL_DATA_PTR; #define ONE_BILLION 1000000000 #ifdef DEBUG @@ -772,8 +772,6 @@ ulong get_PCI_freq (void) int get_clocks (void) { #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) || defined(CONFIG_405) || defined(CONFIG_405EP) - DECLARE_GLOBAL_DATA_PTR; - sys_info_t sys_info; get_sys_info (&sys_info); @@ -783,8 +781,6 @@ int get_clocks (void) #endif /* defined(CONFIG_405GP) || defined(CONFIG_405CR) */ #ifdef CONFIG_IOP480 - DECLARE_GLOBAL_DATA_PTR; - gd->cpu_clk = 66000000; gd->bus_clk = 66000000; #endif diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index c1e787f..f37c1d6 100644 --- a/cpu/ppc4xx/start.S +++ b/cpu/ppc4xx/start.S @@ -383,23 +383,6 @@ _start: mtspr tcr,r0 /* disable all */ mtspr esr,r0 /* clear exception syndrome register */ mtxer r0 /* clear integer exception register */ -#if !defined(CONFIG_440GX) && !defined(CONFIG_440SPE) - lis r1,0x0002 /* set CE bit (Critical Exceptions) */ - ori r1,r1,0x1000 /* set ME bit (Machine Exceptions) */ - mtmsr r1 /* change MSR */ -#elif !defined(CONFIG_440EP) && !defined(CONFIG_440GR) - bl __440gx_msr_set - b __440gx_msr_continue - -__440gx_msr_set: - lis r1, 0x0002 /* set CE bit (Critical Exceptions) */ - ori r1,r1,0x1000 /* set ME bit (Machine Exceptions) */ - mtspr srr1,r1 - mflr r1 - mtspr srr0,r1 - rfi -__440gx_msr_continue: -#endif /*----------------------------------------------------------------*/ /* Debug setup -- some (not very good) ice's need an event*/ @@ -514,9 +497,6 @@ __440gx_msr_continue: mtspr esr,r0 /* clear Exception Syndrome Reg */ mttcr r0 /* timer control register */ mtexier r0 /* disable all interrupts */ - addi r4,r0,0x1000 /* set ME bit (Machine Exceptions) */ - oris r4,r4,0x2 /* set CE bit (Critical Exceptions) */ - mtmsr r4 /* change MSR */ addis r4,r0,0xFFFF /* set r4 to 0xFFFFFFFF (status in the */ ori r4,r4,0xFFFF /* dbsr is cleared by setting bits to 1) */ mtdbsr r4 /* clear/reset the dbsr */ @@ -627,9 +607,6 @@ __440gx_msr_continue: mttcr r4 /* clear Timer Control Reg */ mtxer r4 /* clear Fixed-Point Exception Reg */ mtevpr r4 /* clear Exception Vector Prefix Reg */ - addi r4,r0,0x1000 /* set ME bit (Machine Exceptions) */ - oris r4,r4,0x0002 /* set CE bit (Critical Exceptions) */ - mtmsr r4 /* change MSR */ addi r4,r0,(0xFFFF-0x10000) /* set r4 to 0xFFFFFFFF (status in the */ /* dbsr is cleared by setting bits to 1) */ mtdbsr r4 /* clear/reset the dbsr */ @@ -1277,12 +1254,19 @@ ppcSync: .globl relocate_code relocate_code: #if defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SPE) - dccci 0,0 /* Invalidate data cache, now no longer our stack */ + /* + * On some 440er platforms the cache is enabled in the first TLB (Boot-CS) + * to speed up the boot process. Now this cache needs to be disabled. + */ + iccci 0,0 /* Invalidate inst cache */ + dccci 0,0 /* Invalidate data cache, now no longer our stack */ sync + isync addi r1,r0,0x0000 /* TLB entry #0 */ 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 mr r1, r3 /* Set new stack pointer */ @@ -1484,6 +1468,24 @@ trap_init: cmplw 0, r7, r8 blt 4b +#if !defined(CONFIG_440_GX) && !defined(CONFIG_440SPE) + addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */ + oris r7,r7,0x0002 /* set CE bit (Critical Exceptions) */ + mtmsr r7 /* change MSR */ +#else + bl __440gx_msr_set + b __440gx_msr_continue + +__440gx_msr_set: + addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */ + oris r7,r7,0x0002 /* set CE bit (Critical Exceptions) */ + mtspr srr1,r7 + mflr r7 + mtspr srr0,r7 + rfi +__440gx_msr_continue: +#endif + mtlr r4 /* restore link register */ blr |