[U-Boot-Users] [PATCH 1/9] rtc: Add M41T62 support

This patch add support for the STM M41T62 RTC. It is used and tested on the AMCC Canyonlands 406EX platform.
Signed-off-by: Stefan Roese sr@denx.de --- drivers/rtc/Makefile | 1 + drivers/rtc/m41t62.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+), 0 deletions(-) create mode 100644 drivers/rtc/m41t62.c
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 2af2bf4..17c0f86 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -41,6 +41,7 @@ COBJS-y += ds174x.o COBJS-y += ds3231.o COBJS-y += m41t11.o COBJS-y += m41t60.o +COBJS-y += m41t62.o COBJS-y += max6900.o COBJS-y += m48t35ax.o COBJS-y += mc146818.o diff --git a/drivers/rtc/m41t62.c b/drivers/rtc/m41t62.c new file mode 100644 index 0000000..002ebba --- /dev/null +++ b/drivers/rtc/m41t62.c @@ -0,0 +1,135 @@ +/* + * (C) Copyright 2008 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * based on a the Linux rtc-m41t80.c driver which is: + * Alexander Bigga ab@mycable.de, 2006 (c) mycable GmbH + * + * 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 + */ + +/* + * Date & Time support for STMicroelectronics M41T62 + */ + +/* #define DEBUG */ + +#include <common.h> +#include <command.h> +#include <rtc.h> +#include <i2c.h> +#include <bcd.h> + +#if defined(CONFIG_RTC_M41T62) && defined(CONFIG_CMD_DATE) + +#define M41T62_REG_SSEC 0 +#define M41T62_REG_SEC 1 +#define M41T62_REG_MIN 2 +#define M41T62_REG_HOUR 3 +#define M41T62_REG_WDAY 4 +#define M41T62_REG_DAY 5 +#define M41T62_REG_MON 6 +#define M41T62_REG_YEAR 7 +#define M41T62_REG_ALARM_MON 0xa +#define M41T62_REG_ALARM_DAY 0xb +#define M41T62_REG_ALARM_HOUR 0xc +#define M41T62_REG_ALARM_MIN 0xd +#define M41T62_REG_ALARM_SEC 0xe +#define M41T62_REG_FLAGS 0xf + +#define M41T62_DATETIME_REG_SIZE (M41T62_REG_YEAR + 1) +#define M41T62_ALARM_REG_SIZE \ + (M41T62_REG_ALARM_SEC + 1 - M41T62_REG_ALARM_MON) + +#define M41T62_SEC_ST (1 << 7) /* ST: Stop Bit */ +#define M41T62_ALMON_AFE (1 << 7) /* AFE: AF Enable Bit */ +#define M41T62_ALMON_SQWE (1 << 6) /* SQWE: SQW Enable Bit */ +#define M41T62_ALHOUR_HT (1 << 6) /* HT: Halt Update Bit */ +#define M41T62_FLAGS_AF (1 << 6) /* AF: Alarm Flag Bit */ +#define M41T62_FLAGS_BATT_LOW (1 << 4) /* BL: Battery Low Bit */ + +#define M41T62_FEATURE_HT (1 << 0) +#define M41T62_FEATURE_BL (1 << 1) + +void rtc_get(struct rtc_time *tm) +{ + u8 buf[M41T62_DATETIME_REG_SIZE]; + + i2c_read(CFG_I2C_RTC_ADDR, 0, 1, buf, M41T62_DATETIME_REG_SIZE); + + debug("%s: raw read data - sec=%02x, min=%02x, hr=%02x, " + "mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n", + __FUNCTION__, + buf[0], buf[1], buf[2], buf[3], + buf[4], buf[5], buf[6], buf[7]); + + tm->tm_sec = BCD2BIN(buf[M41T62_REG_SEC] & 0x7f); + tm->tm_min = BCD2BIN(buf[M41T62_REG_MIN] & 0x7f); + tm->tm_hour = BCD2BIN(buf[M41T62_REG_HOUR] & 0x3f); + tm->tm_mday = BCD2BIN(buf[M41T62_REG_DAY] & 0x3f); + tm->tm_wday = buf[M41T62_REG_WDAY] & 0x07; + tm->tm_mon = BCD2BIN(buf[M41T62_REG_MON] & 0x1f) - 1; + + /* assume 20YY not 19YY, and ignore the Century Bit */ + /* U-Boot needs to add 1900 here */ + tm->tm_year = BCD2BIN(buf[M41T62_REG_YEAR]) + 100 + 1900; + + debug("%s: tm is secs=%d, mins=%d, hours=%d, " + "mday=%d, mon=%d, year=%d, wday=%d\n", + __FUNCTION__, + tm->tm_sec, tm->tm_min, tm->tm_hour, + tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); +} + +void rtc_set(struct rtc_time *tm) +{ + u8 buf[M41T62_DATETIME_REG_SIZE]; + + debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, + tm->tm_hour, tm->tm_min, tm->tm_sec); + + i2c_read(CFG_I2C_RTC_ADDR, 0, 1, buf, M41T62_DATETIME_REG_SIZE); + + /* Merge time-data and register flags into buf[0..7] */ + buf[M41T62_REG_SSEC] = 0; + buf[M41T62_REG_SEC] = + BIN2BCD(tm->tm_sec) | (buf[M41T62_REG_SEC] & ~0x7f); + buf[M41T62_REG_MIN] = + BIN2BCD(tm->tm_min) | (buf[M41T62_REG_MIN] & ~0x7f); + buf[M41T62_REG_HOUR] = + BIN2BCD(tm->tm_hour) | (buf[M41T62_REG_HOUR] & ~0x3f) ; + buf[M41T62_REG_WDAY] = + (tm->tm_wday & 0x07) | (buf[M41T62_REG_WDAY] & ~0x07); + buf[M41T62_REG_DAY] = + BIN2BCD(tm->tm_mday) | (buf[M41T62_REG_DAY] & ~0x3f); + buf[M41T62_REG_MON] = + BIN2BCD(tm->tm_mon + 1) | (buf[M41T62_REG_MON] & ~0x1f); + /* assume 20YY not 19YY */ + buf[M41T62_REG_YEAR] = BIN2BCD(tm->tm_year % 100); + + if (i2c_write(CFG_I2C_RTC_ADDR, 0, 1, buf, M41T62_DATETIME_REG_SIZE)) + printf("I2C write failed in %s()\n", __func__); +} + +void rtc_reset(void) +{ + /* + * Nothing to do + */ +} + +#endif

While adding the 460EX/GT support I reworked the 4xx miiphy code. It badly neede some cleanup.
Signed-off-by: Stefan Roese sr@denx.de --- cpu/ppc4xx/miiphy.c | 196 +++++++++++++++++++++------------------------------ 1 files changed, 80 insertions(+), 116 deletions(-)
diff --git a/cpu/ppc4xx/miiphy.c b/cpu/ppc4xx/miiphy.c index 3978773..c882720 100644 --- a/cpu/ppc4xx/miiphy.c +++ b/cpu/ppc4xx/miiphy.c @@ -29,6 +29,11 @@ | +-----------------------------------------------------------------------------*/
+/* define DEBUG for debugging output (obviously ;-)) */ +#if 0 +#define DEBUG +#endif + #include <common.h> #include <asm/processor.h> #include <asm/io.h> @@ -38,7 +43,10 @@ #include <405_mal.h> #include <miiphy.h>
-#undef ET_DEBUG +#if !defined(CONFIG_PHY_CLK_FREQ) +#define CONFIG_PHY_CLK_FREQ 0 +#endif + /***********************************************************/ /* Dump out to the screen PHY regs */ /***********************************************************/ @@ -164,9 +172,21 @@ int phy_setup_aneg (char *devname, unsigned char addr) /***********************************************************/ /* read a phy reg and return the value with a rc */ /***********************************************************/ +/* AMCC_TODO: + * Find out of the choice for the emac for MDIO is from the bridges, + * i.e. ZMII or RGMII as approporiate. If the bridges are not used + * to determine the emac for MDIO, then is the SDR0_ETH_CFG[MDIO_SEL] + * used? If so, then this routine below does not apply to the 460EX/GT. + * + * sr: Currently on 460EX only EMAC0 works with MDIO, so we always + * return EMAC0 offset here + */ unsigned int miiphy_getemac_offset (void) { -#if (defined(CONFIG_440) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE)) && defined(CONFIG_NET_MULTI) +#if (defined(CONFIG_440) && \ + !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \ + !defined(CONFIG_460EX) && !defined(CONFIG_460GT)) && \ + defined(CONFIG_NET_MULTI) unsigned long zmii; unsigned long eoffset;
@@ -217,153 +237,97 @@ unsigned int miiphy_getemac_offset (void) #endif }
-int emac4xx_miiphy_read (char *devname, unsigned char addr, unsigned char reg, - unsigned short *value) +static int emac_miiphy_wait(u32 emac_reg) { - unsigned long sta_reg; /* STA scratch area */ - unsigned long i; - unsigned long emac_reg; + u32 sta_reg; + int i;
- emac_reg = miiphy_getemac_offset (); - /* see if it is ready for 1000 nsec */ + /* wait for completion */ i = 0; - - /* see if it is ready for sec */ - while ((in_be32((void *)EMAC_STACR + emac_reg) & EMAC_STACR_OC) == - EMAC_STACR_OC_MASK) { - udelay (7); - if (i > 5) { -#ifdef ET_DEBUG - sta_reg = in_be32((void *)EMAC_STACR + emac_reg); - printf ("read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */ - printf ("read err 1\n"); -#endif + do { + sta_reg = in_be32((void *)EMAC_STACR + emac_reg); + if (i++ > 5) { + debug("%s [%d]: Timeout! EMAC_STACR=0x%0x\n", __func__, + __LINE__, sta_reg); return -1; } - i++; - } + udelay(10); + } while ((sta_reg & EMAC_STACR_OC) == EMAC_STACR_OC_MASK); + + return 0; +} + +static int emac_miiphy_command(u8 addr, u8 reg, int cmd, u16 value) +{ + u32 emac_reg; + u32 sta_reg; + + emac_reg = miiphy_getemac_offset(); + + /* wait for completion */ + if (emac_miiphy_wait(emac_reg) != 0) + return -1; + sta_reg = reg; /* reg address */ + /* set clock (50Mhz) and read flags */ #if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ defined(CONFIG_405EX) #if defined(CONFIG_IBM_EMAC4_V4) /* EMAC4 V4 changed bit setting */ - sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_READ; + sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | cmd; #else - sta_reg |= EMAC_STACR_READ; + sta_reg |= cmd; #endif #else - sta_reg = (sta_reg | EMAC_STACR_READ) & ~EMAC_STACR_CLK_100MHZ; + sta_reg = (sta_reg | cmd) & ~EMAC_STACR_CLK_100MHZ; #endif
-#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && \ - !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \ - !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX) && \ - !defined(CONFIG_405EX) + /* Some boards (mainly 405EP based) define the PHY clock freqency fixed */ sta_reg = sta_reg | CONFIG_PHY_CLK_FREQ; -#endif - sta_reg = sta_reg | (addr << 5); /* Phy address */ + sta_reg = sta_reg | ((u32)addr << 5); /* Phy address */ sta_reg = sta_reg | EMAC_STACR_OC_MASK; /* new IBM emac v4 */ + if (cmd == EMAC_STACR_WRITE) + memcpy(&sta_reg, &value, 2); /* put in data */ + out_be32((void *)EMAC_STACR + emac_reg, sta_reg); -#ifdef ET_DEBUG - printf ("a2: write: EMAC_STACR=0x%0x\n", sta_reg); /* test-only */ -#endif + debug("%s [%d]: sta_reg=%08x\n", __func__, __LINE__, sta_reg);
- sta_reg = in_be32((void *)EMAC_STACR + emac_reg); -#ifdef ET_DEBUG - printf ("a21: read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */ -#endif - i = 0; - while ((sta_reg & EMAC_STACR_OC) == EMAC_STACR_OC_MASK) { - udelay (7); - if (i > 5) - return -1; + /* wait for completion */ + if (emac_miiphy_wait(emac_reg) != 0) + return -1;
- i++; - sta_reg = in_be32((void *)EMAC_STACR + emac_reg); -#ifdef ET_DEBUG - printf ("a22: read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */ -#endif - } + debug("%s [%d]: sta_reg=%08x\n", __func__, __LINE__, sta_reg); if ((sta_reg & EMAC_STACR_PHYE) != 0) return -1;
- *value = *(short *)(&sta_reg); return 0; +}
-} /* phy_read */ - -/***********************************************************/ -/* write a phy reg and return the value with a rc */ -/***********************************************************/ - -int emac4xx_miiphy_write (char *devname, unsigned char addr, unsigned char reg, - unsigned short value) +int emac4xx_miiphy_read (char *devname, unsigned char addr, unsigned char reg, + unsigned short *value) { - unsigned long sta_reg; /* STA scratch area */ - unsigned long i; + unsigned long sta_reg; unsigned long emac_reg;
emac_reg = miiphy_getemac_offset (); - /* see if it is ready for 1000 nsec */ - i = 0; - - while ((in_be32((void *)EMAC_STACR + emac_reg) & EMAC_STACR_OC) == - EMAC_STACR_OC_MASK) { - if (i > 5) - return -1; - - udelay (7); - i++; - } - sta_reg = 0; - sta_reg = reg; /* reg address */ - /* set clock (50Mhz) and read flags */ -#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_405EX) -#if defined(CONFIG_IBM_EMAC4_V4) /* EMAC4 V4 changed bit setting */ - sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_WRITE; -#else - sta_reg |= EMAC_STACR_WRITE; -#endif -#else - sta_reg = (sta_reg | EMAC_STACR_WRITE) & ~EMAC_STACR_CLK_100MHZ; -#endif - -#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && \ - !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \ - !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX) && \ - !defined(CONFIG_405EX) - sta_reg = sta_reg | CONFIG_PHY_CLK_FREQ; /* Set clock frequency (PLB freq. dependend) */ -#endif - sta_reg = sta_reg | ((unsigned long)addr << 5); /* Phy address */ - sta_reg = sta_reg | EMAC_STACR_OC_MASK; /* new IBM emac v4 */ - memcpy (&sta_reg, &value, 2); /* put in data */
- out_be32((void *)EMAC_STACR + emac_reg, sta_reg); + if (emac_miiphy_command(addr, reg, EMAC_STACR_READ, 0) != 0) + return -1;
- /* wait for completion */ - i = 0; sta_reg = in_be32((void *)EMAC_STACR + emac_reg); -#ifdef ET_DEBUG - printf ("a31: read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */ -#endif - while ((sta_reg & EMAC_STACR_OC) == EMAC_STACR_OC_MASK) { - udelay (7); - if (i > 5) - return -1; - - i++; - sta_reg = in_be32((void *)EMAC_STACR + emac_reg); -#ifdef ET_DEBUG - printf ("a32: read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */ -#endif - } - - if ((sta_reg & EMAC_STACR_PHYE) != 0) - return -1; + *value = *(u16 *)(&sta_reg);
return 0; +}
-} /* phy_write */ +/***********************************************************/ +/* write a phy reg and return the value with a rc */ +/***********************************************************/ + +int emac4xx_miiphy_write (char *devname, unsigned char addr, unsigned char reg, + unsigned short value) +{ + return emac_miiphy_command(addr, reg, EMAC_STACR_WRITE, value); +}

