diff options
Diffstat (limited to 'cpu')
43 files changed, 1596 insertions, 1096 deletions
diff --git a/cpu/74xx_7xx/cache.S b/cpu/74xx_7xx/cache.S index 3a745cb..eac4544 100644 --- a/cpu/74xx_7xx/cache.S +++ b/cpu/74xx_7xx/cache.S @@ -245,6 +245,10 @@ _GLOBAL(icache_enable) * Disable L1 Instruction cache */ _GLOBAL(icache_disable) + mflr r4 + bl invalidate_l1_instruction_cache /* uses r3 */ + sync + mtlr r4 mfspr r3, HID0 li r5, 0 ori r5, r5, HID0_ICE diff --git a/cpu/arm1136/mx31/generic.c b/cpu/arm1136/mx31/generic.c index 29c08c1..dc031c9 100644 --- a/cpu/arm1136/mx31/generic.c +++ b/cpu/arm1136/mx31/generic.c @@ -81,12 +81,12 @@ void mx31_gpio_mux(unsigned long mode) { unsigned long reg, shift, tmp; - reg = IOMUXC_BASE + (mode & 0xfc); + reg = IOMUXC_BASE + (mode & 0x1fc); shift = (~mode & 0x3) * 8; tmp = __REG(reg); tmp &= ~(0xff << shift); - tmp |= ((mode >> 8) & 0xff) << shift; + tmp |= ((mode >> IOMUX_MODE_POS) & 0xff) << shift; __REG(reg) = tmp; } diff --git a/cpu/arm920t/s3c24x0/nand.c b/cpu/arm920t/s3c24x0/nand.c index e1bf128..60174fb 100644 --- a/cpu/arm920t/s3c24x0/nand.c +++ b/cpu/arm920t/s3c24x0/nand.c @@ -27,10 +27,11 @@ #endif #if defined(CONFIG_CMD_NAND) -#if !defined(CFG_NAND_LEGACY) +#if !defined(CONFIG_NAND_LEGACY) #include <nand.h> #include <s3c2410.h> +#include <asm/io.h> #define __REGb(x) (*(volatile unsigned char *)(x)) #define __REGi(x) (*(volatile unsigned int *)(x)) @@ -54,34 +55,33 @@ #define S3C2410_NFCONF_TWRPH0(x) ((x)<<4) #define S3C2410_NFCONF_TWRPH1(x) ((x)<<0) -static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd) +#define S3C2410_ADDR_NALE 4 +#define S3C2410_ADDR_NCLE 8 + +static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *chip = mtd->priv; - DEBUGN("hwcontrol(): 0x%02x: ", cmd); - - switch (cmd) { - case NAND_CTL_SETNCE: - NFCONF &= ~S3C2410_NFCONF_nFCE; - DEBUGN("NFCONF=0x%08x\n", NFCONF); - break; - case NAND_CTL_CLRNCE: - NFCONF |= S3C2410_NFCONF_nFCE; - DEBUGN("NFCONF=0x%08x\n", NFCONF); - break; - case NAND_CTL_SETALE: - chip->IO_ADDR_W = NF_BASE + 0x8; - DEBUGN("SETALE\n"); - break; - case NAND_CTL_SETCLE: - chip->IO_ADDR_W = NF_BASE + 0x4; - DEBUGN("SETCLE\n"); - break; - default: - chip->IO_ADDR_W = NF_BASE + 0xc; - break; + DEBUGN("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl); + + if (ctrl & NAND_CTRL_CHANGE) { + ulong IO_ADDR_W = NF_BASE; + + if (!(ctrl & NAND_CLE)) + IO_ADDR_W |= S3C2410_ADDR_NCLE; + if (!(ctrl & NAND_ALE)) + IO_ADDR_W |= S3C2410_ADDR_NALE; + + chip->IO_ADDR_W = (void *)IO_ADDR_W; + + if (ctrl & NAND_NCE) + NFCONF &= ~S3C2410_NFCONF_nFCE; + else + NFCONF |= S3C2410_NFCONF_nFCE; } - return; + + if (cmd != NAND_CMD_NONE) + writeb(cmd, chip->IO_ADDR_W); } static int s3c2410_dev_ready(struct mtd_info *mtd) @@ -93,7 +93,7 @@ static int s3c2410_dev_ready(struct mtd_info *mtd) #ifdef CONFIG_S3C2410_NAND_HWECC void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode) { - DEBUGN("s3c2410_nand_enable_hwecc(%p, %d)\n", mtd ,mode); + DEBUGN("s3c2410_nand_enable_hwecc(%p, %d)\n", mtd, mode); NFCONF |= S3C2410_NFCONF_INITECC; } @@ -143,23 +143,23 @@ int board_nand_init(struct nand_chip *nand) NFCONF = cfg; /* initialize nand_chip data structure */ - nand->IO_ADDR_R = nand->IO_ADDR_W = 0x4e00000c; + nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e00000c; /* read_buf and write_buf are default */ /* read_byte and write_byte are default */ /* hwcontrol always must be implemented */ - nand->hwcontrol = s3c2410_hwcontrol; + nand->cmd_ctrl = s3c2410_hwcontrol; nand->dev_ready = s3c2410_dev_ready; #ifdef CONFIG_S3C2410_NAND_HWECC - nand->enable_hwecc = s3c2410_nand_enable_hwecc; - nand->calculate_ecc = s3c2410_nand_calculate_ecc; - nand->correct_data = s3c2410_nand_correct_data; - nand->eccmode = NAND_ECC_HW3_512; + nand->ecc.hwctl = s3c2410_nand_enable_hwecc; + nand->ecc.calculate = s3c2410_nand_calculate_ecc; + nand->ecc.correct = s3c2410_nand_correct_data; + nand->ecc.mode = NAND_ECC_HW3_512; #else - nand->eccmode = NAND_ECC_SOFT; + nand->ecc.mode = NAND_ECC_SOFT; #endif #ifdef CONFIG_S3C2410_NAND_BBT diff --git a/cpu/arm926ejs/at91sam9/Makefile b/cpu/arm926ejs/at91/Makefile index 44cde1a..44cde1a 100644 --- a/cpu/arm926ejs/at91sam9/Makefile +++ b/cpu/arm926ejs/at91/Makefile diff --git a/cpu/arm926ejs/at91sam9/config.mk b/cpu/arm926ejs/at91/config.mk index 83040eb..31491a8 100644 --- a/cpu/arm926ejs/at91sam9/config.mk +++ b/cpu/arm926ejs/at91/config.mk @@ -1,3 +1,3 @@ PLATFORM_CPPFLAGS += -march=armv5te PLATFORM_CPPFLAGS += $(call cc-option,-mtune=arm926ejs,) -LDSCRIPT := $(SRCTREE)/cpu/arm926ejs/at91sam9/u-boot.lds +LDSCRIPT := $(SRCTREE)/cpu/arm926ejs/at91/u-boot.lds diff --git a/cpu/arm926ejs/at91sam9/ether.c b/cpu/arm926ejs/at91/ether.c index 7e11fe4..7e11fe4 100644 --- a/cpu/arm926ejs/at91sam9/ether.c +++ b/cpu/arm926ejs/at91/ether.c diff --git a/cpu/arm926ejs/at91sam9/lowlevel_init.S b/cpu/arm926ejs/at91/lowlevel_init.S index ec6ad5d..ec6ad5d 100644 --- a/cpu/arm926ejs/at91sam9/lowlevel_init.S +++ b/cpu/arm926ejs/at91/lowlevel_init.S diff --git a/cpu/arm926ejs/at91sam9/spi.c b/cpu/arm926ejs/at91/spi.c index c9fe6d8..c9fe6d8 100644 --- a/cpu/arm926ejs/at91sam9/spi.c +++ b/cpu/arm926ejs/at91/spi.c diff --git a/cpu/arm926ejs/at91sam9/timer.c b/cpu/arm926ejs/at91/timer.c index c79ec7e..c79ec7e 100644 --- a/cpu/arm926ejs/at91sam9/timer.c +++ b/cpu/arm926ejs/at91/timer.c diff --git a/cpu/arm926ejs/at91sam9/u-boot.lds b/cpu/arm926ejs/at91/u-boot.lds index 996f401..996f401 100644 --- a/cpu/arm926ejs/at91sam9/u-boot.lds +++ b/cpu/arm926ejs/at91/u-boot.lds diff --git a/cpu/arm926ejs/at91sam9/usb.c b/cpu/arm926ejs/at91/usb.c index 2a92f73..2a92f73 100644 --- a/cpu/arm926ejs/at91sam9/usb.c +++ b/cpu/arm926ejs/at91/usb.c diff --git a/cpu/arm926ejs/davinci/nand.c b/cpu/arm926ejs/davinci/nand.c index 36468e6..2aa01d6 100644 --- a/cpu/arm926ejs/davinci/nand.c +++ b/cpu/arm926ejs/davinci/nand.c @@ -42,9 +42,10 @@ */ #include <common.h> +#include <asm/io.h> #ifdef CFG_USE_NAND -#if !defined(CFG_NAND_LEGACY) +#if !defined(CONFIG_NAND_LEGACY) #include <nand.h> #include <asm/arch/nand_defs.h> @@ -52,23 +53,23 @@ extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; -static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd) +static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *this = mtd->priv; u_int32_t IO_ADDR_W = (u_int32_t)this->IO_ADDR_W; IO_ADDR_W &= ~(MASK_ALE|MASK_CLE); - switch (cmd) { - case NAND_CTL_SETCLE: + if (ctrl & NAND_CTRL_CHANGE) { + if ( ctrl & NAND_CLE ) IO_ADDR_W |= MASK_CLE; - break; - case NAND_CTL_SETALE: + if ( ctrl & NAND_ALE ) IO_ADDR_W |= MASK_ALE; - break; + this->IO_ADDR_W = (void __iomem *) IO_ADDR_W; } - this->IO_ADDR_W = (void *)IO_ADDR_W; + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); } /* Set WP on deselect, write enable on select */ @@ -88,18 +89,27 @@ static void nand_davinci_select_chip(struct mtd_info *mtd, int chip) #ifdef CFG_NAND_HW_ECC #ifdef CFG_NAND_LARGEPAGE -static struct nand_oobinfo davinci_nand_oobinfo = { +static struct nand_ecclayout davinci_nand_ecclayout = { .useecc = MTD_NANDECC_AUTOPLACE, .eccbytes = 12, .eccpos = {8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58}, - .oobfree = { {2, 6}, {12, 12}, {28, 12}, {44, 12}, {60, 4} } + .oobfree = { + {.offset = 2, .length = 6}, + {.offset = 12, .length = 12}, + {.offset = 28, .length = 12}, + {.offset = 44, .length = 12}, + {.offset = 60, .length = 4} + } }; #elif defined(CFG_NAND_SMALLPAGE) -static struct nand_oobinfo davinci_nand_oobinfo = { +static struct nand_ecclayout davinci_nand_ecclayout = { .useecc = MTD_NANDECC_AUTOPLACE, .eccbytes = 3, .eccpos = {0, 1, 2}, - .oobfree = { {6, 2}, {8, 8} } + .oobfree = { + {.offset = 6, .length = 2}, + {.offset = 8, .length = 8} + } }; #else #error "Either CFG_NAND_LARGEPAGE or CFG_NAND_SMALLPAGE must be defined!" @@ -145,7 +155,7 @@ static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u int region, n; struct nand_chip *this = mtd->priv; - n = (this->eccmode == NAND_ECC_HW12_2048) ? 4 : 1; + n = (this->ecc.size/512); region = 1; while (n--) { @@ -281,7 +291,7 @@ static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, u_char * int block_count = 0, i, rc; this = mtd->priv; - block_count = (this->eccmode == NAND_ECC_HW12_2048) ? 4 : 1; + block_count = (this->ecc.size/512); for (i = 0; i < block_count; i++) { if (memcmp(read_ecc, calc_ecc, 3) != 0) { rc = nand_davinci_compare_ecc(read_ecc, calc_ecc, dat); @@ -306,7 +316,7 @@ static int nand_davinci_dev_ready(struct mtd_info *mtd) return(emif_addr->NANDFSR & 0x1); } -static int nand_davinci_waitfunc(struct mtd_info *mtd, struct nand_chip *this, int state) +static int nand_davinci_waitfunc(struct mtd_info *mtd, struct nand_chip *this) { while(!nand_davinci_dev_ready(mtd)) {;} *NAND_CE0CLE = NAND_STATUS; @@ -362,22 +372,26 @@ int board_nand_init(struct nand_chip *nand) #endif #ifdef CFG_NAND_HW_ECC #ifdef CFG_NAND_LARGEPAGE - nand->eccmode = NAND_ECC_HW12_2048; + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.size = 2048; + nand->ecc.bytes = 12; #elif defined(CFG_NAND_SMALLPAGE) - nand->eccmode = NAND_ECC_HW3_512; + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.size = 512; + nand->ecc.bytes = 3; #else #error "Either CFG_NAND_LARGEPAGE or CFG_NAND_SMALLPAGE must be defined!" #endif - nand->autooob = &davinci_nand_oobinfo; - nand->calculate_ecc = nand_davinci_calculate_ecc; - nand->correct_data = nand_davinci_correct_data; - nand->enable_hwecc = nand_davinci_enable_hwecc; + nand->ecc.layout = &davinci_nand_ecclayout; + nand->ecc.calculate = nand_davinci_calculate_ecc; + nand->ecc.correct = nand_davinci_correct_data; + nand->ecc.hwctl = nand_davinci_enable_hwecc; #else - nand->eccmode = NAND_ECC_SOFT; + nand->ecc.mode = NAND_ECC_SOFT; #endif /* Set address of hardware control function */ - nand->hwcontrol = nand_davinci_hwcontrol; + nand->cmd_ctrl = nand_davinci_hwcontrol; nand->dev_ready = nand_davinci_dev_ready; nand->waitfunc = nand_davinci_waitfunc; diff --git a/cpu/mcf52x2/cpu_init.c b/cpu/mcf52x2/cpu_init.c index 344bcee..3cacb55 100644 --- a/cpu/mcf52x2/cpu_init.c +++ b/cpu/mcf52x2/cpu_init.c @@ -442,7 +442,7 @@ void cpu_init_f(void) MCFCSM_CSMR0 = MCFCSM_CSMR_BAM(CFG_CS0_SIZE - 1) | MCFCSM_CSMR_V; #endif #else -#waring "Chip Select 0 are not initialized/used" +#warning "Chip Select 0 are not initialized/used" #endif #if defined(CFG_CS1_BASE) & defined(CFG_CS1_SIZE) & \ diff --git a/cpu/mcf52x2/start.S b/cpu/mcf52x2/start.S index a054904..2e8ecfb 100644 --- a/cpu/mcf52x2/start.S +++ b/cpu/mcf52x2/start.S @@ -166,7 +166,7 @@ _after_flashbar_copy: #else /* Setup code to initialize FLASHBAR, if start from external Memory */ move.l #(CFG_INT_FLASH_BASE + CFG_INT_FLASH_ENABLE), %d0 - movec %d0, %RAMBAR1 + movec %d0, %FLASHBAR #endif /* (TEXT_BASE == CFG_INT_FLASH_BASE) */ #endif diff --git a/cpu/mcf5445x/cpu_init.c b/cpu/mcf5445x/cpu_init.c index e07748b..51a9e90 100644 --- a/cpu/mcf5445x/cpu_init.c +++ b/cpu/mcf5445x/cpu_init.c @@ -61,11 +61,13 @@ void cpu_init_f(void) GPIO_PAR_FBCTL_OE | GPIO_PAR_FBCTL_TA_TA | GPIO_PAR_FBCTL_RW_RW | GPIO_PAR_FBCTL_TS_TS; +#if !defined(CONFIG_CF_SBF) #if (defined(CFG_CS0_BASE) && defined(CFG_CS0_MASK) && defined(CFG_CS0_CTRL)) fbcs->csar0 = CFG_CS0_BASE; fbcs->cscr0 = CFG_CS0_CTRL; fbcs->csmr0 = CFG_CS0_MASK; #endif +#endif #if (defined(CFG_CS1_BASE) && defined(CFG_CS1_MASK) && defined(CFG_CS1_CTRL)) /* Latch chipselect */ diff --git a/cpu/mcf5445x/dspi.c b/cpu/mcf5445x/dspi.c index 44d8505..959d6bd 100644 --- a/cpu/mcf5445x/dspi.c +++ b/cpu/mcf5445x/dspi.c @@ -27,9 +27,11 @@ #include <common.h> #include <spi.h> +#include <malloc.h> #if defined(CONFIG_CF_DSPI) #include <asm/immap.h> + void dspi_init(void) { volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; @@ -45,11 +47,30 @@ void dspi_init(void) DSPI_DMCR_CSIS2 | DSPI_DMCR_CSIS1 | DSPI_DMCR_CSIS0 | DSPI_DMCR_CRXF | DSPI_DMCR_CTXF; - dspi->dctar0 = DSPI_DCTAR_TRSZ(7) | DSPI_DCTAR_CPOL | DSPI_DCTAR_CPHA | - DSPI_DCTAR_PCSSCK_1CLK | DSPI_DCTAR_PASC(0) | - DSPI_DCTAR_PDT(0) | DSPI_DCTAR_CSSCK(0) | - DSPI_DCTAR_ASC(0) | DSPI_DCTAR_PBR(0) | - DSPI_DCTAR_DT(1) | DSPI_DCTAR_BR(1); +#ifdef CFG_DSPI_DCTAR0 + dspi->dctar0 = CFG_DSPI_DCTAR0; +#endif +#ifdef CFG_DSPI_DCTAR1 + dspi->dctar1 = CFG_DSPI_DCTAR1; +#endif +#ifdef CFG_DSPI_DCTAR2 + dspi->dctar2 = CFG_DSPI_DCTAR2; +#endif +#ifdef CFG_DSPI_DCTAR3 + dspi->dctar3 = CFG_DSPI_DCTAR3; +#endif +#ifdef CFG_DSPI_DCTAR4 + dspi->dctar4 = CFG_DSPI_DCTAR4; +#endif +#ifdef CFG_DSPI_DCTAR5 + dspi->dctar5 = CFG_DSPI_DCTAR5; +#endif +#ifdef CFG_DSPI_DCTAR6 + dspi->dctar6 = CFG_DSPI_DCTAR6; +#endif +#ifdef CFG_DSPI_DCTAR7 + dspi->dctar7 = CFG_DSPI_DCTAR7; +#endif } void dspi_tx(int chipsel, u8 attrib, u16 data) @@ -70,4 +91,149 @@ u16 dspi_rx(void) return (dspi->drfr & 0xFFFF); } -#endif /* CONFIG_HARD_SPI */ +#if defined(CONFIG_CMD_SPI) +void spi_init_f(void) +{ +} + +void spi_init_r(void) +{ +} + +void spi_init(void) +{ + dspi_init(); +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct spi_slave *slave; + + slave = malloc(sizeof(struct spi_slave)); + if (!slave) + return NULL; + + slave->bus = bus; + slave->cs = cs; + + return slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ + free(slave); +} + +int spi_claim_bus(struct spi_slave *slave) +{ + return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ +} + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, + void *din, unsigned long flags) +{ + static int bWrite = 0; + u8 *spi_rd, *spi_wr; + int len = bitlen >> 3; + + spi_rd = (u8 *) din; + spi_wr = (u8 *) dout; + + /* command handling */ + if (((len == 4) || (len == 1) || (len == 5)) && (dout != NULL)) { + switch (*spi_wr) { + case 0x02: /* Page Prog */ + bWrite = 1; + dspi_tx(slave->cs, 0x80, spi_wr[0]); + dspi_rx(); + dspi_tx(slave->cs, 0x80, spi_wr[1]); + dspi_rx(); + dspi_tx(slave->cs, 0x80, spi_wr[2]); + dspi_rx(); + dspi_tx(slave->cs, 0x80, spi_wr[3]); + dspi_rx(); + return 0; + case 0x05: /* Read Status */ + if (len == 4) + if ((spi_wr[1] == 0xFF) && (spi_wr[2] == 0xFF) + && (spi_wr[3] == 0xFF)) { + dspi_tx(slave->cs, 0x80, *spi_wr); + dspi_rx(); + } + return 0; + case 0x06: /* WREN */ + dspi_tx(slave->cs, 0x00, *spi_wr); + dspi_rx(); + return 0; + case 0x0B: /* Fast read */ + if ((len == 5) && (spi_wr[4] == 0)) { + dspi_tx(slave->cs, 0x80, spi_wr[0]); + dspi_rx(); + dspi_tx(slave->cs, 0x80, spi_wr[1]); + dspi_rx(); + dspi_tx(slave->cs, 0x80, spi_wr[2]); + dspi_rx(); + dspi_tx(slave->cs, 0x80, spi_wr[3]); + dspi_rx(); + dspi_tx(slave->cs, 0x80, spi_wr[4]); + dspi_rx(); + } + return 0; + case 0x9F: /* RDID */ + dspi_tx(slave->cs, 0x80, *spi_wr); + dspi_rx(); + return 0; + case 0xD8: /* Sector erase */ + if (len == 4) + if ((spi_wr[2] == 0) && (spi_wr[3] == 0)) { + dspi_tx(slave->cs, 0x80, spi_wr[0]); + dspi_rx(); + dspi_tx(slave->cs, 0x80, spi_wr[1]); + dspi_rx(); + dspi_tx(slave->cs, 0x80, spi_wr[2]); + dspi_rx(); + dspi_tx(slave->cs, 0x00, spi_wr[3]); + dspi_rx(); + } + return 0; + } + } + + if (bWrite) + len--; + + while (len--) { + if (dout != NULL) { + dspi_tx(slave->cs, 0x80, *spi_wr); + dspi_rx(); + spi_wr++; + } + + if (din != NULL) { + dspi_tx(slave->cs, 0x80, 0); + *spi_rd = dspi_rx(); + spi_rd++; + } + } + + if (flags == SPI_XFER_END) { + if (bWrite) { + dspi_tx(slave->cs, 0x00, *spi_wr); + dspi_rx(); + bWrite = 0; + } else { + dspi_tx(slave->cs, 0x00, 0); + dspi_rx(); + } + } + + return 0; +} +#endif /* CONFIG_CMD_SPI */ + +#endif /* CONFIG_CF_DSPI */ diff --git a/cpu/mcf5445x/speed.c b/cpu/mcf5445x/speed.c index 967becf..f677f3c 100644 --- a/cpu/mcf5445x/speed.c +++ b/cpu/mcf5445x/speed.c @@ -84,26 +84,29 @@ void clock_exit_limp(void) */ int get_clocks(void) { + volatile ccm_t *ccm = (volatile ccm_t *)MMAP_CCM; volatile pll_t *pll = (volatile pll_t *)MMAP_PLL; - volatile u8 *cpld = (volatile u8 *)(CFG_CS2_BASE + 3); - volatile u8 *fpga = (volatile u8 *)(CFG_CS3_BASE + 14); int pllmult_nopci[] = { 20, 10, 24, 18, 12, 6, 16, 8 }; int pllmult_pci[] = { 12, 6, 16, 8 }; - int vco, bPci, temp, fbtemp, pcrvalue; + int vco = 0, bPci, temp, fbtemp, pcrvalue; int *pPllmult = NULL; u16 fbpll_mask; - u8 cpldmode; + +#ifdef CONFIG_M54455EVB + volatile u8 *cpld = (volatile u8 *)(CFG_CS2_BASE + 3); +#endif + u8 bootmode; /* To determine PCI is present or not */ if (((ccm->ccr & CCM_CCR_360_FBCONFIG_MASK) == 0x00e0) || ((ccm->ccr & CCM_CCR_360_FBCONFIG_MASK) == 0x0060)) { pPllmult = &pllmult_pci[0]; - fbpll_mask = 3; + fbpll_mask = 3; /* 11b */ bPci = 1; } else { pPllmult = &pllmult_nopci[0]; - fbpll_mask = 7; + fbpll_mask = 7; /* 111b */ #ifdef CONFIG_PCI gd->pci_clk = 0; #endif @@ -111,20 +114,36 @@ int get_clocks(void) } #ifdef CONFIG_M54455EVB - /* Temporary place here, belongs in board/freescale/... */ - /* Temporary read from CCR- fixed fb issue, must be the same clock - as pci or input clock, causing cpld/fpga read inconsistancy */ - fbtemp = pPllmult[ccm->ccr & fbpll_mask]; + bootmode = (*cpld & 0x03); - /* Break down into small pieces, code still in flex bus */ - pcrvalue = pll->pcr & 0xFFFFF0FF; - temp = fbtemp - 1; - pcrvalue |= PLL_PCR_OUTDIV3(temp); + if (bootmode != 3) { + /* Temporary read from CCR- fixed fb issue, must be the same clock + as pci or input clock, causing cpld/fpga read inconsistancy */ + fbtemp = pPllmult[ccm->ccr & fbpll_mask]; + /* Break down into small pieces, code still in flex bus */ + pcrvalue = pll->pcr & 0xFFFFF0FF; + temp = fbtemp - 1; + pcrvalue |= PLL_PCR_OUTDIV3(temp); + + pll->pcr = pcrvalue; + } +#endif +#ifdef CONFIG_M54451EVB + /* No external logic to read the bootmode, hard coded from built */ +#ifdef CONFIG_CF_SBF + bootmode = 3; +#else + bootmode = 2; + + /* default value is 16 mul, set to 20 mul */ + pcrvalue = (pll->pcr & 0x00FFFFFF) | 0x14000000; pll->pcr = pcrvalue; + while ((pll->psr & PLL_PSR_LOCK) != PLL_PSR_LOCK); +#endif +#endif - cpldmode = *cpld & 0x03; - if (cpldmode == 0) { + if (bootmode == 0) { /* RCON mode */ vco = pPllmult[ccm->rcon & fbpll_mask] * CFG_INPUT_CLKSRC; @@ -151,14 +170,22 @@ int get_clocks(void) pll->pcr = pcrvalue; } gd->vco_clk = vco; /* Vco clock */ - } else if (cpldmode == 2) { + } else if (bootmode == 2) { /* Normal mode */ - vco = pPllmult[ccm->ccr & fbpll_mask] * CFG_INPUT_CLKSRC; + vco = ((pll->pcr & 0xFF000000) >> 24) * CFG_INPUT_CLKSRC; + if ((vco < CLOCK_PLL_FVCO_MIN) || (vco > CLOCK_PLL_FVCO_MAX)) { + /* Default value */ + pcrvalue = (pll->pcr & 0x00FFFFFF); + pcrvalue |= pPllmult[ccm->ccr & fbpll_mask] << 24; + pll->pcr = pcrvalue; + vco = ((pll->pcr & 0xFF000000) >> 24) * CFG_INPUT_CLKSRC; + } gd->vco_clk = vco; /* Vco clock */ - } else if (cpldmode == 3) { + } else if (bootmode == 3) { /* serial mode */ + vco = ((pll->pcr & 0xFF000000) >> 24) * CFG_INPUT_CLKSRC; + gd->vco_clk = vco; /* Vco clock */ } -#endif /* CONFIG_M54455EVB */ if ((ccm->ccr & CCM_MISCCR_LIMP) == CCM_MISCCR_LIMP) { /* Limp mode */ diff --git a/cpu/mcf5445x/start.S b/cpu/mcf5445x/start.S index 89ec7bc..2a6019b 100644 --- a/cpu/mcf5445x/start.S +++ b/cpu/mcf5445x/start.S @@ -46,15 +46,30 @@ addl #60,%sp; /* space for 15 regs */ \ rte; +#if defined(CONFIG_CF_SBF) +#define ASM_DRAMINIT (asm_dram_init - TEXT_BASE + CFG_INIT_RAM_ADDR) +#define ASM_SBF_IMG_HDR (asm_sbf_img_hdr - TEXT_BASE + CFG_INIT_RAM_ADDR) +#endif + .text + /* * Vector table. This is used for initial platform startup. * These vectors are to catch any un-intended traps. */ _vectors: +#if defined(CONFIG_CF_SBF) + +INITSP: .long 0 /* Initial SP */ +INITPC: .long ASM_DRAMINIT /* Initial PC */ + +#else + +INITSP: .long 0 /* Initial SP */ +INITPC: .long _START /* Initial PC */ + +#endif -INITSP: .long 0x00000000 /* Initial SP */ -INITPC: .long _START /* Initial PC */ vector02: .long _FAULT /* Access Error */ vector03: .long _FAULT /* Address Error */ vector04: .long _FAULT /* Illegal Instruction */ @@ -83,6 +98,8 @@ vector1D: .long _FAULT /* Autovector Level 5 */ vector1E: .long _FAULT /* Autovector Level 6 */ vector1F: .long _FAULT /* Autovector Level 7 */ +#if !defined(CONFIG_CF_SBF) + /* TRAP #0 - #15 */ vector20_2F: .long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT @@ -122,9 +139,237 @@ vector192_255: .long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT .long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT .long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +#endif - .text +#if defined(CONFIG_CF_SBF) + /* Image header: chksum 4 bytes, len 4 bytes, img dest 4 bytes */ +asm_sbf_img_hdr: + .long 0x00000000 /* checksum, not yet implemented */ + .long 0x00030000 /* image length */ + .long TEXT_BASE /* image to be relocated at */ + +asm_dram_init: + move.l #(CFG_INIT_RAM_ADDR + CFG_INIT_RAM_CTRL), %d0 + movec %d0, %RAMBAR1 /* init Rambar */ + move.l #(CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET), %sp + clr.l %sp@- + + /* Must disable global address */ + move.l #0xFC008000, %a1 + move.l #(CFG_CS0_BASE), (%a1) + move.l #0xFC008008, %a1 + move.l #(CFG_CS0_CTRL), (%a1) + move.l #0xFC008004, %a1 + move.l #(CFG_CS0_MASK), (%a1) + + /* + * Dram Initialization + * a1, a2, and d0 + */ + /* mscr sdram */ + move.l #0xFC0A4074, %a1 + move.b #(CFG_SDRAM_DRV_STRENGTH), (%a1) + nop + + /* SDRAM Chip 0 and 1 */ + move.l #0xFC0B8110, %a1 + move.l #0xFC0B8114, %a2 + + /* calculate the size */ + move.l #0x13, %d1 + move.l #(CFG_SDRAM_SIZE), %d2 +#ifdef CFG_SDRAM_BASE1 + lsr.l #1, %d2 +#endif + +dramsz_loop: + lsr.l #1, %d2 + add.l #1, %d1 + cmp.l #1, %d2 + bne dramsz_loop + + /* SDRAM Chip 0 and 1 */ + move.l #(CFG_SDRAM_BASE), (%a1) + or.l %d1, (%a1) +#ifdef CFG_SDRAM_BASE1 + move.l #(CFG_SDRAM_BASE1), (%a2) + or.l %d1, (%a2) +#endif + nop + + /* dram cfg1 and cfg2 */ + move.l #0xFC0B8008, %a1 + move.l #(CFG_SDRAM_CFG1), (%a1) + nop + move.l #0xFC0B800C, %a2 + move.l #(CFG_SDRAM_CFG2), (%a2) + nop + + move.l #0xFC0B8000, %a1 /* Mode */ + move.l #0xFC0B8004, %a2 /* Ctrl */ + +#ifdef CONFIG_M54455EVB + /* Issue PALL */ + move.l #(CFG_SDRAM_CTRL + 2), (%a2) + nop + + /* Issue LEMR */ + move.l #(CFG_SDRAM_EMOD + 0x408), (%a1) + nop + move.l #(CFG_SDRAM_MODE + 0x300), (%a1) + nop + + move.l #1000, %d0 +wait1000: + nop + subq.l #1, %d0 + bne wait1000 +#endif + + /* Issue PALL */ + move.l #(CFG_SDRAM_CTRL + 2), (%a2) + nop + + /* Perform two refresh cycles */ + move.l #(CFG_SDRAM_CTRL + 4), %d0 + nop + move.l %d0, (%a2) + move.l %d0, (%a2) + nop +#ifdef CONFIG_M54455EVB + move.l #(CFG_SDRAM_MODE + 0x200), (%a1) + nop +#elif defined(CONFIG_M54451EVB) + /* Issue LEMR */ + move.l #(CFG_SDRAM_MODE), (%a2) + nop + move.l #(CFG_SDRAM_EMOD), (%a2) + nop +#endif + + move.l #500, %d0 +wait500: + nop + subq.l #1, %d0 + bne wait500 + + move.l #(CFG_SDRAM_CTRL), %d0 + and.l #0x7FFFFFFF, %d0 +#ifdef CONFIG_M54455EVB + or.l #0x10000c00, %d0 +#elif defined(CONFIG_M54451EVB) + or.l #0x10000000, %d0 +#endif + move.l %d0, (%a2) + nop + + /* + * DSPI Initialization + * a0 - general, sram - 0x80008000 - 32, see M54455EVB.h + * a1 - dspi status + * a2 - dtfr + * a3 - drfr + * a4 - Dst addr + */ + /* Enable pins for DSPI mode - chip-selects are enabled later */ + move.l #0xFC0A4063, %a0 + move.b #0x7F, (%a0) + + /* Configure DSPI module */ + move.l #0xFC05C000, %a0 + move.l #0x80FF0C00, (%a0) /* Master, clear TX/RX FIFO */ + + move.l #0xFC05C00C, %a0 + move.l #0x3E000011, (%a0) + + move.l #0xFC05C034, %a2 /* dtfr */ + move.l #0xFC05C03B, %a3 /* drfr */ + + move.l #(ASM_SBF_IMG_HDR + 4), %a1 + move.l (%a1)+, %d5 + move.l (%a1), %a4 + + move.l #(CFG_INIT_RAM_ADDR + CFG_SBFHDR_DATA_OFFSET), %a0 + move.l #(CFG_SBFHDR_SIZE), %d4 + + move.l #0xFC05C02C, %a1 /* dspi status */ + + /* Issue commands and address */ + move.l #0x8002000B, %d2 /* Fast Read Cmd */ + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + move.l #0x80020000, %d2 /* Address byte 2 */ + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + move.l #0x80020000, %d2 /* Address byte 1 */ + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + move.l #0x80020000, %d2 /* Address byte 0 */ + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + move.l #0x80020000, %d2 /* Dummy Wr and Rd */ + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + /* Transfer serial boot header to sram */ +asm_dspi_rd_loop1: + move.l #0x80020000, %d2 + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + move.b %d1, (%a0) /* read, copy to dst */ + + add.l #1, %a0 /* inc dst by 1 */ + sub.l #1, %d4 /* dec cnt by 1 */ + bne asm_dspi_rd_loop1 + + /* Transfer u-boot from serial flash to memory */ +asm_dspi_rd_loop2: + move.l #0x80020000, %d2 + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + move.b %d1, (%a4) /* read, copy to dst */ + + add.l #1, %a4 /* inc dst by 1 */ + sub.l #1, %d5 /* dec cnt by 1 */ + bne asm_dspi_rd_loop2 + + move.l #0x00020000, %d2 /* Terminate */ + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + /* jump to memory and execute */ + move.l #(TEXT_BASE + 0x400), %a0 + jmp (%a0) + +asm_dspi_wr_status: + move.l (%a1), %d0 /* status */ + and.l #0x0000F000, %d0 + cmp.l #0x00003000, %d0 + bgt asm_dspi_wr_status + + move.l %d2, (%a2) + rts + +asm_dspi_rd_status: + move.l (%a1), %d0 /* status */ + and.l #0x000000F0, %d0 + lsr.l #4, %d0 + cmp.l #0, %d0 + beq asm_dspi_rd_status + + move.b (%a3), %d1 + rts +#endif /* CONFIG_CF_SBF */ + + .text + . = 0x400 .globl _start _start: nop @@ -132,11 +377,16 @@ _start: move.w #0x2700,%sr /* Mask off Interrupt */ /* Set vector base register at the beginning of the Flash */ +#if defined(CONFIG_CF_SBF) + move.l #TEXT_BASE, %d0 + movec %d0, %VBR +#else move.l #CFG_FLASH_BASE, %d0 movec %d0, %VBR move.l #(CFG_INIT_RAM_ADDR + CFG_INIT_RAM_CTRL), %d0 movec %d0, %RAMBAR1 +#endif /* initialize general use internal ram */ move.l #0, %d0 diff --git a/cpu/mpc512x/Makefile b/cpu/mpc512x/Makefile index 2be35b2..8ba8ae8 100644 --- a/cpu/mpc512x/Makefile +++ b/cpu/mpc512x/Makefile @@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).a START = start.o -COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o serial.o fec.o i2c.o +COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o serial.o fec.o i2c.o iopin.o SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/mpc512x/cpu.c b/cpu/mpc512x/cpu.c index b59f36d..703e188 100644 --- a/cpu/mpc512x/cpu.c +++ b/cpu/mpc512x/cpu.c @@ -131,22 +131,67 @@ void watchdog_reset (void) #endif #ifdef CONFIG_OF_LIBFDT -void ft_cpu_setup(void *blob, bd_t *bd) + +#ifdef CONFIG_OF_SUPPORT_OLD_DEVICE_TREES +/* + * fdt setup for old device trees + * fix up + * cpu clocks + * soc clocks + * ethernet addresses + */ +static void old_ft_cpu_setup(void *blob, bd_t *bd) +{ + /* + * avoid fixing up by path because that + * produces scary error messages + */ + + /* + * old device trees have ethernet nodes with + * device_type = "network" + */ + do_fixup_by_prop(blob, "device_type", "network", 8, + "local-mac-address", bd->bi_enetaddr, 6, 0); + do_fixup_by_prop(blob, "device_type", "network", 8, + "address", bd->bi_enetaddr, 6, 0); + /* + * old device trees have soc nodes with + * device_type = "soc" + */ + do_fixup_by_prop_u32(blob, "device_type", "soc", 4, + "bus-frequency", bd->bi_ipsfreq, 0); +} +#endif + +static void ft_clock_setup(void *blob, bd_t *bd) { char *cpu_path = "/cpus/" OF_CPU; - char *eth_path = "/" OF_SOC "/ethernet@2800"; - char *eth_path_old = "/" OF_SOC_OLD "/ethernet@2800"; - - do_fixup_by_path_u32(blob, cpu_path, "timebase-frequency", OF_TBCLK, 1); - do_fixup_by_path_u32(blob, cpu_path, "bus-frequency", bd->bi_busfreq, 1); - do_fixup_by_path_u32(blob, cpu_path, "clock-frequency", bd->bi_intfreq, 1); - do_fixup_by_path_u32(blob, "/" OF_SOC, "bus-frequency", bd->bi_ipsfreq, 1); - do_fixup_by_path(blob, eth_path, "local-mac-address", bd->bi_enetaddr, 6, 0); - - /* this is so old kernels with old device trees will boot */ - do_fixup_by_path_u32(blob, "/" OF_SOC_OLD, "bus-frequency", bd->bi_ipsfreq, 0); - do_fixup_by_path(blob, eth_path_old, "local-mac-address", - bd->bi_enetaddr, 6, 0); - do_fixup_by_path(blob, eth_path_old, "address", bd->bi_enetaddr, 6, 0); + + /* + * fixup cpu clocks using path + */ + do_fixup_by_path_u32(blob, cpu_path, + "timebase-frequency", OF_TBCLK, 1); + do_fixup_by_path_u32(blob, cpu_path, + "bus-frequency", bd->bi_busfreq, 1); + do_fixup_by_path_u32(blob, cpu_path, + "clock-frequency", bd->bi_intfreq, 1); + /* + * fixup soc clocks using compatible + */ + do_fixup_by_compat_u32(blob, OF_SOC_COMPAT, + "bus-frequency", bd->bi_ipsfreq, 1); +} + +void ft_cpu_setup(void *blob, bd_t *bd) +{ +#ifdef CONFIG_OF_SUPPORT_OLD_DEVICE_TREES + old_ft_cpu_setup(blob, bd); +#endif + ft_clock_setup(blob, bd); +#ifdef CONFIG_HAS_ETH0 + fdt_fixup_ethernet(blob, bd); +#endif } #endif diff --git a/cpu/mpc512x/iopin.c b/cpu/mpc512x/iopin.c new file mode 100644 index 0000000..3d7042d --- /dev/null +++ b/cpu/mpc512x/iopin.c @@ -0,0 +1,49 @@ +/* + * (C) Copyright 2008 + * Martha J Marx, Silicon Turnkey Express, mmarx@silicontkx.com + * mpc512x I/O pin/pad initialization for the ADS5121 board + * 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 <linux/types.h> +#include <mpc512x.h> + +void iopin_initialize(iopin_t *ioregs_init, int len) +{ + short i, j, p; + u_long *reg; + immap_t *im = (immap_t *)CFG_IMMR; + + reg = (u_long *)&(im->io_ctrl.regs[0]); + + if (sizeof(ioregs_init) == 0) + return; + + for (i = 0; i < len; i++) { + for (p = 0, j = ioregs_init[i].p_offset / sizeof(u_long); + p < ioregs_init[i].nr_pins; p++, j++) { + if (ioregs_init[i].bit_or) + reg[j] |= ioregs_init[i].val; + else + reg[j] = ioregs_init[i].val; + } + } + return; +} diff --git a/cpu/mpc8260/pci.c b/cpu/mpc8260/pci.c index 940f5c0..8230364 100644 --- a/cpu/mpc8260/pci.c +++ b/cpu/mpc8260/pci.c @@ -457,7 +457,7 @@ void pci_mpc8250_init (struct pci_controller *hose) void ft_pci_setup(void *blob, bd_t *bd) { do_fixup_by_prop_u32(blob, "device_type", "pci", 4, - "clock-frequency", bd->pci_clk, 1); + "clock-frequency", gd->pci_clk, 1); } #endif diff --git a/cpu/mpc83xx/nand_init.c b/cpu/mpc83xx/nand_init.c new file mode 100644 index 0000000..e92f230 --- /dev/null +++ b/cpu/mpc83xx/nand_init.c @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2004-2008 Freescale Semiconductor, Inc. + * + * 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 <mpc83xx.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Breathe some life into the CPU... + * + * Set up the memory map, + * initialize a bunch of registers, + * initialize the UPM's + */ +void cpu_init_f (volatile immap_t * im) +{ + int i; + + /* Pointer is writable since we allocated a register for it */ + gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET); + + /* Clear initial global data */ + for (i = 0; i < sizeof(gd_t); i++) + ((char *)gd)[i] = 0; + + /* system performance tweaking */ + +#ifdef CFG_ACR_PIPE_DEP + /* Arbiter pipeline depth */ + im->arbiter.acr = (im->arbiter.acr & ~ACR_PIPE_DEP) | + (CFG_ACR_PIPE_DEP << ACR_PIPE_DEP_SHIFT); +#endif + +#ifdef CFG_ACR_RPTCNT + /* Arbiter repeat count */ + im->arbiter.acr = (im->arbiter.acr & ~(ACR_RPTCNT)) | + (CFG_ACR_RPTCNT << ACR_RPTCNT_SHIFT); +#endif + +#ifdef CFG_SPCR_OPT + /* Optimize transactions between CSB and other devices */ + im->sysconf.spcr = (im->sysconf.spcr & ~SPCR_OPT) | + (CFG_SPCR_OPT << SPCR_OPT_SHIFT); +#endif + + /* Enable Time Base & Decrimenter (so we will have udelay()) */ + im->sysconf.spcr |= SPCR_TBEN; + + /* DDR control driver register */ +#ifdef CFG_DDRCDR + im->sysconf.ddrcdr = CFG_DDRCDR; +#endif + /* Output buffer impedance register */ +#ifdef CFG_OBIR + im->sysconf.obir = CFG_OBIR; +#endif + + /* + * Memory Controller: + */ + + /* Map banks 0 and 1 to the FLASH banks 0 and 1 at preliminary + * addresses - these have to be modified later when FLASH size + * has been determined + */ + +#if defined(CFG_NAND_BR_PRELIM) \ + && defined(CFG_NAND_OR_PRELIM) \ + && defined(CFG_NAND_LBLAWBAR_PRELIM) \ + && defined(CFG_NAND_LBLAWAR_PRELIM) + im->lbus.bank[0].br = CFG_NAND_BR_PRELIM; + im->lbus.bank[0].or = CFG_NAND_OR_PRELIM; + im->sysconf.lblaw[0].bar = CFG_NAND_LBLAWBAR_PRELIM; + im->sysconf.lblaw[0].ar = CFG_NAND_LBLAWAR_PRELIM; +#else +#error CFG_NAND_BR_PRELIM, CFG_NAND_OR_PRELIM, CFG_NAND_LBLAWBAR_PRELIM & CFG_NAND_LBLAWAR_PRELIM must be defined +#endif +} + +/* + * Get timebase clock frequency (like cpu_clk in Hz) + */ +unsigned long get_tbclk(void) +{ + return (gd->bus_clk + 3L) / 4L; +} + +void puts(const char *str) +{ + while (*str) + putc(*str++); +} diff --git a/cpu/mpc83xx/start.S b/cpu/mpc83xx/start.S index c182174..16ed494 100644 --- a/cpu/mpc83xx/start.S +++ b/cpu/mpc83xx/start.S @@ -2,7 +2,7 @@ * Copyright (C) 1998 Dan Malek <dmalek@jlc.net> * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> * Copyright (C) 2000, 2001,2002 Wolfgang Denk <wd@denx.de> - * Copyright Freescale Semiconductor, Inc. 2004, 2006. All rights reserved. + * Copyright Freescale Semiconductor, Inc. 2004, 2006, 2008. * * See file CREDITS for list of people who contributed to this * project. @@ -57,6 +57,10 @@ #define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI) #endif +#if !defined(CONFIG_NAND_SPL) && !defined(CFG_RAMBOOT) +#define CFG_FLASHBOOT +#endif + /* * Set up GOT: Global Offset Table * @@ -64,16 +68,16 @@ */ START_GOT GOT_ENTRY(_GOT2_TABLE_) - GOT_ENTRY(_FIXUP_TABLE_) + GOT_ENTRY(__bss_start) + GOT_ENTRY(_end) +#ifndef CONFIG_NAND_SPL + GOT_ENTRY(_FIXUP_TABLE_) GOT_ENTRY(_start) GOT_ENTRY(_start_of_vectors) GOT_ENTRY(_end_of_vectors) GOT_ENTRY(transfer_to_handler) - - GOT_ENTRY(__init_end) - GOT_ENTRY(_end) - GOT_ENTRY(__bss_start) +#endif END_GOT /* @@ -165,7 +169,7 @@ boot_warm: /* time t 5 */ bl init_e300_core -#ifndef CFG_RAMBOOT +#ifdef CFG_FLASHBOOT /* Inflate flash location so it appears everywhere, calculate */ /* the absolute address in final location of the FLASH, jump */ @@ -181,7 +185,7 @@ in_flash: #if 1 /* Remapping flash with LAW0. */ bl remap_flash_by_law0 #endif -#endif /* CFG_RAMBOOT */ +#endif /* CFG_FLASHBOOT */ /* setup the bats */ bl setup_bats @@ -239,6 +243,7 @@ in_flash: /* run 1st part of board init code (in Flash)*/ bl board_init_f +#ifndef CONFIG_NAND_SPL /* * Vector Table */ @@ -428,6 +433,7 @@ int_return: lwz r1,GPR1(r1) SYNC rfi +#endif /* !CONFIG_NAND_SPL */ /* * This code initialises the E300 processor core @@ -496,88 +502,10 @@ init_e300_core: /* time t 10 */ SYNC mtspr HID2, r3 - /* clear all BAT's */ - /*----------------------------------*/ - - xor r0, r0, r0 - mtspr DBAT0U, r0 - mtspr DBAT0L, r0 - mtspr DBAT1U, r0 - mtspr DBAT1L, r0 - mtspr DBAT2U, r0 - mtspr DBAT2L, r0 - mtspr DBAT3U, r0 - mtspr DBAT3L, r0 - mtspr IBAT0U, r0 - mtspr IBAT0L, r0 - mtspr IBAT1U, r0 - mtspr IBAT1L, r0 - mtspr IBAT2U, r0 - mtspr IBAT2L, r0 - mtspr IBAT3U, r0 - mtspr IBAT3L, r0 - SYNC - - /* invalidate all tlb's - * - * From the 603e User Manual: "The 603e provides the ability to - * invalidate a TLB entry. The TLB Invalidate Entry (tlbie) - * instruction invalidates the TLB entry indexed by the EA, and - * operates on both the instruction and data TLBs simultaneously - * invalidating four TLB entries (both sets in each TLB). The - * index corresponds to bits 15-19 of the EA. To invalidate all - * entries within both TLBs, 32 tlbie instructions should be - * issued, incrementing this field by one each time." - * - * "Note that the tlbia instruction is not implemented on the - * 603e." - * - * bits 15-19 correspond to addresses 0x00000000 to 0x0001F000 - * incrementing by 0x1000 each time. The code below is sort of - * based on code in "flush_tlbs" from arch/ppc/kernel/head.S - * - */ - - li r3, 32 - mtctr r3 - li r3, 0 -1: tlbie r3 - addi r3, r3, 0x1000 - bdnz 1b - SYNC - /* Done! */ /*------------------------------*/ blr - .globl invalidate_bats -invalidate_bats: - /* invalidate BATs */ - mtspr IBAT0U, r0 - mtspr IBAT1U, r0 - mtspr IBAT2U, r0 - mtspr IBAT3U, r0 -#ifdef CONFIG_HIGH_BATS - mtspr IBAT4U, r0 - mtspr IBAT5U, r0 - mtspr IBAT6U, r0 - mtspr IBAT7U, r0 -#endif - isync - mtspr DBAT0U, r0 - mtspr DBAT1U, r0 - mtspr DBAT2U, r0 - mtspr DBAT3U, r0 -#ifdef CONFIG_HIGH_BATS - mtspr DBAT4U, r0 - mtspr DBAT5U, r0 - mtspr DBAT6U, r0 - mtspr DBAT7U, r0 -#endif - isync - sync - blr - /* setup_bats - set them up to some initial state */ .globl setup_bats setup_bats: @@ -590,7 +518,6 @@ setup_bats: ori r3, r3, CFG_IBAT0U@l mtspr IBAT0L, r4 mtspr IBAT0U, r3 - isync /* DBAT 0 */ addis r4, r0, CFG_DBAT0L@h @@ -599,7 +526,6 @@ setup_bats: ori r3, r3, CFG_DBAT0U@l mtspr DBAT0L, r4 mtspr DBAT0U, r3 - isync /* IBAT 1 */ addis r4, r0, CFG_IBAT1L@h @@ -608,7 +534,6 @@ setup_bats: ori r3, r3, CFG_IBAT1U@l mtspr IBAT1L, r4 mtspr IBAT1U, r3 - isync /* DBAT 1 */ addis r4, r0, CFG_DBAT1L@h @@ -617,7 +542,6 @@ setup_bats: ori r3, r3, CFG_DBAT1U@l mtspr DBAT1L, r4 mtspr DBAT1U, r3 - isync /* IBAT 2 */ addis r4, r0, CFG_IBAT2L@h @@ -626,7 +550,6 @@ setup_bats: ori r3, r3, CFG_IBAT2U@l mtspr IBAT2L, r4 mtspr IBAT2U, r3 - isync /* DBAT 2 */ addis r4, r0, CFG_DBAT2L@h @@ -635,7 +558,6 @@ setup_bats: ori r3, r3, CFG_DBAT2U@l mtspr DBAT2L, r4 mtspr DBAT2U, r3 - isync /* IBAT 3 */ addis r4, r0, CFG_IBAT3L@h @@ -644,7 +566,6 @@ setup_bats: ori r3, r3, CFG_IBAT3U@l mtspr IBAT3L, r4 mtspr IBAT3U, r3 - isync /* DBAT 3 */ addis r4, r0, CFG_DBAT3L@h @@ -653,7 +574,6 @@ setup_bats: ori r3, r3, CFG_DBAT3U@l mtspr DBAT3L, r4 mtspr DBAT3U, r3 - isync #ifdef CONFIG_HIGH_BATS /* IBAT 4 */ @@ -663,7 +583,6 @@ setup_bats: ori r3, r3, CFG_IBAT4U@l mtspr IBAT4L, r4 mtspr IBAT4U, r3 - isync /* DBAT 4 */ addis r4, r0, CFG_DBAT4L@h @@ -672,7 +591,6 @@ setup_bats: ori r3, r3, CFG_DBAT4U@l mtspr DBAT4L, r4 mtspr DBAT4U, r3 - isync /* IBAT 5 */ addis r4, r0, CFG_IBAT5L@h @@ -681,7 +599,6 @@ setup_bats: ori r3, r3, CFG_IBAT5U@l mtspr IBAT5L, r4 mtspr IBAT5U, r3 - isync /* DBAT 5 */ addis r4, r0, CFG_DBAT5L@h @@ -690,7 +607,6 @@ setup_bats: ori r3, r3, CFG_DBAT5U@l mtspr DBAT5L, r4 mtspr DBAT5U, r3 - isync /* IBAT 6 */ addis r4, r0, CFG_IBAT6L@h @@ -699,7 +615,6 @@ setup_bats: ori r3, r3, CFG_IBAT6U@l mtspr IBAT6L, r4 mtspr IBAT6U, r3 - isync /* DBAT 6 */ addis r4, r0, CFG_DBAT6L@h @@ -708,7 +623,6 @@ setup_bats: ori r3, r3, CFG_DBAT6U@l mtspr DBAT6L, r4 mtspr DBAT6U, r3 - isync /* IBAT 7 */ addis r4, r0, CFG_IBAT7L@h @@ -717,7 +631,6 @@ setup_bats: ori r3, r3, CFG_IBAT7U@l mtspr IBAT7L, r4 mtspr IBAT7U, r3 - isync /* DBAT 7 */ addis r4, r0, CFG_DBAT7L@h @@ -726,12 +639,28 @@ setup_bats: ori r3, r3, CFG_DBAT7U@l mtspr DBAT7L, r4 mtspr DBAT7U, r3 - isync #endif - /* Invalidate TLBs. - * -> for (val = 0; val < 0x20000; val+=0x1000) - * -> tlbie(val); + isync + + /* invalidate all tlb's + * + * From the 603e User Manual: "The 603e provides the ability to + * invalidate a TLB entry. The TLB Invalidate Entry (tlbie) + * instruction invalidates the TLB entry indexed by the EA, and + * operates on both the instruction and data TLBs simultaneously + * invalidating four TLB entries (both sets in each TLB). The + * index corresponds to bits 15-19 of the EA. To invalidate all + * entries within both TLBs, 32 tlbie instructions should be + * issued, incrementing this field by one each time." + * + * "Note that the tlbia instruction is not implemented on the + * 603e." + * + * bits 15-19 correspond to addresses 0x00000000 to 0x0001F000 + * incrementing by 0x1000 each time. The code below is sort of + * based on code in "flush_tlbs" from arch/ppc/kernel/head.S + * */ lis r3, 0 lis r5, 2 @@ -874,7 +803,7 @@ relocate_code: mr r3, r5 /* Destination Address */ lis r4, CFG_MONITOR_BASE@h /* Source Address */ ori r4, r4, CFG_MONITOR_BASE@l - lwz r5, GOT(__init_end) + lwz r5, GOT(__bss_start) sub r5, r5, r4 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */ @@ -987,6 +916,7 @@ in_ram: stw r0,0(r3) bdnz 1b +#ifndef CONFIG_NAND_SPL /* * Now adjust the fixups and the pointers to the fixups * in case we need to move ourselves again. @@ -1004,6 +934,8 @@ in_ram: stw r0,0(r4) bdnz 3b 4: +#endif + clear_bss: /* * Now clear BSS segment @@ -1037,6 +969,7 @@ clear_bss: mr r4, r10 /* Destination Address */ bl board_init_r +#ifndef CONFIG_NAND_SPL /* * Copy exception vector code to low memory * @@ -1119,6 +1052,7 @@ trap_reloc: stw r0, 4(r7) blr +#endif /* !CONFIG_NAND_SPL */ #ifdef CFG_INIT_RAM_LOCK lock_ram_in_cache: @@ -1142,6 +1076,7 @@ lock_ram_in_cache: sync blr +#ifndef CONFIG_NAND_SPL .globl unlock_ram_in_cache unlock_ram_in_cache: /* invalidate the INIT_RAM section */ @@ -1165,8 +1100,10 @@ unlock_ram_in_cache: mtspr HID0, r3 /* no invalidate, unlock */ sync blr -#endif +#endif /* !CONFIG_NAND_SPL */ +#endif /* CFG_INIT_RAM_LOCK */ +#ifdef CFG_FLASHBOOT map_flash_by_law1: /* When booting from ROM (Flash or EPROM), clear the */ /* Address Mask in OR0 so ROM appears everywhere */ @@ -1245,3 +1182,4 @@ remap_flash_by_law0: stw r4, LBLAWBAR1(r3) stw r4, LBLAWAR1(r3) /* Off LBIU LAW1 */ blr +#endif /* CFG_FLASHBOOT */ diff --git a/cpu/mpc85xx/mp.c b/cpu/mpc85xx/mp.c index 554830f..4e09c9c 100644 --- a/cpu/mpc85xx/mp.c +++ b/cpu/mpc85xx/mp.c @@ -147,7 +147,7 @@ static void pq3_mp_up(unsigned long bootpg) out_be32(&gur->devdisr, devdisr); /* release the hounds */ - up = ((1 << CONFIG_NR_CPUS) - 1); + up = ((1 << CONFIG_NUM_CPUS) - 1); bpcr = in_be32(&ecm->eebpcr); bpcr |= (up << 24); out_be32(&ecm->eebpcr, bpcr); @@ -157,7 +157,7 @@ static void pq3_mp_up(unsigned long bootpg) /* wait for everyone */ while (timeout) { int i; - for (i = 0; i < CONFIG_NR_CPUS; i++) { + for (i = 0; i < CONFIG_NUM_CPUS; i++) { if (table[i * NUM_BOOT_ENTRY + BOOT_ENTRY_ADDR_LOWER]) cpu_up_mask |= (1 << i); }; diff --git a/cpu/mpc85xx/release.S b/cpu/mpc85xx/release.S index a47edae..75676b5 100644 --- a/cpu/mpc85xx/release.S +++ b/cpu/mpc85xx/release.S @@ -173,7 +173,7 @@ __secondary_start_page: .align L1_CACHE_SHIFT .globl __spin_table __spin_table: - .space CONFIG_NR_CPUS*ENTRY_SIZE + .space CONFIG_NUM_CPUS*ENTRY_SIZE /* Fill in the empty space. The actual reset vector is * the last word of the page */ diff --git a/cpu/mpc86xx/cache.S b/cpu/mpc86xx/cache.S index 2e4ea02..80ff688 100644 --- a/cpu/mpc86xx/cache.S +++ b/cpu/mpc86xx/cache.S @@ -232,6 +232,10 @@ _GLOBAL(icache_enable) * Disable L1 Instruction cache */ _GLOBAL(icache_disable) + mflr r4 + bl invalidate_l1_instruction_cache /* uses r3 */ + sync + mtlr r4 mfspr r3, HID0 li r5, 0 ori r5, r5, HID0_ICE diff --git a/cpu/mpc86xx/cpu_init.c b/cpu/mpc86xx/cpu_init.c index 78ba1ea..1fda3fe 100644 --- a/cpu/mpc86xx/cpu_init.c +++ b/cpu/mpc86xx/cpu_init.c @@ -26,8 +26,10 @@ * cpu_init.c - low level cpu init */ +#include <config.h> #include <common.h> #include <mpc86xx.h> +#include <asm/mmu.h> #include <asm/fsl_law.h> DECLARE_GLOBAL_DATA_PTR; @@ -121,3 +123,26 @@ int cpu_init_r(void) { return 0; } + +/* Set up BAT registers */ +void setup_bats(void) +{ + write_bat(DBAT0, CFG_DBAT0U, CFG_DBAT0L); + write_bat(IBAT0, CFG_IBAT0U, CFG_IBAT0L); + write_bat(DBAT1, CFG_DBAT1U, CFG_DBAT1L); + write_bat(IBAT1, CFG_IBAT1U, CFG_IBAT1L); + write_bat(DBAT2, CFG_DBAT2U, CFG_DBAT2L); + write_bat(IBAT2, CFG_IBAT2U, CFG_IBAT2L); + write_bat(DBAT3, CFG_DBAT3U, CFG_DBAT3L); + write_bat(IBAT3, CFG_IBAT3U, CFG_IBAT3L); + write_bat(DBAT4, CFG_DBAT4U, CFG_DBAT4L); + write_bat(IBAT4, CFG_IBAT4U, CFG_IBAT4L); + write_bat(DBAT5, CFG_DBAT5U, CFG_DBAT5L); + write_bat(IBAT5, CFG_IBAT5U, CFG_IBAT5L); + write_bat(DBAT6, CFG_DBAT6U, CFG_DBAT6L); + write_bat(IBAT6, CFG_IBAT6U, CFG_IBAT6L); + write_bat(DBAT7, CFG_DBAT7U, CFG_DBAT7L); + write_bat(IBAT7, CFG_IBAT7U, CFG_IBAT7L); + + return; +} diff --git a/cpu/mpc86xx/start.S b/cpu/mpc86xx/start.S index c39dc46..03f2128 100644 --- a/cpu/mpc86xx/start.S +++ b/cpu/mpc86xx/start.S @@ -358,125 +358,6 @@ invalidate_bats: sync blr - - /* setup_bats - set them up to some initial state */ - /* Skip any BATS setup in early_bats */ - .globl setup_bats -setup_bats: - - addis r0, r0, 0x0000 - - /* IBAT 0 */ - addis r4, r0, CFG_IBAT0L@h - ori r4, r4, CFG_IBAT0L@l - addis r3, r0, CFG_IBAT0U@h - ori r3, r3, CFG_IBAT0U@l - mtspr IBAT0L, r4 - mtspr IBAT0U, r3 - isync - - /* DBAT 0 */ - addis r4, r0, CFG_DBAT0L@h - ori r4, r4, CFG_DBAT0L@l - addis r3, r0, CFG_DBAT0U@h - ori r3, r3, CFG_DBAT0U@l - mtspr DBAT0L, r4 - mtspr DBAT0U, r3 - isync - - /* IBAT 1 */ - addis r4, r0, CFG_IBAT1L@h - ori r4, r4, CFG_IBAT1L@l - addis r3, r0, CFG_IBAT1U@h - ori r3, r3, CFG_IBAT1U@l - mtspr IBAT1L, r4 - mtspr IBAT1U, r3 - isync - - /* DBAT 1 */ - addis r4, r0, CFG_DBAT1L@h - ori r4, r4, CFG_DBAT1L@l - addis r3, r0, CFG_DBAT1U@h - ori r3, r3, CFG_DBAT1U@l - mtspr DBAT1L, r4 - mtspr DBAT1U, r3 - isync - - /* IBAT 2 */ - addis r4, r0, CFG_IBAT2L@h - ori r4, r4, CFG_IBAT2L@l - addis r3, r0, CFG_IBAT2U@h - ori r3, r3, CFG_IBAT2U@l - mtspr IBAT2L, r4 - mtspr IBAT2U, r3 - isync - - /* DBAT 2 */ - addis r4, r0, CFG_DBAT2L@h - ori r4, r4, CFG_DBAT2L@l - addis r3, r0, CFG_DBAT2U@h - ori r3, r3, CFG_DBAT2U@l - mtspr DBAT2L, r4 - mtspr DBAT2U, r3 - isync - - /* IBAT 3 */ - addis r4, r0, CFG_IBAT3L@h - ori r4, r4, CFG_IBAT3L@l - addis r3, r0, CFG_IBAT3U@h - ori r3, r3, CFG_IBAT3U@l - mtspr IBAT3L, r4 - mtspr IBAT3U, r3 - isync - - /* DBAT 3 */ - addis r4, r0, CFG_DBAT3L@h - ori r4, r4, CFG_DBAT3L@l - addis r3, r0, CFG_DBAT3U@h - ori r3, r3, CFG_DBAT3U@l - mtspr DBAT3L, r4 - mtspr DBAT3U, r3 - isync - - /* IBAT 4 */ - addis r4, r0, CFG_IBAT4L@h - ori r4, r4, CFG_IBAT4L@l - addis r3, r0, CFG_IBAT4U@h - ori r3, r3, CFG_IBAT4U@l - mtspr IBAT4L, r4 - mtspr IBAT4U, r3 - isync - - /* DBAT 4 */ - addis r4, r0, CFG_DBAT4L@h - ori r4, r4, CFG_DBAT4L@l - addis r3, r0, CFG_DBAT4U@h - ori r3, r3, CFG_DBAT4U@l - mtspr DBAT4L, r4 - mtspr DBAT4U, r3 - isync - - /* IBAT 7 */ - addis r4, r0, CFG_IBAT7L@h - ori r4, r4, CFG_IBAT7L@l - addis r3, r0, CFG_IBAT7U@h - ori r3, r3, CFG_IBAT7U@l - mtspr IBAT7L, r4 - mtspr IBAT7U, r3 - isync - - /* DBAT 7 */ - addis r4, r0, CFG_DBAT7L@h - ori r4, r4, CFG_DBAT7L@l - addis r3, r0, CFG_DBAT7U@h - ori r3, r3, CFG_DBAT7U@l - mtspr DBAT7L, r4 - mtspr DBAT7U, r3 - isync - - sync - blr - /* * early_bats: * diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c index e9940e8..1c36324 100644 --- a/cpu/ppc4xx/44x_spd_ddr2.c +++ b/cpu/ppc4xx/44x_spd_ddr2.c @@ -50,9 +50,19 @@ #include "ecc.h" -#if defined(CONFIG_SPD_EEPROM) && \ - (defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ - defined(CONFIG_460EX) || defined(CONFIG_460GT)) +#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2) + +#define PPC4xx_IBM_DDR2_DUMP_REGISTER(mnemonic) \ + do { \ + u32 data; \ + mfsdram(SDRAM_##mnemonic, data); \ + printf("%20s[%02x] = 0x%08X\n", \ + "SDRAM_" #mnemonic, SDRAM_##mnemonic, data); \ + } while (0) + +static inline void ppc4xx_ibm_ddr2_register_dump(void); + +#if defined(CONFIG_SPD_EEPROM) /*-----------------------------------------------------------------------------+ * Defines @@ -257,7 +267,6 @@ static void test(void); #else static void DQS_calibration_process(void); #endif -static void ppc440sp_sdram_register_dump(void); int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); void dcbz_area(u32 start_address, u32 num_bytes); @@ -607,7 +616,7 @@ phys_size_t initdram(int board_type) remove_tlb(0, dram_size); program_tlb(0, 0, dram_size, MY_TLB_WORD2_I_ENABLE); - ppc440sp_sdram_register_dump(); + ppc4xx_ibm_ddr2_register_dump(); /* * Clear potential errors resulting from auto-calibration. @@ -2760,7 +2769,7 @@ calibration_loop: printf("\nERROR: Cannot determine a common read delay for the " "DIMM(s) installed.\n"); debug("%s[%d] ERROR : \n", __FUNCTION__,__LINE__); - ppc440sp_sdram_register_dump(); + ppc4xx_ibm_ddr2_register_dump(); spd_ddr_init_hang (); } @@ -2946,169 +2955,8 @@ static void test(void) } #endif -#if defined(DEBUG) -static void ppc440sp_sdram_register_dump(void) -{ - unsigned int sdram_reg; - unsigned int sdram_data; - unsigned int dcr_data; - - printf("\n Register Dump:\n"); - sdram_reg = SDRAM_MCSTAT; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_MCSTAT = 0x%08X", sdram_data); - sdram_reg = SDRAM_MCOPT1; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_MCOPT1 = 0x%08X\n", sdram_data); - sdram_reg = SDRAM_MCOPT2; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_MCOPT2 = 0x%08X", sdram_data); - sdram_reg = SDRAM_MODT0; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_MODT0 = 0x%08X\n", sdram_data); - sdram_reg = SDRAM_MODT1; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_MODT1 = 0x%08X", sdram_data); - sdram_reg = SDRAM_MODT2; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_MODT2 = 0x%08X\n", sdram_data); - sdram_reg = SDRAM_MODT3; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_MODT3 = 0x%08X", sdram_data); - sdram_reg = SDRAM_CODT; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_CODT = 0x%08X\n", sdram_data); - sdram_reg = SDRAM_VVPR; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_VVPR = 0x%08X", sdram_data); - sdram_reg = SDRAM_OPARS; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_OPARS = 0x%08X\n", sdram_data); - /* - * OPAR2 is only used as a trigger register. - * No data is contained in this register, and reading or writing - * to is can cause bad things to happen (hangs). Just skip it - * and report NA - * sdram_reg = SDRAM_OPAR2; - * mfsdram(sdram_reg, sdram_data); - * printf(" SDRAM_OPAR2 = 0x%08X\n", sdram_data); - */ - printf(" SDRAM_OPART = N/A "); - sdram_reg = SDRAM_RTR; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_RTR = 0x%08X\n", sdram_data); - sdram_reg = SDRAM_MB0CF; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_MB0CF = 0x%08X", sdram_data); - sdram_reg = SDRAM_MB1CF; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_MB1CF = 0x%08X\n", sdram_data); - sdram_reg = SDRAM_MB2CF; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_MB2CF = 0x%08X", sdram_data); - sdram_reg = SDRAM_MB3CF; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_MB3CF = 0x%08X\n", sdram_data); - sdram_reg = SDRAM_INITPLR0; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_INITPLR0 = 0x%08X", sdram_data); - sdram_reg = SDRAM_INITPLR1; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_INITPLR1 = 0x%08X\n", sdram_data); - sdram_reg = SDRAM_INITPLR2; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_INITPLR2 = 0x%08X", sdram_data); - sdram_reg = SDRAM_INITPLR3; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_INITPLR3 = 0x%08X\n", sdram_data); - sdram_reg = SDRAM_INITPLR4; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_INITPLR4 = 0x%08X", sdram_data); - sdram_reg = SDRAM_INITPLR5; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_INITPLR5 = 0x%08X\n", sdram_data); - sdram_reg = SDRAM_INITPLR6; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_INITPLR6 = 0x%08X", sdram_data); - sdram_reg = SDRAM_INITPLR7; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_INITPLR7 = 0x%08X\n", sdram_data); - sdram_reg = SDRAM_INITPLR8; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_INITPLR8 = 0x%08X", sdram_data); - sdram_reg = SDRAM_INITPLR9; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_INITPLR9 = 0x%08X\n", sdram_data); - sdram_reg = SDRAM_INITPLR10; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_INITPLR10 = 0x%08X", sdram_data); - sdram_reg = SDRAM_INITPLR11; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_INITPLR11 = 0x%08X\n", sdram_data); - sdram_reg = SDRAM_INITPLR12; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_INITPLR12 = 0x%08X", sdram_data); - sdram_reg = SDRAM_INITPLR13; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_INITPLR13 = 0x%08X\n", sdram_data); - sdram_reg = SDRAM_INITPLR14; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_INITPLR14 = 0x%08X", sdram_data); - sdram_reg = SDRAM_INITPLR15; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_INITPLR15 = 0x%08X\n", sdram_data); - sdram_reg = SDRAM_RQDC; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_RQDC = 0x%08X", sdram_data); - sdram_reg = SDRAM_RFDC; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_RFDC = 0x%08X\n", sdram_data); - sdram_reg = SDRAM_RDCC; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_RDCC = 0x%08X", sdram_data); - sdram_reg = SDRAM_DLCR; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_DLCR = 0x%08X\n", sdram_data); - sdram_reg = SDRAM_CLKTR; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_CLKTR = 0x%08X", sdram_data); - sdram_reg = SDRAM_WRDTR; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_WRDTR = 0x%08X\n", sdram_data); - sdram_reg = SDRAM_SDTR1; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_SDTR1 = 0x%08X", sdram_data); - sdram_reg = SDRAM_SDTR2; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_SDTR2 = 0x%08X\n", sdram_data); - sdram_reg = SDRAM_SDTR3; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_SDTR3 = 0x%08X", sdram_data); - sdram_reg = SDRAM_MMODE; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_MMODE = 0x%08X\n", sdram_data); - sdram_reg = SDRAM_MEMODE; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_MEMODE = 0x%08X", sdram_data); - sdram_reg = SDRAM_ECCCR; - mfsdram(sdram_reg, sdram_data); - printf(" SDRAM_ECCCR = 0x%08X\n\n", sdram_data); - - dcr_data = mfdcr(SDRAM_R0BAS); - printf(" MQ0_B0BAS = 0x%08X", dcr_data); - dcr_data = mfdcr(SDRAM_R1BAS); - printf(" MQ1_B0BAS = 0x%08X\n", dcr_data); - dcr_data = mfdcr(SDRAM_R2BAS); - printf(" MQ2_B0BAS = 0x%08X", dcr_data); - dcr_data = mfdcr(SDRAM_R3BAS); - printf(" MQ3_B0BAS = 0x%08X\n", dcr_data); -} -#else /* !defined(DEBUG) */ -static void ppc440sp_sdram_register_dump(void) -{ -} -#endif /* defined(DEBUG) */ -#elif defined(CONFIG_405EX) +#else /* CONFIG_SPD_EEPROM */ + /*----------------------------------------------------------------------------- * Function: initdram * Description: Configures the PPC405EX(r) DDR1/DDR2 SDRAM memory @@ -3222,8 +3070,96 @@ phys_size_t initdram(int board_type) #if defined(CONFIG_DDR_ECC) ecc_init(CFG_SDRAM_BASE, CFG_MBYTES_SDRAM << 20); #endif /* defined(CONFIG_DDR_ECC) */ + + ppc4xx_ibm_ddr2_register_dump(); #endif /* !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL) */ return (CFG_MBYTES_SDRAM << 20); } -#endif /* defined(CONFIG_SPD_EEPROM) && defined(CONFIG_440SP) || ... */ +#endif /* CONFIG_SPD_EEPROM */ + +static inline void ppc4xx_ibm_ddr2_register_dump(void) +{ +#if defined(DEBUG) + printf("\nPPC4xx IBM DDR2 Register Dump:\n"); + +#if (defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT)) + PPC4xx_IBM_DDR2_DUMP_REGISTER(R0BAS); + PPC4xx_IBM_DDR2_DUMP_REGISTER(R1BAS); + PPC4xx_IBM_DDR2_DUMP_REGISTER(R2BAS); + PPC4xx_IBM_DDR2_DUMP_REGISTER(R3BAS); +#endif /* (defined(CONFIG_440SP) || ... */ +#if defined(CONFIG_405EX) + PPC4xx_IBM_DDR2_DUMP_REGISTER(BESR); + PPC4xx_IBM_DDR2_DUMP_REGISTER(BEARL); + PPC4xx_IBM_DDR2_DUMP_REGISTER(BEARH); + PPC4xx_IBM_DDR2_DUMP_REGISTER(WMIRQ); + PPC4xx_IBM_DDR2_DUMP_REGISTER(PLBOPT); + PPC4xx_IBM_DDR2_DUMP_REGISTER(PUABA); +#endif /* defined(CONFIG_405EX) */ + PPC4xx_IBM_DDR2_DUMP_REGISTER(MB0CF); + PPC4xx_IBM_DDR2_DUMP_REGISTER(MB1CF); + PPC4xx_IBM_DDR2_DUMP_REGISTER(MB2CF); + PPC4xx_IBM_DDR2_DUMP_REGISTER(MB3CF); + PPC4xx_IBM_DDR2_DUMP_REGISTER(MCSTAT); + PPC4xx_IBM_DDR2_DUMP_REGISTER(MCOPT1); + PPC4xx_IBM_DDR2_DUMP_REGISTER(MCOPT2); + PPC4xx_IBM_DDR2_DUMP_REGISTER(MODT0); + PPC4xx_IBM_DDR2_DUMP_REGISTER(MODT1); + PPC4xx_IBM_DDR2_DUMP_REGISTER(MODT2); + PPC4xx_IBM_DDR2_DUMP_REGISTER(MODT3); + PPC4xx_IBM_DDR2_DUMP_REGISTER(CODT); +#if (defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT)) + PPC4xx_IBM_DDR2_DUMP_REGISTER(VVPR); + PPC4xx_IBM_DDR2_DUMP_REGISTER(OPARS); + /* + * OPART is only used as a trigger register. + * + * No data is contained in this register, and reading or writing + * to is can cause bad things to happen (hangs). Just skip it and + * report "N/A". + */ + printf("%20s = N/A\n", "SDRAM_OPART"); +#endif /* defined(CONFIG_440SP) || ... */ + PPC4xx_IBM_DDR2_DUMP_REGISTER(RTR); + PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR0); + PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR1); + PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR2); + PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR3); + PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR4); + PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR5); + PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR6); + PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR7); + PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR8); + PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR9); + PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR10); + PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR11); + PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR12); + PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR13); + PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR14); + PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR15); + PPC4xx_IBM_DDR2_DUMP_REGISTER(RQDC); + PPC4xx_IBM_DDR2_DUMP_REGISTER(RFDC); + PPC4xx_IBM_DDR2_DUMP_REGISTER(RDCC); + PPC4xx_IBM_DDR2_DUMP_REGISTER(DLCR); + PPC4xx_IBM_DDR2_DUMP_REGISTER(CLKTR); + PPC4xx_IBM_DDR2_DUMP_REGISTER(WRDTR); + PPC4xx_IBM_DDR2_DUMP_REGISTER(SDTR1); + PPC4xx_IBM_DDR2_DUMP_REGISTER(SDTR2); + PPC4xx_IBM_DDR2_DUMP_REGISTER(SDTR3); + PPC4xx_IBM_DDR2_DUMP_REGISTER(MMODE); + PPC4xx_IBM_DDR2_DUMP_REGISTER(MEMODE); + PPC4xx_IBM_DDR2_DUMP_REGISTER(ECCCR); +#if (defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT)) + PPC4xx_IBM_DDR2_DUMP_REGISTER(CID); +#endif /* defined(CONFIG_440SP) || ... */ + PPC4xx_IBM_DDR2_DUMP_REGISTER(RID); + PPC4xx_IBM_DDR2_DUMP_REGISTER(FCSR); + PPC4xx_IBM_DDR2_DUMP_REGISTER(RTSR); +#endif /* defined(DEBUG) */ +} + +#endif /* CONFIG_SDRAM_PPC4xx_IBM_DDR2 */ diff --git a/cpu/ppc4xx/4xx_enet.c b/cpu/ppc4xx/4xx_enet.c index 4e863dc..8a38335 100644 --- a/cpu/ppc4xx/4xx_enet.c +++ b/cpu/ppc4xx/4xx_enet.c @@ -90,7 +90,6 @@ #include <405_mal.h> #include <miiphy.h> #include <malloc.h> -#include <asm/ppc4xx-intvec.h> /* * Only compile for platform with AMCC EMAC ethernet controller and @@ -122,11 +121,65 @@ * Defines for MAL/EMAC interrupt conditions as reported in the UIC (Universal * Interrupt Controller). *-----------------------------------------------------------------------------*/ -#define MAL_UIC_ERR ( UIC_MAL_SERR | UIC_MAL_TXDE | UIC_MAL_RXDE) -#define MAL_UIC_DEF (UIC_MAL_RXEOB | MAL_UIC_ERR) -#define EMAC_UIC_DEF UIC_ENET -#define EMAC_UIC_DEF1 UIC_ENET1 -#define SEL_UIC_DEF(p) (p ? UIC_ENET1 : UIC_ENET ) +#define ETH_IRQ_NUM(dev) (VECNUM_ETH0 + ((dev) * VECNUM_ETH1_OFFS)) + +#if defined(CONFIG_HAS_ETH3) +#if !defined(CONFIG_440GX) +#define UIC_ETHx (UIC_MASK(ETH_IRQ_NUM(0)) || UIC_MASK(ETH_IRQ_NUM(1)) || \ + UIC_MASK(ETH_IRQ_NUM(2)) || UIC_MASK(ETH_IRQ_NUM(3))) +#else +/* Unfortunately 440GX spreads EMAC interrupts on multiple UIC's */ +#define UIC_ETHx (UIC_MASK(ETH_IRQ_NUM(0)) || UIC_MASK(ETH_IRQ_NUM(1))) +#define UIC_ETHxB (UIC_MASK(ETH_IRQ_NUM(2)) || UIC_MASK(ETH_IRQ_NUM(3))) +#endif /* !defined(CONFIG_440GX) */ +#elif defined(CONFIG_HAS_ETH2) +#define UIC_ETHx (UIC_MASK(ETH_IRQ_NUM(0)) || UIC_MASK(ETH_IRQ_NUM(1)) || \ + UIC_MASK(ETH_IRQ_NUM(2))) +#elif defined(CONFIG_HAS_ETH1) +#define UIC_ETHx (UIC_MASK(ETH_IRQ_NUM(0)) || UIC_MASK(ETH_IRQ_NUM(1))) +#else +#define UIC_ETHx UIC_MASK(ETH_IRQ_NUM(0)) +#endif + +/* + * Define a default version for UIC_ETHxB for non 440GX so that we can + * use common code for all 4xx variants + */ +#if !defined(UIC_ETHxB) +#define UIC_ETHxB 0 +#endif + +#define UIC_MAL_SERR UIC_MASK(VECNUM_MAL_SERR) +#define UIC_MAL_TXDE UIC_MASK(VECNUM_MAL_TXDE) +#define UIC_MAL_RXDE UIC_MASK(VECNUM_MAL_RXDE) +#define UIC_MAL_TXEOB UIC_MASK(VECNUM_MAL_TXEOB) +#define UIC_MAL_RXEOB UIC_MASK(VECNUM_MAL_RXEOB) + +#define MAL_UIC_ERR (UIC_MAL_SERR | UIC_MAL_TXDE | UIC_MAL_RXDE) +#define MAL_UIC_DEF (UIC_MAL_RXEOB | MAL_UIC_ERR) + +/* + * We have 3 different interrupt types: + * - MAL interrupts indicating successful transfer + * - MAL error interrupts indicating MAL related errors + * - EMAC interrupts indicating EMAC related errors + * + * All those interrupts can be on different UIC's, but since + * now at least all interrupts from one type are on the same + * UIC. Only exception is 440GX where the EMAC interrupts are + * spread over two UIC's! + */ +#if defined(CONFIG_440GX) +#define UIC_BASE_MAL UIC1_DCR_BASE +#define UIC_BASE_MAL_ERR UIC2_DCR_BASE +#define UIC_BASE_EMAC UIC2_DCR_BASE +#define UIC_BASE_EMAC_B UIC3_DCR_BASE +#else +#define UIC_BASE_MAL (UIC0_DCR_BASE + (UIC_NR(VECNUM_MAL_TXEOB) * 0x10)) +#define UIC_BASE_MAL_ERR (UIC0_DCR_BASE + (UIC_NR(VECNUM_MAL_SERR) * 0x10)) +#define UIC_BASE_EMAC (UIC0_DCR_BASE + (UIC_NR(ETH_IRQ_NUM(0)) * 0x10)) +#define UIC_BASE_EMAC_B (UIC0_DCR_BASE + (UIC_NR(ETH_IRQ_NUM(0)) * 0x10)) +#endif #undef INFO_4XX_ENET @@ -166,9 +219,6 @@ /*-----------------------------------------------------------------------------+ * Global variables. TX and RX descriptors and buffers. *-----------------------------------------------------------------------------*/ -/* IER globals */ -static uint32_t mal_ier; - #if !defined(CONFIG_NET_MULTI) struct eth_device *emac0_dev = NULL; #endif @@ -200,12 +250,6 @@ struct eth_device *emac0_dev = NULL; #define CONFIG_EMAC_NR_START 0 #endif -#if defined(CONFIG_405EX) || defined(CONFIG_440EPX) -#define ETH_IRQ_NUM(dev) (VECNUM_ETH0 + ((dev))) -#else -#define ETH_IRQ_NUM(dev) (VECNUM_ETH0 + ((dev) * 2)) -#endif - #define MAL_RX_DESC_SIZE 2048 #define MAL_TX_DESC_SIZE 2048 #define MAL_ALLOC_SIZE (MAL_TX_DESC_SIZE + MAL_RX_DESC_SIZE) @@ -465,30 +509,88 @@ int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis) #if defined(CONFIG_405EX) int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis) { - u32 gmiifer = 0; + u32 rgmiifer = 0; /* - * Right now only 2*RGMII is supported. Please extend when needed. - * sr - 2007-09-19 + * The 405EX(r)'s RGMII bridge can operate in one of several + * modes, only one of which (2 x RGMII) allows the + * simultaneous use of both EMACs on the 405EX. */ - switch (1) { - case 1: + + switch (CONFIG_EMAC_PHY_MODE) { + + case EMAC_PHY_MODE_NONE: + /* No ports */ + rgmiifer |= RGMII_FER_DIS << 0; + rgmiifer |= RGMII_FER_DIS << 4; + out_be32((void *)RGMII_FER, rgmiifer); + bis->bi_phymode[0] = BI_PHYMODE_NONE; + bis->bi_phymode[1] = BI_PHYMODE_NONE; + break; + case EMAC_PHY_MODE_NONE_RGMII: + /* 1 x RGMII port on channel 0 */ + rgmiifer |= RGMII_FER_RGMII << 0; + rgmiifer |= RGMII_FER_DIS << 4; + out_be32((void *)RGMII_FER, rgmiifer); + bis->bi_phymode[0] = BI_PHYMODE_RGMII; + bis->bi_phymode[1] = BI_PHYMODE_NONE; + break; + case EMAC_PHY_MODE_RGMII_NONE: + /* 1 x RGMII port on channel 1 */ + rgmiifer |= RGMII_FER_DIS << 0; + rgmiifer |= RGMII_FER_RGMII << 4; + out_be32((void *)RGMII_FER, rgmiifer); + bis->bi_phymode[0] = BI_PHYMODE_NONE; + bis->bi_phymode[1] = BI_PHYMODE_RGMII; + break; + case EMAC_PHY_MODE_RGMII_RGMII: /* 2 x RGMII ports */ - out_be32((void *)RGMII_FER, 0x00000055); + rgmiifer |= RGMII_FER_RGMII << 0; + rgmiifer |= RGMII_FER_RGMII << 4; + out_be32((void *)RGMII_FER, rgmiifer); bis->bi_phymode[0] = BI_PHYMODE_RGMII; bis->bi_phymode[1] = BI_PHYMODE_RGMII; break; - case 2: - /* 2 x SMII ports */ + case EMAC_PHY_MODE_NONE_GMII: + /* 1 x GMII port on channel 0 */ + rgmiifer |= RGMII_FER_GMII << 0; + rgmiifer |= RGMII_FER_DIS << 4; + out_be32((void *)RGMII_FER, rgmiifer); + bis->bi_phymode[0] = BI_PHYMODE_GMII; + bis->bi_phymode[1] = BI_PHYMODE_NONE; + break; + case EMAC_PHY_MODE_NONE_MII: + /* 1 x MII port on channel 0 */ + rgmiifer |= RGMII_FER_MII << 0; + rgmiifer |= RGMII_FER_DIS << 4; + out_be32((void *)RGMII_FER, rgmiifer); + bis->bi_phymode[0] = BI_PHYMODE_MII; + bis->bi_phymode[1] = BI_PHYMODE_NONE; + break; + case EMAC_PHY_MODE_GMII_NONE: + /* 1 x GMII port on channel 1 */ + rgmiifer |= RGMII_FER_DIS << 0; + rgmiifer |= RGMII_FER_GMII << 4; + out_be32((void *)RGMII_FER, rgmiifer); + bis->bi_phymode[0] = BI_PHYMODE_NONE; + bis->bi_phymode[1] = BI_PHYMODE_GMII; + break; + case EMAC_PHY_MODE_MII_NONE: + /* 1 x MII port on channel 1 */ + rgmiifer |= RGMII_FER_DIS << 0; + rgmiifer |= RGMII_FER_MII << 4; + out_be32((void *)RGMII_FER, rgmiifer); + bis->bi_phymode[0] = BI_PHYMODE_NONE; + bis->bi_phymode[1] = BI_PHYMODE_MII; break; default: break; } /* Ensure we setup mdio for this devnum and ONLY this devnum */ - gmiifer = in_be32((void *)RGMII_FER); - gmiifer |= (1 << (19-devnum)); - out_be32((void *)RGMII_FER, gmiifer); + rgmiifer = in_be32((void *)RGMII_FER); + rgmiifer |= (1 << (19-devnum)); + out_be32((void *)RGMII_FER, rgmiifer); return ((int)0x0); } @@ -1377,59 +1479,17 @@ static int ppc_4xx_eth_send (struct eth_device *dev, volatile void *ptr, } } - -#if defined (CONFIG_440) || defined(CONFIG_405EX) - -#if defined(CONFIG_440SP) || defined(CONFIG_440SPE) -/* - * Hack: On 440SP all enet irq sources are located on UIC1 - * Needs some cleanup. --sr - */ -#define UIC0MSR uic1msr -#define UIC0SR uic1sr -#define UIC1MSR uic1msr -#define UIC1SR uic1sr -#elif defined(CONFIG_460EX) || defined(CONFIG_460GT) -/* - * Hack: On 460EX/GT all enet irq sources are located on UIC2 - * Needs some cleanup. --ag - */ -#define UIC0MSR uic2msr -#define UIC0SR uic2sr -#define UIC1MSR uic2msr -#define UIC1SR uic2sr -#else -#define UIC0MSR uic0msr -#define UIC0SR uic0sr -#define UIC1MSR uic1msr -#define UIC1SR uic1sr -#endif - -#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_405EX) -#define UICMSR_ETHX uic0msr -#define UICSR_ETHX uic0sr -#elif defined(CONFIG_460EX) || defined(CONFIG_460GT) -#define UICMSR_ETHX uic2msr -#define UICSR_ETHX uic2sr -#else -#define UICMSR_ETHX uic1msr -#define UICSR_ETHX uic1sr -#endif - int enetInt (struct eth_device *dev) { int serviced; int rc = -1; /* default to not us */ - unsigned long mal_isr; - unsigned long emac_isr = 0; - unsigned long mal_rx_eob; - unsigned long my_uic0msr, my_uic1msr; - unsigned long my_uicmsr_ethx; - -#if defined(CONFIG_440GX) - unsigned long my_uic2msr; -#endif + u32 mal_isr; + u32 emac_isr = 0; + u32 mal_eob; + u32 uic_mal; + u32 uic_mal_err; + u32 uic_emac; + u32 uic_emac_b; EMAC_4XX_HW_PST hw_p; /* @@ -1448,256 +1508,79 @@ int enetInt (struct eth_device *dev) do { serviced = 0; - my_uic0msr = mfdcr (UIC0MSR); - my_uic1msr = mfdcr (UIC1MSR); -#if defined(CONFIG_440GX) - my_uic2msr = mfdcr (uic2msr); -#endif - my_uicmsr_ethx = mfdcr (UICMSR_ETHX); + uic_mal = mfdcr(UIC_BASE_MAL + UIC_MSR); + uic_mal_err = mfdcr(UIC_BASE_MAL_ERR + UIC_MSR); + uic_emac = mfdcr(UIC_BASE_EMAC + UIC_MSR); + uic_emac_b = mfdcr(UIC_BASE_EMAC_B + UIC_MSR); - if (!(my_uic0msr & (UIC_MRE | UIC_MTE)) - && !(my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE)) - && !(my_uicmsr_ethx & (UIC_ETH0 | UIC_ETH1))) { - /* not for us */ - return (rc); - } -#if defined (CONFIG_440GX) - if (!(my_uic0msr & (UIC_MRE | UIC_MTE)) - && !(my_uic2msr & (UIC_ETH2 | UIC_ETH3))) { + if (!(uic_mal & (UIC_MAL_RXEOB | UIC_MAL_TXEOB)) + && !(uic_mal_err & (UIC_MAL_SERR | UIC_MAL_TXDE | UIC_MAL_RXDE)) + && !(uic_emac & UIC_ETHx) && !(uic_emac_b & UIC_ETHxB)) { /* not for us */ return (rc); } -#endif + /* get and clear controller status interrupts */ - /* look at Mal and EMAC interrupts */ - if ((my_uic0msr & (UIC_MRE | UIC_MTE)) - || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) { - /* we have a MAL interrupt */ - mal_isr = mfdcr (malesr); - /* look for mal error */ - if (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE)) { - mal_err (dev, mal_isr, my_uic1msr, MAL_UIC_DEF, MAL_UIC_ERR); - serviced = 1; - rc = 0; - } - } + /* look at MAL and EMAC error interrupts */ + if (uic_mal_err & (UIC_MAL_SERR | UIC_MAL_TXDE | UIC_MAL_RXDE)) { + /* we have a MAL error interrupt */ + mal_isr = mfdcr(malesr); + mal_err(dev, mal_isr, uic_mal_err, + MAL_UIC_DEF, MAL_UIC_ERR); - /* port by port dispatch of emac interrupts */ - if (hw_p->devnum == 0) { - if (UIC_ETH0 & my_uicmsr_ethx) { /* look for EMAC errors */ - emac_isr = in_be32((void *)EMAC_ISR + hw_p->hw_addr); - if ((hw_p->emac_ier & emac_isr) != 0) { - emac_err (dev, emac_isr); - serviced = 1; - rc = 0; - } - } - if ((hw_p->emac_ier & emac_isr) - || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) { - mtdcr (UIC0SR, UIC_MRE | UIC_MTE); /* Clear */ - mtdcr (UIC1SR, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */ - mtdcr (UICSR_ETHX, UIC_ETH0); /* Clear */ - return (rc); /* we had errors so get out */ - } - } + /* clear MAL error interrupt status bits */ + mtdcr(UIC_BASE_MAL_ERR + UIC_SR, + UIC_MAL_SERR | UIC_MAL_TXDE | UIC_MAL_RXDE); -#if !defined(CONFIG_440SP) - if (hw_p->devnum == 1) { - if (UIC_ETH1 & my_uicmsr_ethx) { /* look for EMAC errors */ - emac_isr = in_be32((void *)EMAC_ISR + hw_p->hw_addr); - if ((hw_p->emac_ier & emac_isr) != 0) { - emac_err (dev, emac_isr); - serviced = 1; - rc = 0; - } - } - if ((hw_p->emac_ier & emac_isr) - || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) { - mtdcr (UIC0SR, UIC_MRE | UIC_MTE); /* Clear */ - mtdcr (UIC1SR, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */ - mtdcr (UICSR_ETHX, UIC_ETH1); /* Clear */ - return (rc); /* we had errors so get out */ - } - } -#if defined (CONFIG_440GX) - if (hw_p->devnum == 2) { - if (UIC_ETH2 & my_uic2msr) { /* look for EMAC errors */ - emac_isr = in_be32((void *)EMAC_ISR + hw_p->hw_addr); - if ((hw_p->emac_ier & emac_isr) != 0) { - emac_err (dev, emac_isr); - serviced = 1; - rc = 0; - } - } - if ((hw_p->emac_ier & emac_isr) - || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) { - mtdcr (UIC0SR, UIC_MRE | UIC_MTE); /* Clear */ - mtdcr (UIC1SR, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */ - mtdcr (uic2sr, UIC_ETH2); - return (rc); /* we had errors so get out */ - } + return -1; } - if (hw_p->devnum == 3) { - if (UIC_ETH3 & my_uic2msr) { /* look for EMAC errors */ - emac_isr = in_be32((void *)EMAC_ISR + hw_p->hw_addr); - if ((hw_p->emac_ier & emac_isr) != 0) { - emac_err (dev, emac_isr); - serviced = 1; - rc = 0; - } - } - if ((hw_p->emac_ier & emac_isr) - || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) { - mtdcr (UIC0SR, UIC_MRE | UIC_MTE); /* Clear */ - mtdcr (UIC1SR, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */ - mtdcr (uic2sr, UIC_ETH3); - return (rc); /* we had errors so get out */ - } - } -#endif /* CONFIG_440GX */ -#endif /* !CONFIG_440SP */ + /* look for EMAC errors */ + if ((uic_emac & UIC_ETHx) || (uic_emac_b & UIC_ETHxB)) { + emac_isr = in_be32((void *)EMAC_ISR + hw_p->hw_addr); + emac_err(dev, emac_isr); - /* handle MAX TX EOB interrupt from a tx */ - if (my_uic0msr & UIC_MTE) { - mal_rx_eob = mfdcr (maltxeobisr); - mtdcr (maltxeobisr, mal_rx_eob); - mtdcr (UIC0SR, UIC_MTE); - } - /* handle MAL RX EOB interupt from a receive */ - /* check for EOB on valid channels */ - if (my_uic0msr & UIC_MRE) { - mal_rx_eob = mfdcr (malrxeobisr); - if ((mal_rx_eob & - (0x80000000 >> (hw_p->devnum * MAL_RX_CHAN_MUL))) - != 0) { /* call emac routine for channel x */ - /* clear EOB - mtdcr(malrxeobisr, mal_rx_eob); */ - enet_rcv (dev, emac_isr); - /* indicate that we serviced an interrupt */ - serviced = 1; - rc = 0; - } - } + /* clear EMAC error interrupt status bits */ + mtdcr(UIC_BASE_EMAC + UIC_SR, UIC_ETHx); + mtdcr(UIC_BASE_EMAC_B + UIC_SR, UIC_ETHxB); - mtdcr (UIC0SR, UIC_MRE); /* Clear */ - mtdcr (UIC1SR, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */ - switch (hw_p->devnum) { - case 0: - mtdcr (UICSR_ETHX, UIC_ETH0); - break; - case 1: - mtdcr (UICSR_ETHX, UIC_ETH1); - break; -#if defined (CONFIG_440GX) - case 2: - mtdcr (uic2sr, UIC_ETH2); - break; - case 3: - mtdcr (uic2sr, UIC_ETH3); - break; -#endif /* CONFIG_440GX */ - default: - break; + return -1; } - } while (serviced); - - return (rc); -} - -#else /* CONFIG_440 */ - -int enetInt (struct eth_device *dev) -{ - int serviced; - int rc = -1; /* default to not us */ - unsigned long mal_isr; - unsigned long emac_isr = 0; - unsigned long mal_rx_eob; - unsigned long my_uicmsr; - - EMAC_4XX_HW_PST hw_p; - - /* - * Because the mal is generic, we need to get the current - * eth device - */ -#if defined(CONFIG_NET_MULTI) - dev = eth_get_dev(); -#else - dev = emac0_dev; -#endif - - hw_p = dev->priv; - - /* enter loop that stays in interrupt code until nothing to service */ - do { - serviced = 0; - my_uicmsr = mfdcr (uicmsr); - - if ((my_uicmsr & (MAL_UIC_DEF | EMAC_UIC_DEF)) == 0) { /* not for us */ - return (rc); - } - /* get and clear controller status interrupts */ - /* look at Mal and EMAC interrupts */ - if ((MAL_UIC_DEF & my_uicmsr) != 0) { /* we have a MAL interrupt */ - mal_isr = mfdcr (malesr); - /* look for mal error */ - if ((my_uicmsr & MAL_UIC_ERR) != 0) { - mal_err (dev, mal_isr, my_uicmsr, MAL_UIC_DEF, MAL_UIC_ERR); - serviced = 1; - rc = 0; - } + /* handle MAX TX EOB interrupt from a tx */ + if (uic_mal & UIC_MAL_TXEOB) { + /* clear MAL interrupt status bits */ + mal_eob = mfdcr(maltxeobisr); + mtdcr(maltxeobisr, mal_eob); + mtdcr(UIC_BASE_MAL + UIC_SR, UIC_MAL_TXEOB); + + /* indicate that we serviced an interrupt */ + serviced = 1; + rc = 0; } - /* port by port dispatch of emac interrupts */ + /* handle MAL RX EOB interupt from a receive */ + /* check for EOB on valid channels */ + if (uic_mal & UIC_MAL_RXEOB) { + mal_eob = mfdcr(malrxeobisr); + if (mal_eob & + (0x80000000 >> (hw_p->devnum * MAL_RX_CHAN_MUL))) { + /* push packet to upper layer */ + enet_rcv(dev, emac_isr); - if ((SEL_UIC_DEF(hw_p->devnum) & my_uicmsr) != 0) { /* look for EMAC errors */ - emac_isr = in_be32((void *)EMAC_ISR + hw_p->hw_addr); - if ((hw_p->emac_ier & emac_isr) != 0) { - emac_err (dev, emac_isr); - serviced = 1; - rc = 0; - } - } - if (((hw_p->emac_ier & emac_isr) != 0) || ((MAL_UIC_ERR & my_uicmsr) != 0)) { - mtdcr (uicsr, MAL_UIC_DEF | SEL_UIC_DEF(hw_p->devnum)); /* Clear */ - return (rc); /* we had errors so get out */ - } + /* clear MAL interrupt status bits */ + mtdcr(UIC_BASE_MAL + UIC_SR, UIC_MAL_RXEOB); - /* handle MAX TX EOB interrupt from a tx */ - if (my_uicmsr & UIC_MAL_TXEOB) { - mal_rx_eob = mfdcr (maltxeobisr); - mtdcr (maltxeobisr, mal_rx_eob); - mtdcr (uicsr, UIC_MAL_TXEOB); - } - /* handle MAL RX EOB interupt from a receive */ - /* check for EOB on valid channels */ - if (my_uicmsr & UIC_MAL_RXEOB) - { - mal_rx_eob = mfdcr (malrxeobisr); - if ((mal_rx_eob & (0x80000000 >> hw_p->devnum)) != 0) { /* call emac routine for channel x */ - /* clear EOB - mtdcr(malrxeobisr, mal_rx_eob); */ - enet_rcv (dev, emac_isr); /* indicate that we serviced an interrupt */ serviced = 1; rc = 0; } } - mtdcr (uicsr, MAL_UIC_DEF|EMAC_UIC_DEF|EMAC_UIC_DEF1); /* Clear */ -#if defined(CONFIG_405EZ) - mtsdr (sdricintstat, SDR_ICRX_STAT | SDR_ICTX0_STAT | SDR_ICTX1_STAT); -#endif /* defined(CONFIG_405EZ) */ - } - while (serviced); + } while (serviced); return (rc); } -#endif /* CONFIG_440 */ - /*-----------------------------------------------------------------------------+ * MAL Error Routine *-----------------------------------------------------------------------------*/ @@ -1883,6 +1766,7 @@ int ppc_4xx_eth_initialize (bd_t * bis) EMAC_4XX_HW_PST hw = NULL; u8 ethaddr[4 + CONFIG_EMAC_NR_START][6]; u32 hw_addr[4]; + u32 mal_ier; #if defined(CONFIG_440GX) unsigned long pfc1; @@ -2020,19 +1904,19 @@ int ppc_4xx_eth_initialize (bd_t * bis) mtdcr (malier, mal_ier); /* install MAL interrupt handler */ - irq_install_handler (VECNUM_MS, + irq_install_handler (VECNUM_MAL_SERR, (interrupt_handler_t *) enetInt, dev); - irq_install_handler (VECNUM_MTE, + irq_install_handler (VECNUM_MAL_TXEOB, (interrupt_handler_t *) enetInt, dev); - irq_install_handler (VECNUM_MRE, + irq_install_handler (VECNUM_MAL_RXEOB, (interrupt_handler_t *) enetInt, dev); - irq_install_handler (VECNUM_TXDE, + irq_install_handler (VECNUM_MAL_TXDE, (interrupt_handler_t *) enetInt, dev); - irq_install_handler (VECNUM_RXDE, + irq_install_handler (VECNUM_MAL_RXDE, (interrupt_handler_t *) enetInt, dev); virgin = 1; diff --git a/cpu/ppc4xx/4xx_uart.c b/cpu/ppc4xx/4xx_uart.c index a7587d4..766e586 100644 --- a/cpu/ppc4xx/4xx_uart.c +++ b/cpu/ppc4xx/4xx_uart.c @@ -46,7 +46,7 @@ #include <asm/processor.h> #include <asm/io.h> #include <watchdog.h> -#include <asm/ppc4xx-intvec.h> +#include <ppc4xx.h> #ifdef CONFIG_SERIAL_MULTI #include <serial.h> diff --git a/cpu/ppc4xx/Makefile b/cpu/ppc4xx/Makefile index 800bb41..c773400 100644 --- a/cpu/ppc4xx/Makefile +++ b/cpu/ppc4xx/Makefile @@ -35,10 +35,8 @@ SOBJS += kgdb.o COBJS := 40x_spd_sdram.o COBJS += 44x_spd_ddr.o COBJS += 44x_spd_ddr2.o -COBJS += 4xx_enet.o COBJS += 4xx_pci.o COBJS += 4xx_pcie.o -COBJS += 4xx_uart.o COBJS += bedbug_405.o COBJS += commproc.o COBJS += cpu.o @@ -47,11 +45,9 @@ COBJS += denali_data_eye.o COBJS += denali_spd_ddr2.o COBJS += ecc.o COBJS += fdt.o -COBJS += gpio.o COBJS += i2c.o COBJS += interrupts.o COBJS += iop480_uart.o -COBJS += miiphy.o COBJS += ndfc.o COBJS += sdram.o COBJS += speed.o @@ -60,6 +56,15 @@ COBJS += traps.o COBJS += usb.o COBJS += usb_ohci.o COBJS += usbdev.o +ifndef CONFIG_XILINX_440 +COBJS += 4xx_enet.o +COBJS += 4xx_uart.o +COBJS += gpio.o +COBJS += miiphy.o +COBJS += uic.o +else +COBJS += xilinx_irq.o +endif SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c index 39f439d..bc9335a 100644 --- a/cpu/ppc4xx/cpu.c +++ b/cpu/ppc4xx/cpu.c @@ -184,6 +184,19 @@ static char *bootstrap_str[] = { static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'G', 'F', 'H' }; #endif +#if defined(CONFIG_460SX) +#define SDR0_PINSTP_SHIFT 29 +static char *bootstrap_str[] = { + "EBC (8 bits)", + "EBC (16 bits)", + "EBC (32 bits)", + "NAND (8 bits)", + "I2C (Addr 0x54)", /* A8 */ + "I2C (Addr 0x52)", /* A4 */ +}; +static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'G' }; +#endif + #if defined(CONFIG_405EZ) #define SDR0_PINSTP_SHIFT 28 static char *bootstrap_str[] = { @@ -266,7 +279,11 @@ int checkcpu (void) get_sys_info(&sys_info); +#if defined(CONFIG_XILINX_440) + puts("IBM PowerPC 4"); +#else puts("AMCC PowerPC 4"); +#endif #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || \ defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \ @@ -509,6 +526,30 @@ int checkcpu (void) strcpy(addstr, "Security/Kasumi support"); break; + case PVR_460SX_RA: + puts("SX Rev. A"); + strcpy(addstr, "Security support"); + break; + + case PVR_460SX_RA_V1: + puts("SX Rev. A"); + strcpy(addstr, "No Security support"); + break; + + case PVR_460GX_RA: + puts("GX Rev. A"); + strcpy(addstr, "Security support"); + break; + + case PVR_460GX_RA_V1: + puts("GX Rev. A"); + strcpy(addstr, "No Security support"); + break; + + case PVR_VIRTEX5: + puts("x5 VIRTEX5"); + break; + default: printf (" UNKNOWN (PVR=%08x)", pvr); break; diff --git a/cpu/ppc4xx/cpu_init.c b/cpu/ppc4xx/cpu_init.c index ac64279..e2d0402 100644 --- a/cpu/ppc4xx/cpu_init.c +++ b/cpu/ppc4xx/cpu_init.c @@ -138,9 +138,10 @@ void reconfigure_pll(u32 new_cpu_freq) void cpu_init_f (void) { -#if defined(CONFIG_WATCHDOG) || defined(CONFIG_460EX) +#if defined(CONFIG_WATCHDOG) || defined(CONFIG_440GX) || defined(CONFIG_460EX) u32 val; #endif + reconfigure_pll(CFG_PLL_RECONFIG); #if (defined(CONFIG_405EP) || defined (CONFIG_405EX)) && !defined(CFG_4xx_GPIO_TABLE) @@ -273,6 +274,18 @@ cpu_init_f (void) reset_4xx_watchdog(); #endif /* CONFIG_WATCHDOG */ +#if defined(CONFIG_440GX) + /* Take the GX out of compatibility mode + * Travis Sawyer, 9 Mar 2004 + * NOTE: 440gx user manual inconsistency here + * Compatibility mode and Ethernet Clock select are not + * correct in the manual + */ + mfsdr(sdr_mfr, val); + val &= ~0x10000000; + mtsdr(sdr_mfr,val); +#endif /* CONFIG_440GX */ + #if defined(CONFIG_460EX) /* * Set SDR0_AHB_CFG[A2P_INCR4] (bit 24) and diff --git a/cpu/ppc4xx/interrupts.c b/cpu/ppc4xx/interrupts.c index 8620e2b..494bd8c 100644 --- a/cpu/ppc4xx/interrupts.c +++ b/cpu/ppc4xx/interrupts.c @@ -8,6 +8,10 @@ * (C) Copyright 2003 (440GX port) * Travis B. Sawyer, Sandburst Corporation, tsawyer@sandburst.com * + * (C) Copyright 2008 (PPC440X05 port for Virtex 5 FX) + * Ricardo Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es + * Work supported by Qtechnology (htpp://qtec.com) + * * See file CREDITS for list of people who contributed to this * project. * @@ -31,31 +35,14 @@ #include <watchdog.h> #include <command.h> #include <asm/processor.h> +#include <asm/interrupt.h> #include <ppc4xx.h> #include <ppc_asm.tmpl> #include <commproc.h> -#include <asm/ppc4xx-intvec.h> 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. */ struct irq_action { @@ -63,15 +50,7 @@ struct irq_action { void *arg; int count; }; - -static struct irq_action irq_vecs[UIC_MAX * 32]; - -u32 get_dcr(u16); -void set_dcr(u16, u32); - -#if (UIC_MAX > 1) && !defined(CONFIG_440GX) -static void uic_cascade_interrupt(void *para); -#endif +static struct irq_action irq_vecs[IRQ_MAX]; #if defined(CONFIG_440) @@ -112,7 +91,7 @@ int interrupt_init_cpu (unsigned *decrementer_count) /* * Mark all irqs as free */ - for (vec = 0; vec < (UIC_MAX * 32); vec++) { + for (vec = 0; vec < IRQ_MAX; vec++) { irq_vecs[vec].handler = NULL; irq_vecs[vec].arg = NULL; irq_vecs[vec].count = 0; @@ -156,160 +135,38 @@ int interrupt_init_cpu (unsigned *decrementer_count) */ set_evpr(0x00000000); -#if !defined(CONFIG_440GX) -#if (UIC_MAX > 1) - /* Install the UIC1 handlers */ - 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 (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 - * Compatibility mode and Ethernet Clock select are not - * correct in the manual + /* + * Call uic or xilinx_irq pic_enable */ - mfsdr(sdr_mfr, val); - val &= ~0x10000000; - mtsdr(sdr_mfr,val); - - /* Enable UIC interrupts via UIC Base Enable Register */ - mtdcr(uicb0sr, UICB0_ALL); - mtdcr(uicb0er, 0x54000000); - /* None are critical */ - mtdcr(uicb0cr, 0); -#endif /* !defined(CONFIG_440GX) */ + pic_enable(); return (0); } -/* Handler for UIC interrupt */ -static void uic_interrupt(u32 uic_base, int vec_base) +void timer_interrupt_cpu(struct pt_regs *regs) { - u32 uic_msr; - u32 msr_shift; - int vec; - - /* - * Read masked interrupt status register to determine interrupt source - */ - uic_msr = get_dcr(uic_base + UIC_MSR); - msr_shift = uic_msr; - vec = vec_base; - - 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 { - set_dcr(uic_base + UIC_ER, - get_dcr(uic_base + UIC_ER) & - ~(0x80000000 >> (vec & 0x1f))); - 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 - */ - set_dcr(uic_base + UIC_SR, (0x80000000 >> (vec & 0x1f))); - } - - /* - * Shift msr to next position and increment vector - */ - msr_shift <<= 1; - vec++; - } + /* nothing to do here */ + return; } -#if (UIC_MAX > 1) && !defined(CONFIG_440GX) -static void uic_cascade_interrupt(void *para) +void interrupt_run_handler(int vec) { - external_interrupt(para); -} -#endif - -#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 */ - -/* - * Handle external interrupts - */ -void external_interrupt(struct pt_regs *regs) -{ - u32 uic_msr; - - /* - * Read masked interrupt status register to determine interrupt source - */ - uic_msr = mfdcr(UIC_BMSR); - -#if (UIC_MAX > 1) - if ((UICB0_UIC1CI & uic_msr) || (UICB0_UIC1NCI & uic_msr)) - uic_interrupt(UIC1_DCR_BASE, 32); -#endif - -#if (UIC_MAX > 2) - if ((UICB0_UIC2CI & uic_msr) || (UICB0_UIC2NCI & uic_msr)) - uic_interrupt(UIC2_DCR_BASE, 64); -#endif - -#if (UIC_MAX > 3) - if ((UICB0_UIC3CI & uic_msr) || (UICB0_UIC3NCI & uic_msr)) - uic_interrupt(UIC3_DCR_BASE, 96); -#endif - -#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 */ - - mtdcr(UIC_BSR, uic_msr); + irq_vecs[vec].count++; + + if (irq_vecs[vec].handler != NULL) { + /* call isr */ + (*irq_vecs[vec].handler) (irq_vecs[vec].arg); + } else { + pic_irq_disable(vec); + printf("Masking bogus interrupt vector %d\n", vec); + } + pic_irq_ack(vec); return; } -/* - * Install and free a interrupt handler. - */ void irq_install_handler(int vec, interrupt_handler_t * handler, void *arg) { - int i; - /* * Print warning when replacing with a different irq vector */ @@ -320,55 +177,19 @@ void irq_install_handler(int vec, interrupt_handler_t * handler, void *arg) 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 -#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); + pic_irq_enable(vec); + return; } -void irq_free_handler (int vec) +void irq_free_handler(int vec) { - int i; - debug("Free interrupt for vector %d ==> %p\n", vec, irq_vecs[vec].handler); - 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 + pic_irq_disable(vec); irq_vecs[vec].handler = NULL; irq_vecs[vec].arg = NULL; -} - -void timer_interrupt_cpu (struct pt_regs *regs) -{ - /* nothing to do here */ return; } @@ -380,7 +201,7 @@ int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf ("Interrupt-Information:\n"); printf ("Nr Routine Arg Count\n"); - for (vec = 0; vec < (UIC_MAX * 32); vec++) { + for (vec = 0; vec < IRQ_MAX; vec++) { if (irq_vecs[vec].handler != NULL) { printf ("%02d %08lx %08lx %d\n", vec, diff --git a/cpu/ppc4xx/iop480_uart.c b/cpu/ppc4xx/iop480_uart.c index 3af0767..0e3423f 100644 --- a/cpu/ppc4xx/iop480_uart.c +++ b/cpu/ppc4xx/iop480_uart.c @@ -26,7 +26,6 @@ #include <asm/processor.h> #include <asm/io.h> #include <watchdog.h> -#include <asm/ppc4xx-intvec.h> #ifdef CONFIG_SERIAL_MULTI #include <serial.h> diff --git a/cpu/ppc4xx/ndfc.c b/cpu/ppc4xx/ndfc.c index 5b2ae88..72acfd0 100644 --- a/cpu/ppc4xx/ndfc.c +++ b/cpu/ppc4xx/ndfc.c @@ -31,7 +31,7 @@ #include <common.h> -#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY) && \ +#if defined(CONFIG_CMD_NAND) && !defined(CONFIG_NAND_LEGACY) && \ (defined(CONFIG_440EP) || defined(CONFIG_440GR) || \ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ defined(CONFIG_405EZ) || defined(CONFIG_405EX) || \ @@ -44,65 +44,39 @@ #include <asm/io.h> #include <ppc4xx.h> -static u8 hwctl = 0; +/* + * We need to store the info, which chip-select (CS) is used for the + * chip number. For example on Sequoia NAND chip #0 uses + * CS #3. + */ +static int ndfc_cs[NDFC_MAX_BANKS]; -static void ndfc_hwcontrol(struct mtd_info *mtdinfo, int cmd) +static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - switch (cmd) { - case NAND_CTL_SETCLE: - hwctl |= 0x1; - break; - - case NAND_CTL_CLRCLE: - hwctl &= ~0x1; - break; - - case NAND_CTL_SETALE: - hwctl |= 0x2; - break; - - case NAND_CTL_CLRALE: - hwctl &= ~0x2; - break; - } -} + struct nand_chip *this = mtd->priv; + ulong base = (ulong) this->IO_ADDR_W & 0xffffff00; -static void ndfc_write_byte(struct mtd_info *mtdinfo, u_char byte) -{ - struct nand_chip *this = mtdinfo->priv; - ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc; + if (cmd == NAND_CMD_NONE) + return; - if (hwctl & 0x1) - out_8((u8 *)(base + NDFC_CMD), byte); - else if (hwctl & 0x2) - out_8((u8 *)(base + NDFC_ALE), byte); + if (ctrl & NAND_CLE) + out_8((u8 *)(base + NDFC_CMD), cmd & 0xFF); else - out_8((u8 *)(base + NDFC_DATA), byte); -} - -static u_char ndfc_read_byte(struct mtd_info *mtdinfo) -{ - struct nand_chip *this = mtdinfo->priv; - ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc; - - return (in_8((u8 *)(base + NDFC_DATA))); + out_8((u8 *)(base + NDFC_ALE), cmd & 0xFF); } static int ndfc_dev_ready(struct mtd_info *mtdinfo) { struct nand_chip *this = mtdinfo->priv; - ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc; - - while (!(in_be32((u32 *)(base + NDFC_STAT)) & NDFC_STAT_IS_READY)) - ; + ulong base = (ulong) this->IO_ADDR_W & 0xffffff00; - return 1; + return (in_be32((u32 *)(base + NDFC_STAT)) & NDFC_STAT_IS_READY); } static void ndfc_enable_hwecc(struct mtd_info *mtdinfo, int mode) { struct nand_chip *this = mtdinfo->priv; - ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc; + ulong base = (ulong) this->IO_ADDR_W & 0xffffff00; u32 ccr; ccr = in_be32((u32 *)(base + NDFC_CCR)); @@ -114,7 +88,7 @@ static int ndfc_calculate_ecc(struct mtd_info *mtdinfo, const u_char *dat, u_char *ecc_code) { struct nand_chip *this = mtdinfo->priv; - ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc; + ulong base = (ulong) this->IO_ADDR_W & 0xffffff00; u32 ecc; u8 *p = (u8 *)&ecc; @@ -139,7 +113,7 @@ static int ndfc_calculate_ecc(struct mtd_info *mtdinfo, static void ndfc_read_buf(struct mtd_info *mtdinfo, uint8_t *buf, int len) { struct nand_chip *this = mtdinfo->priv; - ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc; + ulong base = (ulong) this->IO_ADDR_W & 0xffffff00; uint32_t *p = (uint32_t *) buf; for (;len > 0; len -= 4) @@ -154,7 +128,7 @@ static void ndfc_read_buf(struct mtd_info *mtdinfo, uint8_t *buf, int len) static void ndfc_write_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len) { struct nand_chip *this = mtdinfo->priv; - ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc; + ulong base = (ulong) this->IO_ADDR_W & 0xffffff00; uint32_t *p = (uint32_t *) buf; for (; len > 0; len -= 4) @@ -164,7 +138,7 @@ static void ndfc_write_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len static int ndfc_verify_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len) { struct nand_chip *this = mtdinfo->priv; - ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc; + ulong base = (ulong) this->IO_ADDR_W & 0xffffff00; uint32_t *p = (uint32_t *) buf; for (; len > 0; len -= 4) @@ -181,29 +155,43 @@ void board_nand_select_device(struct nand_chip *nand, int chip) * Don't use "chip" to address the NAND device, * generate the cs from the address where it is encoded. */ - int cs = (ulong)nand->IO_ADDR_W & 0x00000003; - ulong base = (ulong)nand->IO_ADDR_W & 0xfffffffc; + ulong base = (ulong)nand->IO_ADDR_W & 0xffffff00; + int cs = ndfc_cs[chip]; /* Set NandFlash Core Configuration Register */ /* 1 col x 2 rows */ out_be32((u32 *)(base + NDFC_CCR), 0x00000000 | (cs << 24)); + out_be32((u32 *)(base + NDFC_BCFG0 + (cs << 2)), 0x80002222); } int board_nand_init(struct nand_chip *nand) { int cs = (ulong)nand->IO_ADDR_W & 0x00000003; - ulong base = (ulong)nand->IO_ADDR_W & 0xfffffffc; + ulong base = (ulong)nand->IO_ADDR_W & 0xffffff00; + static int chip = 0; - nand->hwcontrol = ndfc_hwcontrol; - nand->read_byte = ndfc_read_byte; - nand->read_buf = ndfc_read_buf; - nand->write_byte = ndfc_write_byte; - nand->dev_ready = ndfc_dev_ready; + /* + * Save chip-select for this chip # + */ + ndfc_cs[chip] = cs; - nand->eccmode = NAND_ECC_HW3_256; - nand->enable_hwecc = ndfc_enable_hwecc; - nand->calculate_ecc = ndfc_calculate_ecc; - nand->correct_data = nand_correct_data; + /* + * Select required NAND chip in NDFC + */ + board_nand_select_device(nand, chip); + + nand->IO_ADDR_R = (void __iomem *)(base + NDFC_DATA); + nand->IO_ADDR_W = (void __iomem *)(base + NDFC_DATA); + nand->cmd_ctrl = ndfc_hwcontrol; + nand->chip_delay = 50; + nand->read_buf = ndfc_read_buf; + nand->dev_ready = ndfc_dev_ready; + nand->ecc.correct = nand_correct_data; + nand->ecc.hwctl = ndfc_enable_hwecc; + nand->ecc.calculate = ndfc_calculate_ecc; + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.size = 256; + nand->ecc.bytes = 3; #ifndef CONFIG_NAND_SPL nand->write_buf = ndfc_write_buf; @@ -218,11 +206,7 @@ int board_nand_init(struct nand_chip *nand) mtebc(pb0ap, CFG_EBC_PB0AP); #endif - /* - * Select required NAND chip in NDFC - */ - board_nand_select_device(nand, cs); - out_be32((u32 *)(base + NDFC_BCFG0 + (cs << 2)), 0x80002222); + chip++; return 0; } diff --git a/cpu/ppc4xx/speed.c b/cpu/ppc4xx/speed.c index 34bd721..d21bd82 100644 --- a/cpu/ppc4xx/speed.c +++ b/cpu/ppc4xx/speed.c @@ -205,7 +205,8 @@ ulong get_PCI_freq (void) #elif defined(CONFIG_440) -#if defined(CONFIG_460EX) || defined(CONFIG_460GT) +#if defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ + defined(CONFIG_460SX) static u8 pll_fwdv_multi_bits[] = { /* values for: 1 - 16 */ 0x00, 0x01, 0x0f, 0x04, 0x09, 0x0a, 0x0d, 0x0e, 0x03, 0x0c, @@ -415,7 +416,8 @@ ulong get_PCI_freq (void) return sys_info.freqPCI; } -#elif !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) +#elif !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) \ + && !defined(CONFIG_XILINX_440) void get_sys_info (sys_info_t * sysInfo) { unsigned long strp0; @@ -448,6 +450,8 @@ void get_sys_info (sys_info_t * sysInfo) sysInfo->freqUART = sysInfo->freqPLB; } #else + +#if !defined(CONFIG_XILINX_440) void get_sys_info (sys_info_t * sysInfo) { unsigned long strp0; @@ -534,6 +538,7 @@ void get_sys_info (sys_info_t * sysInfo) } #endif +#endif /* CONFIG_XILINX_440 */ #if defined(CONFIG_YUCCA) unsigned long determine_sysper(void) diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index 426bf3c..97411bd 100644 --- a/cpu/ppc4xx/start.S +++ b/cpu/ppc4xx/start.S @@ -677,7 +677,8 @@ _start: /* not all PPC's have internal SRAM usable as L2-cache */ #if defined(CONFIG_440GX) || \ defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ - defined(CONFIG_460EX) || defined(CONFIG_460GT) + defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ + defined(CONFIG_460SX) mtdcr l2_cache_cfg,r0 /* Ensure L2 Cache is off */ #endif @@ -720,6 +721,19 @@ _start: lis r1,0x4000 /* BAS = 8000_0000 */ ori r1,r1,0x4580 /* 16k */ mtdcr isram0_sb0cr,r1 +#elif defined(CONFIG_460SX) + lis r1,0x0000 /* BAS = 0000_0000 */ + ori r1,r1,0x0B84 /* first 128k */ + mtdcr isram0_sb0cr,r1 + lis r1,0x0001 + ori r1,r1,0x0B84 /* second 128k */ + mtdcr isram0_sb1cr,r1 + lis r1, 0x0002 + ori r1,r1, 0x0B84 /* third 128k */ + mtdcr isram0_sb2cr,r1 + lis r1, 0x0003 + ori r1,r1, 0x0B84 /* fourth 128k */ + mtdcr isram0_sb3cr,r1 #elif defined(CONFIG_440GP) ori r1,r1,0x0380 /* 8k rw */ mtdcr isram0_sb0cr,r1 @@ -1415,7 +1429,8 @@ relocate_code: #if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ - defined(CONFIG_460EX) || defined(CONFIG_460GT) + defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ + defined(CONFIG_460SX) /* * On some 440er platforms the cache is enabled in the first TLB (Boot-CS) * to speed up the boot process. Now this cache needs to be disabled. diff --git a/cpu/ppc4xx/uic.c b/cpu/ppc4xx/uic.c new file mode 100644 index 0000000..7944c6c --- /dev/null +++ b/cpu/ppc4xx/uic.c @@ -0,0 +1,180 @@ +/* + * (C) Copyright 2000-2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 (440 port) + * Scott McNutt, Artesyn Communication Producs, smcnutt@artsyncp.com + * + * (C) Copyright 2003 (440GX port) + * Travis B. Sawyer, Sandburst Corporation, tsawyer@sandburst.com + * + * (C) Copyright 2008 (PPC440X05 port for Virtex 5 FX) + * Ricardo Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es + * Work supported by Qtechnology (htpp://qtec.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will 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 <watchdog.h> +#include <command.h> +#include <asm/processor.h> +#include <asm/interrupt.h> +#include <ppc4xx.h> +#include <ppc_asm.tmpl> +#include <commproc.h> + +#if (UIC_MAX > 3) +#define UICB0_ALL (UIC_MASK(VECNUM_UIC1CI) | UIC_MASK(VECNUM_UIC1NCI) | \ + UIC_MASK(VECNUM_UIC2CI) | UIC_MASK(VECNUM_UIC2NCI) | \ + UIC_MASK(VECNUM_UIC3CI) | UIC_MASK(VECNUM_UIC3NCI)) +#elif (UIC_MAX > 2) +#define UICB0_ALL (UIC_MASK(VECNUM_UIC1CI) | UIC_MASK(VECNUM_UIC1NCI) | \ + UIC_MASK(VECNUM_UIC2CI) | UIC_MASK(VECNUM_UIC2NCI)) +#elif (UIC_MAX > 1) +#define UICB0_ALL (UIC_MASK(VECNUM_UIC1CI) | UIC_MASK(VECNUM_UIC1NCI)) +#else +#define UICB0_ALL 0 +#endif + +u32 get_dcr(u16); + +DECLARE_GLOBAL_DATA_PTR; + +void pic_enable(void) +{ +#if (UIC_MAX > 1) + /* Install the UIC1 handlers */ + irq_install_handler(VECNUM_UIC1NCI, (void *)(void *)external_interrupt, 0); + irq_install_handler(VECNUM_UIC1CI, (void *)(void *)external_interrupt, 0); +#endif +#if (UIC_MAX > 2) + irq_install_handler(VECNUM_UIC2NCI, (void *)(void *)external_interrupt, 0); + irq_install_handler(VECNUM_UIC2CI, (void *)(void *)external_interrupt, 0); +#endif +#if (UIC_MAX > 3) + irq_install_handler(VECNUM_UIC3NCI, (void *)(void *)external_interrupt, 0); + irq_install_handler(VECNUM_UIC3CI, (void *)(void *)external_interrupt, 0); +#endif +} + +/* Handler for UIC interrupt */ +static void uic_interrupt(u32 uic_base, int vec_base) +{ + u32 uic_msr; + u32 msr_shift; + int vec; + + /* + * Read masked interrupt status register to determine interrupt source + */ + uic_msr = get_dcr(uic_base + UIC_MSR); + msr_shift = uic_msr; + vec = vec_base; + + while (msr_shift != 0) { + if (msr_shift & 0x80000000) + interrupt_run_handler(vec); + /* + * Shift msr to next position and increment vector + */ + msr_shift <<= 1; + vec++; + } +} + +/* + * Handle external interrupts + */ +void external_interrupt(struct pt_regs *regs) +{ + u32 uic_msr; + + /* + * Read masked interrupt status register to determine interrupt source + */ + uic_msr = mfdcr(uic0msr); + +#if (UIC_MAX > 1) + if ((UIC_MASK(VECNUM_UIC1CI) & uic_msr) || + (UIC_MASK(VECNUM_UIC1NCI) & uic_msr)) + uic_interrupt(UIC1_DCR_BASE, 32); +#endif + +#if (UIC_MAX > 2) + if ((UIC_MASK(VECNUM_UIC2CI) & uic_msr) || + (UIC_MASK(VECNUM_UIC2NCI) & uic_msr)) + uic_interrupt(UIC2_DCR_BASE, 64); +#endif + +#if (UIC_MAX > 3) + if ((UIC_MASK(VECNUM_UIC3CI) & uic_msr) || + (UIC_MASK(VECNUM_UIC3NCI) & uic_msr)) + uic_interrupt(UIC3_DCR_BASE, 96); +#endif + + if (uic_msr & ~(UICB0_ALL)) + uic_interrupt(UIC0_DCR_BASE, 0); + + mtdcr(uic0sr, uic_msr); + + return; +} + +void pic_irq_ack(unsigned int vec) +{ + if ((vec >= 0) && (vec < 32)) + mtdcr(uicsr, UIC_MASK(vec)); + else if ((vec >= 32) && (vec < 64)) + mtdcr(uic1sr, UIC_MASK(vec)); + else if ((vec >= 64) && (vec < 96)) + mtdcr(uic2sr, UIC_MASK(vec)); + else if (vec >= 96) + mtdcr(uic3sr, UIC_MASK(vec)); +} + +/* + * Install and free a interrupt handler. + */ +void pic_irq_enable(unsigned int vec) +{ + + if ((vec >= 0) && (vec < 32)) + mtdcr(uicer, mfdcr(uicer) | UIC_MASK(vec)); + else if ((vec >= 32) && (vec < 64)) + mtdcr(uic1er, mfdcr(uic1er) | UIC_MASK(vec)); + else if ((vec >= 64) && (vec < 96)) + mtdcr(uic2er, mfdcr(uic2er) | UIC_MASK(vec)); + else if (vec >= 96) + mtdcr(uic3er, mfdcr(uic3er) | UIC_MASK(vec)); + + debug("Install interrupt for vector %d ==> %p\n", vec, handler); +} + +void pic_irq_disable(unsigned int vec) +{ + if ((vec >= 0) && (vec < 32)) + mtdcr(uicer, mfdcr(uicer) & ~UIC_MASK(vec)); + else if ((vec >= 32) && (vec < 64)) + mtdcr(uic1er, mfdcr(uic1er) & ~UIC_MASK(vec)); + else if ((vec >= 64) && (vec < 96)) + mtdcr(uic2er, mfdcr(uic2er) & ~UIC_MASK(vec)); + else if (vec >= 96) + mtdcr(uic3er, mfdcr(uic3er) & ~UIC_MASK(vec)); +} diff --git a/cpu/ppc4xx/usbdev.c b/cpu/ppc4xx/usbdev.c index d71ba77..faf7f08 100644 --- a/cpu/ppc4xx/usbdev.c +++ b/cpu/ppc4xx/usbdev.c @@ -6,8 +6,8 @@ #if (defined(CONFIG_440EP) || defined(CONFIG_440EPX)) && defined(CONFIG_CMD_USB) #include <usb.h> +#include <asm/ppc4xx-uic.h> #include "usbdev.h" -#include <asm/ppc4xx-intvec.h> #define USB_DT_DEVICE 0x01 #define USB_DT_CONFIG 0x02 @@ -197,7 +197,7 @@ void usb_dev_init() /*enable interrupts */ *(unsigned char *)USB2D0_INTRUSBE_8 = 0x0f; - irq_install_handler(VECNUM_HSB2D, (interrupt_handler_t *) usbInt, + irq_install_handler(VECNUM_USBDEV, (interrupt_handler_t *) usbInt, NULL); } #else diff --git a/cpu/ppc4xx/xilinx_irq.c b/cpu/ppc4xx/xilinx_irq.c new file mode 100644 index 0000000..7108777 --- /dev/null +++ b/cpu/ppc4xx/xilinx_irq.c @@ -0,0 +1,100 @@ +/* + * (C) Copyright 2008 + * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es + * This work has been supported by: QTechnology http://qtec.com/ + * Based on interrupts.c Wolfgang Denk-DENX Software Engineering-wd@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, see <http://www.gnu.org/licenses/>. +*/ +#include <common.h> +#include <watchdog.h> +#include <command.h> +#include <asm/processor.h> +#include <asm/interrupt.h> +#include <ppc4xx.h> +#include <ppc_asm.tmpl> +#include <commproc.h> +#include <asm/io.h> +#include <asm/xilinx_irq.h> + +DECLARE_GLOBAL_DATA_PTR; + +void pic_enable(void) +{ + debug("Xilinx PIC at 0x%8x\n", intc); + + /* + * Disable all external interrupts until they are + * explicitly requested. + */ + out_be32((u32 *) IER, 0); + + /* Acknowledge any pending interrupts just in case. */ + out_be32((u32 *) IAR, 0xffffffff); + + /* Turn on the Master Enable. */ + out_be32((u32 *) MER, 0x3UL); + + return; +} + +int xilinx_pic_irq_get(void) +{ + u32 irq; + irq = in_be32((u32 *) IVR); + + /* If no interrupt is pending then all bits of the IVR are set to 1. As + * the IVR is as many bits wide as numbers of inputs are available. + * Therefore, if all bits of the IVR are set to one, its content will + * be bigger than XPAR_INTC_MAX_NUM_INTR_INPUTS. + */ + if (irq >= XPAR_INTC_MAX_NUM_INTR_INPUTS) + irq = -1; /* report no pending interrupt. */ + + debug("get_irq: %d\n", irq); + return (irq); +} + +void pic_irq_enable(unsigned int irq) +{ + u32 mask = IRQ_MASK(irq); + debug("enable: %d\n", irq); + out_be32((u32 *) SIE, mask); +} + +void pic_irq_disable(unsigned int irq) +{ + u32 mask = IRQ_MASK(irq); + debug("disable: %d\n", irq); + out_be32((u32 *) CIE, mask); +} + +void pic_irq_ack(unsigned int irq) +{ + u32 mask = IRQ_MASK(irq); + debug("ack: %d\n", irq); + out_be32((u32 *) IAR, mask); +} + +void external_interrupt(struct pt_regs *regs) +{ + int irq; + + irq = xilinx_pic_irq_get(); + if (irq < 0) + return; + + interrupt_run_handler(irq); + + return; +} |