diff options
Diffstat (limited to 'cpu')
32 files changed, 580 insertions, 403 deletions
diff --git a/cpu/ixp/npe/Makefile b/cpu/ixp/npe/Makefile index 4de34fd5b9..7f020b5d57 100644 --- a/cpu/ixp/npe/Makefile +++ b/cpu/ixp/npe/Makefile @@ -87,7 +87,7 @@ START := $(addprefix $(obj),$(START)) all: $(LIB) -$(LIB): $(obj).depend $(OBJS) +$(LIB): $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) ######################################################################### diff --git a/cpu/microblaze/Makefile b/cpu/microblaze/Makefile index db1afa553d..9d542013cc 100644 --- a/cpu/microblaze/Makefile +++ b/cpu/microblaze/Makefile @@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).a START = start.o -SOBJS = dcache.o icache.o irq.o disable_int.o enable_int.o +SOBJS = irq.o COBJS = cpu.o interrupts.o cache.o exception.o timer.o SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/cpu/microblaze/cache.c b/cpu/microblaze/cache.c index fc388ebb56..4f36a84ec4 100644..100755 --- a/cpu/microblaze/cache.c +++ b/cpu/microblaze/cache.c @@ -23,6 +23,7 @@ */ #include <common.h> +#include <asm/asm.h> #if (CONFIG_COMMANDS & CFG_CMD_CACHE) @@ -45,4 +46,20 @@ int icache_status (void) __asm__ __volatile__ ("and %0,%0,%1"::"r" (i), "r" (mask):"memory"); return i; } + +void icache_enable (void) { + MSRSET(0x20); +} + +void icache_disable(void) { + MSRCLR(0x20); +} + +void dcache_enable (void) { + MSRSET(0x80); +} + +void dcache_disable(void) { + MSRCLR(0x80); +} #endif diff --git a/cpu/microblaze/dcache.S b/cpu/microblaze/dcache.S deleted file mode 100644 index eaf96717eb..0000000000 --- a/cpu/microblaze/dcache.S +++ /dev/null @@ -1,68 +0,0 @@ -/* - * (C) Copyright 2007 Michal Simek - * - * Michal SIMEK <monstr@monstr.eu> - * - * 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 - */ - .text - .globl dcache_enable - .ent dcache_enable - .align 2 -dcache_enable: - /* Make space on stack for a temporary */ - addi r1, r1, -4 - /* Save register r12 */ - swi r12, r1, 0 - /* Read the MSR register */ - mfs r12, rmsr - /* Set the instruction enable bit */ - ori r12, r12, 0x80 - /* Save the MSR register */ - mts rmsr, r12 - /* Load register r12 */ - lwi r12, r1, 0 - /* Return */ - rtsd r15, 8 - /* Update stack in the delay slot */ - addi r1, r1, 4 - .end dcache_enable - - .text - .globl dcache_disable - .ent dcache_disable - .align 2 -dcache_disable: - /* Make space on stack for a temporary */ - addi r1, r1, -4 - /* Save register r12 */ - swi r12, r1, 0 - /* Read the MSR register */ - mfs r12, rmsr - /* Clear the data cache enable bit */ - andi r12, r12, ~0x80 - /* Save the MSR register */ - mts rmsr, r12 - /* Load register r12 */ - lwi r12, r1, 0 - /* Return */ - rtsd r15, 8 - /* Update stack in the delay slot */ - addi r1, r1, 4 - .end dcache_disable diff --git a/cpu/microblaze/disable_int.S b/cpu/microblaze/disable_int.S deleted file mode 100644 index aecd79513c..0000000000 --- a/cpu/microblaze/disable_int.S +++ /dev/null @@ -1,46 +0,0 @@ -/* - * (C) Copyright 2007 Michal Simek - * - * Michal SIMEK <monstr@monstr.eu> - * - * 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 - */ - - .text - .globl microblaze_disable_interrupts - .ent microblaze_disable_interrupts - .align 2 -microblaze_disable_interrupts: - #Make space on stack for a temporary - addi r1, r1, -4 - #Save register r12 - swi r12, r1, 0 - #Read the MSR register - mfs r12, rmsr - #Clear the interrupt enable bit - andi r12, r12, ~2 - #Save the MSR register - mts rmsr, r12 - #Load register r12 - lwi r12, r1, 0 - #Return - rtsd r15, 8 - #Update stack in the delay slot - addi r1, r1, 4 - .end microblaze_disable_interrupts diff --git a/cpu/microblaze/enable_int.S b/cpu/microblaze/enable_int.S deleted file mode 100644 index c096c6c3c0..0000000000 --- a/cpu/microblaze/enable_int.S +++ /dev/null @@ -1,38 +0,0 @@ -/* - * (C) Copyright 2007 Michal Simek - * - * Michal SIMEK <monstrmonstr.eu> - * - * 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 - */ - - .text - .globl microblaze_enable_interrupts - .ent microblaze_enable_interrupts - .align 2 -microblaze_enable_interrupts: - addi r1, r1, -4 - swi r12, r1, 0 - mfs r12, rmsr - ori r12, r12, 2 - mts rmsr, r12 - lwi r12, r1, 0 - rtsd r15, 8 - addi r1, r1, 4 - .end microblaze_enable_interrupts diff --git a/cpu/microblaze/exception.c b/cpu/microblaze/exception.c index b135acbad9..d76b05a526 100644 --- a/cpu/microblaze/exception.c +++ b/cpu/microblaze/exception.c @@ -23,15 +23,16 @@ */ #include <common.h> +#include <asm/asm.h> void _hw_exception_handler (void) { int address = 0; int state = 0; /* loading address of exception EAR */ - __asm__ __volatile ("mfs %0,rear"::"r" (address):"memory"); + MFS (address, rear); /* loading excetpion state register ESR */ - __asm__ __volatile ("mfs %0,resr"::"r" (state):"memory"); + MFS (state, resr); printf ("Hardware exception at 0x%x address\n", address); switch (state & 0x1f) { /* mask on exception cause */ case 0x1: @@ -49,6 +50,11 @@ void _hw_exception_handler (void) case 0x5: puts ("Divide by zero exception\n"); break; +#ifdef MICROBLAZE_V5 + case 0x1000: + puts ("Exception in delay slot\n"); + break; +#endif default: puts ("Undefined cause\n"); break; diff --git a/cpu/microblaze/icache.S b/cpu/microblaze/icache.S deleted file mode 100644 index 25940d106e..0000000000 --- a/cpu/microblaze/icache.S +++ /dev/null @@ -1,69 +0,0 @@ -/* - * (C) Copyright 2007 Michal Simek - * - * Michal SIMEK <monstr@monstr.eu> - * - * 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 - */ - - .text - .globl icache_enable - .ent icache_enable - .align 2 -icache_enable: - /* Make space on stack for a temporary */ - addi r1, r1, -4 - /* Save register r12 */ - swi r12, r1, 0 - /* Read the MSR register */ - mfs r12, rmsr - /* Set the instruction enable bit */ - ori r12, r12, 0x20 - /* Save the MSR register */ - mts rmsr, r12 - /* Load register r12 */ - lwi r12, r1, 0 - /* Return */ - rtsd r15, 8 - /* Update stack in the delay slot */ - addi r1, r1, 4 - .end icache_enable - - .text - .globl icache_disable - .ent icache_disable - .align 2 -icache_disable: - /* Make space on stack for a temporary */ - addi r1, r1, -4 - /* Save register r12 */ - swi r12, r1, 0 - /* Read the MSR register */ - mfs r12, rmsr - /* Clear the instruction enable bit */ - andi r12, r12, ~0x20 - /* Save the MSR register */ - mts rmsr, r12 - /* Load register r12 */ - lwi r12, r1, 0 - /* Return */ - rtsd r15, 8 - /* Update stack in the delay slot */ - addi r1, r1, 4 - .end icache_disable diff --git a/cpu/microblaze/interrupts.c b/cpu/microblaze/interrupts.c index 2db847cd02..b61153f8e6 100644..100755 --- a/cpu/microblaze/interrupts.c +++ b/cpu/microblaze/interrupts.c @@ -27,6 +27,7 @@ #include <common.h> #include <command.h> #include <asm/microblaze_intc.h> +#include <asm/asm.h> #undef DEBUG_INT @@ -35,12 +36,12 @@ extern void microblaze_enable_interrupts (void); void enable_interrupts (void) { - microblaze_enable_interrupts (); + MSRSET(0x2); } int disable_interrupts (void) { - microblaze_disable_interrupts (); + MSRCLR(0x2); return 0; } @@ -48,6 +49,10 @@ int disable_interrupts (void) #ifdef CFG_TIMER_0 extern void timer_init (void); #endif +#ifdef CFG_FSL_2 +extern void fsl_init2 (void); +#endif + static struct irq_action vecs[CFG_INTC_0_NUM]; @@ -106,7 +111,6 @@ void install_interrupt_handler (int irq, interrupt_handler_t * hdlr, void *arg) act->count = 0; enable_one_interrupt (irq); } else { /* disable */ - act->handler = (interrupt_handler_t *) def_hdlr; act->arg = (void *)irq; disable_one_interrupt (irq); @@ -141,18 +145,22 @@ int interrupts_init (void) #ifdef CFG_TIMER_0 timer_init (); #endif +#ifdef CFG_FSL_2 + fsl_init2 (); +#endif enable_interrupts (); return 0; } void interrupt_handler (void) { - int irqs; - irqs = (intc->isr & intc->ier); /* find active interrupt */ - + int irqs = (intc->isr & intc->ier); /* find active interrupt */ + int i = 1; #ifdef DEBUG_INT + int value; printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, intc->iar, intc->mer); + R14(value); printf ("Interrupt handler on %x line, r14 %x\n", irqs, value); #endif struct irq_action *act = vecs; @@ -165,15 +173,19 @@ void interrupt_handler (void) #endif act->handler (act->arg); act->count++; + intc->iar = i; + return; } irqs >>= 1; act++; + i <<= 1; } - intc->iar = 0xFFFFFFFF; /* erase all events */ -#ifdef DEBUG + +#ifdef DEBUG_INT printf ("Dump INTC reg, isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, intc->iar, intc->mer); - printf ("Interrupt handler on %x line, r14\n", irqs); + R14(value); + printf ("Interrupt handler on %x line, r14 %x\n", irqs, value); #endif } #endif diff --git a/cpu/microblaze/irq.S b/cpu/microblaze/irq.S index a4e3fbfad6..e1fc19046c 100644..100755 --- a/cpu/microblaze/irq.S +++ b/cpu/microblaze/irq.S @@ -23,6 +23,7 @@ */ #include <config.h> +#include <asm/asm.h> .text .global _interrupt_handler _interrupt_handler: @@ -151,6 +152,11 @@ _interrupt_handler: addi r1, r1, 4 /* enable_interrupt */ +#ifdef XILINX_USE_MSR_INSTR + msrset r0, 2 +#else + /* FIXME unstable in stressed mode - two irqs */ + nop addi r1, r1, -4 swi r12, r1, 0 mfs r12, rmsr @@ -159,6 +165,7 @@ _interrupt_handler: lwi r12, r1, 0 addi r1, r1, 4 nop +#endif bra r14 nop nop diff --git a/cpu/microblaze/start.S b/cpu/microblaze/start.S index ca3befc24e..3c027ff9bb 100644 --- a/cpu/microblaze/start.S +++ b/cpu/microblaze/start.S @@ -117,3 +117,36 @@ clear_bss: 3: /* jumping to board_init */ brai board_init 1: bri 1b + +/* + * Read 16bit little endian + */ + .text + .global in16 + .ent in16 + .align 2 +in16: lhu r3, r0, r5 + bslli r4, r3, 8 + bsrli r3, r3, 8 + andi r4, r4, 0xffff + or r3, r3, r4 + rtsd r15, 8 + sext16 r3, r3 + .end in16 + +/* + * Write 16bit little endian + * first parameter(r5) - address, second(r6) - short value + */ + .text + .global out16 + .ent out16 + .align 2 +out16: bslli r3, r6, 8 + bsrli r6, r6, 8 + andi r3, r3, 0xffff + or r3, r3, r6 + sh r3, r0, r5 + rtsd r15, 8 + or r0, r0, r0 + .end out16 diff --git a/cpu/microblaze/timer.c b/cpu/microblaze/timer.c index be4fd57cc4..ab1cb12749 100644 --- a/cpu/microblaze/timer.c +++ b/cpu/microblaze/timer.c @@ -24,6 +24,7 @@ #include <common.h> #include <asm/microblaze_timer.h> +#include <asm/microblaze_intc.h> volatile int timestamp = 0; @@ -44,9 +45,6 @@ void set_timer (ulong t) #ifdef CFG_INTC_0 #ifdef CFG_TIMER_0 -extern void install_interrupt_handler (int irq, interrupt_handler_t * hdlr, - void *arg); - microblaze_timer_t *tmr = (microblaze_timer_t *) (CFG_TIMER_0_ADDR); void timer_isr (void *arg) diff --git a/cpu/mpc5xxx/cpu.c b/cpu/mpc5xxx/cpu.c index 813aa7935d..1eac2bbfbe 100644 --- a/cpu/mpc5xxx/cpu.c +++ b/cpu/mpc5xxx/cpu.c @@ -53,12 +53,16 @@ int checkcpu (void) #else svr = get_svr(); pvr = get_pvr(); - switch (SVR_VER (svr)) { - case SVR_MPC5200: - printf ("MPC5200"); + + switch (pvr) { + case PVR_5200: + printf("MPC5200"); + break; + case PVR_5200B: + printf("MPC5200B"); break; default: - printf ("MPC52?? (SVR %08x)", svr); + printf("Unknown MPC5xxx"); break; } @@ -127,5 +131,9 @@ ft_cpu_setup(void *blob, bd_t *bd) p = ft_get_prop(blob, "/" OF_SOC "/ethernet@3000/mac-address", &len); if (p != NULL) memcpy(p, bd->bi_enetaddr, 6); + + p = ft_get_prop(blob, "/" OF_SOC "/ethernet@3000/local-mac-address", &len); + if (p != NULL) + memcpy(p, bd->bi_enetaddr, 6); } #endif diff --git a/cpu/mpc5xxx/cpu_init.c b/cpu/mpc5xxx/cpu_init.c index 7e65821852..d7440308a4 100644 --- a/cpu/mpc5xxx/cpu_init.c +++ b/cpu/mpc5xxx/cpu_init.c @@ -156,21 +156,21 @@ void cpu_init_f (void) *(vu_long *)(MPC5XXX_XLBARB + 0x40) |= (1 << 15); *(vu_long *)(MPC5XXX_XLBARB + 0x70) = CFG_SDRAM_BASE | 0x1d; -# if defined(CFG_IPBSPEED_133) +# if defined(CFG_IPBCLK_EQUALS_XLBCLK) /* Motorola reports IPB should better run at 133 MHz. */ *(vu_long *)MPC5XXX_ADDECR |= 1; /* pci_clk_sel = 0x02, ipb_clk_sel = 0x00; */ addecr = *(vu_long *)MPC5XXX_CDM_CFG; addecr &= ~0x103; -# if defined(CFG_PCISPEED_66) +# if defined(CFG_PCICLK_EQUALS_IPBCLK_DIV2) /* pci_clk_sel = 0x01 -> IPB_CLK/2 */ addecr |= 0x01; # else /* pci_clk_sel = 0x02 -> XLB_CLK/4 = IPB_CLK/4 */ addecr |= 0x02; -# endif /* CFG_PCISPEED_66 */ +# endif /* CFG_PCICLK_EQUALS_IPBCLK_DIV2 */ *(vu_long *)MPC5XXX_CDM_CFG = addecr; -# endif /* CFG_IPBSPEED_133 */ +# endif /* CFG_IPBCLK_EQUALS_XLBCLK */ /* Configure the XLB Arbiter */ *(vu_long *)MPC5XXX_XLBARB_MPRIEN = 0xff; *(vu_long *)MPC5XXX_XLBARB_MPRIVAL = 0x11111111; diff --git a/cpu/mpc5xxx/fec.c b/cpu/mpc5xxx/fec.c index e59bd85e1b..813636655b 100644 --- a/cpu/mpc5xxx/fec.c +++ b/cpu/mpc5xxx/fec.c @@ -428,6 +428,13 @@ static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis) */ fec->eth->imask = 0x00000000; +/* + * In original Promess-provided code PHY initialization is disabled with the + * following comment: "Phy initialization is DISABLED for now. There was a + * problem with running 100 Mbps on PRO board". Thus we temporarily disable + * PHY initialization for the Motion-PRO board, until a proper fix is found. + */ + if (fec->xcv_type != SEVENWIRE) { /* * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock diff --git a/cpu/mpc83xx/Makefile b/cpu/mpc83xx/Makefile index 4b9dcc8180..bb96f774fe 100644 --- a/cpu/mpc83xx/Makefile +++ b/cpu/mpc83xx/Makefile @@ -29,7 +29,7 @@ LIB = $(obj)lib$(CPU).a START = start.o COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o \ - spd_sdram.o qe_io.o + spd_sdram.o qe_io.o pci.o SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c index e934ba638f..e078f27a23 100644 --- a/cpu/mpc83xx/cpu.c +++ b/cpu/mpc83xx/cpu.c @@ -52,13 +52,26 @@ int checkcpu(void) immr = (immap_t *)CFG_IMMR; - if ((pvr & 0xFFFF0000) != PVR_83xx) { - puts("Not MPC83xx Family!!!\n"); - return -1; + puts("CPU: "); + + switch (pvr & 0xffff0000) { + case PVR_E300C1: + printf("e300c1, "); + break; + + case PVR_E300C2: + printf("e300c2, "); + break; + + case PVR_E300C3: + printf("e300c3, "); + break; + + default: + printf("Unknown core, "); } spridr = immr->sysconf.spridr; - puts("CPU: "); switch(spridr) { case SPR_8349E_REV10: case SPR_8349E_REV11: @@ -124,6 +137,18 @@ int checkcpu(void) case SPR_8321_REV11: puts("MPC8321, "); break; + case SPR_8311_REV10: + puts("MPC8311, "); + break; + case SPR_8311E_REV10: + puts("MPC8311E, "); + break; + case SPR_8313_REV10: + puts("MPC8313, "); + break; + case SPR_8313E_REV10: + puts("MPC8313E, "); + break; default: puts("Rev: Unknown revision number.\nWarning: Unsupported cpu revision!\n"); return 0; @@ -133,10 +158,12 @@ int checkcpu(void) /* Multiple revisons of 834x processors may have the same SPRIDR value. * So use PVR to identify the revision number. */ - printf("Rev: %02x at %s MHz\n", PVR_MAJ(pvr)<<4 | PVR_MIN(pvr), strmhz(buf, clock)); + printf("Rev: %02x at %s MHz", PVR_MAJ(pvr)<<4 | PVR_MIN(pvr), strmhz(buf, clock)); #else - printf("Rev: %02x at %s MHz\n", spridr & 0x0000FFFF, strmhz(buf, clock)); + printf("Rev: %02x at %s MHz", spridr & 0x0000FFFF, strmhz(buf, clock)); #endif + printf(", CSB: %4d MHz\n", gd->csb_clk / 1000000); + return 0; } diff --git a/cpu/mpc83xx/pci.c b/cpu/mpc83xx/pci.c new file mode 100644 index 0000000000..785d6129da --- /dev/null +++ b/cpu/mpc83xx/pci.c @@ -0,0 +1,192 @@ +/* + * Copyright (C) Freescale Semiconductor, Inc. 2007 + * + * Author: Scott Wood <scottwood@freescale.com>, + * with some bits from older board-specific PCI initialization. + * + * 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 <pci.h> +#include <ft_build.h> +#include <asm/mpc8349_pci.h> + +#ifdef CONFIG_83XX_GENERIC_PCI +#define MAX_BUSES 2 + +DECLARE_GLOBAL_DATA_PTR; + +static struct pci_controller pci_hose[MAX_BUSES]; +static int pci_num_buses; + +static void pci_init_bus(int bus, struct pci_region *reg) +{ + volatile immap_t *immr = (volatile immap_t *)CFG_IMMR; + volatile pot83xx_t *pot = immr->ios.pot; + volatile pcictrl83xx_t *pci_ctrl = &immr->pci_ctrl[bus]; + struct pci_controller *hose = &pci_hose[bus]; + u32 dev; + u16 reg16; + int i; + + if (bus == 1) + pot += 3; + + /* Setup outbound translation windows */ + for (i = 0; i < 3; i++, reg++, pot++) { + if (reg->size == 0) + break; + + hose->regions[i] = *reg; + hose->region_count++; + + pot->potar = reg->bus_start >> 12; + pot->pobar = reg->phys_start >> 12; + pot->pocmr = ~(reg->size - 1) >> 12; + + if (reg->flags & PCI_REGION_IO) + pot->pocmr |= POCMR_IO; +#ifdef CONFIG_83XX_PCI_STREAMING + else if (reg->flags & PCI_REGION_PREFETCH) + pot->pocmr |= POCMR_SE; +#endif + + if (bus == 1) + pot->pocmr |= POCMR_DST; + + pot->pocmr |= POCMR_EN; + } + + /* Point inbound translation at RAM */ + pci_ctrl->pitar1 = 0; + pci_ctrl->pibar1 = 0; + pci_ctrl->piebar1 = 0; + pci_ctrl->piwar1 = PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | + PIWAR_WTT_SNOOP | (__ilog2(gd->ram_size) - 1); + + i = hose->region_count++; + hose->regions[i].bus_start = 0; + hose->regions[i].phys_start = 0; + hose->regions[i].size = gd->ram_size; + hose->regions[i].flags = PCI_REGION_MEM | PCI_REGION_MEMORY; + + hose->first_busno = 0; + hose->last_busno = 0xff; + + pci_setup_indirect(hose, CFG_IMMR + 0x8300 + bus * 0x80, + CFG_IMMR + 0x8304 + bus * 0x80); + + pci_register_hose(hose); + + /* + * Write to Command register + */ + reg16 = 0xff; + dev = PCI_BDF(hose->first_busno, 0, 0); + pci_hose_read_config_word(hose, dev, PCI_COMMAND, ®16); + reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16); + + /* + * Clear non-reserved bits in status register. + */ + pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff); + pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80); + pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08); + +#ifdef CONFIG_PCI_SCAN_SHOW + printf("PCI: Bus Dev VenId DevId Class Int\n"); +#endif + /* + * Hose scan. + */ + hose->last_busno = pci_hose_scan(hose); +} + +/* + * The caller must have already set OCCR, and the PCI_LAW BARs + * must have been set to cover all of the requested regions. + * + * If fewer than three regions are requested, then the region + * list is terminated with a region of size 0. + */ +void mpc83xx_pci_init(int num_buses, struct pci_region **reg, int warmboot) +{ + volatile immap_t *immr = (volatile immap_t *)CFG_IMMR; + int i; + + if (num_buses > MAX_BUSES) { + printf("%d PCI buses requsted, %d supported\n", + num_buses, MAX_BUSES); + + num_buses = MAX_BUSES; + } + + pci_num_buses = num_buses; + + /* + * Release PCI RST Output signal. + * Power on to RST high must be at least 100 ms as per PCI spec. + * On warm boots only 1 ms is required. + */ + udelay(warmboot ? 1000 : 100000); + + for (i = 0; i < num_buses; i++) + immr->pci_ctrl[i].gcr = 1; + + /* + * RST high to first config access must be at least 2^25 cycles + * as per PCI spec. This could be cut in half if we know we're + * running at 66MHz. This could be insufficiently long if we're + * running the PCI bus at significantly less than 33MHz. + */ + udelay(1020000); + + for (i = 0; i < num_buses; i++) + pci_init_bus(i, reg[i]); +} + +#ifdef CONFIG_OF_FLAT_TREE +void ft_pci_setup(void *blob, bd_t *bd) +{ + u32 *p; + int len; + + if (pci_num_buses < 1) + return; + + p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8500/bus-range", &len); + if (p) { + p[0] = pci_hose[0].first_busno; + p[1] = pci_hose[0].last_busno; + } + + if (pci_num_buses < 2) + return; + + p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8600/bus-range", &len); + if (p) { + p[0] = pci_hose[1].first_busno; + p[1] = pci_hose[1].last_busno; + } +} +#endif /* CONFIG_OF_FLAT_TREE */ + +#endif /* CONFIG_83XX_GENERIC_PCI */ diff --git a/cpu/mpc83xx/spd_sdram.c b/cpu/mpc83xx/spd_sdram.c index d9b8753ca0..647813f68d 100644 --- a/cpu/mpc83xx/spd_sdram.c +++ b/cpu/mpc83xx/spd_sdram.c @@ -58,8 +58,8 @@ picos_to_clk(int picos) int clks; ddr_bus_clk = gd->ddr_clk >> 1; - clks = picos / ((1000000000 / ddr_bus_clk) * 1000); - if (picos % ((1000000000 / ddr_bus_clk) * 1000) != 0) + clks = picos / (1000000000 / (ddr_bus_clk / 1000)); + if (picos % (1000000000 / (ddr_bus_clk / 1000)) != 0) clks++; return clks; @@ -624,7 +624,7 @@ long int spd_sdram() | (1 << (16 + 10)) /* DQS Differential disable */ | (add_lat << (16 + 3)) /* Additive Latency in EMRS1 */ | (mode_odt_enable << 16) /* ODT Enable in EMRS1 */ - | ((twr_clk >> 1) << 9) /* Write Recovery Autopre */ + | ((twr_clk - 1) << 9) /* Write Recovery Autopre */ | (caslat << 4) /* caslat */ | (burstlen << 0) /* Burst length */ ); @@ -693,11 +693,6 @@ long int spd_sdram() #ifdef CFG_DDR_SDRAM_CLK_CNTL /* Optional platform specific value */ ddr->sdram_clk_cntl = CFG_DDR_SDRAM_CLK_CNTL; -#else - /* SS_EN = 0, source synchronous disable - * CLK_ADJST = 0, MCK/MCK# is launched aligned with addr/cmd - */ - ddr->sdram_clk_cntl = 0x00000000; #endif debug("DDR:sdram_clk_cntl=0x%08x\n", ddr->sdram_clk_cntl); diff --git a/cpu/mpc83xx/speed.c b/cpu/mpc83xx/speed.c index c75993059e..bf30616548 100644 --- a/cpu/mpc83xx/speed.c +++ b/cpu/mpc83xx/speed.c @@ -25,6 +25,7 @@ #include <common.h> #include <mpc83xx.h> +#include <command.h> #include <asm/processor.h> DECLARE_GLOBAL_DATA_PTR; @@ -99,12 +100,14 @@ int get_clocks(void) u32 lcrr; u32 csb_clk; -#if defined(CONFIG_MPC834X) +#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X) u32 tsec1_clk; u32 tsec2_clk; - u32 usbmph_clk; u32 usbdr_clk; #endif +#ifdef CONFIG_MPC834X + u32 usbmph_clk; +#endif u32 core_clk; u32 i2c1_clk; #if !defined(CONFIG_MPC832X) @@ -148,7 +151,7 @@ int get_clocks(void) sccr = im->clk.sccr; -#if defined(CONFIG_MPC834X) +#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X) switch ((sccr & SCCR_TSEC1CM) >> SCCR_TSEC1CM_SHIFT) { case 0: tsec1_clk = 0; @@ -167,6 +170,26 @@ int get_clocks(void) return -4; } + switch ((sccr & SCCR_USBDRCM) >> SCCR_USBDRCM_SHIFT) { + case 0: + usbdr_clk = 0; + break; + case 1: + usbdr_clk = csb_clk; + break; + case 2: + usbdr_clk = csb_clk / 2; + break; + case 3: + usbdr_clk = csb_clk / 3; + break; + default: + /* unkown SCCR_USBDRCM value */ + return -8; + } +#endif + +#if defined(CONFIG_MPC834X) switch ((sccr & SCCR_TSEC2CM) >> SCCR_TSEC2CM_SHIFT) { case 0: tsec2_clk = 0; @@ -205,24 +228,6 @@ int get_clocks(void) return -7; } - switch ((sccr & SCCR_USBDRCM) >> SCCR_USBDRCM_SHIFT) { - case 0: - usbdr_clk = 0; - break; - case 1: - usbdr_clk = csb_clk; - break; - case 2: - usbdr_clk = csb_clk / 2; - break; - case 3: - usbdr_clk = csb_clk / 3; - break; - default: - /* unkown SCCR_USBDRCM value */ - return -8; - } - if (usbmph_clk != 0 && usbdr_clk != 0 && usbmph_clk != usbdr_clk) { /* if USB MPH clock is not disabled and * USB DR clock is not disabled then @@ -230,8 +235,16 @@ int get_clocks(void) */ return -9; } +#elif defined(CONFIG_MPC831X) + tsec2_clk = tsec1_clk; + + if (!(sccr & SCCR_TSEC1ON)) + tsec1_clk = 0; + if (!(sccr & SCCR_TSEC2ON)) + tsec2_clk = 0; #endif -#if defined(CONFIG_MPC8360) || defined(CONFIG_MPC832X) + +#if !defined(CONFIG_MPC834X) i2c1_clk = csb_clk; #endif #if !defined(CONFIG_MPC832X) @@ -314,12 +327,14 @@ int get_clocks(void) #endif gd->csb_clk = csb_clk; -#if defined(CONFIG_MPC834X) +#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X) gd->tsec1_clk = tsec1_clk; gd->tsec2_clk = tsec2_clk; - gd->usbmph_clk = usbmph_clk; gd->usbdr_clk = usbdr_clk; #endif +#if defined(CONFIG_MPC834X) + gd->usbmph_clk = usbmph_clk; +#endif gd->core_clk = core_clk; gd->i2c1_clk = i2c1_clk; #if !defined(CONFIG_MPC832X) @@ -351,11 +366,11 @@ ulong get_bus_freq(ulong dummy) return gd->csb_clk; } -int print_clock_conf(void) +int do_clocks (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { printf("Clock configuration:\n"); - printf(" Coherent System Bus: %4d MHz\n", gd->csb_clk / 1000000); printf(" Core: %4d MHz\n", gd->core_clk / 1000000); + printf(" Coherent System Bus: %4d MHz\n", gd->csb_clk / 1000000); #if defined(CONFIG_MPC8360) || defined(CONFIG_MPC832X) printf(" QE: %4d MHz\n", gd->qe_clk / 1000000); printf(" BRG: %4d MHz\n", gd->brg_clk / 1000000); @@ -371,11 +386,18 @@ int print_clock_conf(void) #if !defined(CONFIG_MPC832X) printf(" I2C2: %4d MHz\n", gd->i2c2_clk / 1000000); #endif -#if defined(CONFIG_MPC834X) +#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X) printf(" TSEC1: %4d MHz\n", gd->tsec1_clk / 1000000); printf(" TSEC2: %4d MHz\n", gd->tsec2_clk / 1000000); - printf(" USB MPH: %4d MHz\n", gd->usbmph_clk / 1000000); printf(" USB DR: %4d MHz\n", gd->usbdr_clk / 1000000); #endif +#if defined(CONFIG_MPC834X) + printf(" USB MPH: %4d MHz\n", gd->usbmph_clk / 1000000); +#endif return 0; } + +U_BOOT_CMD(clocks, 1, 0, do_clocks, + "clocks - print clock configuration\n", + " clocks\n" +); diff --git a/cpu/mpc85xx/cpu.c b/cpu/mpc85xx/cpu.c index 0507c47e6e..7735a52ccf 100644 --- a/cpu/mpc85xx/cpu.c +++ b/cpu/mpc85xx/cpu.c @@ -1,5 +1,5 @@ /* - * Copyright 2004 Freescale Semiconductor. + * Copyright 2004,2007 Freescale Semiconductor, Inc. * (C) Copyright 2002, 2003 Motorola Inc. * Xianghua Xiao (X.Xiao@motorola.com) * @@ -70,6 +70,15 @@ int checkcpu (void) case SVR_8548_E: puts("8548_E"); break; + case SVR_8544: + puts("8544"); + break; + case SVR_8544_E: + puts("8544_E"); + break; + case SVR_8568_E: + puts("8568_E"); + break; default: puts("Unknown"); break; @@ -112,7 +121,7 @@ int checkcpu (void) #endif clkdiv = lcrr & 0x0f; if (clkdiv == 2 || clkdiv == 4 || clkdiv == 8) { -#ifdef CONFIG_MPC8548 +#if defined(CONFIG_MPC8548) || defined(CONFIG_MPC8544) /* * Yes, the entire PQ38 family use the same * bit-representation for twice the clock divider values. @@ -140,16 +149,25 @@ int checkcpu (void) int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { + uint pvr; + uint ver; + pvr = get_pvr(); + ver = PVR_VER(pvr); + if (ver & 1){ + /* e500 v2 core has reset control register */ + volatile unsigned int * rstcr; + rstcr = (volatile unsigned int *)(CFG_IMMR + 0xE00B0); + *rstcr = 0x2; /* HRESET_REQ */ + }else{ /* * Initiate hard reset in debug control register DBCR0 * Make sure MSR[DE] = 1 */ - unsigned long val; - - val = mfspr(DBCR0); - val |= 0x70000000; - mtspr(DBCR0,val); - + unsigned long val; + val = mfspr(DBCR0); + val |= 0x70000000; + mtspr(DBCR0,val); + } return 1; } @@ -183,9 +201,9 @@ reset_85xx_watchdog(void) * Clear TSR(WIS) bit by writing 1 */ unsigned long val; - val = mfspr(tsr); - val |= 0x40000000; - mtspr(tsr, val); + val = mfspr(SPRN_TSR); + val |= TSR_WIS; + mtspr(SPRN_TSR, val); } #endif /* CONFIG_WATCHDOG */ @@ -196,6 +214,7 @@ void dma_init(void) { dma->satr0 = 0x02c40000; dma->datr0 = 0x02c40000; + dma->sr0 = 0xfffffff; /* clear any errors */ asm("sync; isync; msync"); return; } @@ -210,6 +229,10 @@ uint dma_check(void) { status = dma->sr0; } + /* clear MR0[CS] channel start bit */ + dma->mr0 &= 0x00000001; + asm("sync;isync;msync"); + if (status != 0) { printf ("DMA Error: status = %x\n", status); } @@ -245,6 +268,10 @@ ft_cpu_setup(void *blob, bd_t *bd) if (p != NULL) *p = cpu_to_be32(clock); + p = ft_get_prop(blob, "/qe@e0080000/" OF_CPU "/bus-frequency", &len); + if (p != NULL) + *p = cpu_to_be32(clock); + p = ft_get_prop(blob, "/" OF_SOC "/serial@4500/clock-frequency", &len); if (p != NULL) *p = cpu_to_be32(clock); @@ -255,21 +282,41 @@ ft_cpu_setup(void *blob, bd_t *bd) #if defined(CONFIG_MPC85XX_TSEC1) p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/mac-address", &len); + if (p) + memcpy(p, bd->bi_enetaddr, 6); + + p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/local-mac-address", &len); + if (p) memcpy(p, bd->bi_enetaddr, 6); #endif #if defined(CONFIG_HAS_ETH1) p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/mac-address", &len); + if (p) + memcpy(p, bd->bi_enet1addr, 6); + + p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/local-mac-address", &len); + if (p) memcpy(p, bd->bi_enet1addr, 6); #endif #if defined(CONFIG_HAS_ETH2) p = ft_get_prop(blob, "/" OF_SOC "/ethernet@26000/mac-address", &len); + if (p) + memcpy(p, bd->bi_enet2addr, 6); + + p = ft_get_prop(blob, "/" OF_SOC "/ethernet@26000/local-mac-address", &len); + if (p) memcpy(p, bd->bi_enet2addr, 6); #endif #if defined(CONFIG_HAS_ETH3) p = ft_get_prop(blob, "/" OF_SOC "/ethernet@27000/mac-address", &len); + if (p) + memcpy(p, bd->bi_enet3addr, 6); + + p = ft_get_prop(blob, "/" OF_SOC "/ethernet@27000/local-mac-address", &len); + if (p) memcpy(p, bd->bi_enet3addr, 6); #endif diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c index 9f4d36c1ab..9517146ed2 100644 --- a/cpu/mpc85xx/cpu_init.c +++ b/cpu/mpc85xx/cpu_init.c @@ -143,12 +143,10 @@ void cpu_init_f (void) memctl->br1 = CFG_BR1_PRELIM; #endif -#if !defined(CONFIG_MPC85xx) #if defined(CFG_BR2_PRELIM) && defined(CFG_OR2_PRELIM) memctl->or2 = CFG_OR2_PRELIM; memctl->br2 = CFG_BR2_PRELIM; #endif -#endif #if defined(CFG_BR3_PRELIM) && defined(CFG_OR3_PRELIM) memctl->or3 = CFG_OR3_PRELIM; diff --git a/cpu/mpc85xx/pci.c b/cpu/mpc85xx/pci.c index 84f839ae1e..3c1a323aad 100644 --- a/cpu/mpc85xx/pci.c +++ b/cpu/mpc85xx/pci.c @@ -90,14 +90,14 @@ pci_mpc85xx_init(struct pci_controller *board_hose) pcix->powbar1 = (CFG_PCI1_MEM_PHYS >> 12) & 0x000fffff; pcix->powbear1 = 0x00000000; pcix->powar1 = (POWAR_EN | POWAR_MEM_READ | - POWAR_MEM_WRITE | POWAR_MEM_512M); + POWAR_MEM_WRITE | (__ilog2(CFG_PCI1_MEM_SIZE) - 1)); pcix->potar2 = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff; pcix->potear2 = 0x00000000; pcix->powbar2 = (CFG_PCI1_IO_PHYS >> 12) & 0x000fffff; pcix->powbear2 = 0x00000000; pcix->powar2 = (POWAR_EN | POWAR_IO_READ | - POWAR_IO_WRITE | POWAR_IO_1M); + POWAR_IO_WRITE | (__ilog2(CFG_PCI1_IO_SIZE) - 1)); pcix->pitar1 = 0x00000000; pcix->piwbar1 = 0x00000000; @@ -175,14 +175,14 @@ pci_mpc85xx_init(struct pci_controller *board_hose) pcix2->powbar1 = (CFG_PCI2_MEM_PHYS >> 12) & 0x000fffff; pcix2->powbear1 = 0x00000000; pcix2->powar1 = (POWAR_EN | POWAR_MEM_READ | - POWAR_MEM_WRITE | POWAR_MEM_512M); + POWAR_MEM_WRITE | (__ilog2(CFG_PCI2_MEM_SIZE) - 1)); pcix2->potar2 = (CFG_PCI2_IO_BASE >> 12) & 0x000fffff; pcix2->potear2 = 0x00000000; pcix2->powbar2 = (CFG_PCI2_IO_PHYS >> 12) & 0x000fffff; pcix2->powbear2 = 0x00000000; pcix2->powar2 = (POWAR_EN | POWAR_IO_READ | - POWAR_IO_WRITE | POWAR_IO_1M); + POWAR_IO_WRITE | (__ilog2(CFG_PCI2_IO_SIZE) - 1)); pcix2->pitar1 = 0x00000000; pcix2->piwbar1 = 0x00000000; diff --git a/cpu/mpc85xx/spd_sdram.c b/cpu/mpc85xx/spd_sdram.c index 6da5367a70..3777f49adc 100644 --- a/cpu/mpc85xx/spd_sdram.c +++ b/cpu/mpc85xx/spd_sdram.c @@ -263,13 +263,14 @@ spd_sdram(void) } /* - * Adjust DDR II IO voltage biasing. It just makes it work. + * Adjust DDR II IO voltage biasing. + * Only 8548 rev 1 needs the fix */ - if (spd.mem_type == SPD_MEMTYPE_DDR2) { - gur->ddrioovcr = (0 - | 0x80000000 /* Enable */ - | 0x10000000 /* VSEL to 1.8V */ - ); + if ((SVR_VER(get_svr()) == SVR_8548_E) && + (SVR_MJREV(get_svr()) == 1) && + (spd.mem_type == SPD_MEMTYPE_DDR2)) { + gur->ddrioovcr = (0x80000000 /* Enable */ + | 0x10000000);/* VSEL to 1.8V */ } /* @@ -786,14 +787,17 @@ spd_sdram(void) * Is this an ECC DDR chip? * But don't mess with it if the DDR controller will init mem. */ -#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) +#ifdef CONFIG_DDR_ECC if (spd.config == 0x02) { +#ifndef CONFIG_ECC_INIT_VIA_DDRCONTROLLER ddr->err_disable = 0x0000000d; +#endif ddr->err_sbe = 0x00ff0000; } + debug("DDR: err_disable = 0x%08x\n", ddr->err_disable); debug("DDR: err_sbe = 0x%08x\n", ddr->err_sbe); -#endif +#endif /* CONFIG_DDR_ECC */ asm("sync;isync;msync"); udelay(500); @@ -991,17 +995,24 @@ setup_laws_and_tlbs(unsigned int memsize) break; case 256: case 512: + tlb_size = BOOKE_PAGESZ_256M; + break; case 1024: case 2048: - tlb_size = BOOKE_PAGESZ_256M; + if (PVR_VER(get_pvr()) > PVR_VER(PVR_85xx)) + tlb_size = BOOKE_PAGESZ_1G; + else + tlb_size = BOOKE_PAGESZ_256M; break; default: puts("DDR: only 16M,32M,64M,128M,256M,512M,1G and 2G are supported.\n"); /* * The memory was not able to be mapped. + * Default to a small size. */ - return 0; + tlb_size = BOOKE_PAGESZ_64M; + memsize=64; break; } diff --git a/cpu/mpc85xx/speed.c b/cpu/mpc85xx/speed.c index ca81ee7352..12359a2d64 100644 --- a/cpu/mpc85xx/speed.c +++ b/cpu/mpc85xx/speed.c @@ -37,49 +37,21 @@ void get_sys_info (sys_info_t * sysInfo) { volatile immap_t *immap = (immap_t *)CFG_IMMR; volatile ccsr_gur_t *gur = &immap->im_gur; - uint plat_ratio,e500_ratio; + uint plat_ratio,e500_ratio,half_freqSystemBus; plat_ratio = (gur->porpllsr) & 0x0000003e; plat_ratio >>= 1; - switch(plat_ratio) { - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x06: - case 0x08: - case 0x09: - case 0x0a: - case 0x0c: - case 0x10: - sysInfo->freqSystemBus = plat_ratio * CONFIG_SYS_CLK_FREQ; - break; - default: - sysInfo->freqSystemBus = 0; - break; - } - + sysInfo->freqSystemBus = plat_ratio * CONFIG_SYS_CLK_FREQ; e500_ratio = (gur->porpllsr) & 0x003f0000; e500_ratio >>= 16; - switch(e500_ratio) { - case 0x04: - sysInfo->freqProcessor = 2*sysInfo->freqSystemBus; - break; - case 0x05: - sysInfo->freqProcessor = 5*sysInfo->freqSystemBus/2; - break; - case 0x06: - sysInfo->freqProcessor = 3*sysInfo->freqSystemBus; - break; - case 0x07: - sysInfo->freqProcessor = 7*sysInfo->freqSystemBus/2; - break; - default: - sysInfo->freqProcessor = 0; - break; - } + + /* Divide before multiply to avoid integer + * overflow for processor speeds above 2GHz */ + half_freqSystemBus = sysInfo->freqSystemBus/2; + sysInfo->freqProcessor = e500_ratio*half_freqSystemBus; } + int get_clocks (void) { sys_info_t sys_info; diff --git a/cpu/mpc85xx/start.S b/cpu/mpc85xx/start.S index f96a4c3f8b..20c7ebc723 100644 --- a/cpu/mpc85xx/start.S +++ b/cpu/mpc85xx/start.S @@ -251,13 +251,10 @@ _start_e500: */ bl tlb1_entry mr r5,r0 - li r1,0x0020 /* max 16 TLB1 plus some TLB0 entries */ - mtctr r1 lwzu r4,0(r5) /* how many TLB1 entries we actually use */ + mtctr r4 -0: cmpwi r4,0 - beq 1f - lwzu r0,4(r5) +0: lwzu r0,4(r5) lwzu r1,4(r5) lwzu r2,4(r5) lwzu r3,4(r5) @@ -269,7 +266,6 @@ _start_e500: msync tlbwe isync - addi r4,r4,-1 bdnz 0b 1: @@ -301,20 +297,16 @@ _start_e500: bl law_entry mr r6,r0 - li r1,0x0007 /* 8 LAWs, but reserve one for boot-over-rio-or-pci */ - mtctr r1 lwzu r5,0(r6) /* how many windows we actually use */ + mtctr r5 li r2,0x0c28 /* the first pair is reserved for boot-over-rio-or-pci */ li r1,0x0c30 -0: cmpwi r5,0 - beq 1f - lwzu r4,4(r6) +0: lwzu r4,4(r6) lwzu r3,4(r6) stwx r4,r7,r2 stwx r3,r7,r1 - addi r5,r5,-1 addi r2,r2,0x0020 addi r1,r1,0x0020 bdnz 0b diff --git a/cpu/mpc86xx/cpu.c b/cpu/mpc86xx/cpu.c index 84f5bef508..a33acfec4d 100644 --- a/cpu/mpc86xx/cpu.c +++ b/cpu/mpc86xx/cpu.c @@ -280,22 +280,38 @@ ft_cpu_setup(void *blob, bd_t *bd) #if defined(CONFIG_MPC86XX_TSEC1) p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/mac-address", &len); - memcpy(p, bd->bi_enetaddr, 6); + if (p != NULL) + memcpy(p, bd->bi_enetaddr, 6); + p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/local-mac-address", &len); + if (p) + memcpy(p, bd->bi_enetaddr, 6); #endif #if defined(CONFIG_MPC86XX_TSEC2) p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/mac-address", &len); - memcpy(p, bd->bi_enet1addr, 6); + if (p != NULL) + memcpy(p, bd->bi_enet1addr, 6); + p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/local-mac-address", &len); + if (p != NULL) + memcpy(p, bd->bi_enet1addr, 6); #endif #if defined(CONFIG_MPC86XX_TSEC3) p = ft_get_prop(blob, "/" OF_SOC "/ethernet@26000/mac-address", &len); - memcpy(p, bd->bi_enet2addr, 6); + if (p != NULL) + memcpy(p, bd->bi_enet2addr, 6); + p = ft_get_prop(blob, "/" OF_SOC "/ethernet@26000/local-mac-address", &len); + if (p != NULL) + memcpy(p, bd->bi_enet2addr, 6); #endif #if defined(CONFIG_MPC86XX_TSEC4) p = ft_get_prop(blob, "/" OF_SOC "/ethernet@27000/mac-address", &len); - memcpy(p, bd->bi_enet3addr, 6); + if (p != NULL) + memcpy(p, bd->bi_enet3addr, 6); + p = ft_get_prop(blob, "/" OF_SOC "/ethernet@27000/local-mac-address", &len); + if (p != NULL) + memcpy(p, bd->bi_enet3addr, 6); #endif } diff --git a/cpu/mpc86xx/spd_sdram.c b/cpu/mpc86xx/spd_sdram.c index ac9ff81ce6..f37ab430b3 100644 --- a/cpu/mpc86xx/spd_sdram.c +++ b/cpu/mpc86xx/spd_sdram.c @@ -51,20 +51,32 @@ extern int dma_xfer(void *dest, uint count, void *src); #define CFG_SUPER_BANK_INTERLEAVING 0 /* - * Convert picoseconds into clock cycles (rounding up if needed). + * Convert picoseconds into DRAM clock cycles (rounding up if needed). */ -int -picos_to_clk(int picos) +static unsigned int +picos_to_clk(unsigned int picos) { - int clks; - - clks = picos / (2000000000 / (get_bus_freq(0) / 1000)); - if (picos % (2000000000 / (get_bus_freq(0) / 1000)) != 0) { + /* use unsigned long long to avoid rounding errors */ + const unsigned long long ULL_2e12 = 2000000000000ULL; + unsigned long long clks; + unsigned long long clks_temp; + + if (! picos) + return 0; + + clks = get_bus_freq(0) * (unsigned long long) picos; + clks_temp = clks; + clks = clks / ULL_2e12; + if (clks_temp % ULL_2e12) { clks++; } - return clks; + if (clks > 0xFFFFFFFFULL) { + clks = 0xFFFFFFFFULL; + } + + return (unsigned int) clks; } diff --git a/cpu/mpc86xx/start.S b/cpu/mpc86xx/start.S index 7406fe2248..67c56db1a3 100644 --- a/cpu/mpc86xx/start.S +++ b/cpu/mpc86xx/start.S @@ -241,26 +241,40 @@ in_flash: bl setup_ccsrbar #endif - /* Fix for SMP linux - Changing arbitration to round-robin */ - lis r3, CFG_CCSRBAR@h - ori r3, r3, 0x1000 - xor r4, r4, r4 - li r4, 0x1000 - stw r4, 0(r3) - /* setup the law entries */ - bl law_entry + /* -- MPC8641 Rev 1.0 MCM Errata fixups -- */ + + /* skip fixups if not Rev 1.0 */ + mfspr r4, SVR + rlwinm r4,r4,0,24,31 + cmpwi r4,0x10 + bne 1f + + lis r3,MCM_ABCR@ha + lwz r4,MCM_ABCR@l(r3) /* ABCR -> r4 */ + + /* set ABCR[A_STRM_CNT] = 0 */ + rlwinm r4,r4,0,0,29 + + /* set ABCR[ARB_POLICY] to 0x1 (round-robin) */ + addi r0,r0,1 + rlwimi r4,r0,12,18,19 + + stw r4,MCM_ABCR@l(r3) /* r4 -> ABCR */ sync - /* Don't use this feature due to bug in 8641D PD4 */ - /* Disable ERD_DIS */ - lis r3, CFG_CCSRBAR@h - ori r3, r3, 0x1008 - lwz r4, 0(r3) + /* Set DBCR[ERD_DIS] */ + lis r3,MCM_DBCR@ha + lwz r4,MCM_DBCR@l(r3) oris r4, r4, 0x4000 - stw r4, 0(r3) + stw r4,MCM_DBCR@l(r3) + sync +1: + /* setup the law entries */ + bl law_entry sync + #if (EMULATOR_RUN == 1) /* On the emulator we want to adjust these ASAP */ /* otherwise things are sloooow */ diff --git a/cpu/ppc4xx/4xx_enet.c b/cpu/ppc4xx/4xx_enet.c index cf56581d84..1200d021af 100644 --- a/cpu/ppc4xx/4xx_enet.c +++ b/cpu/ppc4xx/4xx_enet.c @@ -339,29 +339,41 @@ int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis) int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis) { unsigned long zmiifer=0x0; + unsigned long pfc1; - /* - * Right now only 2*RGMII is supported. Please extend when needed. - * sr - 2006-08-29 - */ - switch (1) { - case 0: + mfsdr(sdr_pfc1, pfc1); + pfc1 &= SDR0_PFC1_SELECT_MASK; + + switch (pfc1) { + case SDR0_PFC1_SELECT_CONFIG_2: /* 1 x GMII port */ out32 (ZMII_FER, 0x00); out32 (RGMII_FER, 0x00000037); bis->bi_phymode[0] = BI_PHYMODE_GMII; bis->bi_phymode[1] = BI_PHYMODE_NONE; break; - case 1: + case SDR0_PFC1_SELECT_CONFIG_4: /* 2 x RGMII ports */ out32 (ZMII_FER, 0x00); out32 (RGMII_FER, 0x00000055); bis->bi_phymode[0] = BI_PHYMODE_RGMII; bis->bi_phymode[1] = BI_PHYMODE_RGMII; break; - case 2: + case SDR0_PFC1_SELECT_CONFIG_6: /* 2 x SMII ports */ - + out32 (ZMII_FER, + ((ZMII_FER_SMII) << ZMII_FER_V(0)) | + ((ZMII_FER_SMII) << ZMII_FER_V(1))); + out32 (RGMII_FER, 0x00000000); + bis->bi_phymode[0] = BI_PHYMODE_SMII; + bis->bi_phymode[1] = BI_PHYMODE_SMII; + break; + case SDR0_PFC1_SELECT_CONFIG_1_2: + /* only 1 x MII supported */ + out32 (ZMII_FER, (ZMII_FER_MII) << ZMII_FER_V(0)); + out32 (RGMII_FER, 0x00000000); + bis->bi_phymode[0] = BI_PHYMODE_MII; + bis->bi_phymode[1] = BI_PHYMODE_NONE; break; default: break; diff --git a/cpu/ppc4xx/ndfc.c b/cpu/ppc4xx/ndfc.c index b198ff46ce..08dfc32952 100644 --- a/cpu/ppc4xx/ndfc.c +++ b/cpu/ppc4xx/ndfc.c @@ -33,12 +33,13 @@ #if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY) && \ (defined(CONFIG_440EP) || defined(CONFIG_440GR) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX)) + defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ + defined(CONFIG_405EZ)) #include <nand.h> #include <linux/mtd/ndfc.h> #include <asm/processor.h> -#include <ppc440.h> +#include <ppc4xx.h> static u8 hwctl = 0; @@ -176,8 +177,7 @@ int board_nand_init(struct nand_chip *nand) /* * Setup EBC (CS0 only right now) */ - mtdcr(ebccfga, xbcfg); - mtdcr(ebccfgd, 0xb8400000); + mtebc(EBC0_CFG, 0xb8400000); mtebc(pb0cr, CFG_EBC_PB0CR); mtebc(pb0ap, CFG_EBC_PB0AP); diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index a96083caa5..85660b40dc 100644 --- a/cpu/ppc4xx/start.S +++ b/cpu/ppc4xx/start.S @@ -783,7 +783,7 @@ _start: mtdcr ocmdscr2, r3 /* Set Data Side */ mtdcr ocmiscr2, r3 /* Set Instruction Side */ addis r3,0,0x0800 /* OCM Data Parity Disable - 1 Wait State */ - mtdcr ocmdsisdpc,r4 + mtdcr ocmdsisdpc,r3 isync #else /* CONFIG_405EZ */ |