This patch changes the physical addess parameter from 32bit to 64bit. This is needed for 36bit 4xx platforms to access areas located beyond the 4GB border, like SoC peripherals (EBC etc.).
Signed-off-by: Stefan Roese sr@denx.de --- board/netstal/hcu5/sdram.c | 2 -- cpu/ppc4xx/tlb.c | 27 ++++++++++++++------------- include/asm-ppc/mmu.h | 18 +++++++++--------- post/cpu/ppc4xx/cache.c | 2 -- 4 files changed, 23 insertions(+), 26 deletions(-)
diff --git a/board/netstal/hcu5/sdram.c b/board/netstal/hcu5/sdram.c index d3c2233..0b16b50 100644 --- a/board/netstal/hcu5/sdram.c +++ b/board/netstal/hcu5/sdram.c @@ -70,8 +70,6 @@ void dflush(void); #define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE /* disable caching on DDR2 */
-void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value); - void board_add_ram_info(int use_default) { PPC4xx_SYS_INFO board_cfg; diff --git a/cpu/ppc4xx/tlb.c b/cpu/ppc4xx/tlb.c index ed493f1..2bfcba1 100644 --- a/cpu/ppc4xx/tlb.c +++ b/cpu/ppc4xx/tlb.c @@ -31,9 +31,9 @@ #include <asm/mmu.h>
typedef struct region { - unsigned long base; - unsigned long size; - unsigned long tlb_word2_i_value; + u64 base; + u32 size; + u32 tlb_word2_i_value; } region_t;
void remove_tlb(u32 vaddr, u32 size) @@ -182,10 +182,10 @@ void change_tlb(u32 vaddr, u32 size, u32 tlb_word2_i_value) asm("isync"); }
-static int add_tlb_entry(unsigned long phys_addr, - unsigned long virt_addr, - unsigned long tlb_word0_size_value, - unsigned long tlb_word2_i_value) +static int add_tlb_entry(u64 phys_addr, + u32 virt_addr, + u32 tlb_word0_size_value, + u32 tlb_word2_i_value) { int i; unsigned long tlb_word0_value; @@ -204,7 +204,8 @@ static int add_tlb_entry(unsigned long phys_addr, /* Second, create the TLB entry */ tlb_word0_value = TLB_WORD0_EPN_ENCODE(virt_addr) | TLB_WORD0_V_ENABLE | TLB_WORD0_TS_0 | tlb_word0_size_value; - tlb_word1_value = TLB_WORD1_RPN_ENCODE(phys_addr) | TLB_WORD1_ERPN_ENCODE(0); + tlb_word1_value = TLB_WORD1_RPN_ENCODE((u32)phys_addr) | + TLB_WORD1_ERPN_ENCODE(phys_addr >> 32); tlb_word2_value = TLB_WORD2_U0_DISABLE | TLB_WORD2_U1_DISABLE | TLB_WORD2_U2_DISABLE | TLB_WORD2_U3_DISABLE | TLB_WORD2_W_DISABLE | tlb_word2_i_value | @@ -228,10 +229,10 @@ static int add_tlb_entry(unsigned long phys_addr, return 0; }
-static void program_tlb_addr(unsigned long phys_addr, - unsigned long virt_addr, - unsigned long mem_size, - unsigned long tlb_word2_i_value) +static void program_tlb_addr(u64 phys_addr, + u32 virt_addr, + u32 mem_size, + u32 tlb_word2_i_value) { int rc; int tlb_i; @@ -331,7 +332,7 @@ static void program_tlb_addr(unsigned long phys_addr, * Common usage for boards with SDRAM DIMM modules to dynamically * configure the TLB's for the SDRAM */ -void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value) +void program_tlb(u64 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value) { region_t region_array;
diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h index 5af22af..49d6860 100644 --- a/include/asm-ppc/mmu.h +++ b/include/asm-ppc/mmu.h @@ -549,14 +549,14 @@ extern int num_tlb_entries; /*----------------------------------------------------------------------------+ | TLB specific defines. +----------------------------------------------------------------------------*/ -#define TLB_256MB_ALIGN_MASK 0xF0000000 -#define TLB_16MB_ALIGN_MASK 0xFF000000 -#define TLB_1MB_ALIGN_MASK 0xFFF00000 -#define TLB_256KB_ALIGN_MASK 0xFFFC0000 -#define TLB_64KB_ALIGN_MASK 0xFFFF0000 -#define TLB_16KB_ALIGN_MASK 0xFFFFC000 -#define TLB_4KB_ALIGN_MASK 0xFFFFF000 -#define TLB_1KB_ALIGN_MASK 0xFFFFFC00 +#define TLB_256MB_ALIGN_MASK 0xFF0000000ULL +#define TLB_16MB_ALIGN_MASK 0xFFF000000ULL +#define TLB_1MB_ALIGN_MASK 0xFFFF00000ULL +#define TLB_256KB_ALIGN_MASK 0xFFFFC0000ULL +#define TLB_64KB_ALIGN_MASK 0xFFFFF0000ULL +#define TLB_16KB_ALIGN_MASK 0xFFFFFC000ULL +#define TLB_4KB_ALIGN_MASK 0xFFFFFF000ULL +#define TLB_1KB_ALIGN_MASK 0xFFFFFFC00ULL #define TLB_256MB_SIZE 0x10000000 #define TLB_16MB_SIZE 0x01000000 #define TLB_1MB_SIZE 0x00100000 @@ -697,7 +697,7 @@ unsigned long mftlb1(unsigned long index); unsigned long mftlb2(unsigned long index); unsigned long mftlb3(unsigned long index);
-void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value); +void program_tlb(u64 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value); void remove_tlb(u32 vaddr, u32 size); void change_tlb(u32 vaddr, u32 size, u32 tlb_word2_i_value); #endif /* __ASSEMBLY__ */ diff --git a/post/cpu/ppc4xx/cache.c b/post/cpu/ppc4xx/cache.c index c86a150..466ca92 100644 --- a/post/cpu/ppc4xx/cache.c +++ b/post/cpu/ppc4xx/cache.c @@ -42,8 +42,6 @@
#define CACHE_POST_SIZE 1024
-void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value); - int cache_post_test1 (int tlb, void *p, int size); int cache_post_test2 (int tlb, void *p, int size); int cache_post_test3 (int tlb, void *p, int size);

This patch is a rework of the 4xx interrupt handling done while adding the 460EX/GT support. Interrupts are needed on 4xx for the EMAC driver.
Signed-off-by: Stefan Roese sr@denx.de --- cpu/ppc4xx/interrupts.c | 589 +++++++++++----------------------------------- 1 files changed, 141 insertions(+), 448 deletions(-)
diff --git a/cpu/ppc4xx/interrupts.c b/cpu/ppc4xx/interrupts.c index 2f3dc32..698bcb5 100644 --- a/cpu/ppc4xx/interrupts.c +++ b/cpu/ppc4xx/interrupts.c @@ -38,7 +38,22 @@
DECLARE_GLOBAL_DATA_PTR;
-/****************************************************************************/ +/* + * Define the number of UIC's + */ +#if defined(CONFIG_440SPE) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) +#define UIC_MAX 4 +#elif defined(CONFIG_440GX) || \ + defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ + defined(CONFIG_405EX) +#define UIC_MAX 3 +#elif defined(CONFIG_440GP) || defined(CONFIG_440SP) || \ + defined(CONFIG_440EP) || defined(CONFIG_440GR) +#define UIC_MAX 2 +#else +#define UIC_MAX 1 +#endif
/* * CPM interrupt vector functions. @@ -49,28 +64,15 @@ struct irq_action { int count; };
-static struct irq_action irq_vecs[32]; -void uic0_interrupt( void * parms); /* UIC0 handler */ +static struct irq_action irq_vecs[UIC_MAX * 32];
-#if defined(CONFIG_440) || defined(CONFIG_405EX) -static struct irq_action irq_vecs1[32]; /* For UIC1 */ +u32 get_dcr(u16); +void set_dcr(u16, u32);
-void uic1_interrupt( void * parms); /* UIC1 handler */ - -#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) -static struct irq_action irq_vecs2[32]; /* For UIC2 */ -void uic2_interrupt( void * parms); /* UIC2 handler */ -#endif /* CONFIG_440GX CONFIG_440SPE */ - -#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX) -static struct irq_action irq_vecs3[32]; /* For UIC3 */ -void uic3_interrupt( void * parms); /* UIC3 handler */ -#endif /* CONFIG_440SPE */ - -#endif /* CONFIG_440 */ +#if (UIC_MAX > 1) && !defined(CONFIG_440GX) +static void uic_cascade_interrupt(void *para); +#endif
-/****************************************************************************/ #if defined(CONFIG_440)
/* SPRN changed in 440 */ @@ -99,8 +101,6 @@ static __inline__ void set_evpr(unsigned long val) } #endif /* defined(CONFIG_440 */
-/****************************************************************************/ - int interrupt_init_cpu (unsigned *decrementer_count) { int vec; @@ -112,26 +112,10 @@ int interrupt_init_cpu (unsigned *decrementer_count) /* * Mark all irqs as free */ - for (vec=0; vec<32; vec++) { + for (vec = 0; vec < (UIC_MAX * 32); vec++) { irq_vecs[vec].handler = NULL; irq_vecs[vec].arg = NULL; irq_vecs[vec].count = 0; -#if defined(CONFIG_440) || defined(CONFIG_405EX) - irq_vecs1[vec].handler = NULL; - irq_vecs1[vec].arg = NULL; - irq_vecs1[vec].count = 0; -#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) - irq_vecs2[vec].handler = NULL; - irq_vecs2[vec].arg = NULL; - irq_vecs2[vec].count = 0; -#endif /* CONFIG_440GX */ -#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX) - irq_vecs3[vec].handler = NULL; - irq_vecs3[vec].arg = NULL; - irq_vecs3[vec].count = 0; -#endif /* CONFIG_440SPE */ -#endif }
#ifdef CONFIG_4xx @@ -172,15 +156,21 @@ int interrupt_init_cpu (unsigned *decrementer_count) */ set_evpr(0x00000000);
-#if defined(CONFIG_440) || defined(CONFIG_405EX) #if !defined(CONFIG_440GX) +#if (UIC_MAX > 1) /* Install the UIC1 handlers */ - irq_install_handler(VECNUM_UIC1NC, uic1_interrupt, 0); - irq_install_handler(VECNUM_UIC1C, uic1_interrupt, 0); + irq_install_handler(VECNUM_UIC1NC, uic_cascade_interrupt, 0); + irq_install_handler(VECNUM_UIC1C, uic_cascade_interrupt, 0); #endif +#if (UIC_MAX > 2) + irq_install_handler(VECNUM_UIC2NC, uic_cascade_interrupt, 0); + irq_install_handler(VECNUM_UIC2C, uic_cascade_interrupt, 0); #endif - -#if defined(CONFIG_440GX) +#if (UIC_MAX > 3) + irq_install_handler(VECNUM_UIC3NC, uic_cascade_interrupt, 0); + irq_install_handler(VECNUM_UIC3C, uic_cascade_interrupt, 0); +#endif +#else /* !defined(CONFIG_440GX) */ /* Take the GX out of compatibility mode * Travis Sawyer, 9 Mar 2004 * NOTE: 440gx user manual inconsistency here @@ -196,110 +186,24 @@ int interrupt_init_cpu (unsigned *decrementer_count) mtdcr(uicb0er, 0x54000000); /* None are critical */ mtdcr(uicb0cr, 0); -#endif +#endif /* !defined(CONFIG_440GX) */
return (0); }
-/****************************************************************************/ - -/* - * Handle external interrupts - */ -#if defined(CONFIG_440GX) -void external_interrupt(struct pt_regs *regs) +/* Handler for UIC interrupt */ +static void uic_interrupt(u32 uic_base, int vec_base) { - ulong uic_msr; - - /* - * Read masked interrupt status register to determine interrupt source - */ - /* 440 GX uses base uic register */ - uic_msr = mfdcr(uicb0msr); - - if ( (UICB0_UIC0CI & uic_msr) || (UICB0_UIC0NCI & uic_msr) ) - uic0_interrupt(0); - - if ( (UICB0_UIC1CI & uic_msr) || (UICB0_UIC1NCI & uic_msr) ) - uic1_interrupt(0); - - if ( (UICB0_UIC2CI & uic_msr) || (UICB0_UIC2NCI & uic_msr) ) - uic2_interrupt(0); - - mtdcr(uicb0sr, uic_msr); - - return; - -} /* external_interrupt CONFIG_440GX */ - -#elif defined(CONFIG_440EPX) || defined(CONFIG_440GRX) -void external_interrupt(struct pt_regs *regs) -{ - ulong uic_msr; - - /* - * Read masked interrupt status register to determine interrupt source - */ - /* 440 SPe uses base uic register */ - uic_msr = mfdcr(uic0msr); - - if ( (UICB0_UIC1CI & uic_msr) || (UICB0_UIC1NCI & uic_msr) ) - uic1_interrupt(0); - - if ( (UICB0_UIC2CI & uic_msr) || (UICB0_UIC2NCI & uic_msr) ) - uic2_interrupt(0); - - if (uic_msr & ~(UICB0_ALL)) - uic0_interrupt(0); - - mtdcr(uic0sr, uic_msr); - - return; - -} /* external_interrupt CONFIG_440EPX & CONFIG_440GRX */ - -#elif defined(CONFIG_440SPE) -void external_interrupt(struct pt_regs *regs) -{ - ulong uic_msr; - - /* - * Read masked interrupt status register to determine interrupt source - */ - /* 440 SPe uses base uic register */ - uic_msr = mfdcr(uic0msr); - - if ( (UICB0_UIC1CI & uic_msr) || (UICB0_UIC1NCI & uic_msr) ) - uic1_interrupt(0); - - if ( (UICB0_UIC2CI & uic_msr) || (UICB0_UIC2NCI & uic_msr) ) - uic2_interrupt(0); - - if ( (UICB0_UIC3CI & uic_msr) || (UICB0_UIC3NCI & uic_msr) ) - uic3_interrupt(0); - - if (uic_msr & ~(UICB0_ALL)) - uic0_interrupt(0); - - mtdcr(uic0sr, uic_msr); - - return; -} /* external_interrupt CONFIG_440SPE */ - -#else - -void external_interrupt(struct pt_regs *regs) -{ - ulong uic_msr; - ulong msr_shift; + u32 uic_msr; + u32 msr_shift; int vec;
/* * Read masked interrupt status register to determine interrupt source */ - uic_msr = mfdcr(uicmsr); + uic_msr = get_dcr(uic_base + UIC_MSR); msr_shift = uic_msr; - vec = 0; + vec = vec_base;
while (msr_shift != 0) { if (msr_shift & 0x80000000) { @@ -312,14 +216,17 @@ void external_interrupt(struct pt_regs *regs) /* call isr */ (*irq_vecs[vec].handler)(irq_vecs[vec].arg); } else { - mtdcr(uicer, mfdcr(uicer) & ~(0x80000000 >> vec)); - printf ("Masking bogus interrupt vector 0x%x\n", vec); + set_dcr(uic_base + UIC_ER, + get_dcr(uic_base + UIC_ER) & + ~(0x80000000 >> vec)); + printf("Masking bogus interrupt vector %d" + " (UIC_BASE=0x%x)\n", vec, uic_base); }
/* * After servicing the interrupt, we have to remove the status indicator. */ - mtdcr(uicsr, (0x80000000 >> vec)); + set_dcr(uic_base + UIC_SR, (0x80000000 >> vec)); }
/* @@ -329,324 +236,150 @@ void external_interrupt(struct pt_regs *regs) vec++; } } -#endif
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) -/* Handler for UIC0 interrupt */ -void uic0_interrupt( void * parms) +#if (UIC_MAX > 1) && !defined(CONFIG_440GX) +static void uic_cascade_interrupt(void *para) { - ulong uic_msr; - ulong msr_shift; - int vec; - - /* - * Read masked interrupt status register to determine interrupt source - */ - uic_msr = mfdcr(uicmsr); - msr_shift = uic_msr; - vec = 0; - - while (msr_shift != 0) { - if (msr_shift & 0x80000000) { - /* - * Increment irq counter (for debug purpose only) - */ - irq_vecs[vec].count++; - - if (irq_vecs[vec].handler != NULL) { - /* call isr */ - (*irq_vecs[vec].handler)(irq_vecs[vec].arg); - } else { - mtdcr(uicer, mfdcr(uicer) & ~(0x80000000 >> vec)); - printf ("Masking bogus interrupt vector (uic0) 0x%x\n", vec); - } - - /* - * After servicing the interrupt, we have to remove the status indicator. - */ - mtdcr(uicsr, (0x80000000 >> vec)); - } - - /* - * Shift msr to next position and increment vector - */ - msr_shift <<= 1; - vec++; - } + external_interrupt(para); } +#endif
-#endif /* CONFIG_440GX */ - -#if defined(CONFIG_440) || defined(CONFIG_405EX) -/* Handler for UIC1 interrupt */ -void uic1_interrupt( void * parms) -{ - ulong uic1_msr; - ulong msr_shift; - int vec; - - /* - * Read masked interrupt status register to determine interrupt source - */ - uic1_msr = mfdcr(uic1msr); - msr_shift = uic1_msr; - vec = 0; - - while (msr_shift != 0) { - if (msr_shift & 0x80000000) { - /* - * Increment irq counter (for debug purpose only) - */ - irq_vecs1[vec].count++; - - if (irq_vecs1[vec].handler != NULL) { - /* call isr */ - (*irq_vecs1[vec].handler)(irq_vecs1[vec].arg); - } else { - mtdcr(uic1er, mfdcr(uic1er) & ~(0x80000000 >> vec)); - printf ("Masking bogus interrupt vector (uic1) 0x%x\n", vec); - } - - /* - * After servicing the interrupt, we have to remove the status indicator. - */ - mtdcr(uic1sr, (0x80000000 >> vec)); - } - - /* - * Shift msr to next position and increment vector - */ - msr_shift <<= 1; - vec++; - } -} -#endif /* defined(CONFIG_440) */ +#if defined(CONFIG_440) +#if defined(CONFIG_440GX) +/* 440GX uses base uic register */ +#define UIC_BMSR uicb0msr +#define UIC_BSR uicb0sr +#else +#define UIC_BMSR uic0msr +#define UIC_BSR uic0sr +#endif +#else /* CONFIG_440 */ +#define UIC_BMSR uicmsr +#define UIC_BSR uicsr +#endif /* CONFIG_440 */
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) -/* Handler for UIC2 interrupt */ -void uic2_interrupt( void * parms) +/* + * Handle external interrupts + */ +void external_interrupt(struct pt_regs *regs) { - ulong uic2_msr; - ulong msr_shift; - int vec; + u32 uic_msr;
/* * Read masked interrupt status register to determine interrupt source */ - uic2_msr = mfdcr(uic2msr); - msr_shift = uic2_msr; - vec = 0; + uic_msr = mfdcr(UIC_BMSR);
- while (msr_shift != 0) { - if (msr_shift & 0x80000000) { - /* - * Increment irq counter (for debug purpose only) - */ - irq_vecs2[vec].count++; - - if (irq_vecs2[vec].handler != NULL) { - /* call isr */ - (*irq_vecs2[vec].handler)(irq_vecs2[vec].arg); - } else { - mtdcr(uic2er, mfdcr(uic2er) & ~(0x80000000 >> vec)); - printf ("Masking bogus interrupt vector (uic2) 0x%x\n", vec); - } - - /* - * After servicing the interrupt, we have to remove the status indicator. - */ - mtdcr(uic2sr, (0x80000000 >> vec)); - } - - /* - * Shift msr to next position and increment vector - */ - msr_shift <<= 1; - vec++; - } -} -#endif /* defined(CONFIG_440GX) */ - -#if defined(CONFIG_440SPE) -/* Handler for UIC3 interrupt */ -void uic3_interrupt( void * parms) -{ - ulong uic3_msr; - ulong msr_shift; - int vec; +#if (UIC_MAX > 1) + if ((UICB0_UIC1CI & uic_msr) || (UICB0_UIC1NCI & uic_msr)) + uic_interrupt(UIC1_DCR_BASE, 32); +#endif
- /* - * Read masked interrupt status register to determine interrupt source - */ - uic3_msr = mfdcr(uic3msr); - msr_shift = uic3_msr; - vec = 0; +#if (UIC_MAX > 2) + if ((UICB0_UIC2CI & uic_msr) || (UICB0_UIC2NCI & uic_msr)) + uic_interrupt(UIC2_DCR_BASE, 64); +#endif
- while (msr_shift != 0) { - if (msr_shift & 0x80000000) { - /* - * Increment irq counter (for debug purpose only) - */ - irq_vecs3[vec].count++; +#if (UIC_MAX > 3) + if ((UICB0_UIC3CI & uic_msr) || (UICB0_UIC3NCI & uic_msr)) + uic_interrupt(UIC3_DCR_BASE, 96); +#endif
- if (irq_vecs3[vec].handler != NULL) { - /* call isr */ - (*irq_vecs3[vec].handler)(irq_vecs3[vec].arg); - } else { - mtdcr(uic3er, mfdcr(uic3er) & ~(0x80000000 >> vec)); - printf ("Masking bogus interrupt vector (uic3) 0x%x\n", vec); - } +#if defined(CONFIG_440) +#if !defined(CONFIG_440GX) + if (uic_msr & ~(UICB0_ALL)) + uic_interrupt(UIC0_DCR_BASE, 0); +#else + if ((UICB0_UIC0CI & uic_msr) || (UICB0_UIC0NCI & uic_msr)) + uic_interrupt(UIC0_DCR_BASE, 0); +#endif +#else /* CONFIG_440 */ + uic_interrupt(UIC0_DCR_BASE, 0); +#endif /* CONFIG_440 */
- /* - * After servicing the interrupt, we have to remove the status indicator. - */ - mtdcr(uic3sr, (0x80000000 >> vec)); - } + mtdcr(UIC_BSR, uic_msr);
- /* - * Shift msr to next position and increment vector - */ - msr_shift <<= 1; - vec++; - } + return; } -#endif /* defined(CONFIG_440SPE) */ - -/****************************************************************************/
/* * Install and free a interrupt handler. */ - -void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg) +void irq_install_handler(int vec, interrupt_handler_t * handler, void *arg) { - struct irq_action *irqa = irq_vecs; - int i = vec; - -#if defined(CONFIG_440) || defined(CONFIG_405EX) -#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) - if ((vec > 31) && (vec < 64)) { - i = vec - 32; - irqa = irq_vecs1; - } else if (vec > 63) { - i = vec - 64; - irqa = irq_vecs2; - } -#else /* CONFIG_440GX */ - if (vec > 31) { - i = vec - 32; - irqa = irq_vecs1; - } -#endif /* CONFIG_440GX */ -#endif /* CONFIG_440 */ + int i;
/* - * print warning when replacing with a different irq vector + * Print warning when replacing with a different irq vector */ - if ((irqa[i].handler != NULL) && (irqa[i].handler != handler)) { - printf ("Interrupt vector %d: handler 0x%x replacing 0x%x\n", - vec, (uint) handler, (uint) irqa[i].handler); + if ((irq_vecs[vec].handler != NULL) && (irq_vecs[vec].handler != handler)) { + printf("Interrupt vector %d: handler 0x%x replacing 0x%x\n", + vec, (uint) handler, (uint) irq_vecs[vec].handler); } - irqa[i].handler = handler; - irqa[i].arg = arg; - -#if defined(CONFIG_440) || defined(CONFIG_405EX) -#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) - if ((vec > 31) && (vec < 64)) - mtdcr (uic1er, mfdcr (uic1er) | (0x80000000 >> i)); - else if (vec > 63) - mtdcr (uic2er, mfdcr (uic2er) | (0x80000000 >> i)); - else -#endif /* CONFIG_440GX */ - if (vec > 31) - mtdcr (uic1er, mfdcr (uic1er) | (0x80000000 >> i)); - else + irq_vecs[vec].handler = handler; + irq_vecs[vec].arg = arg; + + i = vec & 0x1f; + if ((vec >= 0) && (vec < 32)) + mtdcr(uicer, mfdcr(uicer) | (0x80000000 >> i)); +#if (UIC_MAX > 1) + else if ((vec >= 32) && (vec < 64)) + mtdcr(uic1er, mfdcr(uic1er) | (0x80000000 >> i)); +#endif +#if (UIC_MAX > 2) + else if ((vec >= 64) && (vec < 96)) + mtdcr(uic2er, mfdcr(uic2er) | (0x80000000 >> i)); #endif - mtdcr (uicer, mfdcr (uicer) | (0x80000000 >> i)); -#if 0 - printf ("Install interrupt for vector %d ==> %p\n", vec, handler); +#if (UIC_MAX > 3) + else if (vec >= 96) + mtdcr(uic3er, mfdcr(uic3er) | (0x80000000 >> i)); #endif + + debug("Install interrupt for vector %d ==> %p\n", vec, handler); }
void irq_free_handler (int vec) { - struct irq_action *irqa = irq_vecs; - int i = vec; - -#if defined(CONFIG_440) || defined(CONFIG_405EX) -#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) - if ((vec > 31) && (vec < 64)) { - irqa = irq_vecs1; - i = vec - 32; - } else if (vec > 63) { - irqa = irq_vecs2; - i = vec - 64; - } -#endif /* CONFIG_440GX */ - if (vec > 31) { - irqa = irq_vecs1; - i = vec - 32; - } -#endif + int i;
-#if 0 - printf ("Free interrupt for vector %d ==> %p\n", - vec, irq_vecs[vec].handler); -#endif + debug("Free interrupt for vector %d ==> %p\n", + vec, irq_vecs[vec].handler);
-#if defined(CONFIG_440) || defined(CONFIG_405EX) -#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) - if ((vec > 31) && (vec < 64)) - mtdcr (uic1er, mfdcr (uic1er) & ~(0x80000000 >> i)); - else if (vec > 63) - mtdcr (uic2er, mfdcr (uic2er) & ~(0x80000000 >> i)); - else -#endif /* CONFIG_440GX */ - if (vec > 31) - mtdcr (uic1er, mfdcr (uic1er) & ~(0x80000000 >> i)); - else + i = vec & 0x1f; + if ((vec >= 0) && (vec < 32)) + mtdcr(uicer, mfdcr(uicer) & ~(0x80000000 >> i)); +#if (UIC_MAX > 1) + else if ((vec >= 32) && (vec < 64)) + mtdcr(uic1er, mfdcr(uic1er) & ~(0x80000000 >> i)); +#endif +#if (UIC_MAX > 2) + else if ((vec >= 64) && (vec < 96)) + mtdcr(uic2er, mfdcr(uic2er) & ~(0x80000000 >> i)); +#endif +#if (UIC_MAX > 3) + else if (vec >= 96) + mtdcr(uic3er, mfdcr(uic3er) & ~(0x80000000 >> i)); #endif - mtdcr (uicer, mfdcr (uicer) & ~(0x80000000 >> i));
- irqa[i].handler = NULL; - irqa[i].arg = NULL; + irq_vecs[vec].handler = NULL; + irq_vecs[vec].arg = NULL; }
-/****************************************************************************/ - void timer_interrupt_cpu (struct pt_regs *regs) { /* nothing to do here */ return; }
-/****************************************************************************/ - #if defined(CONFIG_CMD_IRQ) - -/******************************************************************************* - * - * irqinfo - print information about PCI devices - * - */ -int -do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { int vec;
- printf ("\nInterrupt-Information:\n"); -#if defined(CONFIG_440) || defined(CONFIG_405EX) - printf ("\nUIC 0\n"); -#endif + printf ("Interrupt-Information:\n"); printf ("Nr Routine Arg Count\n");
- for (vec=0; vec<32; vec++) { + for (vec = 0; vec < (UIC_MAX * 32); vec++) { if (irq_vecs[vec].handler != NULL) { printf ("%02d %08lx %08lx %d\n", vec, @@ -656,46 +389,6 @@ do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } }
-#if defined(CONFIG_440) || defined(CONFIG_405EX) - printf ("\nUIC 1\n"); - printf ("Nr Routine Arg Count\n"); - - for (vec=0; vec<32; vec++) { - if (irq_vecs1[vec].handler != NULL) - printf ("%02d %08lx %08lx %d\n", - vec+31, (ulong)irq_vecs1[vec].handler, - (ulong)irq_vecs1[vec].arg, irq_vecs1[vec].count); - } - printf("\n"); -#endif - -#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) - printf ("\nUIC 2\n"); - printf ("Nr Routine Arg Count\n"); - - for (vec=0; vec<32; vec++) { - if (irq_vecs2[vec].handler != NULL) - printf ("%02d %08lx %08lx %d\n", - vec+63, (ulong)irq_vecs2[vec].handler, - (ulong)irq_vecs2[vec].arg, irq_vecs2[vec].count); - } - printf("\n"); -#endif - -#if defined(CONFIG_440SPE) - printf ("\nUIC 3\n"); - printf ("Nr Routine Arg Count\n"); - - for (vec=0; vec<32; vec++) { - if (irq_vecs3[vec].handler != NULL) - printf ("%02d %08lx %08lx %d\n", - vec+63, (ulong)irq_vecs3[vec].handler, - (ulong)irq_vecs3[vec].arg, irq_vecs3[vec].count); - } - printf("\n"); -#endif - return 0; } #endif

This patch adds support for the AMCC Canyonlands 460EX evaluation board.
Signed-off-by: Stefan Roese sr@denx.de --- MAINTAINERS | 1 + MAKEALL | 1 + Makefile | 3 + board/amcc/canyonlands/Makefile | 51 ++++ board/amcc/canyonlands/bootstrap.c | 169 ++++++++++++ board/amcc/canyonlands/canyonlands.c | 385 ++++++++++++++++++++++++++++ board/amcc/canyonlands/config.mk | 49 ++++ board/amcc/canyonlands/init.S | 114 ++++++++ board/amcc/canyonlands/u-boot.lds | 146 +++++++++++ include/asm-ppc/gpio.h | 5 +- include/configs/canyonlands.h | 470 ++++++++++++++++++++++++++++++++++ 11 files changed, 1392 insertions(+), 2 deletions(-) create mode 100644 board/amcc/canyonlands/Makefile create mode 100644 board/amcc/canyonlands/bootstrap.c create mode 100644 board/amcc/canyonlands/canyonlands.c create mode 100644 board/amcc/canyonlands/config.mk create mode 100644 board/amcc/canyonlands/init.S create mode 100644 board/amcc/canyonlands/u-boot.lds create mode 100644 include/configs/canyonlands.h
diff --git a/MAINTAINERS b/MAINTAINERS index dc13580..f248fff 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -319,6 +319,7 @@ Stefan Roese sr@denx.de alpr PPC440GX bamboo PPC440EP bunbinga PPC405EP + canyonlands PPC460EX ebony PPC440GP haleakala PPC405EXr katmai PPC440SPe diff --git a/MAKEALL b/MAKEALL index 0e1c0cb..f3b1968 100755 --- a/MAKEALL +++ b/MAKEALL @@ -165,6 +165,7 @@ LIST_4xx=" \ bamboo_nand \ bubinga \ CANBT \ + canyonlands \ CMS700 \ CPCI2DP \ CPCI405 \ diff --git a/Makefile b/Makefile index 90198f6..b46e43a 100644 --- a/Makefile +++ b/Makefile @@ -1170,6 +1170,9 @@ bubinga_config: unconfig CANBT_config: unconfig @$(MKCONFIG) $(@:_config=) ppc ppc4xx canbt esd
+canyonlands_config: unconfig + @$(MKCONFIG) $(@:_config=) ppc ppc4xx canyonlands amcc + CATcenter_config \ CATcenter_25_config \ CATcenter_33_config: unconfig diff --git a/board/amcc/canyonlands/Makefile b/board/amcc/canyonlands/Makefile new file mode 100644 index 0000000..a3385c7 --- /dev/null +++ b/board/amcc/canyonlands/Makefile @@ -0,0 +1,51 @@ +# +# (C) Copyright 2008 +# 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 + +LIB = $(obj)lib$(BOARD).a + +COBJS = $(BOARD).o bootstrap.o +SOBJS = init.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/amcc/canyonlands/bootstrap.c b/board/amcc/canyonlands/bootstrap.c new file mode 100644 index 0000000..3f5822e --- /dev/null +++ b/board/amcc/canyonlands/bootstrap.c @@ -0,0 +1,169 @@ +/* + * (C) Copyright 2008 + * 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 <common.h> +#include <command.h> +#include <i2c.h> +#include <asm/io.h> + +/* + * NOR and NAND boot options change bytes 6, 7, 8, 9, 11. The + * values are independent of the rest of the clock settings. + */ + +#define NAND_COMPATIBLE 0x01 +#define NOR_COMPATIBLE 0x02 + +#define I2C_EEPROM_ADDR 0x52 + +static char *config_labels[] = { + "CPU: 600 PLB: 200 OPB: 100 EBC: 100", + "CPU: 800 PLB: 200 OPB: 100 EBC: 100", + NULL +}; + +static u8 boot_configs[][17] = { + { + (NOR_COMPATIBLE), + 0x86, 0x80, 0xce, 0x1f, 0x79, 0x80, 0x00, 0xa0, 0x40, 0x08, + 0x23, 0x50, 0x0d, 0x95, 0x00, 0x00 + }, + { + (NOR_COMPATIBLE), + 0x86, 0x80, 0xba, 0x14, 0x99, 0x80, 0x00, 0xa0, 0x40, 0x08, + 0x23, 0x50, 0x0d, 0x95, 0x00, 0x00 + }, + { + 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } +}; + +/* + * Bytes 6,8,9,11 change for NAND boot + */ +static u8 nand_boot[] = { + 0xd0, 0xa0, 0x68, 0x58 +}; + +static int do_bootstrap(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + u8 *buf, b_nand; + int x, y, nbytes, selcfg; + extern char console_buffer[]; + + if (argc < 2) { + printf("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + if ((strcmp(argv[1], "nor") != 0) && + (strcmp(argv[1], "nand") != 0)) { + printf("Unsupported boot-device - only nor|nand support\n"); + return 1; + } + + /* set the nand flag based on provided input */ + if ((strcmp(argv[1], "nand") == 0)) + b_nand = 1; + else + b_nand = 0; + + printf("Available configurations: \n\n"); + + if (b_nand) { + for(x = 0, y = 0; boot_configs[x][0] != 0; x++) { + /* filter on nand compatible */ + if (boot_configs[x][0] & NAND_COMPATIBLE) { + printf(" %d - %s\n", (y+1), config_labels[x]); + y++; + } + } + } else { + for(x = 0, y = 0; boot_configs[x][0] != 0; x++) { + /* filter on nor compatible */ + if (boot_configs[x][0] & NOR_COMPATIBLE) { + printf(" %d - %s\n", (y+1), config_labels[x]); + y++; + } + } + } + + do { + nbytes = readline(" Selection [1-x / quit]: "); + + if (nbytes) { + if (strcmp(console_buffer, "quit") == 0) + return 0; + selcfg = simple_strtol(console_buffer, NULL, 10); + if ((selcfg < 1) || (selcfg > y)) + nbytes = 0; + } + } while (nbytes == 0); + + + y = (selcfg - 1); + + for (x = 0; boot_configs[x][0] != 0; x++) { + if (b_nand) { + if (boot_configs[x][0] & NAND_COMPATIBLE) { + if (y > 0) + y--; + else if (y < 1) + break; + } + } else { + if (boot_configs[x][0] & NOR_COMPATIBLE) { + if (y > 0) + y--; + else if (y < 1) + break; + } + } + } + + buf = &boot_configs[x][1]; + + if (b_nand) { + buf[6] = nand_boot[0]; + buf[8] = nand_boot[1]; + buf[9] = nand_boot[2]; + buf[11] = nand_boot[3]; + } + + if (i2c_write(I2C_EEPROM_ADDR, 0, 1, buf, 16) != 0) + printf("Error writing to EEPROM at address 0x%x\n", I2C_EEPROM_ADDR); + udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000); + + printf("Done\n"); + printf("Please power-cycle the board for the changes to take effect\n"); + + return 0; +} + +U_BOOT_CMD( + bootstrap, 2, 0, do_bootstrap, + "bootstrap - program the I2C bootstrap EEPROM\n", + "<nand|nor> - strap to boot from NAND or NOR flash\n" + ); diff --git a/board/amcc/canyonlands/canyonlands.c b/board/amcc/canyonlands/canyonlands.c new file mode 100644 index 0000000..8292d2d --- /dev/null +++ b/board/amcc/canyonlands/canyonlands.c @@ -0,0 +1,385 @@ +/* + * (C) Copyright 2008 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * 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 <common.h> +#include <ppc440.h> +#include <libfdt.h> +#include <fdt_support.h> +#include <asm/processor.h> +#include <asm/io.h> +#include <asm/mmu.h> +#include <asm/4xx_pcie.h> + +extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +DECLARE_GLOBAL_DATA_PTR; + +int board_early_init_f(void) +{ + u32 sdr0_cust0; + + /*------------------------------------------------------------------+ + * Setup the interrupt controller polarities, triggers, etc. + *------------------------------------------------------------------*/ + mtdcr(uic0sr, 0xffffffff); /* clear all */ + mtdcr(uic0er, 0x00000000); /* disable all */ + mtdcr(uic0cr, 0x00000005); /* ATI & UIC1 crit are critical */ + mtdcr(uic0pr, 0xffffffff); /* per ref-board manual */ + mtdcr(uic0tr, 0x00000000); /* per ref-board manual */ + mtdcr(uic0vr, 0x00000000); /* int31 highest, base=0x000 */ + mtdcr(uic0sr, 0xffffffff); /* clear all */ + + mtdcr(uic1sr, 0xffffffff); /* clear all */ + mtdcr(uic1er, 0x00000000); /* disable all */ + mtdcr(uic1cr, 0x00000000); /* all non-critical */ + mtdcr(uic1pr, 0xffffffff); /* per ref-board manual */ + mtdcr(uic1tr, 0x00000000); /* per ref-board manual */ + mtdcr(uic1vr, 0x00000000); /* int31 highest, base=0x000 */ + mtdcr(uic1sr, 0xffffffff); /* clear all */ + + mtdcr(uic2sr, 0xffffffff); /* clear all */ + mtdcr(uic2er, 0x00000000); /* disable all */ + mtdcr(uic2cr, 0x00000000); /* all non-critical */ + mtdcr(uic2pr, 0xffffffff); /* per ref-board manual */ + mtdcr(uic2tr, 0x00000000); /* per ref-board manual */ + mtdcr(uic2vr, 0x00000000); /* int31 highest, base=0x000 */ + mtdcr(uic2sr, 0xffffffff); /* clear all */ + + mtdcr(uic3sr, 0xffffffff); /* clear all */ + mtdcr(uic3er, 0x00000000); /* disable all */ + mtdcr(uic3cr, 0x00000000); /* all non-critical */ + mtdcr(uic3pr, 0xffffffff); /* per ref-board manual */ + mtdcr(uic3tr, 0x00000000); /* per ref-board manual */ + mtdcr(uic3vr, 0x00000000); /* int31 highest, base=0x000 */ + mtdcr(uic3sr, 0xffffffff); /* clear all */ + + /* SDR Setting - enable NDFC */ + mfsdr(SDR0_CUST0, sdr0_cust0); + sdr0_cust0 = SDR0_CUST0_MUX_NDFC_SEL | + SDR0_CUST0_NDFC_ENABLE | + SDR0_CUST0_NDFC_BW_8_BIT | + SDR0_CUST0_NDFC_ARE_MASK | + SDR0_CUST0_NDFC_BAC_ENCODE(3) | + (0x80000000 >> (28 + CFG_NAND_CS)); + mtsdr(SDR0_CUST0, sdr0_cust0); + + /* + * Configure PFC (Pin Function Control) registers + * UART0: 4 pins + */ + mtsdr(SDR0_PFC1, 0x00040000); + + /* Enable PCI host functionality in SDR0_PCI0 */ + mtsdr(SDR0_PCI0, 0xe0000000); + + /* Enable ethernet and take out of reset */ + out_8((void *)CFG_BCSR_BASE + 6, 0); + + /* Remove NOR-FLASH, NAND-FLASH & EEPROM hardware write protection */ + out_8((void *)CFG_BCSR_BASE + 5, 0); + + /* Enable USB host & USB-OTG */ + out_8((void *)CFG_BCSR_BASE + 7, 0); + + mtsdr(SDR0_SRST1, 0); /* Pull AHB out of reset default=1 */ + + return 0; +} + +int checkboard (void) +{ + char *s = getenv("serial#"); + u32 pvr = get_pvr(); + + if ((pvr == PVR_460GT_RA) || (pvr == PVR_460GT_SE_RA)) + printf("Board: Glacier - AMCC PPC460GT Evaluation Board"); + else + printf("Board: Canyonlands - AMCC PPC460EX Evaluation Board"); + + if (s != NULL) { + puts(", serial# "); + puts(s); + } + putc('\n'); + + return (0); +} + +/* + * Override the default functions in cpu/ppc4xx/44x_spd_ddr2.c with + * board specific values. + */ +u32 ddr_wrdtr(u32 default_val) { + return (SDRAM_WRDTR_LLWP_1_CYC | SDRAM_WRDTR_WTR_180_DEG_ADV | 0x823); +} + +u32 ddr_clktr(u32 default_val) { + return (SDRAM_CLKTR_CLKP_90_DEG_ADV); +} + +#if defined(CFG_DRAM_TEST) +int testdram(void) +{ + unsigned long *mem = (unsigned long *)0; + const unsigned long kend = (1024 / sizeof(unsigned long)); + unsigned long k, n; + + mtmsr(0); + + for (k = 0; k < CFG_KBYTES_SDRAM; + ++k, mem += (1024 / sizeof(unsigned long))) { + if ((k & 1023) == 0) { + printf("%3d MB\r", k / 1024); + } + + memset(mem, 0xaaaaaaaa, 1024); + for (n = 0; n < kend; ++n) { + if (mem[n] != 0xaaaaaaaa) { + printf("SDRAM test fails at: %08x\n", + (uint) & mem[n]); + return 1; + } + } + + memset(mem, 0x55555555, 1024); + for (n = 0; n < kend; ++n) { + if (mem[n] != 0x55555555) { + printf("SDRAM test fails at: %08x\n", + (uint) & mem[n]); + return 1; + } + } + } + printf("SDRAM test passes\n"); + return 0; +} +#endif + +/************************************************************************* + * pci_target_init + * + * The bootstrap configuration provides default settings for the pci + * inbound map (PIM). But the bootstrap config choices are limited and + * may not be sufficient for a given board. + * + ************************************************************************/ +#if defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT) +void pci_target_init(struct pci_controller * hose ) +{ + /*-------------------------------------------------------------------+ + * Disable everything + *-------------------------------------------------------------------*/ + out_le32((void *)PCIX0_PIM0SA, 0); /* disable */ + out_le32((void *)PCIX0_PIM1SA, 0); /* disable */ + out_le32((void *)PCIX0_PIM2SA, 0); /* disable */ + out_le32((void *)PCIX0_EROMBA, 0); /* disable expansion rom */ + + /*-------------------------------------------------------------------+ + * Map all of SDRAM to PCI address 0x0000_0000. Note that the 440 + * strapping options to not support sizes such as 128/256 MB. + *-------------------------------------------------------------------*/ + out_le32((void *)PCIX0_PIM0LAL, CFG_SDRAM_BASE); + out_le32((void *)PCIX0_PIM0LAH, 0); + out_le32((void *)PCIX0_PIM0SA, ~(gd->ram_size - 1) | 1); + out_le32((void *)PCIX0_BAR0, 0); + + /*-------------------------------------------------------------------+ + * Program the board's subsystem id/vendor id + *-------------------------------------------------------------------*/ + out_le16((void *)PCIX0_SBSYSVID, CFG_PCI_SUBSYS_VENDORID); + out_le16((void *)PCIX0_SBSYSID, CFG_PCI_SUBSYS_DEVICEID); + + out_le16((void *)PCIX0_CMD, in16r(PCIX0_CMD) | PCI_COMMAND_MEMORY); +} +#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT) */ + +#if defined(CONFIG_PCI) +/* + * is_pci_host + * + * This routine is called to determine if a pci scan should be + * performed. With various hardware environments (especially cPCI and + * PPMC) it's insufficient to depend on the state of the arbiter enable + * bit in the strap register, or generic host/adapter assumptions. + * + * Rather than hard-code a bad assumption in the general 440 code, the + * 440 pci code requires the board to decide at runtime. + * + * Return 0 for adapter mode, non-zero for host (monarch) mode. + */ +int is_pci_host(struct pci_controller *hose) +{ + /* Board is always configured as host. */ + return (1); +} + +static struct pci_controller pcie_hose[2] = {{0},{0}}; + +void pcie_setup_hoses(int busno) +{ + struct pci_controller *hose; + int i, bus; + int ret = 0; + char *env; + unsigned int delay; + + /* + * assume we're called after the PCIX hose is initialized, which takes + * bus ID 0 and therefore start numbering PCIe's from 1. + */ + bus = busno; + for (i = 0; i <= 1; i++) { + + if (is_end_point(i)) + ret = ppc4xx_init_pcie_endport(i); + else + ret = ppc4xx_init_pcie_rootport(i); + if (ret) { + printf("PCIE%d: initialization as %s failed\n", i, + is_end_point(i) ? "endpoint" : "root-complex"); + continue; + } + + hose = &pcie_hose[i]; + hose->first_busno = bus; + hose->last_busno = bus; + hose->current_busno = bus; + + /* setup mem resource */ + pci_set_region(hose->regions + 0, + CFG_PCIE_MEMBASE + i * CFG_PCIE_MEMSIZE, + CFG_PCIE_MEMBASE + i * CFG_PCIE_MEMSIZE, + CFG_PCIE_MEMSIZE, + PCI_REGION_MEM); + hose->region_count = 1; + pci_register_hose(hose); + + if (is_end_point(i)) { + ppc4xx_setup_pcie_endpoint(hose, i); + /* + * Reson for no scanning is endpoint can not generate + * upstream configuration accesses. + */ + } else { + ppc4xx_setup_pcie_rootpoint(hose, i); + env = getenv ("pciscandelay"); + if (env != NULL) { + delay = simple_strtoul(env, NULL, 10); + if (delay > 5) + printf("Warning, expect noticable delay before " + "PCIe scan due to 'pciscandelay' value!\n"); + mdelay(delay * 1000); + } + + /* + * Config access can only go down stream + */ + hose->last_busno = pci_hose_scan(hose); + bus = hose->last_busno + 1; + } + } +} +#endif /* CONFIG_PCI */ + +int board_early_init_r (void) +{ + /* + * Canyonlands has 64MBytes of NOR FLASH (Spansion 29GL512), but the + * boot EBC mapping only supports a maximum of 16MBytes + * (4.ff00.0000 - 4.ffff.ffff). + * To solve this problem, the FLASH has to get remapped to another + * EBC address which accepts bigger regions: + * + * 0xfc00.0000 -> 4.cc00.0000 + * + * For this we have to remap the CS0 and re-relocate the envrironment, + * since the original FLASH location which was needed upon startup is + * now not correct anymore. + */ + + /* Remap the NOR FLASH to 0xcc00.0000 ... 0xcfff.ffff */ + mtebc(pb0cr, CFG_FLASH_BASE_PHYS_L | 0xda000); + + /* Remove TLB entry of boot EBC mapping */ + remove_tlb(CFG_BOOT_BASE_ADDR, 16 << 20); + + /* Add TLB entry for 0xfc00.0000 -> 0x4.cc00.0000 */ + program_tlb(CFG_FLASH_BASE_PHYS, CFG_FLASH_BASE, CFG_FLASH_SIZE, + TLB_WORD2_I_ENABLE); + + /* + * Now accessing of the whole 64Mbytes of NOR FLASH at virtual address + * 0xfc00.0000 is possible + */ + + return 0; +} + +int misc_init_r(void) +{ + u32 sdr0_srst1 = 0; + u32 eth_cfg; + + /* + * Set EMAC mode/configuration (GMII, SGMII, RGMII...). + * This is board specific, so let's do it here. + */ + mfsdr(SDR0_ETH_CFG, eth_cfg); + /* disable SGMII mode */ + eth_cfg &= ~(SDR0_ETH_CFG_SGMII2_ENABLE | + SDR0_ETH_CFG_SGMII1_ENABLE | + SDR0_ETH_CFG_SGMII0_ENABLE); + /* Set the for 2 RGMII mode */ + /* GMC0 EMAC4_0, GMC0 EMAC4_1, RGMII Bridge 0 */ + eth_cfg &= ~SDR0_ETH_CFG_GMC0_BRIDGE_SEL; + eth_cfg |= SDR0_ETH_CFG_GMC1_BRIDGE_SEL; + mtsdr(SDR0_ETH_CFG, eth_cfg); + + /* + * The AHB Bridge core is held in reset after power-on or reset + * so enable it now + */ + mfsdr(SDR0_SRST1, sdr0_srst1); + sdr0_srst1 &= ~SDR0_SRST1_AHB; + mtsdr(SDR0_SRST1, sdr0_srst1); + + return 0; +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +void ft_board_setup(void *blob, bd_t *bd) +{ + u32 val[4]; + int rc; + + ft_cpu_setup(blob, bd); + + /* Fixup NOR mapping */ + val[0] = 0; /* chip select number */ + val[1] = 0; /* always 0 */ + val[2] = gd->bd->bi_flashstart; + val[3] = gd->bd->bi_flashsize; + rc = fdt_find_and_setprop(blob, "/plb/opb/ebc", "ranges", + val, sizeof(val), 1); + if (rc) + printf("Unable to update property NOR mapping, err=%s\n", + fdt_strerror(rc)); +} +#endif /* defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) */ diff --git a/board/amcc/canyonlands/config.mk b/board/amcc/canyonlands/config.mk new file mode 100644 index 0000000..1e4bbc4 --- /dev/null +++ b/board/amcc/canyonlands/config.mk @@ -0,0 +1,49 @@ +# +# (C) Copyright 2008 +# Wolfgang Denk, DENX Software Engineering, wd@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 460EX/460GT Evaluation Board (Canyonlands) board +# + +sinclude $(TOPDIR)/board/$(BOARDDIR)/config.tmp + +ifndef TEXT_BASE +TEXT_BASE = 0xFFFA0000 +endif + +ifeq ($(CONFIG_NAND_U_BOOT),y) +LDSCRIPT = $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds +endif + +ifeq ($(CONFIG_PCIBOOT_U_BOOT),y) +LDSCRIPT = $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds +endif + +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/board/amcc/canyonlands/init.S b/board/amcc/canyonlands/init.S new file mode 100644 index 0000000..5d48847 --- /dev/null +++ b/board/amcc/canyonlands/init.S @@ -0,0 +1,114 @@ +/* + * (C) Copyright 2008 + * 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 <ppc_asm.tmpl> +#include <config.h> +#include <asm-ppc/mmu.h> + +/************************************************************************** + * TLB TABLE + * + * This table is used by the cpu boot code to setup the initial tlb + * entries. Rather than make broad assumptions in the cpu source tree, + * this table lets each board set things up however they like. + * + * Pointer to the table is returned in r1 + * + *************************************************************************/ + .section .bootpg,"ax" + .globl tlbtab + +tlbtab: + tlbtab_start + + /* + * BOOT_CS (FLASH) must be first. Before relocation SA_I can be off to + * use the speed up boot process. It is patched after relocation to + * enable SA_I + */ + tlbentry(CFG_BOOT_BASE_ADDR, SZ_16M, CFG_BOOT_BASE_ADDR, 4, AC_R|AC_W|AC_X|SA_G) /* TLB 0 */ + + /* + * TLB entries for SDRAM are not needed on this platform. + * They are dynamically generated in the SPD DDR(2) detection + * routine. + */ + +#ifdef CFG_INIT_RAM_DCACHE + /* TLB-entry for init-ram in dcache (SA_I must be turned off!) */ + tlbentry(CFG_INIT_RAM_ADDR, SZ_4K, CFG_INIT_RAM_ADDR, 0, AC_R|AC_W|AC_X|SA_G) +#endif + + tlbentry(CFG_PCI_BASE, SZ_256M, 0x00000000, 0xC, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCI_MEMBASE, SZ_256M, 0x20000000, 0xC, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE_MEMBASE, SZ_256M, 0xB0000000, 0xD, AC_R|AC_W|SA_G|SA_I) + + tlbentry(CFG_PCIE0_CFGBASE, SZ_16M, 0x00000000, 0xD, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE1_CFGBASE, SZ_16M, 0x20000000, 0xD, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE0_XCFGBASE, SZ_1K, 0x10000000, 0xD, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE1_XCFGBASE, SZ_1K, 0x30000000, 0xD, AC_R|AC_W|SA_G|SA_I) + + /* PCIe UTL register */ + tlbentry(CFG_PCIE_BASE, SZ_16K, 0x08010000, 0xC, AC_R|AC_W|SA_G|SA_I) + + /* TLB-entry for NAND */ + tlbentry(CFG_NAND_ADDR, SZ_16M, CFG_NAND_ADDR, 4, AC_R|AC_W|AC_X|SA_G|SA_I) + + /* TLB-entry for CPLD */ + tlbentry(CFG_BCSR_BASE, SZ_1K, CFG_BCSR_BASE, 4, AC_R|AC_W|SA_G|SA_I) + + /* TLB-entry for OCM */ + tlbentry(CFG_OCM_BASE, SZ_4K, 0x00040000, 4, AC_R|AC_W|AC_X) + + /* TLB-entry for Local Configuration registers => peripherals */ + tlbentry(CFG_LOCAL_CONF_REGS, SZ_16M, CFG_LOCAL_CONF_REGS, 4, AC_R|AC_W|AC_X|SA_G|SA_I) + + tlbtab_end + +#if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) + /* + * For NAND booting the first TLB has to be reconfigured to full size + * and with caching disabled after running from RAM! + */ +#define TLB00 TLB0(CFG_BOOT_BASE_ADDR, SZ_256M) +#define TLB01 TLB1(CFG_BOOT_BASE_ADDR, 1) +#define TLB02 TLB2(AC_R|AC_W|AC_X|SA_G|SA_I) + + .globl reconfig_tlb0 +reconfig_tlb0: + sync + isync + addi r4,r0,0x0000 /* TLB entry #0 */ + lis r5,TLB00@h + ori r5,r5,TLB00@l + tlbwe r5,r4,0x0000 /* Save it out */ + lis r5,TLB01@h + ori r5,r5,TLB01@l + tlbwe r5,r4,0x0001 /* Save it out */ + lis r5,TLB02@h + ori r5,r5,TLB02@l + tlbwe r5,r4,0x0002 /* Save it out */ + sync + isync + blr +#endif diff --git a/board/amcc/canyonlands/u-boot.lds b/board/amcc/canyonlands/u-boot.lds new file mode 100644 index 0000000..7496f48 --- /dev/null +++ b/board/amcc/canyonlands/u-boot.lds @@ -0,0 +1,146 @@ +/* + * (C) Copyright 2008 + * Wolfgang Denk, DENX Software Engineering, wd@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) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + .resetvec 0xFFFFFFFC : + { + *(.resetvec) + } = 0xffff + + .bootpg 0xFFFFF000 : + { + cpu/ppc4xx/start.o (.bootpg) + } = 0xffff + + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + /* WARNING - the following is hand-optimized to fit within */ + /* the sector layout of our flash chips! XXX FIXME XXX */ + + cpu/ppc4xx/start.o (.text) + board/amcc/canyonlands/init.o (.text) + + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; + __fixup_entries = (. - _FIXUP_TABLE_)>>2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + + . = .; + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(256); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(256); + __init_end = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + + ppcenv_assert = ASSERT(. < 0xFFFF8000, ".bss section too big, overlaps .ppcenv section. Please update your confguration: CFG_MONITOR_BASE, CFG_MONITOR_LEN and TEXT_BASE may need to be modified."); + + _end = . ; + PROVIDE (end = .); +} diff --git a/include/asm-ppc/gpio.h b/include/asm-ppc/gpio.h index c3a4a88..fc05dc0 100644 --- a/include/asm-ppc/gpio.h +++ b/include/asm-ppc/gpio.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2007 + * (C) Copyright 2007-2008 * Stefan Roese, DENX Software Engineering, sr@denx.de. * * See file CREDITS for list of people who contributed to this @@ -27,7 +27,8 @@ /* 4xx PPC's have 2 GPIO controllers */ #if defined(CONFIG_405EZ) || \ defined(CONFIG_440EP) || defined(CONFIG_440GR) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) + defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) #define GPIO_GROUP_MAX 2 #else #define GPIO_GROUP_MAX 1 diff --git a/include/configs/canyonlands.h b/include/configs/canyonlands.h new file mode 100644 index 0000000..6d8f230 --- /dev/null +++ b/include/configs/canyonlands.h @@ -0,0 +1,470 @@ +/* + * (C) Copyright 2008 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * 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 + */ + +/************************************************************************ + * canyonlands.h - configuration for Canyonlands (460EX) + ***********************************************************************/ +#ifndef __CONFIG_H +#define __CONFIG_H + +/*----------------------------------------------------------------------- + * High Level Configuration Options + *----------------------------------------------------------------------*/ +#define CONFIG_CANYONLANDS 1 /* Board is Canyonlands */ +#define CONFIG_440 1 +#define CONFIG_4xx 1 /* ... PPC4xx family */ +#define CONFIG_460EX 1 /* Specific PPC460EX support */ + +#define CONFIG_SYS_CLK_FREQ 66666667 /* external freq to pll */ + +#define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_early_init_f */ +#define CONFIG_BOARD_EARLY_INIT_R 1 /* Call board_early_init_r */ +#define CONFIG_MISC_INIT_R 1 /* Call misc_init_r */ + +/*----------------------------------------------------------------------- + * Base addresses -- Note these are effective addresses where the + * actual resources get mapped (not physical addresses) + *----------------------------------------------------------------------*/ +#define CFG_SDRAM_BASE 0x00000000 /* _must_ be 0 */ + +#define CFG_PCI_MEMBASE 0x80000000 /* mapped PCI memory */ +#define CFG_PCI_BASE 0xd0000000 /* internal PCI regs */ +#define CFG_PCI_TARGBASE CFG_PCI_MEMBASE + +#define CFG_PCIE_MEMBASE 0xb0000000 /* mapped PCIe memory */ +#define CFG_PCIE_MEMSIZE 0x08000000 /* smallest incr for PCIe port */ +#define CFG_PCIE_BASE 0xc4000000 /* PCIe UTL regs */ + +#define CFG_PCIE0_CFGBASE 0xc0000000 +#define CFG_PCIE1_CFGBASE 0xc1000000 +#define CFG_PCIE0_XCFGBASE 0xc3000000 +#define CFG_PCIE1_XCFGBASE 0xc3001000 + +#define CFG_PCIE0_UTLBASE 0xc08010000ULL /* 36bit physical addr */ + +/* base address of inbound PCIe window */ +#define CFG_PCIE_INBOUND_BASE 0x000000000ULL /* 36bit physical addr */ + +/* EBC stuff */ +#define CFG_NAND_ADDR 0xE0000000 +#define CFG_BCSR_BASE 0xE1000000 +#define CFG_BOOT_BASE_ADDR 0xFF000000 /* EBC Boot Space: 0xFF000000 */ +#define CFG_FLASH_BASE 0xFC000000 /* later mapped to this addr */ +#define CFG_FLASH_BASE_PHYS_H 0x4 +#define CFG_FLASH_BASE_PHYS_L 0xCC000000 +#define CFG_FLASH_BASE_PHYS (((u64)CFG_FLASH_BASE_PHYS_H << 32) | \ + (u64)CFG_FLASH_BASE_PHYS_L) +#define CFG_FLASH_SIZE (64 << 20) + +#define CFG_OCM_BASE 0xE3000000 /* OCM: 16k */ +#define CFG_SRAM_BASE 0xE8000000 /* SRAM: 256k */ +#define CFG_LOCAL_CONF_REGS 0xEF000000 + +#define CFG_PERIPHERAL_BASE 0xEF600000 /* internal peripherals */ + +#define CFG_MONITOR_BASE TEXT_BASE +#define CFG_MONITOR_LEN (384 * 1024) /* Reserve 384 kB for Monitor */ +#define CFG_MALLOC_LEN (512 * 1024) /* Reserve 512 kB for malloc()*/ + +/*----------------------------------------------------------------------- + * Initial RAM & stack pointer (placed in OCM) + *----------------------------------------------------------------------*/ +#define CFG_INIT_RAM_ADDR CFG_OCM_BASE /* OCM */ +#define CFG_INIT_RAM_END (4 << 10) +#define CFG_GBL_DATA_SIZE 256 /* num bytes initial data */ +#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET + +/*----------------------------------------------------------------------- + * Serial Port + *----------------------------------------------------------------------*/ +#define CONFIG_BAUDRATE 115200 +#define CONFIG_SERIAL_MULTI 1 +#undef CONFIG_UART1_CONSOLE /* define this if you want console on UART1 */ + +#define CFG_BAUDRATE_TABLE \ + {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200} + +/*----------------------------------------------------------------------- + * Environment + *----------------------------------------------------------------------*/ +/* + * Define here the location of the environment variables (FLASH). + */ +#if !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) +#define CFG_ENV_IS_IN_FLASH 1 /* use FLASH for environment vars */ +#define CFG_NAND_CS 3 /* NAND chip connected to CSx */ +#else +#define CFG_ENV_IS_IN_NAND 1 /* use NAND for environment vars */ +#define CFG_NAND_CS 0 /* NAND chip connected to CSx */ +#endif + +/*----------------------------------------------------------------------- + * FLASH related + *----------------------------------------------------------------------*/ +#define CFG_FLASH_CFI /* The flash is CFI compatible */ +#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CFG_FLASH_CFI_AMD_RESET 1 /* Use AMD (Spansion) reset cmd */ + +#define CFG_FLASH_BANKS_LIST {CFG_FLASH_BASE} +#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ +#define CFG_MAX_FLASH_SECT 512 /* max number of sectors on one chip */ + +#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */ +#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */ + +#define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */ +#define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector on flinfo */ + +#ifdef CFG_ENV_IS_IN_FLASH +#define CFG_ENV_SECT_SIZE 0x20000 /* size of one complete sector */ +#define CFG_ENV_ADDR (CFG_MONITOR_BASE - CFG_ENV_SECT_SIZE) +#define CFG_ENV_SIZE 0x4000 /* Total Size of Environment Sector */ + +/* Address and size of Redundant Environment Sector */ +#define CFG_ENV_ADDR_REDUND (CFG_ENV_ADDR - CFG_ENV_SECT_SIZE) +#define CFG_ENV_SIZE_REDUND (CFG_ENV_SIZE) +#endif /* CFG_ENV_IS_IN_FLASH */ + +/*----------------------------------------------------------------------- + * NAND-FLASH related + *----------------------------------------------------------------------*/ +#define CFG_MAX_NAND_DEVICE 1 +#define NAND_MAX_CHIPS 1 +#define CFG_NAND_BASE (CFG_NAND_ADDR + CFG_NAND_CS) +#define CFG_NAND_SELECT_DEVICE 1 /* nand driver supports mutipl. chips */ + +/*------------------------------------------------------------------------------ + * DDR SDRAM + *----------------------------------------------------------------------------*/ +#define CONFIG_SPD_EEPROM 1 /* Use SPD EEPROM for setup */ +#define SPD_EEPROM_ADDRESS {0x50, 0x51} /* SPD i2c spd addresses*/ +#define CONFIG_DDR_ECC 1 /* with ECC support */ +#define CONFIG_DDR_RQDC_FIXED 0x80000038 /* fixed value for RQDC */ + +/*----------------------------------------------------------------------- + * I2C + *----------------------------------------------------------------------*/ +#define CONFIG_HARD_I2C 1 /* I2C with hardware support */ +#undef CONFIG_SOFT_I2C /* I2C bit-banged */ +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + +#define CFG_I2C_MULTI_EEPROMS +#define CFG_I2C_EEPROM_ADDR (0xa8>>1) +#define CFG_I2C_EEPROM_ADDR_LEN 1 +#define CFG_EEPROM_PAGE_WRITE_ENABLE +#define CFG_EEPROM_PAGE_WRITE_BITS 3 +#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 + +/* I2C SYSMON (LM75, AD7414 is almost compatible) */ +#define CONFIG_DTT_LM75 1 /* ON Semi's LM75 */ +#define CONFIG_DTT_AD7414 1 /* use AD7414 */ +#define CONFIG_DTT_SENSORS {0} /* Sensor addresses */ +#define CFG_DTT_MAX_TEMP 70 +#define CFG_DTT_LOW_TEMP -30 +#define CFG_DTT_HYSTERESIS 3 + +/* RTC configuration */ +#define CONFIG_RTC_M41T62 1 +#define CFG_I2C_RTC_ADDR 0x68 + +/*----------------------------------------------------------------------- + * Ethernet + *----------------------------------------------------------------------*/ +#define CONFIG_IBM_EMAC4_V4 1 +#define CONFIG_MII 1 /* MII PHY management */ +#define CONFIG_PHY_ADDR 0 /* PHY address, See schematics */ +#define CONFIG_PHY1_ADDR 1 +#define CONFIG_HAS_ETH0 1 +#define CONFIG_HAS_ETH1 1 /* add support for "eth1addr" */ +#define CONFIG_NET_MULTI 1 + +#define CONFIG_PHY_RESET 1 /* reset phy upon startup */ +#define CONFIG_PHY_GIGE 1 /* Include GbE speed/duplex detection */ +#define CONFIG_PHY_DYNAMIC_ANEG 1 + +#define CFG_RX_ETH_BUFFER 32 /* Number of ethernet rx buffers & descriptors */ + +#define CONFIG_PREBOOT "echo;" \ + "echo Type "run flash_nfs" to mount root filesystem over NFS;" \ + "echo" + +#undef CONFIG_BOOTARGS + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "netdev=eth0\0" \ + "hostname=canyonlands\0" \ + "nfsargs=setenv bootargs root=/dev/nfs rw " \ + "nfsroot=${serverip}:${rootpath}\0" \ + "ramargs=setenv bootargs root=/dev/ram rw\0" \ + "addip=setenv bootargs ${bootargs} " \ + "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}" \ + ":${hostname}:${netdev}:off panic=1\0" \ + "addtty=setenv bootargs ${bootargs} console=ttyS0,${baudrate}\0"\ + "net_nfs=tftp 200000 ${bootfile};" \ + "run nfsargs addip addtty;" \ + "bootm 200000\0" \ + "net_nfs_fdt=tftp 200000 ${bootfile};" \ + "tftp ${fdt_addr} ${fdt_file};" \ + "run nfsargs addip addtty;" \ + "bootm 200000 - ${fdt_addr}\0" \ + "flash_nfs=run nfsargs addip addtty;" \ + "bootm ${kernel_addr}\0" \ + "flash_self=run ramargs addip addtty;" \ + "bootm ${kernel_addr} ${ramdisk_addr}\0" \ + "rootpath=/opt/eldk/ppc_4xxFP\0" \ + "bootfile=canyonlands/uImage\0" \ + "fdt_file=canyonlands/canyonlands.dtb\0" \ + "fdt_addr=400000\0" \ + "kernel_addr=fc000000\0" \ + "ramdisk_addr=fc200000\0" \ + "initrd_high=30000000\0" \ + "load=tftp 200000 canyonlands/u-boot.bin\0" \ + "update=protect off fffa0000 ffffffff;era fffa0000 ffffffff;" \ + "cp.b ${fileaddr} fffa0000 ${filesize};" \ + "setenv filesize;saveenv\0" \ + "upd=run load update\0" \ + "nload=tftp 200000 canyonlands/u-boot-nand.bin\0" \ + "nupdate=nand erase 0 60000;nand write 200000 0 60000;" \ + "setenv filesize;saveenv\0" \ + "nupd=run nload nupdate\0" \ + "pciconfighost=1\0" \ + "pcie_mode=RP:RP\0" \ + "" +#define CONFIG_BOOTCOMMAND "run flash_self" + +#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */ + +#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ +#define CFG_LOADS_BAUD_CHANGE /* allow baudrate change */ + +/* + * BOOTP options + */ +#define CONFIG_BOOTP_BOOTFILESIZE +#define CONFIG_BOOTP_BOOTPATH +#define CONFIG_BOOTP_GATEWAY +#define CONFIG_BOOTP_HOSTNAME +#define CONFIG_BOOTP_SUBNETMASK + +/* + * Command line configuration. + */ +#include <config_cmd_default.h> + +#define CONFIG_CMD_ASKENV +#define CONFIG_CMD_DATE +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_DTT +#define CONFIG_CMD_DIAG +#define CONFIG_CMD_EEPROM +#define CONFIG_CMD_ELF +#define CONFIG_CMD_FAT +#define CONFIG_CMD_I2C +#define CONFIG_CMD_IRQ +#define CONFIG_CMD_MII +#define CONFIG_CMD_NAND +#define CONFIG_CMD_NET +#define CONFIG_CMD_NFS +#define CONFIG_CMD_PCI +#define CONFIG_CMD_PING +#define CONFIG_CMD_REGINFO +#define CONFIG_CMD_SDRAM + +/*----------------------------------------------------------------------- + * Miscellaneous configurable options + *----------------------------------------------------------------------*/ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#if defined(CONFIG_CMD_KGDB) +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +#define CFG_MEMTEST_START 0x0400000 /* memtest works on */ +#define CFG_MEMTEST_END 0x0C00000 /* 4 ... 12 MB in DRAM */ + +#define CFG_LOAD_ADDR 0x100000 /* default load address */ +#define CFG_EXTBDINFO 1 /* To use extended board_into (bd_t) */ + +#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ + +#define CONFIG_CMDLINE_EDITING 1 /* add command line history */ +#define CONFIG_AUTO_COMPLETE 1 /* add autocompletion support */ +#define CONFIG_LOOPW 1 /* enable loopw command */ +#define CONFIG_MX_CYCLIC 1 /* enable mdc/mwc commands */ +#define CONFIG_ZERO_BOOTDELAY_CHECK /* check for keypress on bootdelay==0 */ +#define CONFIG_VERSION_VARIABLE 1 /* include version env variable */ +#define CFG_CONSOLE_INFO_QUIET 1 /* don't print console @ startup*/ + +#define CFG_HUSH_PARSER 1 /* Use the HUSH parser */ +#ifdef CFG_HUSH_PARSER +#define CFG_PROMPT_HUSH_PS2 "> " +#endif + +/*----------------------------------------------------------------------- + * PCI stuff + *----------------------------------------------------------------------*/ +/* General PCI */ +#define CONFIG_PCI /* include pci support */ +#define CONFIG_PCI_PNP /* do pci plug-and-play */ +#define CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ +#define CONFIG_PCI_CONFIG_HOST_BRIDGE + +/* Board-specific PCI */ +#define CFG_PCI_TARGET_INIT /* let board init pci target */ +#undef CFG_PCI_MASTER_INIT + +#define CFG_PCI_SUBSYS_VENDORID 0x1014 /* IBM */ +#define CFG_PCI_SUBSYS_DEVICEID 0xcafe /* Whatever */ + +/* + * For booting Linux, the board info and command line data + * have to be in the first 8 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ + +/* + * Internal Definitions + */ +#if defined(CONFIG_CMD_KGDB) +#define CONFIG_KGDB_BAUDRATE 230400 /* speed to run kgdb serial port */ +#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */ +#endif + +/*----------------------------------------------------------------------- + * External Bus Controller (EBC) Setup + *----------------------------------------------------------------------*/ + +/* + * Canyonlands has 64MBytes of NOR FLASH (Spansion 29GL512), but the + * boot EBC mapping only supports a maximum of 16MBytes + * (4.ff00.0000 - 4.ffff.ffff). + * To solve this problem, the FLASH has to get remapped to another + * EBC address which accepts bigger regions: + * + * 0xfc00.0000 -> 4.cc00.0000 + * + * For this we have to remap the CS0 and re-relocate the envrironment, + * since the original FLASH location which was needed upon startup is + * now not correct anymore. + */ + +/* Memory Bank 0 (NOR-FLASH) initialization */ +#define CFG_EBC_PB0AP 0x10055e00 +#define CFG_EBC_PB0CR (CFG_BOOT_BASE_ADDR | 0x9a000) + +/* Memory Bank 2 (CPLD) initialization */ +#define CFG_EBC_PB2AP 0x00804240 +#define CFG_EBC_PB2CR (CFG_BCSR_BASE | 0x18000) /* BAS=CPLD,BS=1M,BU=RW,BW=32bit */ + +/* Memory Bank 3 (NAND-FLASH) initialization */ +#define CFG_EBC_PB3AP 0x018003c0 +#define CFG_EBC_PB3CR (CFG_NAND_ADDR | 0x1E000) /* BAS=NAND,BS=1MB,BU=R/W,BW=32bit*/ + +#define CFG_EBC_CFG 0xB8400000 /* EBC0_CFG */ + +/* + * PPC4xx GPIO Configuration + */ +#define CFG_4xx_GPIO_TABLE { /* Out GPIO Alternate1 Alternate2 Alternate3 */ \ +{ \ +/* GPIO Core 0 */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO0 GMC1TxD(0) USB2HostD(0) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO1 GMC1TxD(1) USB2HostD(1) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO2 GMC1TxD(2) USB2HostD(2) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO3 GMC1TxD(3) USB2HostD(3) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO4 GMC1TxD(4) USB2HostD(4) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO5 GMC1TxD(5) USB2HostD(5) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO6 GMC1TxD(6) USB2HostD(6) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO7 GMC1TxD(7) USB2HostD(7) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO8 GMC1RxD(0) USB2OTGD(0) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO9 GMC1RxD(1) USB2OTGD(1) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO10 GMC1RxD(2) USB2OTGD(2) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO11 GMC1RxD(3) USB2OTGD(3) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO12 GMC1RxD(4) USB2OTGD(4) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO13 GMC1RxD(5) USB2OTGD(5) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO14 GMC1RxD(6) USB2OTGD(6) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO15 GMC1RxD(7) USB2OTGD(7) */ \ +{GPIO0_BASE, GPIO_OUT, GPIO_ALT2, GPIO_OUT_0}, /* GPIO16 GMC1TxER USB2HostStop */ \ +{GPIO0_BASE, GPIO_IN , GPIO_ALT2, GPIO_OUT_0}, /* GPIO17 GMC1CD USB2HostNext */ \ +{GPIO0_BASE, GPIO_IN , GPIO_ALT2, GPIO_OUT_0}, /* GPIO18 GMC1RxER USB2HostDir */ \ +{GPIO0_BASE, GPIO_OUT, GPIO_ALT2, GPIO_OUT_0}, /* GPIO19 GMC1TxEN USB2OTGStop */ \ +{GPIO0_BASE, GPIO_IN , GPIO_ALT2, GPIO_OUT_0}, /* GPIO20 GMC1CRS USB2OTGNext */ \ +{GPIO0_BASE, GPIO_IN , GPIO_ALT2, GPIO_OUT_0}, /* GPIO21 GMC1RxDV USB2OTGDir */ \ +{GPIO0_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO22 NFRDY */ \ +{GPIO0_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO23 NFREN */ \ +{GPIO0_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO24 NFWEN */ \ +{GPIO0_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO25 NFCLE */ \ +{GPIO0_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO26 NFALE */ \ +{GPIO0_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO27 IRQ(0) */ \ +{GPIO0_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO28 IRQ(1) */ \ +{GPIO0_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO29 IRQ(2) */ \ +{GPIO0_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_1}, /* GPIO30 PerPar0 DMAReq2 IRQ(7)*/ \ +{GPIO0_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_1}, /* GPIO31 PerPar1 DMAAck2 IRQ(8)*/ \ +}, \ +{ \ +/* GPIO Core 1 */ \ +{GPIO1_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_1}, /* GPIO32 PerPar2 EOT2/TC2 IRQ(9)*/ \ +{GPIO1_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_1}, /* GPIO33 PerPar3 DMAReq3 IRQ(4)*/ \ +{GPIO1_BASE, GPIO_OUT, GPIO_ALT3, GPIO_OUT_1}, /* GPIO34 UART0_DCD_N UART1_DSR_CTS_N UART2_SOUT*/ \ +{GPIO1_BASE, GPIO_IN , GPIO_ALT3, GPIO_OUT_0}, /* GPIO35 UART0_8PIN_DSR_N UART1_RTS_DTR_N UART2_SIN*/ \ +{GPIO1_BASE, GPIO_IN , GPIO_ALT3, GPIO_OUT_0}, /* GPIO36 UART0_8PIN_CTS_N DMAAck3 UART3_SIN*/ \ +{GPIO1_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO37 UART0_RTS_N EOT3/TC3 UART3_SOUT*/ \ +{GPIO1_BASE, GPIO_OUT, GPIO_ALT2, GPIO_OUT_1}, /* GPIO38 UART0_DTR_N UART1_SOUT */ \ +{GPIO1_BASE, GPIO_IN , GPIO_ALT2, GPIO_OUT_0}, /* GPIO39 UART0_RI_N UART1_SIN */ \ +{GPIO1_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO40 IRQ(3) */ \ +{GPIO1_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO41 CS(1) */ \ +{GPIO1_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO42 CS(2) */ \ +{GPIO1_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO43 CS(3) DMAReq1 IRQ(10)*/ \ +{GPIO1_BASE, GPIO_IN , GPIO_ALT3, GPIO_OUT_0}, /* GPIO44 CS(4) DMAAck1 IRQ(11)*/ \ +{GPIO1_BASE, GPIO_IN , GPIO_ALT3, GPIO_OUT_0}, /* GPIO45 CS(5) EOT/TC1 IRQ(12)*/ \ +{GPIO1_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO46 PerAddr(5) DMAReq0 IRQ(13)*/ \ +{GPIO1_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO47 PerAddr(6) DMAAck0 IRQ(14)*/ \ +{GPIO1_BASE, GPIO_OUT, GPIO_ALT1, GPIO_OUT_0}, /* GPIO48 PerAddr(7) EOT/TC0 IRQ(15)*/ \ +{GPIO1_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO49 Unselect via TraceSelect Bit */ \ +{GPIO1_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO50 Unselect via TraceSelect Bit */ \ +{GPIO1_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO51 Unselect via TraceSelect Bit */ \ +{GPIO1_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO52 Unselect via TraceSelect Bit */ \ +{GPIO1_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO53 Unselect via TraceSelect Bit */ \ +{GPIO1_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO54 Unselect via TraceSelect Bit */ \ +{GPIO1_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO55 Unselect via TraceSelect Bit */ \ +{GPIO1_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO56 Unselect via TraceSelect Bit */ \ +{GPIO1_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO57 Unselect via TraceSelect Bit */ \ +{GPIO1_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO58 Unselect via TraceSelect Bit */ \ +{GPIO1_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO59 Unselect via TraceSelect Bit */ \ +{GPIO1_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO60 Unselect via TraceSelect Bit */ \ +{GPIO1_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO61 Unselect via TraceSelect Bit */ \ +{GPIO1_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO62 Unselect via TraceSelect Bit */ \ +{GPIO1_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO63 Unselect via TraceSelect Bit */ \ +} \ +} + +/* pass open firmware flat tree */ +#define CONFIG_OF_LIBFDT 1 +#define CONFIG_OF_BOARD_SETUP 1 + +#endif /* __CONFIG_H */

This patch adds basic support for the AMCC 460EX/460GT PPC's.
Enable high bandwidth access on 460EX/GT. This should/could probably be done on other PPC's too, like 440SPe. This is currently not used, but with this setup it is possible to use it later on in e.g. the Linux EMAC driver for performance gain.
Signed-off-by: Stefan Roese sr@denx.de --- cpu/ppc4xx/44x_spd_ddr2.c | 41 +++- cpu/ppc4xx/4xx_enet.c | 369 ++++++++++++++++++++----- cpu/ppc4xx/4xx_pci.c | 9 +- cpu/ppc4xx/4xx_pcie.c | 203 +++++++++++++- cpu/ppc4xx/4xx_uart.c | 24 +- cpu/ppc4xx/cpu.c | 45 +++- cpu/ppc4xx/cpu_init.c | 1 + cpu/ppc4xx/ndfc.c | 3 +- cpu/ppc4xx/speed.c | 125 ++++++++- cpu/ppc4xx/start.S | 11 +- include/405_mal.h | 1 + include/4xx_i2c.h | 3 +- include/asm-ppc/4xx_pcie.h | 79 +++++- include/asm-ppc/ppc4xx-intvec.h | 71 +++++ include/asm-ppc/processor.h | 4 + include/asm-ppc/u-boot.h | 6 +- include/common.h | 4 +- include/ppc405.h | 23 ++- include/ppc440.h | 590 +++++++++++++++++++++++++++++++++------ include/ppc4xx_enet.h | 18 +- 20 files changed, 1426 insertions(+), 204 deletions(-)
Unfortunately this patch is too big for the list (101k). So please find a gzipped version attached.
Best regards, Stefan

In message 200803111426.50492.sr@denx.de you wrote:
Unfortunately this patch is too big for the list (101k). So please find a gzipped version attached.
Grrrghh.... Please stick to the rules!
Binary attachments are not allowed!
Best regards,
Wolfgang Denk

On Tuesday 11 March 2008, Wolfgang Denk wrote:
In message 200803111426.50492.sr@denx.de you wrote:
Unfortunately this patch is too big for the list (101k). So please find a gzipped version attached.
Grrrghh.... Please stick to the rules!
Binary attachments are not allowed!
I'm sure that I have expressed before that I don't like these limits on this mailing list. You might have noticed that the linuxppc-dev mailing list nowadays has a limit of 400k. From my experience this 40k rule makes all our lives harder. Yours, since you have to manually moderate this list, and mine because I now have to rework the patch series.
And yes, I know that the patch you rejected is > 100k, which is the "hard limit".
But fine, I'll rework the patch series and resend soon.
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de =====================================================================

460EX doesn't support a fixed bootstrap option to boot from 512 byte page NAND devices. The only bootstrap option for NAND booting is option F for 2k page devices. So to boot from a 512 bype page device, the I2C bootstrap EEPROM needs to be programmed accordingly.
This patch adds basic NAND booting support for the AMCC Canyonlands aval board and also adds support to the "bootstrap" command, to enable NAND booting I2C setting.
Tested with 512 byte page NAND device (32MByte) on Canyonlands.
Signed-off-by: Stefan Roese sr@denx.de --- MAKEALL | 1 + Makefile | 8 ++ board/amcc/canyonlands/Makefile | 2 +- board/amcc/canyonlands/bootstrap.c | 23 +++-- board/amcc/canyonlands/canyonlands.c | 27 +++++- board/amcc/canyonlands/init.S | 7 +- board/amcc/canyonlands/u-boot-nand.lds | 137 ++++++++++++++++++++++++++ cpu/ppc4xx/start.S | 8 ++- include/configs/canyonlands.h | 89 +++++++++++++++-- nand_spl/board/amcc/canyonlands/Makefile | 100 +++++++++++++++++++ nand_spl/board/amcc/canyonlands/config.mk | 49 +++++++++ nand_spl/board/amcc/canyonlands/ddr2_fixed.c | 96 ++++++++++++++++++ nand_spl/board/amcc/canyonlands/u-boot.lds | 65 ++++++++++++ 13 files changed, 586 insertions(+), 26 deletions(-) create mode 100644 board/amcc/canyonlands/u-boot-nand.lds create mode 100644 nand_spl/board/amcc/canyonlands/Makefile create mode 100644 nand_spl/board/amcc/canyonlands/config.mk create mode 100644 nand_spl/board/amcc/canyonlands/ddr2_fixed.c create mode 100644 nand_spl/board/amcc/canyonlands/u-boot.lds
diff --git a/MAKEALL b/MAKEALL index f3b1968..15b011d 100755 --- a/MAKEALL +++ b/MAKEALL @@ -166,6 +166,7 @@ LIST_4xx=" \ bubinga \ CANBT \ canyonlands \ + canyonlands_nand \ CMS700 \ CPCI2DP \ CPCI405 \ diff --git a/Makefile b/Makefile index b46e43a..730448a 100644 --- a/Makefile +++ b/Makefile @@ -1173,6 +1173,14 @@ CANBT_config: unconfig canyonlands_config: unconfig @$(MKCONFIG) $(@:_config=) ppc ppc4xx canyonlands amcc
+canyonlands_nand_config: unconfig + @mkdir -p $(obj)include $(obj)board/amcc/canyonlands + @mkdir -p $(obj)nand_spl/board/amcc/canyonlands + @echo "#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h + @$(MKCONFIG) -n $@ -a canyonlands ppc ppc4xx canyonlands amcc + @echo "TEXT_BASE = 0x01000000" > $(obj)board/amcc/canyonlands/config.tmp + @echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk + CATcenter_config \ CATcenter_25_config \ CATcenter_33_config: unconfig diff --git a/board/amcc/canyonlands/Makefile b/board/amcc/canyonlands/Makefile index a3385c7..3238c15 100644 --- a/board/amcc/canyonlands/Makefile +++ b/board/amcc/canyonlands/Makefile @@ -33,7 +33,7 @@ OBJS := $(addprefix $(obj),$(COBJS)) SOBJS := $(addprefix $(obj),$(SOBJS))
$(LIB): $(OBJS) $(SOBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
clean: rm -f $(SOBJS) $(OBJS) diff --git a/board/amcc/canyonlands/bootstrap.c b/board/amcc/canyonlands/bootstrap.c index 3f5822e..37fa1c9 100644 --- a/board/amcc/canyonlands/bootstrap.c +++ b/board/amcc/canyonlands/bootstrap.c @@ -28,7 +28,7 @@ #include <asm/io.h>
/* - * NOR and NAND boot options change bytes 6, 7, 8, 9, 11. The + * NOR and NAND boot options change bytes 5, 6, 8, 9, 11. The * values are independent of the rest of the clock settings. */
@@ -45,14 +45,14 @@ static char *config_labels[] = {
static u8 boot_configs[][17] = { { - (NOR_COMPATIBLE), + (NAND_COMPATIBLE | NOR_COMPATIBLE), 0x86, 0x80, 0xce, 0x1f, 0x79, 0x80, 0x00, 0xa0, 0x40, 0x08, - 0x23, 0x50, 0x0d, 0x95, 0x00, 0x00 + 0x23, 0x50, 0x0d, 0x05, 0x00, 0x00 }, { - (NOR_COMPATIBLE), + (NAND_COMPATIBLE | NOR_COMPATIBLE), 0x86, 0x80, 0xba, 0x14, 0x99, 0x80, 0x00, 0xa0, 0x40, 0x08, - 0x23, 0x50, 0x0d, 0x95, 0x00, 0x00 + 0x23, 0x50, 0x0d, 0x05, 0x00, 0x00 }, { 0, @@ -61,10 +61,10 @@ static u8 boot_configs[][17] = { };
/* - * Bytes 6,8,9,11 change for NAND boot + * Bytes 5,6,8,9,11 change for NAND boot */ static u8 nand_boot[] = { - 0xd0, 0xa0, 0x68, 0x58 + 0x90, 0x01, 0xa0, 0x68, 0x58 };
static int do_bootstrap(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) @@ -146,10 +146,11 @@ static int do_bootstrap(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) buf = &boot_configs[x][1];
if (b_nand) { - buf[6] = nand_boot[0]; - buf[8] = nand_boot[1]; - buf[9] = nand_boot[2]; - buf[11] = nand_boot[3]; + buf[5] = nand_boot[0]; + buf[6] = nand_boot[1]; + buf[8] = nand_boot[2]; + buf[9] = nand_boot[3]; + buf[11] = nand_boot[4]; }
if (i2c_write(I2C_EEPROM_ADDR, 0, 1, buf, 16) != 0) diff --git a/board/amcc/canyonlands/canyonlands.c b/board/amcc/canyonlands/canyonlands.c index 8292d2d..3551429 100644 --- a/board/amcc/canyonlands/canyonlands.c +++ b/board/amcc/canyonlands/canyonlands.c @@ -134,6 +134,18 @@ u32 ddr_clktr(u32 default_val) { return (SDRAM_CLKTR_CLKP_90_DEG_ADV); }
+#if defined(CONFIG_NAND_U_BOOT) +/* + * NAND booting U-Boot version uses a fixed initialization, since the whole + * I2C SPD DIMM autodetection/calibration doesn't fit into the 4k of boot + * code. + */ +long int initdram(int board_type) +{ + return CFG_MBYTES_SDRAM << 20; +} +#endif + #if defined(CFG_DRAM_TEST) int testdram(void) { @@ -308,14 +320,14 @@ int board_early_init_r (void) * EBC address which accepts bigger regions: * * 0xfc00.0000 -> 4.cc00.0000 - * - * For this we have to remap the CS0 and re-relocate the envrironment, - * since the original FLASH location which was needed upon startup is - * now not correct anymore. */
/* Remap the NOR FLASH to 0xcc00.0000 ... 0xcfff.ffff */ +#if defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL) + mtebc(pb3cr, CFG_FLASH_BASE_PHYS_L | 0xda000); +#else mtebc(pb0cr, CFG_FLASH_BASE_PHYS_L | 0xda000); +#endif
/* Remove TLB entry of boot EBC mapping */ remove_tlb(CFG_BOOT_BASE_ADDR, 16 << 20); @@ -329,6 +341,13 @@ int board_early_init_r (void) * 0xfc00.0000 is possible */
+ /* + * Clear potential errors resulting from auto-calibration. + * If not done, then we could get an interrupt later on when + * exceptions are enabled. + */ + set_mcsr(get_mcsr()); + return 0; }
diff --git a/board/amcc/canyonlands/init.S b/board/amcc/canyonlands/init.S index 5d48847..b7cac23 100644 --- a/board/amcc/canyonlands/init.S +++ b/board/amcc/canyonlands/init.S @@ -46,7 +46,12 @@ tlbtab: * use the speed up boot process. It is patched after relocation to * enable SA_I */ +#ifndef CONFIG_NAND_SPL tlbentry(CFG_BOOT_BASE_ADDR, SZ_16M, CFG_BOOT_BASE_ADDR, 4, AC_R|AC_W|AC_X|SA_G) /* TLB 0 */ +#else + tlbentry(CFG_NAND_BOOT_SPL_SRC, SZ_4K, CFG_NAND_BOOT_SPL_SRC, 4, AC_R|AC_W|AC_X|SA_G) + tlbentry(CFG_SDRAM_BASE, SZ_256M, CFG_SDRAM_BASE, 0, AC_R|AC_W|AC_X|SA_G|SA_I) +#endif
/* * TLB entries for SDRAM are not needed on this platform. @@ -78,7 +83,7 @@ tlbtab: tlbentry(CFG_BCSR_BASE, SZ_1K, CFG_BCSR_BASE, 4, AC_R|AC_W|SA_G|SA_I)
/* TLB-entry for OCM */ - tlbentry(CFG_OCM_BASE, SZ_4K, 0x00040000, 4, AC_R|AC_W|AC_X) + tlbentry(CFG_OCM_BASE, SZ_16K, 0x00040000, 4, AC_R|AC_W|AC_X|SA_I)
/* TLB-entry for Local Configuration registers => peripherals */ tlbentry(CFG_LOCAL_CONF_REGS, SZ_16M, CFG_LOCAL_CONF_REGS, 4, AC_R|AC_W|AC_X|SA_G|SA_I) diff --git a/board/amcc/canyonlands/u-boot-nand.lds b/board/amcc/canyonlands/u-boot-nand.lds new file mode 100644 index 0000000..12a5dcf --- /dev/null +++ b/board/amcc/canyonlands/u-boot-nand.lds @@ -0,0 +1,137 @@ +/* + * (C) Copyright 2008 + * 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) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + /* WARNING - the following is hand-optimized to fit within */ + /* the sector layout of our flash chips! XXX FIXME XXX */ + + cpu/ppc4xx/start.o (.text) + + /* Align to next NAND block */ + . = ALIGN(0x4000); + common/environment.o (.ppcenv) + /* Keep some space here for redundant env and potential bad env blocks */ + . = ALIGN(0x10000); + + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; + __fixup_entries = (. - _FIXUP_TABLE_)>>2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + + . = .; + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(256); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(256); + __init_end = .; + + __bss_start = .; + .bss (NOLOAD) : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + + _end = . ; + PROVIDE (end = .); +} diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index cdfc943..8d2777d 100644 --- a/cpu/ppc4xx/start.S +++ b/cpu/ppc4xx/start.S @@ -403,7 +403,8 @@ rsttlb: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/ 2:
#if defined(CONFIG_NAND_SPL) -#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) +#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) */ @@ -415,6 +416,11 @@ 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 +#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) /* diff --git a/include/configs/canyonlands.h b/include/configs/canyonlands.h index 6d8f230..0e6484f 100644 --- a/include/configs/canyonlands.h +++ b/include/configs/canyonlands.h @@ -114,6 +114,65 @@ #else #define CFG_ENV_IS_IN_NAND 1 /* use NAND for environment vars */ #define CFG_NAND_CS 0 /* NAND chip connected to CSx */ +#define CFG_ENV_IS_EMBEDDED 1 /* use embedded environment */ +#endif + +/* + * 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 (CFG_OCM_BASE + (12 << 10)) /* 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 */ +#undef CFG_NAND_4_ADDR_CYCLE /* No 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/canyonlands/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
/*----------------------------------------------------------------------- @@ -154,10 +213,18 @@ /*------------------------------------------------------------------------------ * DDR SDRAM *----------------------------------------------------------------------------*/ +#if !defined(CONFIG_NAND_U_BOOT) +/* + * NAND booting U-Boot version uses a fixed initialization, since the whole + * I2C SPD DIMM autodetection/calibration doesn't fit into the 4k of boot + * code. + */ #define CONFIG_SPD_EEPROM 1 /* Use SPD EEPROM for setup */ #define SPD_EEPROM_ADDRESS {0x50, 0x51} /* SPD i2c spd addresses*/ #define CONFIG_DDR_ECC 1 /* with ECC support */ #define CONFIG_DDR_RQDC_FIXED 0x80000038 /* fixed value for RQDC */ +#endif +#define CFG_MBYTES_SDRAM 256 /* 256MB */
/*----------------------------------------------------------------------- * I2C @@ -367,23 +434,29 @@ * EBC address which accepts bigger regions: * * 0xfc00.0000 -> 4.cc00.0000 - * - * For this we have to remap the CS0 and re-relocate the envrironment, - * since the original FLASH location which was needed upon startup is - * now not correct anymore. */
+#if defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL) +/* Memory Bank 3 (NOR-FLASH) initialization */ +#define CFG_EBC_PB3AP 0x10055e00 +#define CFG_EBC_PB3CR (CFG_BOOT_BASE_ADDR | 0x9a000) + +/* Memory Bank 0 (NAND-FLASH) initialization */ +#define CFG_EBC_PB0AP 0x018003c0 +#define CFG_EBC_PB0CR (CFG_NAND_ADDR | 0x1E000) /* BAS=NAND,BS=1MB,BU=R/W,BW=32bit*/ +#else /* Memory Bank 0 (NOR-FLASH) initialization */ #define CFG_EBC_PB0AP 0x10055e00 #define CFG_EBC_PB0CR (CFG_BOOT_BASE_ADDR | 0x9a000)
-/* Memory Bank 2 (CPLD) initialization */ -#define CFG_EBC_PB2AP 0x00804240 -#define CFG_EBC_PB2CR (CFG_BCSR_BASE | 0x18000) /* BAS=CPLD,BS=1M,BU=RW,BW=32bit */ - /* Memory Bank 3 (NAND-FLASH) initialization */ #define CFG_EBC_PB3AP 0x018003c0 #define CFG_EBC_PB3CR (CFG_NAND_ADDR | 0x1E000) /* BAS=NAND,BS=1MB,BU=R/W,BW=32bit*/ +#endif + +/* Memory Bank 2 (CPLD) initialization */ +#define CFG_EBC_PB2AP 0x00804240 +#define CFG_EBC_PB2CR (CFG_BCSR_BASE | 0x18000) /* BAS=CPLD,BS=1M,BU=RW,BW=32bit */
#define CFG_EBC_CFG 0xB8400000 /* EBC0_CFG */
diff --git a/nand_spl/board/amcc/canyonlands/Makefile b/nand_spl/board/amcc/canyonlands/Makefile new file mode 100644 index 0000000..0a3c9c0 --- /dev/null +++ b/nand_spl/board/amcc/canyonlands/Makefile @@ -0,0 +1,100 @@ +# +# (C) Copyright 2008 +# 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 = ddr2_fixed.o nand_boot.o nand_ecc.o ndfc.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/canyonlands/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/mtd/nand directory +$(obj)nand_ecc.c: + @rm -f $(obj)nand_ecc.c + ln -s $(SRCTREE)/drivers/mtd/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/canyonlands/config.mk b/nand_spl/board/amcc/canyonlands/config.mk new file mode 100644 index 0000000..6dad876 --- /dev/null +++ b/nand_spl/board/amcc/canyonlands/config.mk @@ -0,0 +1,49 @@ +# +# (C) Copyright 2008 +# 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 460EX Reference Platform (Canyonlands) board +# + +# +# TEXT_BASE for SPL: +# +# On 460EX platforms the SPL is located at 0xfffff000...0xffffffff, +# in the last 4kBytes of memory space in cache. +# We will copy this SPL into internal SRAM in start.S. So we set +# TEXT_BASE to starting address in internal SRAM here. +# +TEXT_BASE = 0xE3003000 + +# PAD_TO used to generate a 16kByte binary needed for the combined image +# -> PAD_TO = TEXT_BASE + 0x4000 +PAD_TO = 0xE3007000 + +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/canyonlands/ddr2_fixed.c b/nand_spl/board/amcc/canyonlands/ddr2_fixed.c new file mode 100644 index 0000000..48708a8 --- /dev/null +++ b/nand_spl/board/amcc/canyonlands/ddr2_fixed.c @@ -0,0 +1,96 @@ +/* + * (C) Copyright 2008 + * 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 <common.h> +#include <ppc4xx.h> +#include <asm/io.h> +#include <asm/processor.h> + +static void wait_init_complete(void) +{ + u32 val; + + do { + mfsdram(SDRAM_MCSTAT, val); + } while (!(val & 0x80000000)); +} + +long int initdram(int board_type) +{ + /* + * Reset the DDR-SDRAM controller. + */ + mtsdr(SDR0_SRST, (0x80000000 >> 10)); + mtsdr(SDR0_SRST, 0x00000000); + + /* + * These values are cloned from a running NOR booting + * Canyonlands with SPD-DDR2 detection and calibration + * enabled. This will only work for the same memory + * configuration as used here: + * + * Crucial CT3264AC53E.4FD - 256MB SO-DIMM + * + */ + mtsdram(SDRAM_MCOPT2, 0x00000000); + mtsdram(SDRAM_MCOPT1, 0x05122000); + mtsdram(SDRAM_MODT0, 0x01000000); + mtsdram(SDRAM_CODT, 0x00800021); + mtsdram(SDRAM_WRDTR, 0x82000823); + mtsdram(SDRAM_CLKTR, 0x40000000); + mtsdram(SDRAM_MB0CF, 0x00000201); + mtsdram(SDRAM_RTR, 0x06180000); + mtsdram(SDRAM_SDTR1, 0x80201000); + mtsdram(SDRAM_SDTR2, 0x42103243); + mtsdram(SDRAM_SDTR3, 0x0A0D0D16); + mtsdram(SDRAM_MMODE, 0x00000632); + mtsdram(SDRAM_MEMODE, 0x00000040); + mtsdram(SDRAM_INITPLR0, 0xB5380000); + mtsdram(SDRAM_INITPLR1, 0x82100400); + mtsdram(SDRAM_INITPLR2, 0x80820000); + mtsdram(SDRAM_INITPLR3, 0x80830000); + mtsdram(SDRAM_INITPLR4, 0x80810040); + mtsdram(SDRAM_INITPLR5, 0x80800532); + mtsdram(SDRAM_INITPLR6, 0x82100400); + mtsdram(SDRAM_INITPLR7, 0x8A080000); + mtsdram(SDRAM_INITPLR8, 0x8A080000); + mtsdram(SDRAM_INITPLR9, 0x8A080000); + mtsdram(SDRAM_INITPLR10, 0x8A080000); + mtsdram(SDRAM_INITPLR11, 0x80000432); + mtsdram(SDRAM_INITPLR12, 0x808103C0); + mtsdram(SDRAM_INITPLR13, 0x80810040); + mtsdram(SDRAM_INITPLR14, 0x00000000); + mtsdram(SDRAM_INITPLR15, 0x00000000); + + mtsdram(SDRAM_MCOPT2, 0x28000000); + + wait_init_complete(); + + mtdcr(SDRAM_R0BAS, 0x0000F800); /* MQ0_B0BAS */ + + mtsdram(SDRAM_RDCC, 0x40000000); + mtsdram(SDRAM_RQDC, 0x80000038); + mtsdram(SDRAM_RFDC, 0x00000257); + + return CFG_MBYTES_SDRAM << 20; +} diff --git a/nand_spl/board/amcc/canyonlands/u-boot.lds b/nand_spl/board/amcc/canyonlands/u-boot.lds new file mode 100644 index 0000000..5bffb5b --- /dev/null +++ b/nand_spl/board/amcc/canyonlands/u-boot.lds @@ -0,0 +1,65 @@ +/* + * (C) Copyright 2008 + * 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 0xE3003FFC : + { + *(.resetvec) + } = 0xffff + + .text : + { + start.o (.text) + init.o (.text) + nand_boot.o (.text) + ddr2_fixed.o (.text) + ndfc.o (.text) + + *(.text) + *(.fixup) + } + _etext = .; + + .data : + { + *(.rodata*) + *(.data*) + *(.sdata*) + __got2_start = .; + *(.got2) + __got2_end = .; + } + + _edata = .; + + __bss_start = .; + .bss (NOLOAD) : + { + *(.sbss) + *(.bss) + } + + _end = . ; +}

This patch adds CFG_OHCI_USE_NPS to the common USB-OHCI driver. This way a board just needs to define this new option to enable the "force NoPowerSwitching mode" instead of adding new CPU/architecture defines to the USB source itself.
This new option will be used first with the new AMCC 460EX Canyonlands board port, which will be posted in a few days.
This patch also fixes a small compilation problem when DEBUG is enabled.
Signed-off-by: Stefan Roese sr@denx.de --- drivers/usb/usb_ohci.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/usb_ohci.c b/drivers/usb/usb_ohci.c index fb4726f..829bbca 100644 --- a/drivers/usb/usb_ohci.c +++ b/drivers/usb/usb_ohci.c @@ -68,7 +68,8 @@ defined(CONFIG_S3C2410) || \ defined(CONFIG_440EP) || \ defined(CONFIG_PCI_OHCI) || \ - defined(CONFIG_MPC5200) + defined(CONFIG_MPC5200) || \ + defined(CFG_OHCI_USE_NPS) # define OHCI_USE_NPS /* force NoPowerSwitching mode */ #endif
@@ -415,7 +416,7 @@ static void ohci_dump (ohci_t *controller, int verbose) ep_print_int_eds (controller, "hcca"); dbg ("hcca frame #%04x", controller->hcca->frame_no); ohci_dump_roothub (controller, 1); - +} #endif /* DEBUG */
/*-------------------------------------------------------------------------*

This patch adds USB OHCI support to the Canyonlands board port. It also enables EXT2 support.
Signed-off-by: Stefan Roese sr@denx.de --- board/amcc/canyonlands/canyonlands.c | 14 +++++++ board/amcc/canyonlands/init.S | 3 + include/configs/canyonlands.h | 68 +++++++++++++++++++++++----------- include/ppc440.h | 3 + 4 files changed, 66 insertions(+), 22 deletions(-)
diff --git a/board/amcc/canyonlands/canyonlands.c b/board/amcc/canyonlands/canyonlands.c index 3551429..36779f5 100644 --- a/board/amcc/canyonlands/canyonlands.c +++ b/board/amcc/canyonlands/canyonlands.c @@ -26,6 +26,7 @@ #include <asm/io.h> #include <asm/mmu.h> #include <asm/4xx_pcie.h> +#include <asm/gpio.h>
extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
@@ -100,6 +101,19 @@ int board_early_init_f(void)
mtsdr(SDR0_SRST1, 0); /* Pull AHB out of reset default=1 */
+ /* Setup PLB4-AHB bridge based on the system address map */ + mtdcr(AHB_TOP, 0x8000004B); + mtdcr(AHB_BOT, 0x8000004B); + + /* + * Configure USB-STP pins as alternate and not GPIO + * It seems to be neccessary to configure the STP pins as GPIO + * input at powerup (perhaps while USB reset is asserted). So + * we configure those pins to their "real" function now. + */ + gpio_config(16, GPIO_OUT, GPIO_ALT1, GPIO_OUT_1); + gpio_config(19, GPIO_OUT, GPIO_ALT1, GPIO_OUT_1); + return 0; }
diff --git a/board/amcc/canyonlands/init.S b/board/amcc/canyonlands/init.S index b7cac23..bd4cab5 100644 --- a/board/amcc/canyonlands/init.S +++ b/board/amcc/canyonlands/init.S @@ -88,6 +88,9 @@ tlbtab: /* TLB-entry for Local Configuration registers => peripherals */ tlbentry(CFG_LOCAL_CONF_REGS, SZ_16M, CFG_LOCAL_CONF_REGS, 4, AC_R|AC_W|AC_X|SA_G|SA_I)
+ /* AHB: Internal USB Peripherals (USB, SATA) */ + tlbentry(CFG_AHB_BASE, SZ_1M, 0xbff00000, 4, AC_R|AC_W|AC_X|SA_G|SA_I) + tlbtab_end
#if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) diff --git a/include/configs/canyonlands.h b/include/configs/canyonlands.h index 0e6484f..55390ca 100644 --- a/include/configs/canyonlands.h +++ b/include/configs/canyonlands.h @@ -79,6 +79,8 @@
#define CFG_PERIPHERAL_BASE 0xEF600000 /* internal peripherals */
+#define CFG_AHB_BASE 0xE2000000 /* internal AHB peripherals */ + #define CFG_MONITOR_BASE TEXT_BASE #define CFG_MONITOR_LEN (384 * 1024) /* Reserve 384 kB for Monitor */ #define CFG_MALLOC_LEN (512 * 1024) /* Reserve 512 kB for malloc()*/ @@ -270,6 +272,21 @@
#define CFG_RX_ETH_BUFFER 32 /* Number of ethernet rx buffers & descriptors */
+/*----------------------------------------------------------------------- + * USB-OHCI + *----------------------------------------------------------------------*/ +#define CONFIG_USB_OHCI_NEW +#define CONFIG_USB_STORAGE +#undef CFG_OHCI_BE_CONTROLLER /* 460EX has little endian descriptors */ +#define CFG_OHCI_SWAP_REG_ACCESS /* 460EX has little endian register */ +#define CFG_OHCI_USE_NPS /* force NoPowerSwitching mode */ +#define CFG_USB_OHCI_REGS_BASE (CFG_AHB_BASE | 0xd0000) +#define CFG_USB_OHCI_SLOT_NAME "ppc440" +#define CFG_USB_OHCI_MAX_ROOT_PORTS 15 + +/*----------------------------------------------------------------------- + * Default environment + *----------------------------------------------------------------------*/ #define CONFIG_PREBOOT "echo;" \ "echo Type "run flash_nfs" to mount root filesystem over NFS;" \ "echo" @@ -344,6 +361,7 @@ #define CONFIG_CMD_DIAG #define CONFIG_CMD_EEPROM #define CONFIG_CMD_ELF +#define CONFIG_CMD_EXT2 #define CONFIG_CMD_FAT #define CONFIG_CMD_I2C #define CONFIG_CMD_IRQ @@ -355,6 +373,12 @@ #define CONFIG_CMD_PING #define CONFIG_CMD_REGINFO #define CONFIG_CMD_SDRAM +#define CONFIG_CMD_USB + +/* Partitions */ +#define CONFIG_MAC_PARTITION +#define CONFIG_DOS_PARTITION +#define CONFIG_ISO_PARTITION
/*----------------------------------------------------------------------- * Miscellaneous configurable options @@ -466,28 +490,28 @@ #define CFG_4xx_GPIO_TABLE { /* Out GPIO Alternate1 Alternate2 Alternate3 */ \ { \ /* GPIO Core 0 */ \ -{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO0 GMC1TxD(0) USB2HostD(0) */ \ -{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO1 GMC1TxD(1) USB2HostD(1) */ \ -{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO2 GMC1TxD(2) USB2HostD(2) */ \ -{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO3 GMC1TxD(3) USB2HostD(3) */ \ -{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO4 GMC1TxD(4) USB2HostD(4) */ \ -{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO5 GMC1TxD(5) USB2HostD(5) */ \ -{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO6 GMC1TxD(6) USB2HostD(6) */ \ -{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO7 GMC1TxD(7) USB2HostD(7) */ \ -{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO8 GMC1RxD(0) USB2OTGD(0) */ \ -{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO9 GMC1RxD(1) USB2OTGD(1) */ \ -{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO10 GMC1RxD(2) USB2OTGD(2) */ \ -{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO11 GMC1RxD(3) USB2OTGD(3) */ \ -{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO12 GMC1RxD(4) USB2OTGD(4) */ \ -{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO13 GMC1RxD(5) USB2OTGD(5) */ \ -{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO14 GMC1RxD(6) USB2OTGD(6) */ \ -{GPIO0_BASE, GPIO_BI , GPIO_ALT2, GPIO_OUT_0}, /* GPIO15 GMC1RxD(7) USB2OTGD(7) */ \ -{GPIO0_BASE, GPIO_OUT, GPIO_ALT2, GPIO_OUT_0}, /* GPIO16 GMC1TxER USB2HostStop */ \ -{GPIO0_BASE, GPIO_IN , GPIO_ALT2, GPIO_OUT_0}, /* GPIO17 GMC1CD USB2HostNext */ \ -{GPIO0_BASE, GPIO_IN , GPIO_ALT2, GPIO_OUT_0}, /* GPIO18 GMC1RxER USB2HostDir */ \ -{GPIO0_BASE, GPIO_OUT, GPIO_ALT2, GPIO_OUT_0}, /* GPIO19 GMC1TxEN USB2OTGStop */ \ -{GPIO0_BASE, GPIO_IN , GPIO_ALT2, GPIO_OUT_0}, /* GPIO20 GMC1CRS USB2OTGNext */ \ -{GPIO0_BASE, GPIO_IN , GPIO_ALT2, GPIO_OUT_0}, /* GPIO21 GMC1RxDV USB2OTGDir */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT1, GPIO_OUT_0}, /* GPIO0 GMC1TxD(0) USB2HostD(0) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT1, GPIO_OUT_0}, /* GPIO1 GMC1TxD(1) USB2HostD(1) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT1, GPIO_OUT_0}, /* GPIO2 GMC1TxD(2) USB2HostD(2) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT1, GPIO_OUT_0}, /* GPIO3 GMC1TxD(3) USB2HostD(3) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT1, GPIO_OUT_0}, /* GPIO4 GMC1TxD(4) USB2HostD(4) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT1, GPIO_OUT_0}, /* GPIO5 GMC1TxD(5) USB2HostD(5) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT1, GPIO_OUT_0}, /* GPIO6 GMC1TxD(6) USB2HostD(6) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT1, GPIO_OUT_0}, /* GPIO7 GMC1TxD(7) USB2HostD(7) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT1, GPIO_OUT_0}, /* GPIO8 GMC1RxD(0) USB2OTGD(0) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT1, GPIO_OUT_0}, /* GPIO9 GMC1RxD(1) USB2OTGD(1) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT1, GPIO_OUT_0}, /* GPIO10 GMC1RxD(2) USB2OTGD(2) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT1, GPIO_OUT_0}, /* GPIO11 GMC1RxD(3) USB2OTGD(3) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT1, GPIO_OUT_0}, /* GPIO12 GMC1RxD(4) USB2OTGD(4) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT1, GPIO_OUT_0}, /* GPIO13 GMC1RxD(5) USB2OTGD(5) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT1, GPIO_OUT_0}, /* GPIO14 GMC1RxD(6) USB2OTGD(6) */ \ +{GPIO0_BASE, GPIO_BI , GPIO_ALT1, GPIO_OUT_0}, /* GPIO15 GMC1RxD(7) USB2OTGD(7) */ \ +{GPIO0_BASE, GPIO_IN , GPIO_SEL, GPIO_OUT_0}, /* GPIO16 GMC1TxER USB2HostStop */ \ +{GPIO0_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO17 GMC1CD USB2HostNext */ \ +{GPIO0_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO18 GMC1RxER USB2HostDir */ \ +{GPIO0_BASE, GPIO_IN, GPIO_SEL, GPIO_OUT_0}, /* GPIO19 GMC1TxEN USB2OTGStop */ \ +{GPIO0_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO20 GMC1CRS USB2OTGNext */ \ +{GPIO0_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO21 GMC1RxDV USB2OTGDir */ \ {GPIO0_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO22 NFRDY */ \ {GPIO0_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO23 NFREN */ \ {GPIO0_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO24 NFWEN */ \ diff --git a/include/ppc440.h b/include/ppc440.h index cf29fe7..80dd332 100644 --- a/include/ppc440.h +++ b/include/ppc440.h @@ -3355,6 +3355,9 @@ #define SDR0_DDR0_DDRM_DECODE(n) ((((unsigned long)(n))>>29)&0x03) #define SDR0_DDR0_TUNE_ENCODE(n) ((((unsigned long)(n))&0x2FF)<<0) #define SDR0_DDR0_TUNE_DECODE(n) ((((unsigned long)(n))>>0)&0x2FF) + +#define AHB_TOP 0xA4 +#define AHB_BOT 0xA5 #endif /* CONFIG_460EX || CONFIG_460GT */
#define SDR0_SDCS_SDD (0x80000000 >> 31)
participants (2)
-
Stefan Roese
-
Wolfgang Denk