From 982efcf23fd03647e01e2fbe28a7a36239156cc0 Mon Sep 17 00:00:00 2001 From: Andy Fleming Date: Tue, 5 Jun 2007 16:38:44 -0500 Subject: From: eran liberty adds the reset register to 85xx immap Signed-off-by: Eran Liberty Signed-off-by: Andy Fleming --- include/asm-ppc/immap_85xx.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/asm-ppc') diff --git a/include/asm-ppc/immap_85xx.h b/include/asm-ppc/immap_85xx.h index 5377c2eb5be..e002d2838e9 100644 --- a/include/asm-ppc/immap_85xx.h +++ b/include/asm-ppc/immap_85xx.h @@ -1548,7 +1548,9 @@ typedef struct ccsr_gur { char res9[12]; uint pvr; /* 0xe00a0 - Processor version register */ uint svr; /* 0xe00a4 - System version register */ - char res10[3416]; + char res10a[8]; + uint rstcr; /* 0xe00b0 - Reset control register */ + char res10b[3404]; uint clkocr; /* 0xe0e00 - Clock out select register */ char res11[12]; uint ddrdllcr; /* 0xe0e10 - DDR DLL control register */ -- cgit v1.3.1 From 5743a9207a370b90f09b20ebd61167c806b937f3 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 16 Jul 2007 08:53:51 +0200 Subject: ppc4xx: Add remove_tlb() function to remove a mem area from TLB setup The new function remove_tlb() can be used to remove the TLB's used to map a specific memory region. This is especially useful for the DDR(2) setup routines which configure the SDRAM area temporarily as a cached area (for speedup on auto-calibration and ECC generation) and later need this area uncached for normal usage. Signed-off-by: Stefan Roese --- cpu/ppc4xx/tlb.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++- include/asm-ppc/mmu.h | 3 +++ 2 files changed, 64 insertions(+), 1 deletion(-) (limited to 'include/asm-ppc') diff --git a/cpu/ppc4xx/tlb.c b/cpu/ppc4xx/tlb.c index 049a7854950..098694caf49 100644 --- a/cpu/ppc4xx/tlb.c +++ b/cpu/ppc4xx/tlb.c @@ -25,7 +25,6 @@ #if defined(CONFIG_440) -#include #include #include #include @@ -36,6 +35,67 @@ typedef struct region { unsigned long tlb_word2_i_value; } region_t; +void remove_tlb(u32 vaddr, u32 size) +{ + int i; + u32 tlb_word0_value; + u32 tlb_vaddr; + u32 tlb_size = 0; + + /* First, find the index of a TLB entry not being used */ + for (i=0; i= vaddr)) { + /* + * TLB is enabled and start address is lower or equal + * than the area we are looking for. Now we only have + * to check the size/end address for a match. + */ + switch (tlb_word0_value & TLB_WORD0_SIZE_MASK) { + case TLB_WORD0_SIZE_1KB: + tlb_size = 1 << 10; + break; + case TLB_WORD0_SIZE_4KB: + tlb_size = 4 << 10; + break; + case TLB_WORD0_SIZE_16KB: + tlb_size = 16 << 10; + break; + case TLB_WORD0_SIZE_64KB: + tlb_size = 64 << 10; + break; + case TLB_WORD0_SIZE_256KB: + tlb_size = 256 << 10; + break; + case TLB_WORD0_SIZE_1MB: + tlb_size = 1 << 20; + break; + case TLB_WORD0_SIZE_16MB: + tlb_size = 16 << 20; + break; + case TLB_WORD0_SIZE_256MB: + tlb_size = 256 << 20; + break; + } + + /* + * Now check the end-address if it's in the range + */ + if ((tlb_vaddr + tlb_size - 1) <= (vaddr + size - 1)) + /* + * Found a TLB in the range. + * Disable it by writing 0 to tlb0 word. + */ + mttlb1(i, 0); + } + } + + /* Execute an ISYNC instruction so that the new TLB entry takes effect */ + asm("isync"); +} + static int add_tlb_entry(unsigned long phys_addr, unsigned long virt_addr, unsigned long tlb_word0_size_value, diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h index 48fd9829506..b3cfa9b3726 100644 --- a/include/asm-ppc/mmu.h +++ b/include/asm-ppc/mmu.h @@ -645,6 +645,9 @@ void mttlb3(unsigned long index, unsigned long value); unsigned long mftlb1(unsigned long index); unsigned long mftlb2(unsigned long index); unsigned long mftlb3(unsigned long index); + +void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value); +void remove_tlb(u32 vaddr, u32 size); #endif /* __ASSEMBLY__ */ #endif /* CONFIG_440 */ -- cgit v1.3.1 From cc3023b9f95d7ac959a764471a65001062aecf41 Mon Sep 17 00:00:00 2001 From: Rafal Jaworowski Date: Thu, 19 Jul 2007 17:12:28 +0200 Subject: Fix breakage of 8xx boards from recent commit. This patch fixes the negative consequences for 8xx of the recent "ppc4xx: Clean up 440 exceptions handling" commit. Signed-off-by: Rafal Jaworowski --- include/asm-ppc/processor.h | 6 ++++++ include/ppc_asm.tmpl | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'include/asm-ppc') diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h index 9780fe15c0d..4898dd41cc3 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-ppc/processor.h @@ -628,6 +628,12 @@ #define MAS6 SPRN_MAS6 #define MAS7 SPRN_MAS7 +#if defined(CONFIG_4xx) || defined(CONFIG_44x) || defined(CONFIG_MPC85xx) +#define DAR_DEAR DEAR +#else +#define DAR_DEAR DAR +#endif + /* Device Control Registers */ #define DCRN_BEAR 0x090 /* Bus Error Address Register */ diff --git a/include/ppc_asm.tmpl b/include/ppc_asm.tmpl index 9f4029f2afc..ac8f3176831 100644 --- a/include/ppc_asm.tmpl +++ b/include/ppc_asm.tmpl @@ -235,7 +235,7 @@ stw r22,_CTR(r21); \ mfspr r20,XER; \ stw r20,_XER(r21); \ - mfspr r20,DEAR; \ + mfspr r20, DAR_DEAR; \ stw r20,_DAR(r21); \ mfspr r22,reg1; \ mfspr r23,reg2; \ -- cgit v1.3.1 From 1863cfb7b100ba0ee3401799457a01dc058745f8 Mon Sep 17 00:00:00 2001 From: Rafal Jaworowski Date: Fri, 27 Jul 2007 14:22:04 +0200 Subject: [PPC] Remove unused MSR_USER definition Signed-off-by: Rafal Jaworowski --- include/asm-ppc/processor.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/asm-ppc') diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h index 4898dd41cc3..71e2e847a46 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-ppc/processor.h @@ -58,7 +58,6 @@ #else #define MSR_KERNEL MSR_ME #endif -#define MSR_USER MSR_KERNEL|MSR_PR|MSR_EE /* Floating Point Status and Control Register (FPSCR) Fields */ -- cgit v1.3.1 From 8993e54b6f397973794f3d6f47d3b3c0c98dd4f6 Mon Sep 17 00:00:00 2001 From: Rafal Jaworowski Date: Fri, 27 Jul 2007 14:43:59 +0200 Subject: [ADS5121] Support for the ADS5121 board The following MPC5121e subsystems are supported: - low-level CPU init - NOR Boot Flash (common CFI driver) - DDR SDRAM - FEC - I2C - Watchdog Signed-off-by: Grzegorz Bernacki Signed-off-by: Rafal Jaworowski Signed-off-by: Jan Wrobel --- MAKEALL | 10 +- Makefile | 7 + board/ads5121/Makefile | 50 +++ board/ads5121/ads5121.c | 188 ++++++++++ board/ads5121/config.mk | 23 ++ board/ads5121/u-boot.lds | 122 +++++++ cpu/mpc512x/Makefile | 46 +++ cpu/mpc512x/config.mk | 25 ++ cpu/mpc512x/cpu.c | 127 +++++++ cpu/mpc512x/cpu_init.c | 87 +++++ cpu/mpc512x/fec.c | 801 ++++++++++++++++++++++++++++++++++++++++++ cpu/mpc512x/fec.h | 224 ++++++++++++ cpu/mpc512x/i2c.c | 431 +++++++++++++++++++++++ cpu/mpc512x/interrupts.c | 61 ++++ cpu/mpc512x/serial.c | 197 +++++++++++ cpu/mpc512x/speed.c | 135 +++++++ cpu/mpc512x/start.S | 780 ++++++++++++++++++++++++++++++++++++++++ cpu/mpc512x/traps.c | 205 +++++++++++ include/asm-ppc/e300.h | 1 + include/asm-ppc/global_data.h | 4 + include/asm-ppc/immap_512x.h | 569 ++++++++++++++++++++++++++++++ include/common.h | 8 +- include/configs/ads5121.h | 410 +++++++++++++++++++++ include/mpc512x.h | 398 +++++++++++++++++++++ net/eth.c | 4 + 25 files changed, 4911 insertions(+), 2 deletions(-) create mode 100644 board/ads5121/Makefile create mode 100644 board/ads5121/ads5121.c create mode 100644 board/ads5121/config.mk create mode 100644 board/ads5121/u-boot.lds create mode 100644 cpu/mpc512x/Makefile create mode 100644 cpu/mpc512x/config.mk create mode 100644 cpu/mpc512x/cpu.c create mode 100644 cpu/mpc512x/cpu_init.c create mode 100644 cpu/mpc512x/fec.c create mode 100644 cpu/mpc512x/fec.h create mode 100644 cpu/mpc512x/i2c.c create mode 100644 cpu/mpc512x/interrupts.c create mode 100644 cpu/mpc512x/serial.c create mode 100644 cpu/mpc512x/speed.c create mode 100644 cpu/mpc512x/start.S create mode 100644 cpu/mpc512x/traps.c create mode 100644 include/asm-ppc/immap_512x.h create mode 100644 include/configs/ads5121.h create mode 100644 include/mpc512x.h (limited to 'include/asm-ppc') diff --git a/MAKEALL b/MAKEALL index 127faa83a32..2a03b687083 100755 --- a/MAKEALL +++ b/MAKEALL @@ -43,6 +43,14 @@ LIST_5xxx=" \ TQM5200S v38b \ " +######################################################################### +## MPC512x Systems +######################################################################### + +LIST_512x=" \ + ads5121 \ +" + ######################################################################### ## MPC8xx Systems ######################################################################### @@ -365,7 +373,7 @@ do microblaze| \ mips|mips_el| \ nios|nios2| \ - ppc|5xx|5xxx|8xx|8220|824x|8260|83xx|85xx|86xx|4xx|7xx|74xx| \ + ppc|5xx|5xxx|512x|8xx|8220|824x|8260|83xx|85xx|86xx|4xx|7xx|74xx| \ x86|I486) for target in `eval echo '$LIST_'${arg}` do diff --git a/Makefile b/Makefile index 3af9962e678..5b87aad5b9f 100644 --- a/Makefile +++ b/Makefile @@ -641,6 +641,13 @@ motionpro_config: unconfig @$(MKCONFIG) motionpro ppc mpc5xxx motionpro +######################################################################### +## MPC512x Systems +######################################################################### +ads5121_config: unconfig + @$(MKCONFIG) ads5121 ppc mpc512x ads5121 + + ######################################################################### ## MPC8xx Systems ######################################################################### diff --git a/board/ads5121/Makefile b/board/ads5121/Makefile new file mode 100644 index 00000000000..cd8148c43ea --- /dev/null +++ b/board/ads5121/Makefile @@ -0,0 +1,50 @@ +# +# (C) Copyright 2007 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).a + +COBJS := $(BOARD).o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/ads5121/ads5121.c b/board/ads5121/ads5121.c new file mode 100644 index 00000000000..0a99a34ac05 --- /dev/null +++ b/board/ads5121/ads5121.c @@ -0,0 +1,188 @@ +/* + * (C) Copyright 2007 DENX Software Engineering + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include +#include +#include +#include + +/* Clocks in use */ +#define SCCR1_CLOCKS_EN (CLOCK_SCCR1_CFG_EN | \ + CLOCK_SCCR1_LPC_EN | \ + CLOCK_SCCR1_PSC_EN(CONFIG_PSC_CONSOLE) | \ + CLOCK_SCCR1_PSCFIFO_EN | \ + CLOCK_SCCR1_DDR_EN | \ + CLOCK_SCCR1_FEC_EN) + +#define SCCR2_CLOCKS_EN (CLOCK_SCCR2_MEM_EN | \ + CLOCK_SCCR2_SPDIF_EN | \ + CLOCK_SCCR2_I2C_EN) + +#define CSAW_START(start) ((start) & 0xFFFF0000) +#define CSAW_STOP(start, size) (((start) + (size) - 1) >> 16) + +long int fixed_sdram(void); + +int board_early_init_f (void) +{ + volatile immap_t *im = (immap_t *) CFG_IMMR; + u32 lpcaw; + + /* + * Initialize Local Window for the CPLD registers access (CS2 selects + * the CPLD chip) + */ + im->sysconf.lpcs2aw = CSAW_START(CFG_CPLD_BASE) | + CSAW_STOP(CFG_CPLD_BASE, CFG_CPLD_SIZE); + im->lpc.cs_cfg[2] = CFG_CS2_CFG; + + /* + * According to MPC5121e RM, configuring local access windows should + * be followed by a dummy read of the config register that was + * modified last and an isync + */ + lpcaw = im->sysconf.lpcs2aw; + __asm__ __volatile__ ("isync"); + + /* + * Disable Boot NOR FLASH write protect - CPLD Reg 8 NOR FLASH Control + * + * Without this the flash identification routine fails, as it needs to issue + * write commands in order to establish the device ID. + */ + *((volatile u8 *)(CFG_CPLD_BASE + 0x08)) = 0xC1; + + /* + * Enable clocks + */ + im->clk.sccr[0] = SCCR1_CLOCKS_EN; + im->clk.sccr[1] = SCCR2_CLOCKS_EN; + + return 0; +} + +long int initdram (int board_type) +{ + u32 msize = 0; + + puts ("Initializing\n"); + msize = fixed_sdram (); + puts (" DDR RAM: "); + + return msize; +} + +/* + * fixed sdram init -- the board doesn't use memory modules that have serial presence + * detect or similar mechanism for discovery of the DRAM settings + */ +long int fixed_sdram (void) +{ + volatile immap_t *im = (immap_t *) CFG_IMMR; + u32 msize = CFG_DDR_SIZE * 1024 * 1024; + u32 msize_log2 = __ilog2 (msize); + u32 i; + + /* Initialize IO Control */ + im->io_ctrl.regs[MEM_IDX] = IOCTRL_MUX_DDR; + + /* Initialize DDR Local Window */ + im->sysconf.ddrlaw.bar = CFG_DDR_BASE & 0xFFFFF000; + im->sysconf.ddrlaw.ar = msize_log2 - 1; + + /* + * According to MPC5121e RM, configuring local access windows should + * be followed by a dummy read of the config register that was + * modified last and an isync + */ + i = im->sysconf.ddrlaw.ar; + __asm__ __volatile__ ("isync"); + + /* Enable DDR */ + im->mddrc.ddr_sys_config = CFG_MDDRC_SYS_CFG_EN; + + /* Initialize DDR Priority Manager */ + im->mddrc.prioman_config1 = CFG_MDDRCGRP_PM_CFG1; + im->mddrc.prioman_config2 = CFG_MDDRCGRP_PM_CFG2; + im->mddrc.hiprio_config = CFG_MDDRCGRP_HIPRIO_CFG; + im->mddrc.lut_table0_main_upper = CFG_MDDRCGRP_LUT0_MU; + im->mddrc.lut_table1_main_upper = CFG_MDDRCGRP_LUT1_MU; + im->mddrc.lut_table2_main_upper = CFG_MDDRCGRP_LUT2_MU; + im->mddrc.lut_table3_main_upper = CFG_MDDRCGRP_LUT3_MU; + im->mddrc.lut_table4_main_upper = CFG_MDDRCGRP_LUT4_MU; + im->mddrc.lut_table0_main_lower = CFG_MDDRCGRP_LUT0_ML; + im->mddrc.lut_table1_main_lower = CFG_MDDRCGRP_LUT1_ML; + im->mddrc.lut_table2_main_lower = CFG_MDDRCGRP_LUT2_ML; + im->mddrc.lut_table3_main_lower = CFG_MDDRCGRP_LUT3_ML; + im->mddrc.lut_table4_main_lower = CFG_MDDRCGRP_LUT4_ML; + im->mddrc.lut_table0_alternate_upper = CFG_MDDRCGRP_LUT0_AU; + im->mddrc.lut_table1_alternate_upper = CFG_MDDRCGRP_LUT1_AU; + im->mddrc.lut_table2_alternate_upper = CFG_MDDRCGRP_LUT2_AU; + im->mddrc.lut_table3_alternate_upper = CFG_MDDRCGRP_LUT3_AU; + im->mddrc.lut_table4_alternate_upper = CFG_MDDRCGRP_LUT4_AU; + im->mddrc.lut_table0_alternate_lower = CFG_MDDRCGRP_LUT0_AU; + im->mddrc.lut_table1_alternate_lower = CFG_MDDRCGRP_LUT1_AL; + im->mddrc.lut_table2_alternate_lower = CFG_MDDRCGRP_LUT2_AL; + im->mddrc.lut_table3_alternate_lower = CFG_MDDRCGRP_LUT3_AL; + im->mddrc.lut_table4_alternate_lower = CFG_MDDRCGRP_LUT4_AL; + + /* Initialize MDDRC */ + im->mddrc.ddr_sys_config = CFG_MDDRC_SYS_CFG; + im->mddrc.ddr_time_config0 = CFG_MDDRC_TIME_CFG0; + im->mddrc.ddr_time_config1 = CFG_MDDRC_TIME_CFG1; + im->mddrc.ddr_time_config2 = CFG_MDDRC_TIME_CFG2; + + /* Initialize DDR */ + for (i = 0; i < 10; i++) + im->mddrc.ddr_command = CFG_MICRON_NOP; + + im->mddrc.ddr_command = CFG_MICRON_PCHG_ALL; + im->mddrc.ddr_command = CFG_MICRON_EM2; + im->mddrc.ddr_command = CFG_MICRON_EM3; + im->mddrc.ddr_command = CFG_MICRON_EN_DLL; + im->mddrc.ddr_command = CFG_MICRON_RST_DLL; + im->mddrc.ddr_command = CFG_MICRON_PCHG_ALL; + im->mddrc.ddr_command = CFG_MICRON_RFSH; + im->mddrc.ddr_command = CFG_MICRON_INIT_DEV_OP; + im->mddrc.ddr_command = CFG_MICRON_OCD_DEFAULT; + im->mddrc.ddr_command = CFG_MICRON_OCD_EXIT; + + for (i = 0; i < 10; i++) + im->mddrc.ddr_command = CFG_MICRON_NOP; + + /* Start MDDRC */ + im->mddrc.ddr_time_config0 = CFG_MDDRC_TIME_CFG0_RUN; + im->mddrc.ddr_sys_config = CFG_MDDRC_SYS_CFG_RUN; + + return msize; +} + +int checkboard (void) +{ + ushort brd_rev = *(vu_short *) (CFG_CPLD_BASE + 0x00); + uchar cpld_rev = *(vu_char *) (CFG_CPLD_BASE + 0x02); + + printf ("Board: ADS5121 rev. 0x%04x (CPLD rev. 0x%02x)\n", + brd_rev, cpld_rev); + return 0; +} diff --git a/board/ads5121/config.mk b/board/ads5121/config.mk new file mode 100644 index 00000000000..14998f47506 --- /dev/null +++ b/board/ads5121/config.mk @@ -0,0 +1,23 @@ +# +# (C) Copyright 2007 DENX Software Engineering +# +# 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_BASE = 0xFFF00000 diff --git a/board/ads5121/u-boot.lds b/board/ads5121/u-boot.lds new file mode 100644 index 00000000000..038d8495531 --- /dev/null +++ b/board/ads5121/u-boot.lds @@ -0,0 +1,122 @@ +/* + * (C) Copyright 2007 DENX Software Engineering. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(powerpc) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + cpu/mpc512x/start.o (.text) + *(.text) + *(.fixup) + *(.got1) + . = ALIGN(16); + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + *(.eh_frame) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x0FFF) & 0xFFFFF000; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2; + __fixup_entries = (. - _FIXUP_TABLE_) >> 2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + + . = .; + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(4096); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(4096); + __init_end = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); +} +ENTRY(_start) diff --git a/cpu/mpc512x/Makefile b/cpu/mpc512x/Makefile new file mode 100644 index 00000000000..2be35b2bc62 --- /dev/null +++ b/cpu/mpc512x/Makefile @@ -0,0 +1,46 @@ +# +# (C) Copyright 2007 DENX Software Engineering +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(CPU).a + +START = start.o +COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o serial.o fec.o i2c.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/cpu/mpc512x/config.mk b/cpu/mpc512x/config.mk new file mode 100644 index 00000000000..8a07c5a3b67 --- /dev/null +++ b/cpu/mpc512x/config.mk @@ -0,0 +1,25 @@ +# +# (C) Copyright 2007 DENX Software Engineering +# +# 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 +# +PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi + +PLATFORM_CPPFLAGS += -DCONFIG_MPC512X -DCONFIG_E300 \ + -ffixed-r2 -ffixed-r29 -msoft-float -mcpu=603e diff --git a/cpu/mpc512x/cpu.c b/cpu/mpc512x/cpu.c new file mode 100644 index 00000000000..3be565ad034 --- /dev/null +++ b/cpu/mpc512x/cpu.c @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2004-2006 Freescale Semiconductor, Inc. + * (C) Copyright 2007 DENX Software Engineering + * + * 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 + */ + +/* + * CPU specific code for the MPC512x family. + * + * Derived from the MPC83xx code. + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int checkcpu (void) +{ + volatile immap_t *immr = (immap_t *) CFG_IMMR; + ulong clock = gd->cpu_clk; + u32 pvr = get_pvr (); + u32 spridr = immr->sysconf.spridr; + char buf[32]; + + puts("CPU: "); + + switch (spridr & 0xffff0000) { + case SPR_5121E: + puts ("MPC5121e "); + break; + default: + printf ("Unknown part ID %08x ", spridr & 0xffff0000); + } + printf ("rev. %d.%d, Core ", SVR_MJREV (spridr), SVR_MNREV (spridr)); + + switch (pvr & 0xffff0000) { + case PVR_E300C4: + puts ("e300c4 "); + break; + default: + puts ("unknown "); + } + printf ("at %s MHz, CSB at %3d MHz\n", strmhz(buf, clock), + gd->csb_clk / 1000000); + return 0; +} + + +int +do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + ulong msr; + volatile immap_t *immap = (immap_t *) CFG_IMMR; + + /* Interrupts and MMU off */ + __asm__ __volatile__ ("mfmsr %0":"=r" (msr):); + + msr &= ~( MSR_EE | MSR_IR | MSR_DR); + __asm__ __volatile__ ("mtmsr %0"::"r" (msr)); + + /* + * Enable Reset Control Reg - "RSTE" is the magic word that let us go + */ + immap->reset.rpr = 0x52535445; + + /* Verify Reset Control Reg is enabled */ + while (!((immap->reset.rcer) & RCER_CRE)) + ; + + printf ("Resetting the board.\n"); + udelay(200); + + /* Perform reset */ + immap->reset.rcr = RCR_SWHR; + + /* Unreached... */ + return 1; +} + + +/* + * Get timebase clock frequency (like cpu_clk in Hz) + */ +unsigned long get_tbclk (void) +{ + ulong tbclk; + + tbclk = (gd->bus_clk + 3L) / 4L; + + return tbclk; +} + + +#if defined(CONFIG_WATCHDOG) +void watchdog_reset (void) +{ + int re_enable = disable_interrupts (); + + /* Reset watchdog */ + volatile immap_t *immr = (immap_t *) CFG_IMMR; + immr->wdt.swsrr = 0x556c; + immr->wdt.swsrr = 0xaa39; + + if (re_enable) + enable_interrupts (); +} +#endif diff --git a/cpu/mpc512x/cpu_init.c b/cpu/mpc512x/cpu_init.c new file mode 100644 index 00000000000..566e08b0ddd --- /dev/null +++ b/cpu/mpc512x/cpu_init.c @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2004-2006 Freescale Semiconductor, Inc. + * (C) Copyright 2007 DENX Software Engineering + * + * 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 + * + * Derived from the MPC83xx code. + * + */ + +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Set up the memory map, initialize registers, + */ +void cpu_init_f (volatile immap_t * im) +{ + u32 ips_div; + + /* 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 */ + memset ((void *) gd, 0, sizeof (gd_t)); + + /* 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 + + /* RSR - Reset Status Register - clear all status */ + gd->reset_status = im->reset.rsr; + im->reset.rsr = ~(RSR_RES); + + /* + * RMR - Reset Mode Register - enable checkstop reset + */ + im->reset.rmr = (RMR_CSRE & (1 << RMR_CSRE_SHIFT)); + + /* Set IPS-CSB divider: IPS = 1/2 CSB */ + ips_div = im->clk.scfr[0]; + ips_div &= ~(SCFR1_IPS_DIV_MASK); + ips_div |= SCFR1_IPS_DIV << SCFR1_IPS_DIV_SHIFT; + im->clk.scfr[0] = ips_div; + + /* + * Enable Time Base/Decrementer + * + * NOTICE: TB needs to be enabled as early as possible in order to + * have udelay() working; if not enabled, usually leads to a hang, like + * during FLASH chip identification etc. + */ + im->sysconf.spcr |= SPCR_TBEN; +} + +int cpu_init_r (void) +{ + return 0; +} diff --git a/cpu/mpc512x/fec.c b/cpu/mpc512x/fec.c new file mode 100644 index 00000000000..f1b7a2563ed --- /dev/null +++ b/cpu/mpc512x/fec.c @@ -0,0 +1,801 @@ +/* + * (C) Copyright 2003-2007 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Derived from the MPC8xx FEC driver. + * Adapted for MPC512x by Grzegorz Bernacki + */ + +#include +#include +#include +#include +#include +#include "fec.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define DEBUG 0 + +#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) && \ + defined(CONFIG_MPC512x_FEC) + +#if !(defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)) +#error "CONFIG_MII has to be defined!" +#endif + +#if (DEBUG & 0x40) +static uint32 local_crc32(char *string, unsigned int crc_value, int len); +#endif + +int fec512x_miiphy_read(char *devname, uint8 phyAddr, uint8 regAddr, uint16 * retVal); +int fec512x_miiphy_write(char *devname, uint8 phyAddr, uint8 regAddr, uint16 data); +int mpc512x_fec_init_phy(struct eth_device *dev, bd_t * bis); + +/********************************************************************/ +#if (DEBUG & 0x2) +static void mpc512x_fec_phydump (char *devname) +{ + uint16 phyStatus, i; + uint8 phyAddr = CONFIG_PHY_ADDR; + uint8 reg_mask[] = { + /* regs to print: 0...8, 21,27,31 */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, + }; + + for (i = 0; i < 32; i++) { + if (reg_mask[i]) { + miiphy_read (devname, phyAddr, i, &phyStatus); + printf ("Mii reg %d: 0x%04x\n", i, phyStatus); + } + } +} +#endif + +/********************************************************************/ +static int mpc512x_fec_bd_init (mpc512x_fec_priv *fec) +{ + int ix; + + /* + * Receive BDs init + */ + for (ix = 0; ix < FEC_RBD_NUM; ix++) { + fec->bdBase->rbd[ix].dataPointer = (uint32)&fec->bdBase->recv_frames[ix]; + fec->bdBase->rbd[ix].status = FEC_RBD_EMPTY; + fec->bdBase->rbd[ix].dataLength = 0; + } + + /* + * have the last RBD to close the ring + */ + fec->bdBase->rbd[ix - 1].status |= FEC_RBD_WRAP; + fec->rbdIndex = 0; + + /* + * Trasmit BDs init + */ + for (ix = 0; ix < FEC_TBD_NUM; ix++) { + fec->bdBase->tbd[ix].status = 0; + } + + /* + * Have the last TBD to close the ring + */ + fec->bdBase->tbd[ix - 1].status |= FEC_TBD_WRAP; + + /* + * Initialize some indices + */ + fec->tbdIndex = 0; + fec->usedTbdIndex = 0; + fec->cleanTbdNum = FEC_TBD_NUM; + + return 0; +} + +/********************************************************************/ +static void mpc512x_fec_rbd_clean (mpc512x_fec_priv *fec, volatile FEC_RBD * pRbd) +{ + /* + * Reset buffer descriptor as empty + */ + if ((fec->rbdIndex) == (FEC_RBD_NUM - 1)) + pRbd->status = (FEC_RBD_WRAP | FEC_RBD_EMPTY); + else + pRbd->status = FEC_RBD_EMPTY; + + pRbd->dataLength = 0; + + /* + * Increment BD count + */ + fec->rbdIndex = (fec->rbdIndex + 1) % FEC_RBD_NUM; + + /* + * Now, we have an empty RxBD, notify FEC + */ + fec->eth->r_des_active = 0x01000000; /* Descriptor polling active */ +} + +/********************************************************************/ +static void mpc512x_fec_tbd_scrub (mpc512x_fec_priv *fec) +{ + volatile FEC_TBD *pUsedTbd; + +#if (DEBUG & 0x1) + printf ("tbd_scrub: fec->cleanTbdNum = %d, fec->usedTbdIndex = %d\n", + fec->cleanTbdNum, fec->usedTbdIndex); +#endif + + /* + * process all the consumed TBDs + */ + while (fec->cleanTbdNum < FEC_TBD_NUM) { + pUsedTbd = &fec->bdBase->tbd[fec->usedTbdIndex]; + if (pUsedTbd->status & FEC_TBD_READY) { +#if (DEBUG & 0x20) + printf ("Cannot clean TBD %d, in use\n", fec->usedTbdIndex); +#endif + return; + } + + /* + * clean this buffer descriptor + */ + if (fec->usedTbdIndex == (FEC_TBD_NUM - 1)) + pUsedTbd->status = FEC_TBD_WRAP; + else + pUsedTbd->status = 0; + + /* + * update some indeces for a correct handling of the TBD ring + */ + fec->cleanTbdNum++; + fec->usedTbdIndex = (fec->usedTbdIndex + 1) % FEC_TBD_NUM; + } +} + +/********************************************************************/ +static void mpc512x_fec_set_hwaddr (mpc512x_fec_priv *fec, char *mac) +{ + uint8 currByte; /* byte for which to compute the CRC */ + int byte; /* loop - counter */ + int bit; /* loop - counter */ + uint32 crc = 0xffffffff; /* initial value */ + + /* + * The algorithm used is the following: + * we loop on each of the six bytes of the provided address, + * and we compute the CRC by left-shifting the previous + * value by one position, so that each bit in the current + * byte of the address may contribute the calculation. If + * the latter and the MSB in the CRC are different, then + * the CRC value so computed is also ex-ored with the + * "polynomium generator". The current byte of the address + * is also shifted right by one bit at each iteration. + * This is because the CRC generatore in hardware is implemented + * as a shift-register with as many ex-ores as the radixes + * in the polynomium. This suggests that we represent the + * polynomiumm itself as a 32-bit constant. + */ + for (byte = 0; byte < 6; byte++) { + currByte = mac[byte]; + for (bit = 0; bit < 8; bit++) { + if ((currByte & 0x01) ^ (crc & 0x01)) { + crc >>= 1; + crc = crc ^ 0xedb88320; + } else { + crc >>= 1; + } + currByte >>= 1; + } + } + + crc = crc >> 26; + + /* + * Set individual hash table register + */ + if (crc >= 32) { + fec->eth->iaddr1 = (1 << (crc - 32)); + fec->eth->iaddr2 = 0; + } else { + fec->eth->iaddr1 = 0; + fec->eth->iaddr2 = (1 << crc); + } + + /* + * Set physical address + */ + fec->eth->paddr1 = (mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3]; + fec->eth->paddr2 = (mac[4] << 24) + (mac[5] << 16) + 0x8808; +} + +/********************************************************************/ +static int mpc512x_fec_init (struct eth_device *dev, bd_t * bis) +{ + mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv; + +#if (DEBUG & 0x1) + printf ("mpc512x_fec_init... Begin\n"); +#endif + + /* Set interrupt mask register */ + fec->eth->imask = 0x00000000; + + /* Clear FEC-Lite interrupt event register(IEVENT) */ + fec->eth->ievent = 0xffffffff; + + /* Set transmit fifo watermark register(X_WMRK), default = 64 */ + fec->eth->x_wmrk = 0x0; + + /* Set Opcode/Pause Duration Register */ + fec->eth->op_pause = 0x00010020; + + /* Frame length=1518; MII mode */ + fec->eth->r_cntrl = 0x05ee000c; + + /* Half-duplex, heartbeat disabled */ + fec->eth->x_cntrl = 0x00000000; + + /* Enable MIB counters */ + fec->eth->mib_control = 0x0; + + /* Setup recv fifo start and buff size */ + fec->eth->r_fstart = 0x500; + fec->eth->r_buff_size = 0x5e0; + + /* Setup BD base addresses */ + fec->eth->r_des_start = (uint32)fec->bdBase->rbd; + fec->eth->x_des_start = (uint32)fec->bdBase->tbd; + + /* DMA Control */ + fec->eth->dma_control = 0xc0000000; + + /* Enable FEC */ + fec->eth->ecntrl |= 0x00000006; + + /* Initilize addresses and status words of BDs */ + mpc512x_fec_bd_init (fec); + + /* Descriptor polling active */ + fec->eth->r_des_active = 0x01000000; + +#if (DEBUG & 0x1) + printf("mpc512x_fec_init... Done \n"); +#endif + return 1; +} + +/********************************************************************/ +int mpc512x_fec_init_phy (struct eth_device *dev, bd_t * bis) +{ + mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv; + const uint8 phyAddr = CONFIG_PHY_ADDR; /* Only one PHY */ + int timeout = 1; + uint16 phyStatus; + +#if (DEBUG & 0x1) + printf ("mpc512x_fec_init_phy... Begin\n"); +#endif + + /* + * Clear FEC-Lite interrupt event register(IEVENT) + */ + fec->eth->ievent = 0xffffffff; + + /* + * Set interrupt mask register + */ + fec->eth->imask = 0x00000000; + + if (fec->xcv_type != SEVENWIRE) { + /* + * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock + * and do not drop the Preamble. + */ + fec->eth->mii_speed = (((gd->ipb_clk / 1000000) / 5) + 1) << 1; + + /* + * Reset PHY, then delay 300ns + */ + miiphy_write (dev->name, phyAddr, 0x0, 0x8000); + udelay (1000); + + if (fec->xcv_type == MII10) { + /* + * Force 10Base-T, FDX operation + */ +#if (DEBUG & 0x2) + printf ("Forcing 10 Mbps ethernet link... "); +#endif + miiphy_read (dev->name, phyAddr, 0x1, &phyStatus); + + miiphy_write (dev->name, phyAddr, 0x0, 0x0180); + + timeout = 20; + do { /* wait for link status to go down */ + udelay (10000); + if ((timeout--) == 0) { +#if (DEBUG & 0x2) + printf ("hmmm, should not have waited..."); +#endif + break; + } + miiphy_read (dev->name, phyAddr, 0x1, &phyStatus); +#if (DEBUG & 0x2) + printf ("="); +#endif + } while ((phyStatus & 0x0004)); /* !link up */ + + timeout = 1000; + do { /* wait for link status to come back up */ + udelay (10000); + if ((timeout--) == 0) { + printf ("failed. Link is down.\n"); + break; + } + miiphy_read (dev->name, phyAddr, 0x1, &phyStatus); +#if (DEBUG & 0x2) + printf ("+"); +#endif + } while (!(phyStatus & 0x0004)); /* !link up */ + +#if (DEBUG & 0x2) + printf ("done.\n"); +#endif + } else { /* MII100 */ + /* + * Set the auto-negotiation advertisement register bits + */ + miiphy_write (dev->name, phyAddr, 0x4, 0x01e1); + + /* + * Set MDIO bit 0.12 = 1(&& bit 0.9=1?) to enable auto-negotiation + */ + miiphy_write (dev->name, phyAddr, 0x0, 0x1200); + + /* + * Wait for AN completion + */ + timeout = 50000; + do { + udelay (1000); + + if ((timeout--) == 0) { +#if (DEBUG & 0x2) + printf ("PHY auto neg 0 failed...\n"); +#endif + return -1; + } + + if (miiphy_read (dev->name, phyAddr, 0x1, &phyStatus) != 0) { +#if (DEBUG & 0x2) + printf ("PHY auto neg 1 failed 0x%04x...\n", phyStatus); +#endif + return -1; + } + } while (!(phyStatus & 0x0004)); + +#if (DEBUG & 0x2) + printf ("PHY auto neg complete! \n"); +#endif + } + } + +#if (DEBUG & 0x2) + if (fec->xcv_type != SEVENWIRE) + mpc512x_fec_phydump (dev->name); +#endif + +#if (DEBUG & 0x1) + printf ("mpc512x_fec_init_phy... Done \n"); +#endif + return 1; +} + +/********************************************************************/ +static void mpc512x_fec_halt (struct eth_device *dev) +{ + mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv; + int counter = 0xffff; + +#if (DEBUG & 0x2) + if (fec->xcv_type != SEVENWIRE) + mpc512x_fec_phydump (dev->name); +#endif + + /* + * mask FEC chip interrupts + */ + fec->eth->imask = 0; + + /* + * issue graceful stop command to the FEC transmitter if necessary + */ + fec->eth->x_cntrl |= 0x00000001; + + /* + * wait for graceful stop to register + */ + while ((counter--) && (!(fec->eth->ievent & 0x10000000))) ; + + /* + * Disable the Ethernet Controller + */ + fec->eth->ecntrl &= 0xfffffffd; + + /* + * Issue a reset command to the FEC chip + */ + fec->eth->ecntrl |= 0x1; + + /* + * wait at least 16 clock cycles + */ + udelay (10); +#if (DEBUG & 0x3) + printf ("Ethernet task stopped\n"); +#endif +} + +/********************************************************************/ + +static int mpc512x_fec_send (struct eth_device *dev, volatile void *eth_data, + int data_length) +{ + /* + * This routine transmits one frame. This routine only accepts + * 6-byte Ethernet addresses. + */ + mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv; + volatile FEC_TBD *pTbd; + +#if (DEBUG & 0x20) + printf("tbd status: 0x%04x\n", fec->tbdBase[fec->tbdIndex].status); +#endif + + /* + * Clear Tx BD ring at first + */ + mpc512x_fec_tbd_scrub (fec); + + /* + * Check for valid length of data. + */ + if ((data_length > 1500) || (data_length <= 0)) { + return -1; + } + + /* + * Check the number of vacant TxBDs. + */ + if (fec->cleanTbdNum < 1) { +#if (DEBUG & 0x20) + printf ("No available TxBDs ...\n"); +#endif + return -1; + } + + /* + * Get the first TxBD to send the mac header + */ + pTbd = &fec->bdBase->tbd[fec->tbdIndex]; + pTbd->dataLength = data_length; + pTbd->dataPointer = (uint32)eth_data; + pTbd->status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY; + fec->tbdIndex = (fec->tbdIndex + 1) % FEC_TBD_NUM; + + /* Activate transmit Buffer Descriptor polling */ + fec->eth->x_des_active = 0x01000000; /* Descriptor polling active */ + +#if (DEBUG & 0x8) + printf ( "+" ); +#endif + + fec->cleanTbdNum -= 1; + + /* + * wait until frame is sent . + */ + while (pTbd->status & FEC_TBD_READY) { + udelay (10); +#if (DEBUG & 0x8) + printf ("TDB status = %04x\n", pTbd->status); +#endif + } + + return 0; +} + + +/********************************************************************/ +static int mpc512x_fec_recv (struct eth_device *dev) +{ + /* + * This command pulls one frame from the card + */ + mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv; + volatile FEC_RBD *pRbd = &fec->bdBase->rbd[fec->rbdIndex]; + unsigned long ievent; + int frame_length, len = 0; + uchar buff[FEC_MAX_PKT_SIZE]; + +#if (DEBUG & 0x1) + printf ("mpc512x_fec_recv %d Start...\n", fec->rbdIndex); +#endif +#if (DEBUG & 0x8) + printf( "-" ); +#endif + + /* + * Check if any critical events have happened + */ + ievent = fec->eth->ievent; + fec->eth->ievent = ievent; + if (ievent & 0x20060000) { + /* BABT, Rx/Tx FIFO errors */ + mpc512x_fec_halt (dev); + mpc512x_fec_init (dev, NULL); + return 0; + } + if (ievent & 0x80000000) { + /* Heartbeat error */ + fec->eth->x_cntrl |= 0x00000001; + } + if (ievent & 0x10000000) { + /* Graceful stop complete */ + if (fec->eth->x_cntrl & 0x00000001) { + mpc512x_fec_halt (dev); + fec->eth->x_cntrl &= ~0x00000001; + mpc512x_fec_init (dev, NULL); + } + } + + if (!(pRbd->status & FEC_RBD_EMPTY)) { + if ((pRbd->status & FEC_RBD_LAST) && + !(pRbd->status & FEC_RBD_ERR) && + ((pRbd->dataLength - 4) > 14)) { + + /* + * Get buffer size + */ + frame_length = pRbd->dataLength - 4; + +#if (DEBUG & 0x20) + { + int i; + printf ("recv data hdr:"); + for (i = 0; i < 14; i++) + printf ("%x ", *((uint8*)pRbd->dataPointer + i)); + printf("\n"); + } +#endif + + /* + * Fill the buffer and pass it to upper layers + */ + memcpy (buff, (void*)pRbd->dataPointer, frame_length); + NetReceive ((uchar*)buff, frame_length); + len = frame_length; + } + + /* + * Reset buffer descriptor as empty + */ + mpc512x_fec_rbd_clean (fec, pRbd); + } + + /* Try to fill Buffer Descriptors */ + fec->eth->r_des_active = 0x01000000; /* Descriptor polling active */ + return len; +} + +/********************************************************************/ +int mpc512x_fec_initialize (bd_t * bis) +{ + + immap_t *im = (immap_t*) CFG_IMMR; + mpc512x_fec_priv *fec; + struct eth_device *dev; + int i; + char *tmp, *end, env_enetaddr[6]; + uint32 *reg; + void * bd; + + fec = (mpc512x_fec_priv *) malloc (sizeof(*fec)); + dev = (struct eth_device *) malloc (sizeof(*dev)); + memset (dev, 0, sizeof *dev); + + fec->eth = (ethernet_regs *) MPC512X_FEC; + +# ifndef CONFIG_FEC_10MBIT + fec->xcv_type = MII100; +# else + fec->xcv_type = MII10; +# endif + dev->priv = (void *)fec; + dev->iobase = MPC512X_FEC; + dev->init = mpc512x_fec_init; + dev->halt = mpc512x_fec_halt; + dev->send = mpc512x_fec_send; + dev->recv = mpc512x_fec_recv; + + sprintf (dev->name, "FEC ETHERNET"); + eth_register (dev); + +#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) + miiphy_register (dev->name, + fec512x_miiphy_read, fec512x_miiphy_write); +#endif + + /* + * Initialize I\O pins + */ + reg = (uint32 *) &(im->io_ctrl.regs[PSC0_0_IDX]); + + for (i = 0; i < 15; i++) + reg[i] = IOCTRL_MUX_FEC | 0x00000001; + + im->io_ctrl.regs[SPDIF_TXCLOCK_IDX] = IOCTRL_MUX_FEC | 0x00000001; + im->io_ctrl.regs[SPDIF_TX_IDX] = IOCTRL_MUX_FEC | 0x00000001; + im->io_ctrl.regs[SPDIF_RX_IDX] = IOCTRL_MUX_FEC | 0x00000001; + + /* Clean up space FEC's MIB and FIFO RAM ...*/ + memset ((void *) MPC512X_FEC + 0x200, 0x00, 0x400); + + /* + * Malloc space for BDs (must be quad word-aligned) + * this pointer is lost, so cannot be freed + */ + bd = malloc (sizeof(mpc512x_buff_descs) + 0x1f); + fec->bdBase = (mpc512x_buff_descs*)((uint32)bd & 0xfffffff0); + memset ((void *) bd, 0x00, sizeof(mpc512x_buff_descs) + 0x1f); + + /* + * Set interrupt mask register + */ + fec->eth->imask = 0x00000000; + + /* + * Clear FEC-Lite interrupt event register(IEVENT) + */ + fec->eth->ievent = 0xffffffff; + + /* + * Try to set the mac address now. The fec mac address is + * a garbage after reset. When not using fec for booting + * the Linux fec driver will try to work with this garbage. + */ + tmp = getenv ("ethaddr"); + if (tmp) { + for (i=0; i<6; i++) { + env_enetaddr[i] = tmp ? simple_strtoul (tmp, &end, 16) : 0; + if (tmp) + tmp = (*end) ? end+1 : end; + } + mpc512x_fec_set_hwaddr (fec, env_enetaddr); + fec->eth->gaddr1 = 0x00000000; + fec->eth->gaddr2 = 0x00000000; + } + + mpc512x_fec_init_phy (dev, bis); + + return 1; +} + +/* MII-interface related functions */ +/********************************************************************/ +int fec512x_miiphy_read (char *devname, uint8 phyAddr, uint8 regAddr, uint16 * retVal) +{ + ethernet_regs *eth = (ethernet_regs *) MPC512X_FEC; + uint32 reg; /* convenient holder for the PHY register */ + uint32 phy; /* convenient holder for the PHY */ + int timeout = 0xffff; + + /* + * reading from any PHY's register is done by properly + * programming the FEC's MII data register. + */ + reg = regAddr << FEC_MII_DATA_RA_SHIFT; + phy = phyAddr << FEC_MII_DATA_PA_SHIFT; + + eth->mii_data = (FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD | FEC_MII_DATA_TA | phy | reg); + + /* + * wait for the related interrupt + */ + while ((timeout--) && (!(eth->ievent & 0x00800000))) ; + + if (timeout == 0) { +#if (DEBUG & 0x2) + printf ("Read MDIO failed...\n"); +#endif + return -1; + } + + /* + * clear mii interrupt bit + */ + eth->ievent = 0x00800000; + + /* + * it's now safe to read the PHY's register + */ + *retVal = (uint16) eth->mii_data; + + return 0; +} + +/********************************************************************/ +int fec512x_miiphy_write (char *devname, uint8 phyAddr, uint8 regAddr, uint16 data) +{ + ethernet_regs *eth = (ethernet_regs *) MPC512X_FEC; + uint32 reg; /* convenient holder for the PHY register */ + uint32 phy; /* convenient holder for the PHY */ + int timeout = 0xffff; + + reg = regAddr << FEC_MII_DATA_RA_SHIFT; + phy = phyAddr << FEC_MII_DATA_PA_SHIFT; + + eth->mii_data = (FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR | + FEC_MII_DATA_TA | phy | reg | data); + + /* + * wait for the MII interrupt + */ + while ((timeout--) && (!(eth->ievent & 0x00800000))) ; + + if (timeout == 0) { +#if (DEBUG & 0x2) + printf ("Write MDIO failed...\n"); +#endif + return -1; + } + + /* + * clear MII interrupt bit + */ + eth->ievent = 0x00800000; + + return 0; +} + +#if (DEBUG & 0x40) +static uint32 local_crc32 (char *string, unsigned int crc_value, int len) +{ + int i; + char c; + unsigned int crc, count; + + /* + * crc32 algorithm + */ + /* + * crc = 0xffffffff; * The initialized value should be 0xffffffff + */ + crc = crc_value; + + for (i = len; --i >= 0;) { + c = *string++; + for (count = 0; count < 8; count++) { + if ((c & 0x01) ^ (crc & 0x01)) { + crc >>= 1; + crc = crc ^ 0xedb88320; + } else { + crc >>= 1; + } + c >>= 1; + } + } + + /* + * In big endian system, do byte swaping for crc value + */ + /**/ return crc; +} +#endif /* DEBUG */ + +#endif /* CONFIG_MPC512x_FEC */ diff --git a/cpu/mpc512x/fec.h b/cpu/mpc512x/fec.h new file mode 100644 index 00000000000..71459197a51 --- /dev/null +++ b/cpu/mpc512x/fec.h @@ -0,0 +1,224 @@ +/* + * (C) Copyright 2003 - 2007 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Derived from the MPC8xx driver's header file. + */ + +#ifndef __MPC512X_FEC_H +#define __MPC512X_FEC_H + +#include +#include + +typedef unsigned long uint32; +typedef unsigned short uint16; +typedef unsigned char uint8; + +typedef struct ethernet_register_set { + +/* [10:2]addr = 00 */ + +/* Control and status Registers (offset 000-1FF) */ + + volatile uint32 fec_id; /* MBAR_ETH + 0x000 */ + volatile uint32 ievent; /* MBAR_ETH + 0x004 */ + volatile uint32 imask; /* MBAR_ETH + 0x008 */ + + volatile uint32 RES0[1]; /* MBAR_ETH + 0x00C */ + volatile uint32 r_des_active; /* MBAR_ETH + 0x010 */ + volatile uint32 x_des_active; /* MBAR_ETH + 0x014 */ + + volatile uint32 RES1[3]; /* MBAR_ETH + 0x018-020 */ + volatile uint32 ecntrl; /* MBAR_ETH + 0x024 */ + + volatile uint32 RES2[6]; /* MBAR_ETH + 0x028-03C */ + volatile uint32 mii_data; /* MBAR_ETH + 0x040 */ + volatile uint32 mii_speed; /* MBAR_ETH + 0x044 */ + + volatile uint32 RES3[7]; /* MBAR_ETH + 0x048-060 */ + volatile uint32 mib_control; /* MBAR_ETH + 0x064 */ + + volatile uint32 RES4[7]; /* MBAR_ETH + 0x068-80 */ + volatile uint32 r_cntrl; /* MBAR_ETH + 0x084 */ + volatile uint32 r_hash; /* MBAR_ETH + 0x088 */ + + volatile uint32 RES5[14]; /* MBAR_ETH + 0x08c-0C0 */ + volatile uint32 x_cntrl; /* MBAR_ETH + 0x0C4 */ + + volatile uint32 RES6[7]; /* MBAR_ETH + 0x0C8-0E0 */ + volatile uint32 paddr1; /* MBAR_ETH + 0x0E4 */ + volatile uint32 paddr2; /* MBAR_ETH + 0x0E8 */ + volatile uint32 op_pause; /* MBAR_ETH + 0x0EC */ + + volatile uint32 RES7[10]; /* MBAR_ETH + 0x0F0-114 */ + volatile uint32 iaddr1; /* MBAR_ETH + 0x118 */ + volatile uint32 iaddr2; /* MBAR_ETH + 0x11C */ + volatile uint32 gaddr1; /* MBAR_ETH + 0x120 */ + volatile uint32 gaddr2; /* MBAR_ETH + 0x124 */ + + volatile uint32 RES8[6]; /* MBAR_ETH + 0x128-13C */ + volatile uint32 fifo_id; /* MBAR_ETH + 0x140 */ + volatile uint32 x_wmrk; /* MBAR_ETH + 0x144 */ + volatile uint32 RES9[1]; /* MBAR_ETH + 0x148 */ + volatile uint32 r_bound; /* MBAR_ETH + 0x14C */ + volatile uint32 r_fstart; /* MBAR_ETH + 0x150 */ + + volatile uint32 RES10[11]; /* MBAR_ETH + 0x154-17C */ + volatile uint32 r_des_start; /* MBAR_ETH + 0x180 */ + volatile uint32 x_des_start; /* MBAR_ETH + 0x184 */ + volatile uint32 r_buff_size; /* MBAR_ETH + 0x188 */ + volatile uint32 RES11[26]; /* MBAR_ETH + 0x18C-1F0 */ + volatile uint32 dma_control; /* MBAR_ETH + 0x1F4 */ + volatile uint32 RES12[2]; /* MBAR_ETH + 0x1F8-1FC */ + +/* MIB COUNTERS (Offset 200-2FF) */ + + volatile uint32 rmon_t_drop; /* MBAR_ETH + 0x200 */ + volatile uint32 rmon_t_packets; /* MBAR_ETH + 0x204 */ + volatile uint32 rmon_t_bc_pkt; /* MBAR_ETH + 0x208 */ + volatile uint32 rmon_t_mc_pkt; /* MBAR_ETH + 0x20C */ + volatile uint32 rmon_t_crc_align; /* MBAR_ETH + 0x210 */ + volatile uint32 rmon_t_undersize; /* MBAR_ETH + 0x214 */ + volatile uint32 rmon_t_oversize; /* MBAR_ETH + 0x218 */ + volatile uint32 rmon_t_frag; /* MBAR_ETH + 0x21C */ + volatile uint32 rmon_t_jab; /* MBAR_ETH + 0x220 */ + volatile uint32 rmon_t_col; /* MBAR_ETH + 0x224 */ + volatile uint32 rmon_t_p64; /* MBAR_ETH + 0x228 */ + volatile uint32 rmon_t_p65to127; /* MBAR_ETH + 0x22C */ + volatile uint32 rmon_t_p128to255; /* MBAR_ETH + 0x230 */ + volatile uint32 rmon_t_p256to511; /* MBAR_ETH + 0x234 */ + volatile uint32 rmon_t_p512to1023; /* MBAR_ETH + 0x238 */ + volatile uint32 rmon_t_p1024to2047; /* MBAR_ETH + 0x23C */ + volatile uint32 rmon_t_p_gte2048; /* MBAR_ETH + 0x240 */ + volatile uint32 rmon_t_octets; /* MBAR_ETH + 0x244 */ + volatile uint32 ieee_t_drop; /* MBAR_ETH + 0x248 */ + volatile uint32 ieee_t_frame_ok; /* MBAR_ETH + 0x24C */ + volatile uint32 ieee_t_1col; /* MBAR_ETH + 0x250 */ + volatile uint32 ieee_t_mcol; /* MBAR_ETH + 0x254 */ + volatile uint32 ieee_t_def; /* MBAR_ETH + 0x258 */ + volatile uint32 ieee_t_lcol; /* MBAR_ETH + 0x25C */ + volatile uint32 ieee_t_excol; /* MBAR_ETH + 0x260 */ + volatile uint32 ieee_t_macerr; /* MBAR_ETH + 0x264 */ + volatile uint32 ieee_t_cserr; /* MBAR_ETH + 0x268 */ + volatile uint32 ieee_t_sqe; /* MBAR_ETH + 0x26C */ + volatile uint32 t_fdxfc; /* MBAR_ETH + 0x270 */ + volatile uint32 ieee_t_octets_ok; /* MBAR_ETH + 0x274 */ + + volatile uint32 RES13[2]; /* MBAR_ETH + 0x278-27C */ + volatile uint32 rmon_r_drop; /* MBAR_ETH + 0x280 */ + volatile uint32 rmon_r_packets; /* MBAR_ETH + 0x284 */ + volatile uint32 rmon_r_bc_pkt; /* MBAR_ETH + 0x288 */ + volatile uint32 rmon_r_mc_pkt; /* MBAR_ETH + 0x28C */ + volatile uint32 rmon_r_crc_align; /* MBAR_ETH + 0x290 */ + volatile uint32 rmon_r_undersize; /* MBAR_ETH + 0x294 */ + volatile uint32 rmon_r_oversize; /* MBAR_ETH + 0x298 */ + volatile uint32 rmon_r_frag; /* MBAR_ETH + 0x29C */ + volatile uint32 rmon_r_jab; /* MBAR_ETH + 0x2A0 */ + + volatile uint32 rmon_r_resvd_0; /* MBAR_ETH + 0x2A4 */ + + volatile uint32 rmon_r_p64; /* MBAR_ETH + 0x2A8 */ + volatile uint32 rmon_r_p65to127; /* MBAR_ETH + 0x2AC */ + volatile uint32 rmon_r_p128to255; /* MBAR_ETH + 0x2B0 */ + volatile uint32 rmon_r_p256to511; /* MBAR_ETH + 0x2B4 */ + volatile uint32 rmon_r_p512to1023; /* MBAR_ETH + 0x2B8 */ + volatile uint32 rmon_r_p1024to2047; /* MBAR_ETH + 0x2BC */ + volatile uint32 rmon_r_p_gte2048; /* MBAR_ETH + 0x2C0 */ + volatile uint32 rmon_r_octets; /* MBAR_ETH + 0x2C4 */ + volatile uint32 ieee_r_drop; /* MBAR_ETH + 0x2C8 */ + volatile uint32 ieee_r_frame_ok; /* MBAR_ETH + 0x2CC */ + volatile uint32 ieee_r_crc; /* MBAR_ETH + 0x2D0 */ + volatile uint32 ieee_r_align; /* MBAR_ETH + 0x2D4 */ + volatile uint32 r_macerr; /* MBAR_ETH + 0x2D8 */ + volatile uint32 r_fdxfc; /* MBAR_ETH + 0x2DC */ + volatile uint32 ieee_r_octets_ok; /* MBAR_ETH + 0x2E0 */ + + volatile uint32 RES14[6]; /* MBAR_ETH + 0x2E4-2FC */ + + volatile uint32 RES15[64]; /* MBAR_ETH + 0x300-3FF */ +} ethernet_regs; + +/* Receive & Transmit Buffer Descriptor definitions */ +typedef struct BufferDescriptor { + uint16 status; + uint16 dataLength; + uint32 dataPointer; +} FEC_RBD; + +typedef struct { + uint16 status; + uint16 dataLength; + uint32 dataPointer; +} FEC_TBD; + +/* private structure */ +typedef enum { + SEVENWIRE, /* 7-wire */ + MII10, /* MII 10Mbps */ + MII100 /* MII 100Mbps */ +} xceiver_type; + +/* BD Numer definitions */ +#define FEC_TBD_NUM 48 /* The user can adjust this value */ +#define FEC_RBD_NUM 32 /* The user can adjust this value */ + +/* packet size limit */ +#define FEC_MAX_PKT_SIZE 1536 + +typedef struct { + uint8 frame[FEC_MAX_PKT_SIZE]; +} mpc512x_frame; + +typedef struct { + FEC_RBD rbd[FEC_RBD_NUM]; /* RBD ring */ + FEC_TBD tbd[FEC_TBD_NUM]; /* TBD ring */ + mpc512x_frame recv_frames[FEC_RBD_NUM]; /* receive buff */ +} mpc512x_buff_descs; + +typedef struct { + ethernet_regs *eth; + xceiver_type xcv_type; /* transceiver type */ + mpc512x_buff_descs *bdBase; /* BD rings and recv buffer */ + uint16 rbdIndex; /* next receive BD to read */ + uint16 tbdIndex; /* next transmit BD to send */ + uint16 usedTbdIndex; /* next transmit BD to clean */ + uint16 cleanTbdNum; /* the number of available transmit BDs */ +} mpc512x_fec_priv; + +/* RBD bits definitions */ +#define FEC_RBD_EMPTY 0x8000 /* Buffer is empty */ +#define FEC_RBD_WRAP 0x2000 /* Last BD in ring */ +#define FEC_RBD_LAST 0x0800 /* Buffer is last in frame(useless) */ +#define FEC_RBD_MISS 0x0100 /* Miss bit for prom mode */ +#define FEC_RBD_BC 0x0080 /* The received frame is broadcast frame */ +#define FEC_RBD_MC 0x0040 /* The received frame is multicast frame */ +#define FEC_RBD_LG 0x0020 /* Frame length violation */ +#define FEC_RBD_NO 0x0010 /* Nonoctet align frame */ +#define FEC_RBD_SH 0x0008 /* Short frame */ +#define FEC_RBD_CR 0x0004 /* CRC error */ +#define FEC_RBD_OV 0x0002 /* Receive FIFO overrun */ +#define FEC_RBD_TR 0x0001 /* Frame is truncated */ +#define FEC_RBD_ERR (FEC_RBD_LG | FEC_RBD_NO | FEC_RBD_CR | \ + FEC_RBD_OV | FEC_RBD_TR) + +/* TBD bits definitions */ +#define FEC_TBD_READY 0x8000 /* Buffer is ready */ +#define FEC_TBD_WRAP 0x2000 /* Last BD in ring */ +#define FEC_TBD_LAST 0x0800 /* Buffer is last in frame */ +#define FEC_TBD_TC 0x0400 /* Transmit the CRC */ +#define FEC_TBD_ABC 0x0200 /* Append bad CRC */ + +/* MII-related definitios */ +#define FEC_MII_DATA_ST 0x40000000 /* Start of frame delimiter */ +#define FEC_MII_DATA_OP_RD 0x20000000 /* Perform a read operation */ +#define FEC_MII_DATA_OP_WR 0x10000000 /* Perform a write operation */ +#define FEC_MII_DATA_PA_MSK 0x0f800000 /* PHY Address field mask */ +#define FEC_MII_DATA_RA_MSK 0x007c0000 /* PHY Register field mask */ +#define FEC_MII_DATA_TA 0x00020000 /* Turnaround */ +#define FEC_MII_DATA_DATAMSK 0x0000ffff /* PHY data field */ + +#define FEC_MII_DATA_RA_SHIFT 18 /* MII Register address bits */ +#define FEC_MII_DATA_PA_SHIFT 23 /* MII PHY address bits */ + +#endif /* __MPC512X_FEC_H */ diff --git a/cpu/mpc512x/i2c.c b/cpu/mpc512x/i2c.c new file mode 100644 index 00000000000..00e28d6404d --- /dev/null +++ b/cpu/mpc512x/i2c.c @@ -0,0 +1,431 @@ +/* + * (C) Copyright 2003 - 2007 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Based on the MPC5xxx code. + */ + +#include + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_HARD_I2C + +#include +#include + +#define immr ((immap_t *)CFG_IMMR) + +/* by default set I2C bus 0 active */ +static unsigned int bus_num = 0; + +#define I2C_TIMEOUT 100 +#define I2C_RETRIES 3 + +struct mpc512x_i2c_tap { + int scl2tap; + int tap2tap; +}; + +static int mpc_reg_in(volatile u32 *reg); +static void mpc_reg_out(volatile u32 *reg, int val, int mask); +static int wait_for_bb(void); +static int wait_for_pin(int *status); +static int do_address(uchar chip, char rdwr_flag); +static int send_bytes(uchar chip, char *buf, int len); +static int receive_bytes(uchar chip, char *buf, int len); +static int mpc_get_fdr(int); + +static int mpc_reg_in (volatile u32 *reg) +{ + int ret = *reg >> 24; + __asm__ __volatile__ ("eieio"); + return ret; +} + +static void mpc_reg_out (volatile u32 *reg, int val, int mask) +{ + int tmp; + + if (!mask) { + *reg = val << 24; + } else { + tmp = mpc_reg_in (reg); + *reg = ((tmp & ~mask) | (val & mask)) << 24; + } + __asm__ __volatile__ ("eieio"); + + return; +} + +static int wait_for_bb (void) +{ + i2c512x_dev_t *regs = &immr->i2c.dev[bus_num]; + int timeout = I2C_TIMEOUT; + int status; + + status = mpc_reg_in (®s->msr); + + while (timeout-- && (status & I2C_BB)) { + volatile int temp; + mpc_reg_out (®s->mcr, I2C_STA, I2C_STA); + temp = mpc_reg_in (®s->mdr); + mpc_reg_out (®s->mcr, 0, I2C_STA); + mpc_reg_out (®s->mcr, 0, 0); + mpc_reg_out (®s->mcr, I2C_EN, 0); + + udelay (1000); + status = mpc_reg_in (®s->msr); + } + + return (status & I2C_BB); +} + +static int wait_for_pin (int *status) +{ + i2c512x_dev_t *regs = &immr->i2c.dev[bus_num]; + int timeout = I2C_TIMEOUT; + + *status = mpc_reg_in (®s->msr); + + while (timeout-- && !(*status & I2C_IF)) { + udelay (1000); + *status = mpc_reg_in (®s->msr); + } + + if (!(*status & I2C_IF)) { + return -1; + } + + mpc_reg_out (®s->msr, 0, I2C_IF); + + return 0; +} + +static int do_address (uchar chip, char rdwr_flag) +{ + i2c512x_dev_t *regs = &immr->i2c.dev[bus_num]; + int status; + + chip <<= 1; + + if (rdwr_flag) { + chip |= 1; + } + + mpc_reg_out (®s->mcr, I2C_TX, I2C_TX); + mpc_reg_out (®s->mdr, chip, 0); + + if (wait_for_pin (&status)) { + return -2; + } + + if (status & I2C_RXAK) { + return -3; + } + + return 0; +} + +static int send_bytes (uchar chip, char *buf, int len) +{ + i2c512x_dev_t *regs = &immr->i2c.dev[bus_num]; + int wrcount; + int status; + + for (wrcount = 0; wrcount < len; ++wrcount) { + + mpc_reg_out (®s->mdr, buf[wrcount], 0); + + if (wait_for_pin (&status)) { + break; + } + + if (status & I2C_RXAK) { + break; + } + + } + + return !(wrcount == len); +} + +static int receive_bytes (uchar chip, char *buf, int len) +{ + i2c512x_dev_t *regs = &immr->i2c.dev[bus_num]; + int dummy = 1; + int rdcount = 0; + int status; + int i; + + mpc_reg_out (®s->mcr, 0, I2C_TX); + + for (i = 0; i < len; ++i) { + buf[rdcount] = mpc_reg_in (®s->mdr); + + if (dummy) { + dummy = 0; + } else { + rdcount++; + } + + if (wait_for_pin (&status)) { + return -4; + } + } + + mpc_reg_out (®s->mcr, I2C_TXAK, I2C_TXAK); + buf[rdcount++] = mpc_reg_in (®s->mdr); + + if (wait_for_pin (&status)) { + return -5; + } + + mpc_reg_out (®s->mcr, 0, I2C_TXAK); + + return 0; +} + +/**************** I2C API ****************/ + +void i2c_init (int speed, int saddr) +{ + int i; + for(i = 0; i < I2C_BUS_CNT; i++){ + i2c512x_dev_t *regs = &immr->i2c.dev[i]; + mpc_reg_out (®s->mcr, 0, 0); + + /* Set clock */ + mpc_reg_out (®s->mfdr, mpc_get_fdr (speed), 0); + mpc_reg_out (®s->madr, saddr << 1, 0); + + /* Enable module */ + mpc_reg_out (®s->mcr, I2C_EN, I2C_INIT_MASK); + mpc_reg_out (®s->msr, 0, I2C_IF); + } + + /* Disable interrupts */ + immr->i2c.icr = 0; + /* Turn off filters */ + immr->i2c.mifr = 0; + return; +} + +static int mpc_get_fdr (int speed) +{ + static int fdr = -1; + + if (fdr == -1) { + ulong best_speed = 0; + ulong divider; + ulong ipb, scl; + ulong bestmatch = 0xffffffffUL; + int best_i = 0, best_j = 0, i, j; + int SCL_Tap[] = { 9, 10, 12, 15, 5, 6, 7, 8}; + struct mpc512x_i2c_tap scltap[] = { + {4, 1}, + {4, 2}, + {6, 4}, + {6, 8}, + {14, 16}, + {30, 32}, + {62, 64}, + {126, 128} + }; + + ipb = gd->ipb_clk; + for (i = 7; i >= 0; i--) { + for (j = 7; j >= 0; j--) { + scl = 2 * (scltap[j].scl2tap + + (SCL_Tap[i] - 1) * scltap[j].tap2tap + + 2); + if (ipb <= speed*scl) { + if ((speed*scl - ipb) < bestmatch) { + bestmatch = speed*scl - ipb; + best_i = i; + best_j = j; + best_speed = ipb/scl; + } + } + } + } + divider = (best_i & 3) | ((best_i & 4) << 3) | (best_j << 2); + if (gd->flags & GD_FLG_RELOC) { + fdr = divider; + } else { + debug("%ld kHz, \n", best_speed / 1000); + return divider; + } + } + + return fdr; +} + +int i2c_probe (uchar chip) +{ + i2c512x_dev_t *regs = &immr->i2c.dev[bus_num]; + int i; + + for (i = 0; i < I2C_RETRIES; i++) { + mpc_reg_out (®s->mcr, I2C_STA, I2C_STA); + + if (! do_address (chip, 0)) { + mpc_reg_out (®s->mcr, 0, I2C_STA); + udelay (500); + break; + } + + mpc_reg_out (®s->mcr, 0, I2C_STA); + udelay (500); + } + + return (i == I2C_RETRIES); +} + +int i2c_read (uchar chip, uint addr, int alen, uchar *buf, int len) +{ + char xaddr[4]; + i2c512x_dev_t *regs = &immr->i2c.dev[bus_num]; + int ret = -1; + + xaddr[0] = (addr >> 24) & 0xFF; + xaddr[1] = (addr >> 16) & 0xFF; + xaddr[2] = (addr >> 8) & 0xFF; + xaddr[3] = addr & 0xFF; + + if (wait_for_bb ()) { + printf ("i2c_read: bus is busy\n"); + goto Done; + } + + mpc_reg_out (®s->mcr, I2C_STA, I2C_STA); + if (do_address (chip, 0)) { + printf ("i2c_read: failed to address chip\n"); + goto Done; + } + + if (send_bytes (chip, &xaddr[4-alen], alen)) { + printf ("i2c_read: send_bytes failed\n"); + goto Done; + } + + mpc_reg_out (®s->mcr, I2C_RSTA, I2C_RSTA); + if (do_address (chip, 1)) { + printf ("i2c_read: failed to address chip\n"); + goto Done; + } + + if (receive_bytes (chip, (char *)buf, len)) { + printf ("i2c_read: receive_bytes failed\n"); + goto Done; + } + + ret = 0; +Done: + mpc_reg_out (®s->mcr, 0, I2C_STA); + return ret; +} + +int i2c_write (uchar chip, uint addr, int alen, uchar *buf, int len) +{ + char xaddr[4]; + i2c512x_dev_t *regs = &immr->i2c.dev[bus_num]; + int ret = -1; + + xaddr[0] = (addr >> 24) & 0xFF; + xaddr[1] = (addr >> 16) & 0xFF; + xaddr[2] = (addr >> 8) & 0xFF; + xaddr[3] = addr & 0xFF; + + if (wait_for_bb ()) { + printf ("i2c_write: bus is busy\n"); + goto Done; + } + + mpc_reg_out (®s->mcr, I2C_STA, I2C_STA); + if (do_address (chip, 0)) { + printf ("i2c_write: failed to address chip\n"); + goto Done; + } + + if (send_bytes (chip, &xaddr[4-alen], alen)) { + printf ("i2c_write: send_bytes failed\n"); + goto Done; + } + + if (send_bytes (chip, (char *)buf, len)) { + printf ("i2c_write: send_bytes failed\n"); + goto Done; + } + + ret = 0; +Done: + mpc_reg_out (®s->mcr, 0, I2C_STA); + return ret; +} + +uchar i2c_reg_read (uchar chip, uchar reg) +{ + uchar buf; + + i2c_read (chip, reg, 1, &buf, 1); + + return buf; +} + +void i2c_reg_write (uchar chip, uchar reg, uchar val) +{ + i2c_write (chip, reg, 1, &val, 1); + + return; +} + + +int i2c_set_bus_num (unsigned int bus) +{ + if (bus >= I2C_BUS_CNT) { + return -1; + } + bus_num = bus; + + return 0; +} + +unsigned int i2c_get_bus_num (void) +{ + return bus_num; +} + +/* TODO */ +unsigned int i2c_get_bus_speed (void) +{ + return -1; +} + +int i2c_set_bus_speed (unsigned int speed) +{ + if (speed != CFG_I2C_SPEED) + return -1; + + return 0; +} + +#endif /* CONFIG_HARD_I2C */ diff --git a/cpu/mpc512x/interrupts.c b/cpu/mpc512x/interrupts.c new file mode 100644 index 00000000000..8cc241c8998 --- /dev/null +++ b/cpu/mpc512x/interrupts.c @@ -0,0 +1,61 @@ +/* + * (C) Copyright 2000-2007 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright 2004 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 + * + * Derived from the MPC83xx code. + */ + +#include + +DECLARE_GLOBAL_DATA_PTR; + +struct irq_action { + interrupt_handler_t *handler; + void *arg; + ulong count; +}; + +int interrupt_init_cpu (unsigned *decrementer_count) +{ + *decrementer_count = get_tbclk () / CFG_HZ; + + return 0; +} + +/* + * Install and free an interrupt handler. + */ +void +irq_install_handler (int irq, interrupt_handler_t * handler, void *arg) +{ +} + +void irq_free_handler (int irq) +{ +} + +void timer_interrupt_cpu (struct pt_regs *regs) +{ + /* nothing to do here */ + return; +} diff --git a/cpu/mpc512x/serial.c b/cpu/mpc512x/serial.c new file mode 100644 index 00000000000..200ff2c4964 --- /dev/null +++ b/cpu/mpc512x/serial.c @@ -0,0 +1,197 @@ +/* + * (C) Copyright 2000 - 2007 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Based ont the MPC5200 PSC driver. + * Adapted for MPC512x by Jan Wrobel + */ + +/* + * Minimal serial functions needed to use one of the PSC ports + * as serial console interface. + */ + +#include + +DECLARE_GLOBAL_DATA_PTR; + +#if defined(CONFIG_PSC_CONSOLE) + +static void fifo_init (volatile psc512x_t *psc) +{ + volatile immap_t *im = (immap_t *) CFG_IMMR; + + /* reset Rx & Tx fifo slice */ + psc->rfcmd = PSC_FIFO_RESET_SLICE; + psc->tfcmd = PSC_FIFO_RESET_SLICE; + + /* disable Tx & Rx FIFO interrupts */ + psc->rfintmask = 0; + psc->tfintmask = 0; + + psc->tfsize = CONSOLE_FIFO_TX_SIZE | (CONSOLE_FIFO_TX_ADDR << 16); + psc->rfsize = CONSOLE_FIFO_RX_SIZE | (CONSOLE_FIFO_RX_ADDR << 16); + + /* enable Tx & Rx FIFO slice */ + psc->rfcmd = PSC_FIFO_ENABLE_SLICE; + psc->tfcmd = PSC_FIFO_ENABLE_SLICE; + + im->fifoc.fifoc_cmd = FIFOC_DISABLE_CLOCK_GATE; + __asm__ volatile ("sync"); +} + +int serial_init(void) +{ + volatile immap_t *im = (immap_t *) CFG_IMMR; + volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; + unsigned long baseclk; + int div; + + fifo_init (psc); + + /* set MR register to point to MR1 */ + psc->command = PSC_SEL_MODE_REG_1; + + /* disable Tx/Rx */ + psc->command = PSC_TX_DISABLE | PSC_RX_DISABLE; + + /* choose the prescaler by 16 for the Tx/Rx clock generation */ + psc->psc_clock_select = 0xdd00; + + /* switch to UART mode */ + psc->sicr = 0; + + /* mode register points to mr1 */ + /* configure parity, bit length and so on in mode register 1*/ + psc->mode = PSC_MODE_8_BITS | PSC_MODE_PARNONE; + /* now, mode register points to mr2 */ + psc->mode = PSC_MODE_1_STOPBIT; + + /* calculate dividor for setting PSC CTUR and CTLR registers */ + baseclk = (gd->ipb_clk + 8) / 16; + div = (baseclk + (gd->baudrate / 2)) / gd->baudrate; + + psc->ctur = (div >> 8) & 0xff; + /* set baudrate */ + psc->ctlr = div & 0xff; + + /* disable all interrupts */ + psc->psc_imr = 0; + + /* reset and enable Rx/Tx */ + psc->command = PSC_RST_RX; + psc->command = PSC_RST_TX; + psc->command = PSC_RX_ENABLE | PSC_TX_ENABLE; + + return 0; +} + +void serial_putc (const char c) +{ + volatile immap_t *im = (immap_t *)CFG_IMMR; + volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; + + if (c == '\n') + serial_putc ('\r'); + + /* Wait for last character to go. */ + while (!(psc->psc_status & PSC_SR_TXEMP)) + ; + + psc->tfdata_8 = c; +} + +void serial_putc_raw (const char c) +{ + volatile immap_t *im = (immap_t *) CFG_IMMR; + volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; + + /* Wait for last character to go. */ + while (!(psc->psc_status & PSC_SR_TXEMP)) + ; + + psc->tfdata_8 = c; +} + + +void serial_puts (const char *s) +{ + while (*s) { + serial_putc (*s++); + } +} + +int serial_getc (void) +{ + volatile immap_t *im = (immap_t *) CFG_IMMR; + volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; + + /* Wait for a character to arrive. */ + while (psc->rfstat & PSC_FIFO_EMPTY) + ; + + return psc->rfdata_8; +} + +int serial_tstc (void) +{ + volatile immap_t *im = (immap_t *) CFG_IMMR; + volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; + + return !(psc->rfstat & PSC_FIFO_EMPTY); +} + +void serial_setbrg (void) +{ + volatile immap_t *im = (immap_t *) CFG_IMMR; + volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; + unsigned long baseclk, div; + + baseclk = (gd->csb_clk + 8) / 16; + div = (baseclk + (gd->baudrate / 2)) / gd->baudrate; + + psc->ctur = (div >> 8) & 0xFF; + psc->ctlr = div & 0xff; /* set baudrate */ +} + +void serial_setrts(int s) +{ + volatile immap_t *im = (immap_t *) CFG_IMMR; + volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; + + if (s) { + /* Assert RTS (become LOW) */ + psc->op1 = 0x1; + } + else { + /* Negate RTS (become HIGH) */ + psc->op0 = 0x1; + } +} + +int serial_getcts(void) +{ + volatile immap_t *im = (immap_t *) CFG_IMMR; + volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; + + return (psc->ip & 0x1) ? 0 : 1; +} +#endif /* CONFIG_PSC_CONSOLE */ diff --git a/cpu/mpc512x/speed.c b/cpu/mpc512x/speed.c new file mode 100644 index 00000000000..9a31155ed2d --- /dev/null +++ b/cpu/mpc512x/speed.c @@ -0,0 +1,135 @@ +/* + * (C) Copyright 2000-2007 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2006 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 + * + * Based on the MPC83xx code. + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static int spmf_mult[] = { + 68, 1, 12, 16, + 20, 24, 28, 32, + 36, 40, 44, 48, + 52, 56, 60, 64 +}; + +static int cpmf_mult[][2] = { + {0, 1}, {0, 1}, /* 0 and 1 are not valid */ + {1, 1}, {3, 2}, + {2, 1}, {5, 2}, + {3, 1}, {7, 2}, + {0, 1}, {0, 1}, /* and all above 7 are not valid too */ + {0, 1}, {0, 1}, + {0, 1}, {0, 1}, + {0, 1}, {0, 1} +}; + +static int sys_dividors[][2] = { + {2, 1}, {5, 2}, {3, 1}, {7, 2}, {4, 1}, + {9, 2}, {5, 1}, {7, 1}, {6, 1}, {8, 1}, + {9, 1}, {11, 1}, {10, 1}, {12, 1}, {13, 1}, + {15, 1}, {14, 1}, {16, 1}, {17, 1}, {19, 1}, + {18, 1}, {20, 1}, {21, 1}, {23, 1}, {22, 1}, + {24, 1}, {25, 1}, {27, 1}, {26, 1}, {28, 1}, + {29, 1}, {31, 1}, {30, 1}, {32, 1}, {33, 1} +}; + +int get_clocks (void) +{ + volatile immap_t *im = (immap_t *) CFG_IMMR; + u8 spmf; + u8 cpmf; + u8 sys_div; + u8 ips_div; + u32 ref_clk = CFG_MPC512X_CLKIN; + u32 spll; + u32 sys_clk; + u32 core_clk; + u32 csb_clk; + u32 ips_clk; + + if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im) + return -1; + + spmf = (im->clk.spmr & SPMR_SPMF) >> SPMR_SPMF_SHIFT; + spll = ref_clk * spmf_mult[spmf]; + + sys_div = (im->clk.scfr[1] & SCFR2_SYS_DIV) >> SCFR2_SYS_DIV_SHIFT; + sys_clk = (spll * sys_dividors[sys_div][1]) / sys_dividors[sys_div][0]; + + csb_clk = sys_clk / 2; + + cpmf = (im->clk.spmr & SPMR_CPMF) >> SPMR_CPMF_SHIFT; + core_clk = (csb_clk * cpmf_mult[cpmf][0]) / cpmf_mult[cpmf][1]; + + ips_div = (im->clk.scfr[0] & SCFR1_IPS_DIV_MASK) >> SCFR1_IPS_DIV_SHIFT; + if (ips_div != 0) { + ips_clk = csb_clk / ips_div; + } else { + /* in case we cannot get a sane IPS divisor, fail gracefully */ + ips_clk = 0; + } + + gd->ipb_clk = ips_clk; + gd->csb_clk = csb_clk; + gd->cpu_clk = core_clk; + gd->bus_clk = csb_clk; + return 0; + +} + +/******************************************** + * get_bus_freq + * return system bus freq in Hz + *********************************************/ +ulong get_bus_freq (ulong dummy) +{ + return gd->csb_clk; +} + +int do_clocks (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + printf ("Clock configuration:\n"); + printf (" CPU: %4d MHz\n", gd->cpu_clk / 1000000); + printf (" Coherent System Bus: %4d MHz\n", gd->csb_clk / 1000000); + printf (" IPS Bus: %4d MHz\n", gd->ipb_clk / 1000000); + printf (" DDR: %4d MHz\n", 2 * gd->csb_clk / 1000000); + return 0; +} + +U_BOOT_CMD(clocks, 1, 0, do_clocks, + "clocks - print clock configuration\n", + " clocks\n" +); + +int prt_mpc512x_clks (void) +{ + do_clocks (NULL, 0, 0, NULL); + return (0); +} diff --git a/cpu/mpc512x/start.S b/cpu/mpc512x/start.S new file mode 100644 index 00000000000..8b749ac54e9 --- /dev/null +++ b/cpu/mpc512x/start.S @@ -0,0 +1,780 @@ +/* + * Copyright (C) 1998 Dan Malek + * Copyright (C) 1999 Magnus Damm + * Copyright (C) 2000, 2001, 2002, 2007 Wolfgang Denk + * Copyright Freescale Semiconductor, Inc. 2004, 2006. All rights reserved. + * + * 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 + * + * Based on the MPC83xx code. + */ + +/* + * U-Boot - Startup Code for MPC512x based Embedded Boards + */ + +#include +#include +#include + +#define CONFIG_521X 1 /* needed for Linux kernel header files*/ + +#include +#include + +#include +#include + +#ifndef CONFIG_IDENT_STRING +#define CONFIG_IDENT_STRING "MPC512X" +#endif + +/* + * Floating Point enable, Machine Check and Recoverable Interr. + */ +#undef MSR_KERNEL +#ifdef DEBUG +#define MSR_KERNEL (MSR_FP|MSR_RI) +#else +#define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI) +#endif + +/* Macros for manipulating CSx_START/STOP */ +#define START_REG(start) ((start) >> 16) +#define STOP_REG(start, size) (((start) + (size) - 1) >> 16) + +/* + * Set up GOT: Global Offset Table + * + * Use r14 to access the GOT + */ + START_GOT + GOT_ENTRY(_GOT2_TABLE_) + 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) + END_GOT + +/* + * Magic number and version string + */ + .long 0x27051956 /* U-Boot Magic Number */ + .globl version_string +version_string: + .ascii U_BOOT_VERSION + .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " ", CONFIG_IDENT_STRING, "\0" + +/* + * Vector Table + */ + .text + . = EXC_OFF_SYS_RESET + + .globl _start + /* Start from here after reset/power on */ +_start: + li r21, BOOTFLAG_COLD /* Normal Power-On: Boot from FLASH */ + b boot_cold + + .globl _start_of_vectors +_start_of_vectors: + +/* Machine check */ + STD_EXCEPTION(0x200, MachineCheck, MachineCheckException) + +/* Data Storage exception. */ + STD_EXCEPTION(0x300, DataStorage, UnknownException) + +/* Instruction Storage exception. */ + STD_EXCEPTION(0x400, InstStorage, UnknownException) + +/* External Interrupt exception. */ + STD_EXCEPTION(0x500, ExtInterrupt, UnknownException) + +/* Alignment exception. */ + . = 0x600 +Alignment: + EXCEPTION_PROLOG(SRR0, SRR1) + mfspr r4,DAR + stw r4,_DAR(r21) + mfspr r5,DSISR + stw r5,_DSISR(r21) + addi r3,r1,STACK_FRAME_OVERHEAD + li r20,MSR_KERNEL + rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ + rlwimi r20,r23,0,25,25 /* copy IP bit from saved MSR */ + lwz r6,GOT(transfer_to_handler) + mtlr r6 + blrl +.L_Alignment: + .long AlignmentException - _start + EXC_OFF_SYS_RESET + .long int_return - _start + EXC_OFF_SYS_RESET + +/* Program check exception */ + . = 0x700 +ProgramCheck: + EXCEPTION_PROLOG(SRR0, SRR1) + addi r3,r1,STACK_FRAME_OVERHEAD + li r20,MSR_KERNEL + rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ + rlwimi r20,r23,0,25,25 /* copy IP bit from saved MSR */ + lwz r6,GOT(transfer_to_handler) + mtlr r6 + blrl +.L_ProgramCheck: + .long ProgramCheckException - _start + EXC_OFF_SYS_RESET + .long int_return - _start + EXC_OFF_SYS_RESET + +/* Floating Point Unit unavailable exception */ + STD_EXCEPTION(0x800, FPUnavailable, UnknownException) + +/* Decrementer */ + STD_EXCEPTION(0x900, Decrementer, timer_interrupt) + +/* Critical interrupt */ + STD_EXCEPTION(0xa00, Critical, UnknownException) + +/* System Call */ + STD_EXCEPTION(0xc00, SystemCall, UnknownException) + +/* Trace interrupt */ + STD_EXCEPTION(0xd00, Trace, UnknownException) + +/* Performance Monitor interrupt */ + STD_EXCEPTION(0xf00, PerfMon, UnknownException) + +/* Intruction Translation Miss */ + STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException) + +/* Data Load Translation Miss */ + STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException) + +/* Data Store Translation Miss */ + STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException) + +/* Instruction Address Breakpoint */ + STD_EXCEPTION(0x1300, InstructionAddrBreakpoint, DebugException) + +/* System Management interrupt */ + STD_EXCEPTION(0x1400, SystemMgmtInterrupt, UnknownException) + + .globl _end_of_vectors +_end_of_vectors: + + . = 0x3000 +boot_cold: + /* Save msr contents */ + mfmsr r5 + + /* Set IMMR area to our preferred location */ + lis r4, CONFIG_DEFAULT_IMMR@h + lis r3, CFG_IMMR@h + ori r3, r3, CFG_IMMR@l + stw r3, IMMRBAR(r4) + mtspr MBAR, r3 /* IMMRBAR is mirrored into the MBAR SPR (311) */ + + /* Initialise the machine */ + bl cpu_early_init + + /* + * Set up Local Access Windows: + * + * 1) Boot/CS0 (boot FLASH) + * 2) On-chip SRAM (initial stack purposes) + */ + + /* Boot CS/CS0 window range */ + lis r3, CFG_IMMR@h + ori r3, r3, CFG_IMMR@l + + lis r4, START_REG(CFG_FLASH_BASE) + ori r4, r4, STOP_REG(CFG_FLASH_BASE, CFG_FLASH_SIZE) + stw r4, LPCS0AW(r3) + + /* + * The SRAM window has a fixed size (256K), so only the start address + * is necessary + */ + lis r4, START_REG(CFG_SRAM_BASE) & 0xff00 + stw r4, SRAMBAR(r3) + + /* + * According to MPC5121e RM, configuring local access windows should + * be followed by a dummy read of the config register that was + * modified last and an isync + */ + lwz r4, SRAMBAR(r3) + isync + + /* + * Set configuration of the Boot/CS0, the SRAM window does not have a + * config register so no params can be set for it + */ + lis r3, (CFG_IMMR + LPC_OFFSET)@h + ori r3, r3, (CFG_IMMR + LPC_OFFSET)@l + + lis r4, CFG_CS0_CFG@h + ori r4, r4, CFG_CS0_CFG@l + stw r4, CS0_CONFIG(r3) + + /* Master enable all CS's */ + lis r4, CS_CTRL_ME@h + ori r4, r4, CS_CTRL_ME@l + stw r4, CS_CTRL(r3) + + lis r4, (CFG_MONITOR_BASE)@h + ori r4, r4, (CFG_MONITOR_BASE)@l + addi r5, r4, in_flash - _start + EXC_OFF_SYS_RESET + mtlr r5 + blr + +in_flash: + lis r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h + ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l + + li r0, 0 /* Make room for stack frame header and */ + stwu r0, -4(r1) /* clear final stack frame so that */ + stwu r0, -4(r1) /* stack backtraces terminate cleanly */ + + /* let the C-code set up the rest */ + /* */ + /* Be careful to keep code relocatable & stack humble */ + /*------------------------------------------------------*/ + + GET_GOT /* initialize GOT access */ + + /* r3: IMMR */ + lis r3, CFG_IMMR@h + /* run low-level CPU init code (in Flash) */ + bl cpu_init_f + + /* r3: BOOTFLAG */ + mr r3, r21 + /* run 1st part of board init code (in Flash) */ + bl board_init_f + + /* NOTREACHED - board_init_f() does not return */ + +/* + * This code finishes saving the registers to the exception frame + * and jumps to the appropriate handler for the exception. + * Register r21 is pointer into trap frame, r1 has new stack pointer. + */ + .globl transfer_to_handler +transfer_to_handler: + stw r22,_NIP(r21) + lis r22,MSR_POW@h + andc r23,r23,r22 + stw r23,_MSR(r21) + SAVE_GPR(7, r21) + SAVE_4GPRS(8, r21) + SAVE_8GPRS(12, r21) + SAVE_8GPRS(24, r21) + mflr r23 + andi. r24,r23,0x3f00 /* get vector offset */ + stw r24,TRAP(r21) + li r22,0 + stw r22,RESULT(r21) + lwz r24,0(r23) /* virtual address of handler */ + lwz r23,4(r23) /* where to go when done */ + mtspr SRR0,r24 + mtspr SRR1,r20 + mtlr r23 + SYNC + rfi /* jump to handler, enable MMU */ + +int_return: + mfmsr r28 /* Disable interrupts */ + li r4,0 + ori r4,r4,MSR_EE + andc r28,r28,r4 + SYNC /* Some chip revs need this... */ + mtmsr r28 + SYNC + lwz r2,_CTR(r1) + lwz r0,_LINK(r1) + mtctr r2 + mtlr r0 + lwz r2,_XER(r1) + lwz r0,_CCR(r1) + mtspr XER,r2 + mtcrf 0xFF,r0 + REST_10GPRS(3, r1) + REST_10GPRS(13, r1) + REST_8GPRS(23, r1) + REST_GPR(31, r1) + lwz r2,_NIP(r1) /* Restore environment */ + lwz r0,_MSR(r1) + mtspr SRR0,r2 + mtspr SRR1,r0 + lwz r0,GPR0(r1) + lwz r2,GPR2(r1) + lwz r1,GPR1(r1) + SYNC + rfi + +/* + * This code initialises the machine, it expects original MSR contents to be in r5. + */ +cpu_early_init: + /* Initialize machine status; enable machine check interrupt */ + /*-----------------------------------------------------------*/ + + li r3, MSR_KERNEL /* Set ME and RI flags */ + rlwimi r3, r5, 0, 25, 25 /* preserve IP bit */ +#ifdef DEBUG + rlwimi r3, r5, 0, 21, 22 /* debugger might set SE, BE bits */ +#endif + mtmsr r3 + SYNC + mtspr SRR1, r3 /* Mirror current MSR state in SRR1 */ + + lis r3, CFG_IMMR@h + +#if defined(CONFIG_WATCHDOG) + /* Initialise the watchdog and reset it */ + /*--------------------------------------*/ + lis r4, CFG_WATCHDOG_VALUE + ori r4, r4, (SWCRR_SWEN | SWCRR_SWRI | SWCRR_SWPR) + stw r4, SWCRR(r3) + + /* reset */ + li r4, 0x556C + sth r4, SWSRR@l(r3) + li r4, 0x0 + ori r4, r4, 0xAA39 + sth r4, SWSRR@l(r3) +#else + /* Disable the watchdog */ + /*----------------------*/ + lwz r4, SWCRR(r3) + /* + * Check to see if it's enabled for disabling: once disabled by s/w + * it's not possible to re-enable it + */ + andi. r4, r4, 0x4 + beq 1f + xor r4, r4, r4 + stw r4, SWCRR(r3) +1: +#endif /* CONFIG_WATCHDOG */ + + /* Initialize the Hardware Implementation-dependent Registers */ + /* HID0 also contains cache control */ + /*------------------------------------------------------*/ + lis r3, CFG_HID0_INIT@h + ori r3, r3, CFG_HID0_INIT@l + SYNC + mtspr HID0, r3 + + lis r3, CFG_HID0_FINAL@h + ori r3, r3, CFG_HID0_FINAL@l + SYNC + mtspr HID0, r3 + + lis r3, CFG_HID2@h + ori r3, r3, CFG_HID2@l + SYNC + mtspr HID2, r3 + sync + blr + + +/* Cache functions. + * + * Note: requires that all cache bits in + * HID0 are in the low half word. + */ + .globl icache_enable +icache_enable: + mfspr r3, HID0 + ori r3, r3, HID0_ICE + lis r4, 0 + ori r4, r4, HID0_ILOCK + andc r3, r3, r4 + ori r4, r3, HID0_ICFI + isync + mtspr HID0, r4 /* sets enable and invalidate, clears lock */ + isync + mtspr HID0, r3 /* clears invalidate */ + blr + + .globl icache_disable +icache_disable: + mfspr r3, HID0 + lis r4, 0 + ori r4, r4, HID0_ICE|HID0_ILOCK + andc r3, r3, r4 + ori r4, r3, HID0_ICFI + isync + mtspr HID0, r4 /* sets invalidate, clears enable and lock*/ + isync + mtspr HID0, r3 /* clears invalidate */ + blr + + .globl icache_status +icache_status: + mfspr r3, HID0 + rlwinm r3, r3, (31 - HID0_ICE_SHIFT + 1), 31, 31 + blr + + .globl dcache_enable +dcache_enable: + mfspr r3, HID0 + li r5, HID0_DCFI|HID0_DLOCK + andc r3, r3, r5 + mtspr HID0, r3 /* no invalidate, unlock */ + ori r3, r3, HID0_DCE + ori r5, r3, HID0_DCFI + mtspr HID0, r5 /* enable + invalidate */ + mtspr HID0, r3 /* enable */ + sync + blr + + .globl dcache_disable +dcache_disable: + mfspr r3, HID0 + lis r4, 0 + ori r4, r4, HID0_DCE|HID0_DLOCK + andc r3, r3, r4 + ori r4, r3, HID0_DCI + sync + mtspr HID0, r4 /* sets invalidate, clears enable and lock */ + sync + mtspr HID0, r3 /* clears invalidate */ + blr + + .globl dcache_status +dcache_status: + mfspr r3, HID0 + rlwinm r3, r3, (31 - HID0_DCE_SHIFT + 1), 31, 31 + blr + + .globl get_pvr +get_pvr: + mfspr r3, PVR + blr + +/*------------------------------------------------------------------------------- */ +/* Function: ppcDcbf */ +/* Description: Data Cache block flush */ +/* Input: r3 = effective address */ +/* Output: none. */ +/*------------------------------------------------------------------------------- */ + .globl ppcDcbf +ppcDcbf: + dcbf r0,r3 + blr + +/*------------------------------------------------------------------------------- */ +/* Function: ppcDcbi */ +/* Description: Data Cache block Invalidate */ +/* Input: r3 = effective address */ +/* Output: none. */ +/*------------------------------------------------------------------------------- */ + .globl ppcDcbi +ppcDcbi: + dcbi r0,r3 + blr + +/*-------------------------------------------------------------------------- + * Function: ppcDcbz + * Description: Data Cache block zero. + * Input: r3 = effective address + * Output: none. + *-------------------------------------------------------------------------- */ + + .globl ppcDcbz +ppcDcbz: + dcbz r0,r3 + blr + + .globl ppcDWstore +ppcDWstore: + lfd 1, 0(r4) + stfd 1, 0(r3) + blr + + .globl ppcDWload +ppcDWload: + lfd 1, 0(r3) + stfd 1, 0(r4) + blr + +/*-------------------------------------------------------------------*/ + +/* + * void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM + * after relocating the monitor code. + * + * r3 = dest + * r4 = src + * r5 = length in bytes + * r6 = cachelinesize + */ + .globl relocate_code +relocate_code: + mr r1, r3 /* Set new stack pointer */ + mr r9, r4 /* Save copy of Global Data pointer */ + mr r10, r5 /* Save copy of Destination Address */ + + 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) + sub r5, r5, r4 + li r6, CFG_CACHELINE_SIZE /* Cache Line Size */ + + /* + * Fix GOT pointer: + * + * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + * + Destination Address + * + * Offset: + */ + sub r15, r10, r4 + + /* First our own GOT */ + add r14, r14, r15 + /* then the one used by the C code */ + add r30, r30, r15 + + /* + * Now relocate code + */ + cmplw cr1,r3,r4 + addi r0,r5,3 + srwi. r0,r0,2 + beq cr1,4f /* In place copy is not necessary */ + beq 7f /* Protect against 0 count */ + mtctr r0 + bge cr1,2f + la r8,-4(r4) + la r7,-4(r3) + + /* copy */ +1: lwzu r0,4(r8) + stwu r0,4(r7) + bdnz 1b + + addi r0,r5,3 + srwi. r0,r0,2 + mtctr r0 + la r8,-4(r4) + la r7,-4(r3) + + /* and compare */ +20: lwzu r20,4(r8) + lwzu r21,4(r7) + xor. r22, r20, r21 + bne 30f + bdnz 20b + b 4f + + /* compare failed */ +30: li r3, 0 + blr + +2: slwi r0,r0,2 /* re copy in reverse order ... y do we needed it? */ + add r8,r4,r0 + add r7,r3,r0 +3: lwzu r0,-4(r8) + stwu r0,-4(r7) + bdnz 3b + +/* + * Now flush the cache: note that we must start from a cache aligned + * address. Otherwise we might miss one cache line. + */ +4: cmpwi r6,0 + add r5,r3,r5 + beq 7f /* Always flush prefetch queue in any case */ + subi r0,r6,1 + andc r3,r3,r0 + mr r4,r3 +5: dcbst 0,r4 + add r4,r4,r6 + cmplw r4,r5 + blt 5b + sync /* Wait for all dcbst to complete on bus */ + mr r4,r3 +6: icbi 0,r4 + add r4,r4,r6 + cmplw r4,r5 + blt 6b +7: sync /* Wait for all icbi to complete on bus */ + isync + +/* + * We are done. Do not return, instead branch to second part of board + * initialization, now running from RAM. + */ + addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET + mtlr r0 + blr + +in_ram: + /* + * Relocation Function, r14 point to got2+0x8000 + * + * Adjust got2 pointers, no need to check for 0, this code + * already puts a few entries in the table. + */ + li r0,__got2_entries@sectoff@l + la r3,GOT(_GOT2_TABLE_) + lwz r11,GOT(_GOT2_TABLE_) + mtctr r0 + sub r11,r3,r11 + addi r3,r3,-4 +1: lwzu r0,4(r3) + add r0,r0,r11 + stw r0,0(r3) + bdnz 1b + + /* + * Now adjust the fixups and the pointers to the fixups + * in case we need to move ourselves again. + */ +2: li r0,__fixup_entries@sectoff@l + lwz r3,GOT(_FIXUP_TABLE_) + cmpwi r0,0 + mtctr r0 + addi r3,r3,-4 + beq 4f +3: lwzu r4,4(r3) + lwzux r0,r4,r11 + add r0,r0,r11 + stw r10,0(r3) + stw r0,0(r4) + bdnz 3b +4: +clear_bss: + /* + * Now clear BSS segment + */ + lwz r3,GOT(__bss_start) + lwz r4,GOT(_end) + + cmplw 0, r3, r4 + beq 6f + + li r0, 0 +5: + stw r0, 0(r3) + addi r3, r3, 4 + cmplw 0, r3, r4 + bne 5b +6: + mr r3, r9 /* Global Data pointer */ + mr r4, r10 /* Destination Address */ + bl board_init_r + + /* + * Copy exception vector code to low memory + * + * r3: dest_addr + * r7: source address, r8: end address, r9: target address + */ + .globl trap_init +trap_init: + lwz r7, GOT(_start) + lwz r8, GOT(_end_of_vectors) + + li r9, 0x100 /* reset vector at 0x100 */ + + cmplw 0, r7, r8 + bgelr /* return if r7>=r8 - just in case */ + + mflr r4 /* save link register */ +1: + lwz r0, 0(r7) + stw r0, 0(r9) + addi r7, r7, 4 + addi r9, r9, 4 + cmplw 0, r7, r8 + bne 1b + + /* + * relocate `hdlr' and `int_return' entries + */ + li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET + li r8, Alignment - _start + EXC_OFF_SYS_RESET +2: + bl trap_reloc + addi r7, r7, 0x100 /* next exception vector */ + cmplw 0, r7, r8 + blt 2b + + li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET + bl trap_reloc + + li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET + bl trap_reloc + + li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET + li r8, SystemCall - _start + EXC_OFF_SYS_RESET +3: + bl trap_reloc + addi r7, r7, 0x100 /* next exception vector */ + cmplw 0, r7, r8 + blt 3b + + li r7, .L_Trace - _start + EXC_OFF_SYS_RESET + li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET +4: + bl trap_reloc + addi r7, r7, 0x100 /* next exception vector */ + cmplw 0, r7, r8 + blt 4b + + mfmsr r3 /* now that the vectors have */ + lis r7, MSR_IP@h /* relocated into low memory */ + ori r7, r7, MSR_IP@l /* MSR[IP] can be turned off */ + andc r3, r3, r7 /* (if it was on) */ + SYNC /* Some chip revs need this... */ + mtmsr r3 + SYNC + + mtlr r4 /* restore link register */ + blr + + /* + * Function: relocate entries for one exception vector + */ +trap_reloc: + lwz r0, 0(r7) /* hdlr ... */ + add r0, r0, r3 /* ... += dest_addr */ + stw r0, 0(r7) + + lwz r0, 4(r7) /* int_return ... */ + add r0, r0, r3 /* ... += dest_addr */ + stw r0, 4(r7) + + blr diff --git a/cpu/mpc512x/traps.c b/cpu/mpc512x/traps.c new file mode 100644 index 00000000000..40281a2cbb4 --- /dev/null +++ b/cpu/mpc512x/traps.c @@ -0,0 +1,205 @@ +/* + * (C) Copyright 2000 - 2007 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * 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 + * + * Derived from the MPC83xx code. + */ + +/* + * This file handles the architecture-dependent parts of hardware + * exceptions + */ + +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +extern unsigned long search_exception_table(unsigned long); + +#define END_OF_MEM (gd->bd->bi_memstart + gd->bd->bi_memsize) + +/* + * Trap & Exception support + */ + +void +print_backtrace (unsigned long *sp) +{ + int cnt = 0; + unsigned long i; + + puts ("Call backtrace: "); + while (sp) { + if ((uint)sp > END_OF_MEM) + break; + + i = sp[1]; + if (cnt++ % 7 == 0) + putc ('\n'); + printf ("%08lX ", i); + if (cnt > 32) break; + sp = (unsigned long *) *sp; + } + putc ('\n'); +} + +void show_regs (struct pt_regs * regs) +{ + int i; + + printf ("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DAR: %08lX\n", + regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar); + printf ("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n", + regs->msr, regs->msr & MSR_EE ? 1 : 0, regs->msr & MSR_PR ? 1 : 0, + regs->msr & MSR_FP ? 1 : 0,regs->msr & MSR_ME ? 1 : 0, + regs->msr & MSR_IR ? 1 : 0, + regs->msr & MSR_DR ? 1 : 0); + + putc ('\n'); + for (i = 0; i < 32; i++) { + if ((i % 8) == 0) { + printf ("GPR%02d: ", i); + } + + printf ("%08lX ", regs->gpr[i]); + if ((i % 8) == 7) { + putc ('\n'); + } + } +} + + +void +_exception (int signr, struct pt_regs *regs) +{ + show_regs (regs); + print_backtrace ((unsigned long *)regs->gpr[1]); + panic ("Exception at pc %lx signal %d", regs->nip,signr); +} + + +void +MachineCheckException (struct pt_regs *regs) +{ + unsigned long fixup; + + if ((fixup = search_exception_table (regs->nip)) != 0) { + regs->nip = fixup; + return; + } + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + return; +#endif + + puts ("Machine check.\nCaused by (from msr): "); + printf ("regs %p ",regs); + switch (regs->msr & 0x00FF0000) { + case (0x80000000 >> 10): + puts ("Instruction cache parity signal\n"); + break; + case (0x80000000 >> 11): + puts ("Data cache parity signal\n"); + break; + case (0x80000000 >> 12): + puts ("Machine check signal\n"); + break; + case (0x80000000 >> 13): + puts ("Transfer error ack signal\n"); + break; + case (0x80000000 >> 14): + puts ("Data parity signal\n"); + break; + case (0x80000000 >> 15): + puts ("Address parity signal\n"); + break; + default: + puts ("Unknown values in msr\n"); + } + show_regs (regs); + print_backtrace ((unsigned long *)regs->gpr[1]); + + panic ("machine check"); +} + +void +AlignmentException (struct pt_regs *regs) +{ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + return; +#endif + show_regs (regs); + print_backtrace ((unsigned long *)regs->gpr[1]); + panic ("Alignment Exception"); +} + +void +ProgramCheckException (struct pt_regs *regs) +{ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + return; +#endif + show_regs (regs); + print_backtrace ((unsigned long *)regs->gpr[1]); + panic ("Program Check Exception"); +} + +void +SoftEmuException (struct pt_regs *regs) +{ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + return; +#endif + show_regs (regs); + print_backtrace ((unsigned long *)regs->gpr[1]); + panic ("Software Emulation Exception"); +} + + +void +UnknownException (struct pt_regs *regs) +{ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + return; +#endif + printf ("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", + regs->nip, regs->msr, regs->trap); + _exception (0, regs); +} + +#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) +extern void do_bedbug_breakpoint (struct pt_regs *); +#endif + +void +DebugException (struct pt_regs *regs) +{ + printf ("Debugger trap at @ %lx\n", regs->nip ); + show_regs (regs); +#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) + do_bedbug_breakpoint (regs); +#endif +} diff --git a/include/asm-ppc/e300.h b/include/asm-ppc/e300.h index d1bb159aefa..de8239965aa 100644 --- a/include/asm-ppc/e300.h +++ b/include/asm-ppc/e300.h @@ -9,6 +9,7 @@ #define PVR_E300C1 0x80830000 #define PVR_E300C2 0x80840000 #define PVR_E300C3 0x80850000 +#define PVR_E300C4 0x80860000 /* * Hardware Implementation-Dependent Register 0 (HID0) diff --git a/include/asm-ppc/global_data.h b/include/asm-ppc/global_data.h index cd2463643ce..bbaeb3f575f 100644 --- a/include/asm-ppc/global_data.h +++ b/include/asm-ppc/global_data.h @@ -85,6 +85,10 @@ typedef struct global_data { unsigned long ipb_clk; unsigned long pci_clk; #endif +#if defined(CONFIG_MPC512X) + u32 ipb_clk; + u32 csb_clk; +#endif /* CONFIG_MPC512X */ #if defined(CONFIG_MPC8220) unsigned long bExtUart; unsigned long inp_clk; diff --git a/include/asm-ppc/immap_512x.h b/include/asm-ppc/immap_512x.h new file mode 100644 index 00000000000..23d10d4eb41 --- /dev/null +++ b/include/asm-ppc/immap_512x.h @@ -0,0 +1,569 @@ +/* + * (C) Copyright 2007 DENX Software Engineering + * + * MPC512x Internal Memory Map + * + * 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 + * + * Based on the MPC83xx header. + */ + +#ifndef __IMMAP_512x__ +#define __IMMAP_512x__ + +#include + +typedef struct law512x { + u32 bar; /* Base Addr Register */ + u32 ar; /* Attributes Register */ +} law521x_t; + +/* + * System configuration registers + */ +typedef struct sysconf512x { + u32 immrbar; /* Internal memory map base address register */ + u8 res0[0x1c]; + u32 lpbaw; /* LP Boot Access Window */ + u32 lpcs0aw; /* LP CS0 Access Window */ + u32 lpcs1aw; /* LP CS1 Access Window */ + u32 lpcs2aw; /* LP CS2 Access Window */ + u32 lpcs3aw; /* LP CS3 Access Window */ + u32 lpcs4aw; /* LP CS4 Access Window */ + u32 lpcs5aw; /* LP CS5 Access Window */ + u32 lpcs6aw; /* LP CS6 Access Window */ + u32 lpcs7aw; /* LP CS7 Access Window */ + u8 res1[0x1c]; + law521x_t pcilaw[3]; /* PCI Local Access Window 0-2 Registers */ + u8 res2[0x28]; + law521x_t ddrlaw; /* DDR Local Access Window */ + u8 res3[0x18]; + u32 mbxbar; /* MBX Base Address */ + u32 srambar; /* SRAM Base Address */ + u32 nfcbar; /* NFC Base Address */ + u8 res4[0x34]; + u32 spridr; /* System Part and Revision ID Register */ + u32 spcr; /* System Priority Configuration Register */ + u8 res5[0xf8]; +} sysconf512x_t; + +/* + * Watch Dog Timer (WDT) Registers + */ +typedef struct wdt512x { + u8 res0[4]; + u32 swcrr; /* System watchdog control register */ + u32 swcnr; /* System watchdog count register */ + u8 res1[2]; + u16 swsrr; /* System watchdog service register */ + u8 res2[0xF0]; +} wdt512x_t; + +/* + * RTC Module Registers + */ +typedef struct rtclk512x { + u8 fixme[0x100]; +} rtclk512x_t; + +/* + * General Purpose Timer + */ +typedef struct gpt512x { + u8 fixme[0x100]; +} gpt512x_t; + +/* + * Integrated Programmable Interrupt Controller + */ +typedef struct ipic512x { + u8 fixme[0x100]; +} ipic512x_t; + +/* + * System Arbiter Registers + */ +typedef struct arbiter512x { + u32 acr; /* Arbiter Configuration Register */ + u32 atr; /* Arbiter Timers Register */ + u32 ater; /* Arbiter Transfer Error Register */ + u32 aer; /* Arbiter Event Register */ + u32 aidr; /* Arbiter Interrupt Definition Register */ + u32 amr; /* Arbiter Mask Register */ + u32 aeatr; /* Arbiter Event Attributes Register */ + u32 aeadr; /* Arbiter Event Address Register */ + u32 aerr; /* Arbiter Event Response Register */ + u8 res1[0xDC]; +} arbiter512x_t; + +/* + * Reset Module + */ +typedef struct reset512x { + u32 rcwl; /* Reset Configuration Word Low Register */ + u32 rcwh; /* Reset Configuration Word High Register */ + u8 res0[8]; + u32 rsr; /* Reset Status Register */ + u32 rmr; /* Reset Mode Register */ + u32 rpr; /* Reset protection Register */ + u32 rcr; /* Reset Control Register */ + u32 rcer; /* Reset Control Enable Register */ + u8 res1[0xDC]; +} reset512x_t; + +/* + * Clock Module + */ +typedef struct clk512x { + u32 spmr; /* System PLL Mode Register */ + u32 sccr[2]; /* System Clock Control Registers */ + u32 scfr[2]; /* System Clock Frequency Registers */ + u8 res0[4]; + u32 bcr; /* Bread Crumb Register */ + u32 pscccr[12]; /* PSC0-11 Clock Control Registers */ + u32 spccr; /* SPDIF Clock Control Registers */ + u32 cccr; /* CFM Clock Control Registers */ + u32 dccr; /* DIU Clock Control Registers */ + u8 res1[0xa8]; +} clk512x_t; + +/* + * Power Management Control Module + */ +typedef struct pmc512x { + u8 fixme[0x100]; +} pmc512x_t; + +/* + * General purpose I/O module + */ +typedef struct gpio512x { + u8 fixme[0x100]; +} gpio512x_t; + +/* + * DDR Memory Controller Memory Map + */ +typedef struct ddr512x { + u32 ddr_sys_config; /* System Configuration Register */ + u32 ddr_time_config0; /* Timing Configuration Register */ + u32 ddr_time_config1; /* Timing Configuration Register */ + u32 ddr_time_config2; /* Timing Configuration Register */ + u32 ddr_command; /* Command Register */ + u32 ddr_compact_command; /* Compact Command Register */ + u32 self_refresh_cmd_0; /* Enter/Exit Self Refresh Registers */ + u32 self_refresh_cmd_1; /* Enter/Exit Self Refresh Registers */ + u32 self_refresh_cmd_2; /* Enter/Exit Self Refresh Registers */ + u32 self_refresh_cmd_3; /* Enter/Exit Self Refresh Registers */ + u32 self_refresh_cmd_4; /* Enter/Exit Self Refresh Registers */ + u32 self_refresh_cmd_5; /* Enter/Exit Self Refresh Registers */ + u32 self_refresh_cmd_6; /* Enter/Exit Self Refresh Registers */ + u32 self_refresh_cmd_7; /* Enter/Exit Self Refresh Registers */ + u32 DQS_config_offset_count; /* DQS Config Offset Count */ + u32 DQS_config_offset_time; /* DQS Config Offset Time */ + u32 DQS_delay_status; /* DQS Delay Status */ + u32 res0[0xF]; + u32 prioman_config1; /* Priority Manager Configuration */ + u32 prioman_config2; /* Priority Manager Configuration */ + u32 hiprio_config; /* High Priority Configuration */ + u32 lut_table0_main_upper; /* LUT0 Main Upper */ + u32 lut_table1_main_upper; /* LUT1 Main Upper */ + u32 lut_table2_main_upper; /* LUT2 Main Upper */ + u32 lut_table3_main_upper; /* LUT3 Main Upper */ + u32 lut_table4_main_upper; /* LUT4 Main Upper */ + u32 lut_table0_main_lower; /* LUT0 Main Lower */ + u32 lut_table1_main_lower; /* LUT1 Main Lower */ + u32 lut_table2_main_lower; /* LUT2 Main Lower */ + u32 lut_table3_main_lower; /* LUT3 Main Lower */ + u32 lut_table4_main_lower; /* LUT4 Main Lower */ + u32 lut_table0_alternate_upper; /* LUT0 Alternate Upper */ + u32 lut_table1_alternate_upper; /* LUT1 Alternate Upper */ + u32 lut_table2_alternate_upper; /* LUT2 Alternate Upper */ + u32 lut_table3_alternate_upper; /* LUT3 Alternate Upper */ + u32 lut_table4_alternate_upper; /* LUT4 Alternate Upper */ + u32 lut_table0_alternate_lower; /* LUT0 Alternate Lower */ + u32 lut_table1_alternate_lower; /* LUT1 Alternate Lower */ + u32 lut_table2_alternate_lower; /* LUT2 Alternate Lower */ + u32 lut_table3_alternate_lower; /* LUT3 Alternate Lower */ + u32 lut_table4_alternate_lower; /* LUT4 Alternate Lower */ + u32 performance_monitor_config; + u32 event_time_counter; + u32 event_time_preset; + u32 performance_monitor1_address_low; + u32 performance_monitor2_address_low; + u32 performance_monitor1_address_hi; + u32 performance_monitor2_address_hi; + u32 res1[2]; + u32 performance_monitor1_read_counter; + u32 performance_monitor2_read_counter; + u32 performance_monitor1_write_counter; + u32 performance_monitor2_write_counter; + u32 granted_ack_counter0; + u32 granted_ack_counter1; + u32 granted_ack_counter2; + u32 granted_ack_counter3; + u32 granted_ack_counter4; + u32 cumulative_wait_counter0; + u32 cumulative_wait_counter1; + u32 cumulative_wait_counter2; + u32 cumulative_wait_counter3; + u32 cumulative_wait_counter4; + u32 summed_priority_counter0; + u32 summed_priority_counter1; + u32 summed_priority_counter2; + u32 summed_priority_counter3; + u32 summed_priority_counter4; + u32 res2[0x3AD]; +} ddr512x_t; + + +/* + * DMA/Messaging Unit + */ +typedef struct dma512x { + u8 fixme[0x1800]; +} dma512x_t; + +/* + * PCI Software Configuration Registers + */ +typedef struct pciconf512x { + u8 fixme[0x80]; +} pciconf512x_t; + +/* + * Sequencer + */ +typedef struct ios512x { + u8 fixme[0x100]; +} ios512x_t; + +/* + * PCI Controller + */ +typedef struct pcictrl512x { + u8 fixme[0x100]; +} pcictrl512x_t; + + +/* + * MSCAN + */ +typedef struct mscan512x { + u8 fixme[0x100]; +} mscan512x_t; + +/* + * BDLC + */ +typedef struct bdlc512x { + u8 fixme[0x100]; +} bdlc512x_t; + +/* + * SDHC + */ +typedef struct sdhc512x { + u8 fixme[0x100]; +} sdhc512x_t; + +/* + * SPDIF + */ +typedef struct spdif512x { + u8 fixme[0x100]; +} spdif512x_t; + +/* + * I2C + */ +typedef struct i2c512x_dev { + volatile u32 madr; /* I2Cn + 0x00 */ + volatile u32 mfdr; /* I2Cn + 0x04 */ + volatile u32 mcr; /* I2Cn + 0x08 */ + volatile u32 msr; /* I2Cn + 0x0C */ + volatile u32 mdr; /* I2Cn + 0x10 */ + u8 res0[0x0C]; +} i2c512x_dev_t; + +typedef struct i2c512x { + i2c512x_dev_t dev[3]; + volatile u32 icr; + volatile u32 mifr; + u8 res0[0x98]; +} i2c512x_t; + +/* + * AXE + */ +typedef struct axe512x { + u8 fixme[0x100]; +} axe512x_t; + +/* + * DIU + */ +typedef struct diu512x { + u8 fixme[0x100]; +} diu512x_t; + +/* + * CFM + */ +typedef struct cfm512x { + u8 fixme[0x100]; +} cfm512x_t; + +/* + * FEC + */ +typedef struct fec512x { + u8 fixme[0x800]; +} fec512x_t; + +/* + * ULPI + */ +typedef struct ulpi512x { + u8 fixme[0x600]; +} ulpi512x_t; + +/* + * UTMI + */ +typedef struct utmi512x { + u8 fixme[0x3000]; +} utmi512x_t; + +/* + * PCI DMA + */ +typedef struct pcidma512x { + u8 fixme[0x300]; +} pcidma512x_t; + +/* + * IO Control + */ +typedef struct ioctrl512x { + u32 regs[0x400]; +} ioctrl512x_t; + +/* + * IIM + */ +typedef struct iim512x { + u8 fixme[0x1000]; +} iim512x_t; + +/* + * LPC + */ +typedef struct lpc512x { + u32 cs_cfg[8]; /* Chip Select N Configuration Registers + No dedicated entry for CS Boot as == CS0 */ + u32 cs_cr; /* Chip Select Control Register */ + u32 cs_sr; /* Chip Select Status Register */ + u32 cs_bcr; /* Chip Select Burst Control Register */ + u32 cs_dccr; /* Chip Select Deadcycle Control Register */ + u32 cs_hccr; /* Chip Select Holdcycle Control Register */ + u8 res0[0xcc]; + u32 sclpc_psr; /* SCLPC Packet Size Register */ + u32 sclpc_sar; /* SCLPC Start Address Register */ + u32 sclpc_cr; /* SCLPC Control Register */ + u32 sclpc_er; /* SCLPC Enable Register */ + u32 sclpc_nar; /* SCLPC NextAddress Register */ + u32 sclpc_sr; /* SCLPC Status Register */ + u32 sclpc_bdr; /* SCLPC Bytes Done Register */ + u32 emb_scr; /* EMB Share Counter Register */ + u32 emb_pcr; /* EMB Pause Control Register */ + u8 res1[0x1c]; + u32 lpc_fdwr; /* LPC RX/TX FIFO Data Word Register */ + u32 lpc_fsr; /* LPC RX/TX FIFO Status Register */ + u32 lpc_cr; /* LPC RX/TX FIFO Control Register */ + u32 lpc_ar; /* LPC RX/TX FIFO Alarm Register */ + u8 res2[0xb0]; +} lpc512x_t; + +/* + * PATA + */ +typedef struct pata512x { + u8 fixme[0x100]; +} pata512x_t; + +/* + * PSC + */ +typedef struct psc512x { + volatile u8 mode; /* PSC + 0x00 */ + volatile u8 res0[3]; + union { /* PSC + 0x04 */ + volatile u16 status; + volatile u16 clock_select; + } sr_csr; +#define psc_status sr_csr.status +#define psc_clock_select sr_csr.clock_select + volatile u16 res1; + volatile u8 command; /* PSC + 0x08 */ + volatile u8 res2[3]; + union { /* PSC + 0x0c */ + volatile u8 buffer_8; + volatile u16 buffer_16; + volatile u32 buffer_32; + } buffer; +#define psc_buffer_8 buffer.buffer_8 +#define psc_buffer_16 buffer.buffer_16 +#define psc_buffer_32 buffer.buffer_32 + union { /* PSC + 0x10 */ + volatile u8 ipcr; + volatile u8 acr; + } ipcr_acr; +#define psc_ipcr ipcr_acr.ipcr +#define psc_acr ipcr_acr.acr + volatile u8 res3[3]; + union { /* PSC + 0x14 */ + volatile u16 isr; + volatile u16 imr; + } isr_imr; +#define psc_isr isr_imr.isr +#define psc_imr isr_imr.imr + volatile u16 res4; + volatile u8 ctur; /* PSC + 0x18 */ + volatile u8 res5[3]; + volatile u8 ctlr; /* PSC + 0x1c */ + volatile u8 res6[3]; + volatile u32 ccr; /* PSC + 0x20 */ + volatile u8 res7[12]; + volatile u8 ivr; /* PSC + 0x30 */ + volatile u8 res8[3]; + volatile u8 ip; /* PSC + 0x34 */ + volatile u8 res9[3]; + volatile u8 op1; /* PSC + 0x38 */ + volatile u8 res10[3]; + volatile u8 op0; /* PSC + 0x3c */ + volatile u8 res11[3]; + volatile u32 sicr; /* PSC + 0x40 */ + volatile u8 res12[60]; + volatile u32 tfcmd; /* PSC + 0x80 */ + volatile u32 tfalarm; /* PSC + 0x84 */ + volatile u32 tfstat; /* PSC + 0x88 */ + volatile u32 tfintstat; /* PSC + 0x8C */ + volatile u32 tfintmask; /* PSC + 0x90 */ + volatile u32 tfcount; /* PSC + 0x94 */ + volatile u16 tfwptr; /* PSC + 0x98 */ + volatile u16 tfrptr; /* PSC + 0x9A */ + volatile u32 tfsize; /* PSC + 0x9C */ + volatile u8 res13[28]; + union { /* PSC + 0xBC */ + volatile u8 buffer_8; + volatile u16 buffer_16; + volatile u32 buffer_32; + } tfdata_buffer; +#define tfdata_8 tfdata_buffer.buffer_8 +#define tfdata_16 tfdata_buffer.buffer_16 +#define tfdata_32 tfdata_buffer.buffer_32 + + volatile u32 rfcmd; /* PSC + 0xC0 */ + volatile u32 rfalarm; /* PSC + 0xC4 */ + volatile u32 rfstat; /* PSC + 0xC8 */ + volatile u32 rfintstat; /* PSC + 0xCC */ + volatile u32 rfintmask; /* PSC + 0xD0 */ + volatile u32 rfcount; /* PSC + 0xD4 */ + volatile u16 rfwptr; /* PSC + 0xD8 */ + volatile u16 rfrptr; /* PSC + 0xDA */ + volatile u32 rfsize; /* PSC + 0xDC */ + volatile u8 res18[28]; + union { /* PSC + 0xFC */ + volatile u8 buffer_8; + volatile u16 buffer_16; + volatile u32 buffer_32; + } rfdata_buffer; +#define rfdata_8 rfdata_buffer.buffer_8 +#define rfdata_16 rfdata_buffer.buffer_16 +#define rfdata_32 rfdata_buffer.buffer_32 +} psc512x_t; + +/* + * FIFOC + */ +typedef struct fifoc512x { + u32 fifoc_cmd; + u32 fifoc_int; + u32 fifoc_dma; + u32 fifoc_axe; + u32 fifoc_debug; + u8 fixme[0xEC]; +} fifoc512x_t; + +/* + * SATA + */ +typedef struct sata512x { + u8 fixme[0x2000]; +} sata512x_t; + +typedef struct immap { + sysconf512x_t sysconf; /* System configuration */ + u8 res0[0x700]; + wdt512x_t wdt; /* Watch Dog Timer (WDT) */ + rtclk512x_t rtc; /* Real Time Clock Module */ + gpt512x_t gpt; /* General Purpose Timer */ + ipic512x_t ipic; /* Integrated Programmable Interrupt Controller */ + arbiter512x_t arbiter; /* CSB Arbiter */ + reset512x_t reset; /* Reset Module */ + clk512x_t clk; /* Clock Module */ + pmc512x_t pmc; /* Power Management Control Module */ + gpio512x_t gpio; /* General purpose I/O module */ + u8 res1[0x100]; + mscan512x_t mscan; /* MSCAN */ + bdlc512x_t bdlc; /* BDLC */ + sdhc512x_t sdhc; /* SDHC */ + spdif512x_t spdif; /* SPDIF */ + i2c512x_t i2c; /* I2C Controllers */ + u8 res2[0x800]; + axe512x_t axe; /* AXE */ + diu512x_t diu; /* Display Interface Unit */ + cfm512x_t cfm; /* Clock Frequency Measurement */ + u8 res3[0x500]; + fec512x_t fec; /* Fast Ethernet Controller */ + ulpi512x_t ulpi; /* USB ULPI */ + u8 res4[0xa00]; + utmi512x_t utmi; /* USB UTMI */ + u8 res5[0x1000]; + pcidma512x_t pci_dma; /* PCI DMA */ + pciconf512x_t pci_conf; /* PCI Configuration */ + u8 res6[0x80]; + ios512x_t ios; /* PCI Sequencer */ + pcictrl512x_t pci_ctrl; /* PCI Controller Control and Status */ + u8 res7[0xa00]; + ddr512x_t mddrc; /* Multi-port DDR Memory Controller */ + ioctrl512x_t io_ctrl; /* IO Control */ + iim512x_t iim; /* IC Identification module */ + u8 res8[0x4000]; + lpc512x_t lpc; /* LocalPlus Controller */ + pata512x_t pata; /* Parallel ATA */ + u8 res9[0xd00]; + psc512x_t psc[12]; /* PSCs */ + u8 res10[0x300]; + fifoc512x_t fifoc; /* FIFO Controller */ + u8 res11[0x2000]; + dma512x_t dma; /* DMA */ + u8 res12[0xa800]; + sata512x_t sata; /* Serial ATA */ + u8 res13[0xde000]; +} immap_t; +#endif /* __IMMAP_512x__ */ diff --git a/include/common.h b/include/common.h index 23f93907ee4..d823733b67f 100644 --- a/include/common.h +++ b/include/common.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2004 + * (C) Copyright 2000-2007 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * See file CREDITS for list of people who contributed to this @@ -65,6 +65,9 @@ typedef volatile unsigned char vu_char; #include #elif defined(CONFIG_MPC5xxx) #include +#elif defined(CONFIG_MPC512X) +#include +#include #elif defined(CONFIG_MPC8220) #include #elif defined(CONFIG_8260) @@ -448,6 +451,9 @@ int prt_8260_clks (void); #elif defined(CONFIG_MPC5xxx) int prt_mpc5xxx_clks (void); #endif +#if defined(CONFIG_MPC512x) +int prt_mpc512xxx_clks (void); +#endif #if defined(CONFIG_MPC8220) int prt_mpc8220_clks (void); #endif diff --git a/include/configs/ads5121.h b/include/configs/ads5121.h new file mode 100644 index 00000000000..a1b8eefa02c --- /dev/null +++ b/include/configs/ads5121.h @@ -0,0 +1,410 @@ +/* + * (C) Copyright 2007 DENX Software Engineering + * + * 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 + */ + +/* + * ADS5121 board configuration file + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#define DEBUG +#undef DEBUG + +/* + * Memory map for the ADS5121 board: + * + * 0x0000_0000 - 0x0FFF_FFFF DDR RAM (256 MB) + * 0x3000_0000 - 0x3001_FFFF SRAM (128 KB) + * 0x8000_0000 - 0x803F_FFFF IMMR (4 MB) + * 0x8200_0000 - 0x8200_001F CPLD (32 B) + * 0xFC00_0000 - 0xFFFF_FFFF NOR Boot FLASH (64 MB) + */ + +/* + * High Level Configuration Options + */ +#define CONFIG_E300 1 /* E300 Family */ +#define CONFIG_MPC512X 1 /* MPC512X family */ + +#undef CONFIG_PCI + +#define CFG_MPC512X_CLKIN 66000000 /* in Hz */ + +#define CONFIG_BOARD_EARLY_INIT_F /* call board_early_init_f() */ + +#define CFG_IMMR 0x80000000 + +#define CFG_MEMTEST_START 0x00200000 /* memtest region */ +#define CFG_MEMTEST_END 0x00400000 + +/* + * DDR Setup - manually set all parameters as there's no SPD etc. + */ +#define CFG_DDR_SIZE 256 /* MB */ +#define CFG_DDR_BASE 0x00000000 /* DDR is system memory*/ +#define CFG_SDRAM_BASE CFG_DDR_BASE + +/* DDR Controller Configuration + +SYS_CFG: + [31:31] MDDRC Soft Reset: Diabled + [30:30] DRAM CKE pin: Enabled + [29:29] DRAM CLK: Enabled + [28:28] Command Mode: Enabled (For initialization only) + [27:25] DRAM Row Select: dram_row[15:0] = magenta_address[25:10] + [24:21] DRAM Bank Select: dram_bank[1:0] = magenta_address[11:10] + [20:19] Read Test: DON'T USE + [18:18] Self Refresh: Enabled + [17:17] 16bit Mode: Disabled + [16:13] Ready Delay: 2 + [12:12] Half DQS Delay: Disabled + [11:11] Quarter DQS Delay: Disabled + [10:08] Write Delay: 2 + [07:07] Early ODT: Disabled + [06:06] On DIE Termination: Disabled + [05:05] FIFO Overflow Clear: DON'T USE here + [04:04] FIFO Underflow Clear: DON'T USE here + [03:03] FIFO Overflow Pending: DON'T USE here + [02:02] FIFO Underlfow Pending: DON'T USE here + [01:01] FIFO Overlfow Enabled: Enabled + [00:00] FIFO Underflow Enabled: Enabled + TIME_CFG0 + [31:16] DRAM Refresh Time: 0 CSB clocks + [15:8] DRAM Command Time: 0 CSB clocks + [07:00] DRAM Precharge Time: 0 CSB clocks + TIME_CFG1 + [31:26] DRAM tRFC: + [25:21] DRAM tWR1: + [20:17] DRAM tWRT1: + [16:11] DRAM tDRR: + [10:05] DRAM tRC: + [04:00] DRAM tRAS: + TIME_CFG2 + [31:28] DRAM tRCD: + [27:23] DRAM tFAW: + [22:19] DRAM tRTW1: + [18:15] DRAM tCCD: + [14:10] DRAM tRTP: + [09:05] DRAM tRP: + [04:00] DRAM tRPA */ + +#define CFG_MDDRC_SYS_CFG 0xF8604200 +#define CFG_MDDRC_SYS_CFG_RUN 0xE8604200 +#define CFG_MDDRC_SYS_CFG_EN 0x30000000 +#define CFG_MDDRC_TIME_CFG0 0x0000281E +#define CFG_MDDRC_TIME_CFG0_RUN 0x01F4281E +#define CFG_MDDRC_TIME_CFG1 0x54EC1168 +#define CFG_MDDRC_TIME_CFG2 0x35210864 + +#define CFG_MICRON_NOP 0x01380000 +#define CFG_MICRON_PCHG_ALL 0x01100400 +#define CFG_MICRON_MR 0x01000022 +#define CFG_MICRON_EM2 0x01020000 +#define CFG_MICRON_EM3 0x01030000 +#define CFG_MICRON_EN_DLL 0x01010000 +#define CFG_MICRON_RST_DLL 0x01000932 +#define CFG_MICRON_RFSH 0x01080000 +#define CFG_MICRON_INIT_DEV_OP 0x01000832 +#define CFG_MICRON_OCD_DEFAULT 0x01010780 +#define CFG_MICRON_OCD_EXIT 0x01010400 + +/* DDR Priority Manager Configuration */ +#define CFG_MDDRCGRP_PM_CFG1 0x000777AA +#define CFG_MDDRCGRP_PM_CFG2 0x00000055 +#define CFG_MDDRCGRP_HIPRIO_CFG 0x00000000 +#define CFG_MDDRCGRP_LUT0_MU 0x11111117 +#define CFG_MDDRCGRP_LUT0_ML 0x7777777A +#define CFG_MDDRCGRP_LUT1_MU 0x4444EEEE +#define CFG_MDDRCGRP_LUT1_ML 0xEEEEEEEE +#define CFG_MDDRCGRP_LUT2_MU 0x44444444 +#define CFG_MDDRCGRP_LUT2_ML 0x44444444 +#define CFG_MDDRCGRP_LUT3_MU 0x55555555 +#define CFG_MDDRCGRP_LUT3_ML 0x55555558 +#define CFG_MDDRCGRP_LUT4_MU 0x11111111 +#define CFG_MDDRCGRP_LUT4_ML 0x1111117C +#define CFG_MDDRCGRP_LUT0_AU 0x33333377 +#define CFG_MDDRCGRP_LUT0_AL 0x7777EEEE +#define CFG_MDDRCGRP_LUT1_AU 0x11111111 +#define CFG_MDDRCGRP_LUT1_AL 0x11111111 +#define CFG_MDDRCGRP_LUT2_AU 0x11111111 +#define CFG_MDDRCGRP_LUT2_AL 0x11111111 +#define CFG_MDDRCGRP_LUT3_AU 0x11111111 +#define CFG_MDDRCGRP_LUT3_AL 0x11111111 +#define CFG_MDDRCGRP_LUT4_AU 0x11111111 +#define CFG_MDDRCGRP_LUT4_AL 0x11111111 + +/* + * NOR FLASH on the Local Bus + */ +#define CFG_FLASH_CFI /* use the Common Flash Interface */ +#define CFG_FLASH_CFI_DRIVER /* use the CFI driver */ +#define CFG_FLASH_BASE 0xFC000000 /* start of FLASH */ +#define CFG_FLASH_SIZE 0x04000000 /* max flash size in bytes */ +#define CFG_FLASH_USE_BUFFER_WRITE + +#define CFG_MAX_FLASH_BANKS 1 /* number of banks */ +#define CFG_FLASH_BANKS_LIST {CFG_FLASH_BASE} +#define CFG_MAX_FLASH_SECT 256 /* max sectors per device */ + +#undef CFG_FLASH_CHECKSUM + +/* + * CPLD registers area is really only 32 bytes in size, but the smallest possible LP + * window is 64KB + */ +#define CFG_CPLD_BASE 0x82000000 +#define CFG_CPLD_SIZE 0x00010000 /* 64 KB */ + +#define CFG_SRAM_BASE 0x30000000 +#define CFG_SRAM_SIZE 0x00020000 /* 128 KB */ + +#define CFG_CS0_CFG 0x05059310 /* ALE active low, data size 4bytes */ +#define CFG_CS2_CFG 0x05059010 /* ALE active low, data size 1byte */ + +/* Use SRAM for initial stack */ +#define CFG_INIT_RAM_ADDR CFG_SRAM_BASE /* Initial RAM address */ +#define CFG_INIT_RAM_END CFG_SRAM_SIZE /* End of used area in RAM */ + +#define CFG_GBL_DATA_SIZE 0x100 /* num bytes initial data */ +#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET + +#define CFG_MONITOR_BASE TEXT_BASE /* Start of monitor */ +#define CFG_MONITOR_LEN (256 * 1024) /* Reserve 256 kB for Mon */ +#define CFG_MALLOC_LEN (512 * 1024) /* Reserved for malloc */ + +/* + * Serial Port + */ +#define CONFIG_CONS_INDEX 1 +#undef CONFIG_SERIAL_SOFTWARE_FIFO + +/* + * Serial console configuration + */ +#define CONFIG_PSC_CONSOLE 3 /* console is on PSC3 */ +#if CONFIG_PSC_CONSOLE != 3 +#error CONFIG_PSC_CONSOLE must be 3 +#endif +#define CONFIG_BAUDRATE 115200 /* ... at 115200 bps */ +#define CFG_BAUDRATE_TABLE \ + {300, 600, 1200, 2400, 4800, 9600, 19200, 38400,115200} + +#define CONSOLE_FIFO_TX_SIZE FIFOC_PSC3_TX_SIZE +#define CONSOLE_FIFO_TX_ADDR FIFOC_PSC3_TX_ADDR +#define CONSOLE_FIFO_RX_SIZE FIFOC_PSC3_RX_SIZE +#define CONSOLE_FIFO_RX_ADDR FIFOC_PSC3_RX_ADDR + +#define CONFIG_CMDLINE_EDITING 1 /* add command line history */ +/* Use the HUSH parser */ +#define CFG_HUSH_PARSER +#ifdef CFG_HUSH_PARSER +#define CFG_PROMPT_HUSH_PS2 "> " +#endif + +/* I2C */ +#define CONFIG_HARD_I2C /* I2C with hardware support */ +#undef CONFIG_SOFT_I2C /* so disable bit-banged I2C */ +#define CONFIG_I2C_MULTI_BUS +#define CONFIG_I2C_CMD_TREE +#define CFG_I2C_SPEED 100000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F +#if 0 +#define CFG_I2C_NOPROBES {{0,0x69}} * Don't probe these addrs */ +#endif + +/* + * Ethernet configuration + */ +#define CONFIG_MPC512x_FEC 1 +#define CONFIG_NET_MULTI +#define CONFIG_PHY_ADDR 0x1 +#define CONFIG_MII 1 /* MII PHY management */ +#define CONFIG_ETHADDR 00:e0:5e:00:e5:14 + +#if 0 +/* + * Configure on-board RTC + */ +#define CONFIG_RTC_DS1374 /* use ds1374 rtc via i2c */ +#define CFG_I2C_RTC_ADDR 0x68 /* at address 0x68 */ +#endif + +/* + * Environment + */ +#define CFG_ENV_IS_IN_FLASH 1 +/* This has to be a multiple of the Flash sector size */ +#define CFG_ENV_ADDR (CFG_MONITOR_BASE + CFG_MONITOR_LEN) +#define CFG_ENV_SIZE 0x2000 +#define CFG_ENV_SECT_SIZE 0x40000 /* one sector (256K) for env */ + +/* Address and size of Redundant Environment Sector */ +#define CFG_ENV_ADDR_REDUND (CFG_ENV_ADDR + CFG_ENV_SECT_SIZE) +#define CFG_ENV_SIZE_REDUND (CFG_ENV_SIZE) + +#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ +#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ + +#if defined(CONFIG_PCI) +#define CONFIG_COMMANDS (CONFIG_CMD_DFL \ + | CFG_CMD_PCI \ + | CFG_CMD_NET \ + | CFG_CMD_PING \ + ) +#else +#define CONFIG_COMMANDS (CONFIG_CMD_DFL \ + | CFG_CMD_NET \ + | CFG_CMD_PING \ + | CFG_CMD_MII \ + | CFG_CMD_I2C) +#endif + +#include + +/* + * Watchdog timeout = CFG_WATCHDOG_VALUE * 65536 / IPS clock. + * For example, when IPS is set to 66MHz and CFG_WATCHDOG_VALUE is set + * to 0xFFFF, watchdog timeouts after about 64s. For details refer + * to chapter 36 of the MPC5121e Reference Manual. + */ +#define CONFIG_WATCHDOG /* enable watchdog */ +#define CFG_WATCHDOG_VALUE 0xFFFF + + /* + * Miscellaneous configurable options + */ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_LOAD_ADDR 0x2000000 /* default load address */ +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + #define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else + #define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif + + +#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ +#define CFG_HZ 1000 /* decrementer freq: 1ms ticks */ + +/* + * For booting Linux, the board info and command line data + * have to be in the first 8 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux*/ + +/* Cache Configuration */ +#define CFG_DCACHE_SIZE 32768 +#define CFG_CACHELINE_SIZE 32 +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CFG_CACHELINE_SHIFT 5 /*log base 2 of the above value*/ +#endif + +#define CFG_HID0_INIT 0x000000000 +#define CFG_HID0_FINAL HID0_ENABLE_MACHINE_CHECK +#define CFG_HID2 HID2_HBE + +/* + * Internal Definitions + * + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CONFIG_KGDB_BAUDRATE 230400 /* speed of kgdb serial port */ +#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */ +#endif + +/* + * Environment Configuration + */ +#define CONFIG_ENV_OVERWRITE + +#define CONFIG_HOSTNAME ads5121 +#define CONFIG_ROOTPATH /nfsroot/rootfs +#define CONFIG_BOOTFILE uImage + +#define CONFIG_IPADDR 192.168.160.77 +#define CONFIG_SERVERIP 192.168.1.1 +#define CONFIG_GATEWAYIP 192.168.1.1 +#define CONFIG_NETMASK 255.255.0.0 + +#define CONFIG_LOADADDR 200000 /* default location for tftp and bootm */ + +//#define CONFIG_BOOTDELAY 6 /* -1 disables auto-boot */ +#define CONFIG_BOOTDELAY -1 +#undef CONFIG_BOOTARGS /* the boot command will set bootargs */ + +#define CONFIG_BAUDRATE 115200 + +#define CONFIG_PREBOOT "echo;" \ + "echo Type \"run flash_nfs\" to mount root filesystem over NFS;" \ + "echo" + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "netdev=eth0\0" \ + "nfsargs=setenv bootargs root=/dev/nfs rw " \ + "nfsroot=${serverip}:${rootpath}\0" \ + "ramargs=setenv bootargs root=/dev/ram rw\0" \ + "addip=setenv bootargs ${bootargs} " \ + "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}" \ + ":${hostname}:${netdev}:off panic=1\0" \ + "addtty=setenv bootargs ${bootargs} console=ttyS0,${baudrate}\0"\ + "flash_nfs=run nfsargs addip addtty;" \ + "bootm ${kernel_addr}\0" \ + "flash_self=run ramargs addip addtty;" \ + "bootm ${kernel_addr} ${ramdisk_addr}\0" \ + "net_nfs=tftp 200000 ${bootfile};run nfsargs addip addtty;" \ + "bootm\0" \ + "load=tftp 100000 /tftpboot/ads5121/u-boot.bin\0" \ + "update=protect off fff00000 fff3ffff; " \ + "era fff00000 fff3ffff; cp.b 100000 fff00000 ${filesize}\0" \ + "upd=run load;run update\0" \ + "" + +#define CONFIG_NFSBOOTCOMMAND \ + "setenv bootargs root=/dev/nfs rw " \ + "nfsroot=$serverip:$rootpath " \ + "ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off " \ + "console=$consoledev,$baudrate $othbootargs;" \ + "tftp $loadaddr $bootfile;" \ + "tftp $fdtaddr $fdtfile;" \ + "bootm $loadaddr - $fdtaddr" + +#define CONFIG_RAMBOOTCOMMAND \ + "setenv bootargs root=/dev/ram rw " \ + "console=$consoledev,$baudrate $othbootargs;" \ + "tftp $ramdiskaddr $ramdiskfile;" \ + "tftp $loadaddr $bootfile;" \ + "tftp $fdtaddr $fdtfile;" \ + "bootm $loadaddr $ramdiskaddr $fdtaddr" + +#define CONFIG_BOOTCOMMAND "run flash_self" + +#endif /* __CONFIG_H */ diff --git a/include/mpc512x.h b/include/mpc512x.h new file mode 100644 index 00000000000..03e0e9a1473 --- /dev/null +++ b/include/mpc512x.h @@ -0,0 +1,398 @@ +/* + * Copyright (C) 2004-2006 Freescale Semiconductor, Inc. + * (C) Copyright 2007 DENX Software Engineering + * + * 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. + * + * Derived from the MPC83xx header. + */ + +#ifndef __MPC512X_H__ +#define __MPC512X_H__ + +#include +#if defined(CONFIG_E300) +#include +#endif + +/* System reset offset (PowerPC standard) + */ +#define EXC_OFF_SYS_RESET 0x0100 +#define _START_OFFSET EXC_OFF_SYS_RESET + + +/* IMMRBAR - Internal Memory Register Base Address + */ +#define CONFIG_DEFAULT_IMMR 0xFF400000 /* Default IMMR base address */ +#define IMMRBAR 0x0000 /* Register offset to immr */ +#define IMMRBAR_BASE_ADDR 0xFFF00000 /* Base address mask */ +#define IMMRBAR_RES ~(IMMRBAR_BASE_ADDR) + +/* LAWBAR - Local Access Window Base Address Register + */ +#define LPBAW 0x0020 /* Register offset to immr */ +#define LPCS0AW 0x0024 +#define LPCS1AW 0x0028 +#define LPCS2AW 0x002C +#define LPCS3AW 0x0030 +#define LPCS4AW 0x0034 +#define LPCS5AW 0x0038 +#define LPCS6AW 0x003C +#define LPCA7AW 0x0040 +#define SRAMBAR 0x00C4 + +#define LPC_OFFSET 0x10000 + +#define CS0_CONFIG 0x00000 +#define CS1_CONFIG 0x00004 +#define CS2_CONFIG 0x00008 +#define CS3_CONFIG 0x0000C +#define CS4_CONFIG 0x00010 +#define CS5_CONFIG 0x00014 +#define CS6_CONFIG 0x00018 +#define CS7_CONFIG 0x0001C + +#define CS_CTRL 0x00020 +#define CS_CTRL_ME 0x01000000 /* CS Master Enable bit */ +#define CS_CTRL_IE 0x08000000 /* CS Interrupt Enable bit */ + +/* SPRIDR - System Part and Revision ID Register + */ +#define SPRIDR_PARTID 0xFFFF0000 /* Part Identification */ +#define SPRIDR_REVID 0x0000FFFF /* Revision Identification */ + +#define SPR_5121E 0x80180000 + +/* SPCR - System Priority Configuration Register + */ +#define SPCR_PCIHPE 0x10000000 /* PCI Highest Priority Enable */ +#define SPCR_PCIHPE_SHIFT (31-3) +#define SPCR_PCIPR 0x03000000 /* PCI bridge system bus request priority */ +#define SPCR_PCIPR_SHIFT (31-7) +#define SPCR_TBEN 0x00400000 /* E300 PowerPC core time base unit enable */ +#define SPCR_TBEN_SHIFT (31-9) +#define SPCR_COREPR 0x00300000 /* E300 PowerPC Core system bus request priority */ +#define SPCR_COREPR_SHIFT (31-11) + +/* SWCRR - System Watchdog Control Register + */ +#define SWCRR 0x0904 /* Register offset to immr */ +#define SWCRR_SWTC 0xFFFF0000 /* Software Watchdog Time Count */ +#define SWCRR_SWEN 0x00000004 /* Watchdog Enable bit */ +#define SWCRR_SWRI 0x00000002 /* Software Watchdog Reset/Interrupt Select bit */ +#define SWCRR_SWPR 0x00000001 /* Software Watchdog Counter Prescale bit */ +#define SWCRR_RES ~(SWCRR_SWTC | SWCRR_SWEN | SWCRR_SWRI | SWCRR_SWPR) + +/* SWCNR - System Watchdog Counter Register + */ +#define SWCNR 0x0908 /* Register offset to immr */ +#define SWCNR_SWCN 0x0000FFFF /* Software Watchdog Count mask */ +#define SWCNR_RES ~(SWCNR_SWCN) + +/* SWSRR - System Watchdog Service Register + */ +#define SWSRR 0x090E /* Register offset to immr */ + +/* ACR - Arbiter Configuration Register + */ +#define ACR_COREDIS 0x10000000 /* Core disable */ +#define ACR_COREDIS_SHIFT (31-7) +#define ACR_PIPE_DEP 0x00070000 /* Pipeline depth */ +#define ACR_PIPE_DEP_SHIFT (31-15) +#define ACR_PCI_RPTCNT 0x00007000 /* PCI repeat count */ +#define ACR_PCI_RPTCNT_SHIFT (31-19) +#define ACR_RPTCNT 0x00000700 /* Repeat count */ +#define ACR_RPTCNT_SHIFT (31-23) +#define ACR_APARK 0x00000030 /* Address parking */ +#define ACR_APARK_SHIFT (31-27) +#define ACR_PARKM 0x0000000F /* Parking master */ +#define ACR_PARKM_SHIFT (31-31) + +/* ATR - Arbiter Timers Register + */ +#define ATR_DTO 0x00FF0000 /* Data time out */ +#define ATR_ATO 0x000000FF /* Address time out */ + +/* AER - Arbiter Event Register + */ +#define AER_ETEA 0x00000020 /* Transfer error */ +#define AER_RES 0x00000010 /* Reserved transfer type */ +#define AER_ECW 0x00000008 /* External control word transfer type */ +#define AER_AO 0x00000004 /* Address Only transfer type */ +#define AER_DTO 0x00000002 /* Data time out */ +#define AER_ATO 0x00000001 /* Address time out */ + +/* AEATR - Arbiter Event Address Register + */ +#define AEATR_EVENT 0x07000000 /* Event type */ +#define AEATR_MSTR_ID 0x001F0000 /* Master Id */ +#define AEATR_TBST 0x00000800 /* Transfer burst */ +#define AEATR_TSIZE 0x00000700 /* Transfer Size */ +#define AEATR_TTYPE 0x0000001F /* Transfer Type */ + +/* RSR - Reset Status Register + */ +#define RSR_SWSR 0x00002000 /* software soft reset */ +#define RSR_SWSR_SHIFT 13 +#define RSR_SWHR 0x00001000 /* software hard reset */ +#define RSR_SWHR_SHIFT 12 +#define RSR_JHRS 0x00000200 /* jtag hreset */ +#define RSR_JHRS_SHIFT 9 +#define RSR_JSRS 0x00000100 /* jtag sreset status */ +#define RSR_JSRS_SHIFT 8 +#define RSR_CSHR 0x00000010 /* checkstop reset status */ +#define RSR_CSHR_SHIFT 4 +#define RSR_SWRS 0x00000008 /* software watchdog reset status */ +#define RSR_SWRS_SHIFT 3 +#define RSR_BMRS 0x00000004 /* bus monitop reset status */ +#define RSR_BMRS_SHIFT 2 +#define RSR_SRS 0x00000002 /* soft reset status */ +#define RSR_SRS_SHIFT 1 +#define RSR_HRS 0x00000001 /* hard reset status */ +#define RSR_HRS_SHIFT 0 +#define RSR_RES ~(RSR_SWSR | RSR_SWHR |\ + RSR_JHRS | RSR_JSRS | RSR_CSHR | RSR_SWRS |\ + RSR_BMRS | RSR_SRS | RSR_HRS) +/* RMR - Reset Mode Register + */ +#define RMR_CSRE 0x00000001 /* checkstop reset enable */ +#define RMR_CSRE_SHIFT 0 +#define RMR_RES ~(RMR_CSRE) + +/* RCR - Reset Control Register + */ +#define RCR_SWHR 0x00000002 /* software hard reset */ +#define RCR_SWSR 0x00000001 /* software soft reset */ +#define RCR_RES ~(RCR_SWHR | RCR_SWSR) + +/* RCER - Reset Control Enable Register + */ +#define RCER_CRE 0x00000001 /* software hard reset */ +#define RCER_RES ~(RCER_CRE) + +/* SPMR - System PLL Mode Register + */ +#define SPMR_SPMF 0x0F000000 +#define SPMR_SPMF_SHIFT 24 +#define SPMR_CPMF 0x000F0000 +#define SPMR_CPMF_SHIFT 16 + +/* SCFR1 System Clock Frequency Register 1 + */ +#define SCFR1_IPS_DIV 0x2 +#define SCFR1_IPS_DIV_MASK 0x03800000 +#define SCFR1_IPS_DIV_SHIFT 23 + +/* SCFR2 System Clock Frequency Register 2 + */ +#define SCFR2_SYS_DIV 0xFC000000 +#define SCFR2_SYS_DIV_SHIFT 26 + +/* SCCR - System Clock Control Registers + */ + +/* System Clock Control Register 1 commands */ +#define CLOCK_SCCR1_CFG_EN 0x80000000 +#define CLOCK_SCCR1_LPC_EN 0x40000000 +#define CLOCK_SCCR1_NFC_EN 0x20000000 +#define CLOCK_SCCR1_PATA_EN 0x10000000 +#define CLOCK_SCCR1_PSC_EN(cn) (0x08000000 >> (cn)) +#define CLOCK_SCCR1_PSCFIFO_EN 0x00008000 +#define CLOCK_SCCR1_SATA_EN 0x00004000 +#define CLOCK_SCCR1_FEC_EN 0x00002000 +#define CLOCK_SCCR1_TPR_EN 0x00001000 +#define CLOCK_SCCR1_PCI_EN 0x00000800 +#define CLOCK_SCCR1_DDR_EN 0x00000400 + +/* System Clock Control Register 2 commands */ +#define CLOCK_SCCR2_DIU_EN 0x80000000 +#define CLOCK_SCCR2_AXE_EN 0x40000000 +#define CLOCK_SCCR2_MEM_EN 0x20000000 +#define CLOCK_SCCR2_USB2_EN 0x10000000 +#define CLOCK_SCCR2_USB1_EN 0x08000000 +#define CLOCK_SCCR2_I2C_EN 0x04000000 +#define CLOCK_SCCR2_BDLC_EN 0x02000000 +#define CLOCK_SCCR2_SDHC_EN 0x01000000 +#define CLOCK_SCCR2_SPDIF_EN 0x00800000 +#define CLOCK_SCCR2_MBX_BUS_EN 0x00400000 +#define CLOCK_SCCR2_MBX_EN 0x00200000 +#define CLOCK_SCCR2_MBX_3D_EN 0x00100000 +#define CLOCK_SCCR2_IIM_EN 0x00080000 + +/* PSC FIFO Command values */ +#define PSC_FIFO_RESET_SLICE 0x80 +#define PSC_FIFO_ENABLE_SLICE 0x01 + +/* PSC FIFO Controller Command values */ +#define FIFOC_ENABLE_CLOCK_GATE 0x01 +#define FIFOC_DISABLE_CLOCK_GATE 0x00 + +/* PSC FIFO status */ +#define PSC_FIFO_EMPTY 0x01 + +/* PSC Command values */ +#define PSC_RX_ENABLE 0x01 +#define PSC_RX_DISABLE 0x02 +#define PSC_TX_ENABLE 0x04 +#define PSC_TX_DISABLE 0x08 +#define PSC_SEL_MODE_REG_1 0x10 +#define PSC_RST_RX 0x20 +#define PSC_RST_TX 0x30 +#define PSC_RST_ERR_STAT 0x40 +#define PSC_RST_BRK_CHG_INT 0x50 +#define PSC_START_BRK 0x60 +#define PSC_STOP_BRK 0x70 + +/* PSC status register bits */ +#define PSC_SR_CDE 0x0080 +#define PSC_SR_TXEMP 0x0800 +#define PSC_SR_OE 0x1000 +#define PSC_SR_PE 0x2000 +#define PSC_SR_FE 0x4000 +#define PSC_SR_RB 0x8000 + +/* PSC mode fields */ +#define PSC_MODE_5_BITS 0x00 +#define PSC_MODE_6_BITS 0x01 +#define PSC_MODE_7_BITS 0x02 +#define PSC_MODE_8_BITS 0x03 +#define PSC_MODE_PAREVEN 0x00 +#define PSC_MODE_PARODD 0x04 +#define PSC_MODE_PARFORCE 0x08 +#define PSC_MODE_PARNONE 0x10 +#define PSC_MODE_ENTIMEOUT 0x20 +#define PSC_MODE_RXRTS 0x80 +#define PSC_MODE_1_STOPBIT 0x07 + +/* + * Centralized FIFO Controller has internal memory for all 12 PSCs FIFOs + * + * NOTE: individual PSC units are free to use whatever area (and size) of the + * FIFOC internal memory, so make sure memory areas for FIFO slices used by + * different PSCs do not overlap! + * + * Overall size of FIFOC memory is not documented in the MPC5121e RM, but + * tests indicate that it is 1024 words total. + */ +#define FIFOC_PSC0_TX_SIZE 0x0 /* number of 4-byte words for FIFO slice */ +#define FIFOC_PSC0_TX_ADDR 0x0 +#define FIFOC_PSC0_RX_SIZE 0x0 +#define FIFOC_PSC0_RX_ADDR 0x0 + +#define FIFOC_PSC1_TX_SIZE 0x0 +#define FIFOC_PSC1_TX_ADDR 0x0 +#define FIFOC_PSC1_RX_SIZE 0x0 +#define FIFOC_PSC1_RX_ADDR 0x0 + +#define FIFOC_PSC2_TX_SIZE 0x0 +#define FIFOC_PSC2_TX_ADDR 0x0 +#define FIFOC_PSC2_RX_SIZE 0x0 +#define FIFOC_PSC2_RX_ADDR 0x0 + +#define FIFOC_PSC3_TX_SIZE 0x04 +#define FIFOC_PSC3_TX_ADDR 0x0 +#define FIFOC_PSC3_RX_SIZE 0x04 +#define FIFOC_PSC3_RX_ADDR 0x10 + +#define FIFOC_PSC4_TX_SIZE 0x0 +#define FIFOC_PSC4_TX_ADDR 0x0 +#define FIFOC_PSC4_RX_SIZE 0x0 +#define FIFOC_PSC4_RX_ADDR 0x0 + +#define FIFOC_PSC5_TX_SIZE 0x0 +#define FIFOC_PSC5_TX_ADDR 0x0 +#define FIFOC_PSC5_RX_SIZE 0x0 +#define FIFOC_PSC5_RX_ADDR 0x0 + +#define FIFOC_PSC6_TX_SIZE 0x0 +#define FIFOC_PSC6_TX_ADDR 0x0 +#define FIFOC_PSC6_RX_SIZE 0x0 +#define FIFOC_PSC6_RX_ADDR 0x0 + +#define FIFOC_PSC7_TX_SIZE 0x0 +#define FIFOC_PSC7_TX_ADDR 0x0 +#define FIFOC_PSC7_RX_SIZE 0x0 +#define FIFOC_PSC7_RX_ADDR 0x0 + +#define FIFOC_PSC8_TX_SIZE 0x0 +#define FIFOC_PSC8_TX_ADDR 0x0 +#define FIFOC_PSC8_RX_SIZE 0x0 +#define FIFOC_PSC8_RX_ADDR 0x0 + +#define FIFOC_PSC9_TX_SIZE 0x0 +#define FIFOC_PSC9_TX_ADDR 0x0 +#define FIFOC_PSC9_RX_SIZE 0x0 +#define FIFOC_PSC9_RX_ADDR 0x0 + +#define FIFOC_PSC10_TX_SIZE 0x0 +#define FIFOC_PSC10_TX_ADDR 0x0 +#define FIFOC_PSC10_RX_SIZE 0x0 +#define FIFOC_PSC10_RX_ADDR 0x0 + +#define FIFOC_PSC11_TX_SIZE 0x0 +#define FIFOC_PSC11_TX_ADDR 0x0 +#define FIFOC_PSC11_RX_SIZE 0x0 +#define FIFOC_PSC11_RX_ADDR 0x0 + +/* IO Control Register + */ + +/* Indexes in regs array */ +#define MEM_IDX 0x00 +#define SPDIF_TXCLOCK_IDX 0x73 +#define SPDIF_TX_IDX 0x74 +#define SPDIF_RX_IDX 0x75 +#define PSC0_0_IDX 0x83 +#define PSC0_1_IDX 0x84 +#define PSC0_2_IDX 0x85 +#define PSC0_3_IDX 0x86 +#define PSC0_4_IDX 0x87 +#define PSC1_0_IDX 0x88 +#define PSC1_1_IDX 0x89 +#define PSC1_2_IDX 0x8a +#define PSC1_3_IDX 0x8b +#define PSC1_4_IDX 0x8c +#define PSC2_0_IDX 0x8d +#define PSC2_1_IDX 0x8e +#define PSC2_2_IDX 0x8f +#define PSC2_3_IDX 0x90 +#define PSC2_4_IDX 0x91 + +#define IOCTRL_FUNCMUX_SHIFT 7 +#define IOCTRL_FUNCMUX_FEC 1 +#define IOCTRL_MUX_FEC (IOCTRL_FUNCMUX_FEC << IOCTRL_FUNCMUX_SHIFT) + +/* Set for DDR */ +#define IOCTRL_MUX_DDR 0x00000036 + + /* Register Offset Base */ +#define MPC512X_FEC (CFG_IMMR + 0x02800) + +/* Number of I2C buses */ +#define I2C_BUS_CNT 3 + +/* I2Cn control register bits */ +#define I2C_EN 0x80 +#define I2C_IEN 0x40 +#define I2C_STA 0x20 +#define I2C_TX 0x10 +#define I2C_TXAK 0x08 +#define I2C_RSTA 0x04 +#define I2C_INIT_MASK (I2C_EN | I2C_STA | I2C_TX | I2C_RSTA) + +/* I2Cn status register bits */ +#define I2C_CF 0x80 +#define I2C_AAS 0x40 +#define I2C_BB 0x20 +#define I2C_AL 0x10 +#define I2C_SRW 0x04 +#define I2C_IF 0x02 +#define I2C_RXAK 0x01 + +#endif /* __MPC512X_H__ */ diff --git a/net/eth.c b/net/eth.c index 9fb3a10edb8..68e2c54b2ea 100644 --- a/net/eth.c +++ b/net/eth.c @@ -40,6 +40,7 @@ extern int eth_3com_initialize(bd_t*); extern int fec_initialize(bd_t*); extern int inca_switch_initialize(bd_t*); extern int mpc5xxx_fec_initialize(bd_t*); +extern int mpc512x_fec_initialize(bd_t*); extern int mpc8220_fec_initialize(bd_t*); extern int mv6436x_eth_initialize(bd_t *); extern int mv6446x_eth_initialize(bd_t *); @@ -168,6 +169,9 @@ int eth_initialize(bd_t *bis) #if defined(CONFIG_MPC5xxx_FEC) mpc5xxx_fec_initialize(bis); #endif +#if defined(CONFIG_MPC512x_FEC) + mpc512x_fec_initialize (bis); +#endif #if defined(CONFIG_MPC8220_FEC) mpc8220_fec_initialize(bis); #endif -- cgit v1.3.1 From 63cec5814fab5d2b1c86982327433807a5ac0249 Mon Sep 17 00:00:00 2001 From: Ed Swarthout Date: Thu, 2 Aug 2007 14:09:49 -0500 Subject: Make MPC8641's PCI/PCI-E driver a common driver for many FSL parts. All of the PCI/PCI-Express driver and initialization code that was in the MPC8641HPCN port has now been moved into the common drivers/fsl_pci_init.c. In a subsequent patch, this will be utilized by the 85xx ports as well. Common PCI-E IMMAP register blocks for FSL 85xx/86xx are added. Also enable the second PCI-Express controller on 8641 by getting its BATS and CFG_ setup right. Fixed a u16 vendor compiler warning in AHCI driver too. Signed-off-by: Ed Swarthout Signed-off-by: Zhang Wei Signed-off-by: Jon Loeliger --- board/mpc8641hpcn/mpc8641hpcn.c | 165 +++++++++++++++++++++++++-------- board/mpc8641hpcn/u-boot.lds | 1 - cpu/mpc86xx/Makefile | 3 +- cpu/mpc86xx/pci.c | 146 ----------------------------- cpu/mpc86xx/pcie_indirect.c | 199 ---------------------------------------- drivers/Makefile | 2 +- drivers/ahci.c | 3 +- drivers/fsl_pci_init.c | 180 ++++++++++++++++++++++++++++++++++++ include/asm-ppc/immap_fsl_pci.h | 150 ++++++++++++++++++++++++++++++ include/configs/MPC8641HPCN.h | 44 +++++---- include/pci.h | 6 ++ 11 files changed, 493 insertions(+), 406 deletions(-) delete mode 100644 cpu/mpc86xx/pci.c delete mode 100644 cpu/mpc86xx/pcie_indirect.c create mode 100644 drivers/fsl_pci_init.c create mode 100644 include/asm-ppc/immap_fsl_pci.h (limited to 'include/asm-ppc') diff --git a/board/mpc8641hpcn/mpc8641hpcn.c b/board/mpc8641hpcn/mpc8641hpcn.c index 5e02cc5a5e6..d2182aba5f0 100644 --- a/board/mpc8641hpcn/mpc8641hpcn.c +++ b/board/mpc8641hpcn/mpc8641hpcn.c @@ -11,7 +11,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -55,37 +56,6 @@ int checkboard(void) { puts("Board: MPC8641HPCN\n"); -#ifdef CONFIG_PCI - - volatile immap_t *immap = (immap_t *) CFG_CCSRBAR; - volatile ccsr_gur_t *gur = &immap->im_gur; - volatile ccsr_pex_t *pex1 = &immap->im_pex1; - - uint devdisr = gur->devdisr; - uint io_sel = (gur->pordevsr & MPC86xx_PORDEVSR_IO_SEL) >> 16; -#ifdef DEBUG - uint host1_agent = (gur->porbmsr & MPC86xx_PORBMSR_HA) >> 17; - uint pex1_agent = (host1_agent == 0) || (host1_agent == 1); -#endif - if ((io_sel == 2 || io_sel == 3 || io_sel == 5 - || io_sel == 6 || io_sel == 7 || io_sel == 0xF) - && !(devdisr & MPC86xx_DEVDISR_PCIEX1)) { - debug("PCI-EXPRESS 1: %s \n", pex1_agent ? "Agent" : "Host"); - debug("0x%08x=0x%08x ", &pex1->pme_msg_det, pex1->pme_msg_det); - if (pex1->pme_msg_det) { - pex1->pme_msg_det = 0xffffffff; - debug(" with errors. Clearing. Now 0x%08x", - pex1->pme_msg_det); - } - debug("\n"); - } else { - puts("PCI-EXPRESS 1: Disabled\n"); - } - -#else - puts("PCI-EXPRESS1: Disabled\n"); -#endif - return 0; } @@ -220,21 +190,138 @@ static struct pci_config_table pci_fsl86xxads_config_table[] = { #endif -static struct pci_controller hose = { +static struct pci_controller pci1_hose = { #ifndef CONFIG_PCI_PNP - config_table:pci_mpc86xxcts_config_table, + config_table:pci_mpc86xxcts_config_table #endif }; - #endif /* CONFIG_PCI */ +#ifdef CONFIG_PCI2 +static struct pci_controller pci2_hose; +#endif /* CONFIG_PCI2 */ + +int first_free_busno = 0; + + void pci_init_board(void) { -#ifdef CONFIG_PCI - extern void pci_mpc86xx_init(struct pci_controller *hose); + volatile immap_t *immap = (immap_t *) CFG_CCSRBAR; + volatile ccsr_gur_t *gur = &immap->im_gur; + uint devdisr = gur->devdisr; + uint io_sel = (gur->pordevsr & MPC86xx_PORDEVSR_IO_SEL) >> 16; + +#ifdef CONFIG_PCI1 +{ + volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) CFG_PCI1_ADDR; + extern void fsl_pci_init(struct pci_controller *hose); + struct pci_controller *hose = &pci1_hose; +#ifdef DEBUG + uint host1_agent = (gur->porbmsr & MPC86xx_PORBMSR_HA) >> 17; + uint pex1_agent = (host1_agent == 0) || (host1_agent == 1); +#endif + if ((io_sel == 2 || io_sel == 3 || io_sel == 5 + || io_sel == 6 || io_sel == 7 || io_sel == 0xF) + && !(devdisr & MPC86xx_DEVDISR_PCIEX1)) { + debug("PCI-EXPRESS 1: %s \n", pex1_agent ? "Agent" : "Host"); + debug("0x%08x=0x%08x ", &pci->pme_msg_det, pci->pme_msg_det); + if (pci->pme_msg_det) { + pci->pme_msg_det = 0xffffffff; + debug(" with errors. Clearing. Now 0x%08x", + pci->pme_msg_det); + } + debug("\n"); + + /* inbound */ + pci_set_region(hose->regions + 0, + CFG_PCI_MEMORY_BUS, + CFG_PCI_MEMORY_PHYS, + CFG_PCI_MEMORY_SIZE, + PCI_REGION_MEM | PCI_REGION_MEMORY); + + /* outbound memory */ + pci_set_region(hose->regions + 1, + CFG_PCI1_MEM_BASE, + CFG_PCI1_MEM_PHYS, + CFG_PCI1_MEM_SIZE, + PCI_REGION_MEM); + + /* outbound io */ + pci_set_region(hose->regions + 2, + CFG_PCI1_IO_BASE, + CFG_PCI1_IO_PHYS, + CFG_PCI1_IO_SIZE, + PCI_REGION_IO); + + hose->region_count = 3; + + hose->first_busno=first_free_busno; + pci_setup_indirect(hose, (int) &pci->cfg_addr, (int) &pci->cfg_data); + + fsl_pci_init(hose); + + first_free_busno=hose->last_busno+1; + printf (" PCI-EXPRESS 1 on bus %02x - %02x\n", + hose->first_busno,hose->last_busno); + + /* + * Activate ULI1575 legacy chip by performing a fake + * memory access. Needed to make ULI RTC work. + */ + in_be32((unsigned *) CFG_PCI1_MEM_BASE + + CFG_PCI1_MEM_SIZE - 0x1000000); + + } else { + puts("PCI-EXPRESS 1: Disabled\n"); + } +} +#else + puts("PCI-EXPRESS1: Disabled\n"); +#endif /* CONFIG_PCI1 */ + +#ifdef CONFIG_PCI2 +{ + volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) CFG_PCI2_ADDR; + extern void fsl_pci_init(struct pci_controller *hose); + struct pci_controller *hose = &pci2_hose; + + + /* inbound */ + pci_set_region(hose->regions + 0, + CFG_PCI_MEMORY_BUS, + CFG_PCI_MEMORY_PHYS, + CFG_PCI_MEMORY_SIZE, + PCI_REGION_MEM | PCI_REGION_MEMORY); + + /* outbound memory */ + pci_set_region(hose->regions + 1, + CFG_PCI2_MEM_BASE, + CFG_PCI2_MEM_PHYS, + CFG_PCI2_MEM_SIZE, + PCI_REGION_MEM); + + /* outbound io */ + pci_set_region(hose->regions + 2, + CFG_PCI2_IO_BASE, + CFG_PCI2_IO_PHYS, + CFG_PCI2_IO_SIZE, + PCI_REGION_IO); + + hose->region_count = 3; + + hose->first_busno=first_free_busno; + pci_setup_indirect(hose, (int) &pci->cfg_addr, (int) &pci->cfg_data); + + fsl_pci_init(hose); + + first_free_busno=hose->last_busno+1; + printf (" PCI-EXPRESS 2 on bus %02x - %02x\n", + hose->first_busno,hose->last_busno); +} +#else + puts("PCI-EXPRESS 2: Disabled\n"); +#endif /* CONFIG_PCI2 */ - pci_mpc86xx_init(&hose); -#endif /* CONFIG_PCI */ } #if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) diff --git a/board/mpc8641hpcn/u-boot.lds b/board/mpc8641hpcn/u-boot.lds index 34b50e4be20..e4792ef1998 100644 --- a/board/mpc8641hpcn/u-boot.lds +++ b/board/mpc8641hpcn/u-boot.lds @@ -57,7 +57,6 @@ SECTIONS cpu/mpc86xx/cpu_init.o (.text) cpu/mpc86xx/cpu.o (.text) cpu/mpc86xx/speed.o (.text) - cpu/mpc86xx/pci.o (.text) common/dlmalloc.o (.text) lib_generic/crc32.o (.text) lib_ppc/extable.o (.text) diff --git a/cpu/mpc86xx/Makefile b/cpu/mpc86xx/Makefile index fffcfd24029..6d9300e22e7 100644 --- a/cpu/mpc86xx/Makefile +++ b/cpu/mpc86xx/Makefile @@ -1,4 +1,5 @@ # +# Copyright 2007 Freescale Semiconductor, Inc. # (C) Copyright 2002,2003 Motorola Inc. # Xianghua Xiao,X.Xiao@motorola.com # @@ -30,7 +31,7 @@ LIB = $(obj)lib$(CPU).a START = start.o #resetvec.o SOBJS = cache.o COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o \ - pci.o pcie_indirect.o spd_sdram.o + spd_sdram.o SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/mpc86xx/pci.c b/cpu/mpc86xx/pci.c deleted file mode 100644 index b86548db4f9..00000000000 --- a/cpu/mpc86xx/pci.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) Freescale Semiconductor,Inc. - * 2005, 2006. All rights reserved. - * - * Ed Swarthout (ed.swarthout@freescale.com) - * Jason Jin (Jason.jin@freescale.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 - */ - -/* - * PCIE Configuration space access support for PCIE Bridge - */ -#include -#include - -#if defined(CONFIG_PCI) -void -pci_mpc86xx_init(struct pci_controller *hose) -{ - volatile immap_t *immap = (immap_t *) CFG_CCSRBAR; - volatile ccsr_pex_t *pcie1 = &immap->im_pex1; - u16 temp16; - u32 temp32; - - volatile ccsr_gur_t *gur = &immap->im_gur; - uint host1_agent = (gur->porbmsr & MPC86xx_PORBMSR_HA) >> 17; - uint pcie1_host = (host1_agent == 2) || (host1_agent == 3); - uint pcie1_agent = (host1_agent == 0) || (host1_agent == 1); - uint devdisr = gur->devdisr; - uint io_sel = (gur->pordevsr & MPC86xx_PORDEVSR_IO_SEL) >> 16; - - if ((io_sel == 2 || io_sel == 3 || io_sel == 5 || io_sel == 6 || - io_sel == 7 || io_sel == 0xf) - && !(devdisr & MPC86xx_DEVDISR_PCIEX1)) { - printf("PCI-EXPRESS 1: Configured as %s \n", - pcie1_agent ? "Agent" : "Host"); - if (pcie1_agent) - return; /*Don't scan bus when configured as agent */ - printf(" Scanning PCIE bus"); - debug("0x%08x=0x%08x ", - &pcie1->pme_msg_det, - pcie1->pme_msg_det); - if (pcie1->pme_msg_det) { - pcie1->pme_msg_det = 0xffffffff; - debug(" with errors. Clearing. Now 0x%08x", - pcie1->pme_msg_det); - } - debug("\n"); - } else { - printf("PCI-EXPRESS 1 disabled!\n"); - return; - } - - /* - * Set first_bus=0 only skipped B0:D0:F0 which is - * a reserved device in M1575, but make it easy for - * most of the scan process. - */ - hose->first_busno = 0x00; - hose->last_busno = 0xfe; - - pcie_setup_indirect(hose, (CFG_IMMR + 0x8000), (CFG_IMMR + 0x8004)); - - pci_hose_read_config_word(hose, - PCI_BDF(0, 0, 0), PCI_COMMAND, &temp16); - temp16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | - PCI_COMMAND_MEMORY | PCI_COMMAND_IO; - pci_hose_write_config_word(hose, - PCI_BDF(0, 0, 0), PCI_COMMAND, temp16); - - pci_hose_write_config_word(hose, PCI_BDF(0, 0, 0), PCI_STATUS, 0xffff); - pci_hose_write_config_byte(hose, - PCI_BDF(0, 0, 0), PCI_LATENCY_TIMER, 0x80); - - pci_hose_read_config_dword(hose, PCI_BDF(0, 0, 0), PCI_PRIMARY_BUS, - &temp32); - temp32 = (temp32 & 0xff000000) | (0xff) | (0x0 << 8) | (0xfe << 16); - pci_hose_write_config_dword(hose, PCI_BDF(0, 0, 0), PCI_PRIMARY_BUS, - temp32); - - pcie1->powar1 = 0; - pcie1->powar2 = 0; - pcie1->piwar1 = 0; - pcie1->piwar1 = 0; - - pcie1->powbar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff; - pcie1->powar1 = 0x8004401c; /* 512M MEM space */ - pcie1->potar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff; - pcie1->potear1 = 0x00000000; - - pcie1->powbar2 = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff; - pcie1->powar2 = 0x80088017; /* 16M IO space */ - pcie1->potar2 = 0x00000000; - pcie1->potear2 = 0x00000000; - - pcie1->pitar1 = 0x00000000; - pcie1->piwbar1 = 0x00000000; - /* Enable, Prefetch, Local Mem, * Snoop R/W, 2G */ - pcie1->piwar1 = 0xa0f5501e; - - pci_set_region(hose->regions + 0, - CFG_PCI_MEMORY_BUS, - CFG_PCI_MEMORY_PHYS, - CFG_PCI_MEMORY_SIZE, - PCI_REGION_MEM | PCI_REGION_MEMORY); - - pci_set_region(hose->regions + 1, - CFG_PCI1_MEM_BASE, - CFG_PCI1_MEM_PHYS, - CFG_PCI1_MEM_SIZE, - PCI_REGION_MEM); - - pci_set_region(hose->regions + 2, - CFG_PCI1_IO_BASE, - CFG_PCI1_IO_PHYS, - CFG_PCI1_IO_SIZE, - PCI_REGION_IO); - - hose->region_count = 3; - - pci_register_hose(hose); - - hose->last_busno = pci_hose_scan(hose); - debug("pcie_mpc86xx_init: last_busno %x\n", hose->last_busno); - debug("pcie_mpc86xx init: current_busno %x\n ", hose->current_busno); - - printf("....PCIE1 scan & enumeration done\n"); -} -#endif /* CONFIG_PCI */ diff --git a/cpu/mpc86xx/pcie_indirect.c b/cpu/mpc86xx/pcie_indirect.c deleted file mode 100644 index b00ad76ab89..00000000000 --- a/cpu/mpc86xx/pcie_indirect.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Support for indirect PCI bridges. - * - * Copyright (c) Freescale Semiconductor, Inc. - * 2006. All rights reserved. - * - * Jason Jin - * - * 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. - * - * partly derived from - * arch/powerpc/platforms/86xx/mpc86xx_pcie.c - */ - -#include - -#ifdef CONFIG_PCI - -#include -#include -#include - -#define PCI_CFG_OUT out_be32 -#define PEX_FIX out_be32(hose->cfg_addr+0x4, 0x0400ffff) - -static int -indirect_read_config_pcie(struct pci_controller *hose, - pci_dev_t dev, - int offset, - int len, - u32 *val) -{ - int bus = PCI_BUS(dev); - - volatile unsigned char *cfg_data; - u32 temp; - - PEX_FIX; - if (bus == 0xff) { - PCI_CFG_OUT(hose->cfg_addr, - dev | (offset & 0xfc) | 0x80000001); - } else { - PCI_CFG_OUT(hose->cfg_addr, - dev | (offset & 0xfc) | 0x80000000); - } - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - /* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */ - cfg_data = hose->cfg_data; - PEX_FIX; - temp = in_le32((u32 *) cfg_data); - switch (len) { - case 1: - *val = (temp >> (((offset & 3)) * 8)) & 0xff; - break; - case 2: - *val = (temp >> (((offset & 3)) * 8)) & 0xffff; - break; - default: - *val = temp; - break; - } - - return 0; -} - -static int -indirect_write_config_pcie(struct pci_controller *hose, - pci_dev_t dev, - int offset, - int len, - u32 val) -{ - int bus = PCI_BUS(dev); - volatile unsigned char *cfg_data; - u32 temp; - - PEX_FIX; - if (bus == 0xff) { - PCI_CFG_OUT(hose->cfg_addr, - dev | (offset & 0xfc) | 0x80000001); - } else { - PCI_CFG_OUT(hose->cfg_addr, - dev | (offset & 0xfc) | 0x80000000); - } - - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - /* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */ - cfg_data = hose->cfg_data; - switch (len) { - case 1: - PEX_FIX; - temp = in_le32((u32 *) cfg_data); - temp = (temp & ~(0xff << ((offset & 3) * 8))) | - (val << ((offset & 3) * 8)); - PEX_FIX; - out_le32((u32 *) cfg_data, temp); - break; - case 2: - PEX_FIX; - temp = in_le32((u32 *) cfg_data); - temp = (temp & ~(0xffff << ((offset & 3) * 8))); - temp |= (val << ((offset & 3) * 8)); - PEX_FIX; - out_le32((u32 *) cfg_data, temp); - break; - default: - PEX_FIX; - out_le32((u32 *) cfg_data, val); - break; - } - PEX_FIX; - return 0; -} - -static int -indirect_read_config_byte_pcie(struct pci_controller *hose, - pci_dev_t dev, - int offset, - u8 *val) -{ - u32 val32; - indirect_read_config_pcie(hose, dev, offset, 1, &val32); - *val = (u8) val32; - return 0; -} - -static int -indirect_read_config_word_pcie(struct pci_controller *hose, - pci_dev_t dev, - int offset, - u16 *val) -{ - u32 val32; - indirect_read_config_pcie(hose, dev, offset, 2, &val32); - *val = (u16) val32; - return 0; -} - -static int -indirect_read_config_dword_pcie(struct pci_controller *hose, - pci_dev_t dev, - int offset, - u32 *val) -{ - return indirect_read_config_pcie(hose, dev, offset, 4, val); -} - -static int -indirect_write_config_byte_pcie(struct pci_controller *hose, - pci_dev_t dev, - int offset, - u8 val) -{ - return indirect_write_config_pcie(hose, dev, offset, 1, (u32) val); -} - -static int -indirect_write_config_word_pcie(struct pci_controller *hose, - pci_dev_t dev, - int offset, - unsigned short val) -{ - return indirect_write_config_pcie(hose, dev, offset, 2, (u32) val); -} - -static int -indirect_write_config_dword_pcie(struct pci_controller *hose, - pci_dev_t dev, - int offset, - u32 val) -{ - return indirect_write_config_pcie(hose, dev, offset, 4, val); -} - -void -pcie_setup_indirect(struct pci_controller *hose, u32 cfg_addr, u32 cfg_data) -{ - pci_set_ops(hose, - indirect_read_config_byte_pcie, - indirect_read_config_word_pcie, - indirect_read_config_dword_pcie, - indirect_write_config_byte_pcie, - indirect_write_config_word_pcie, - indirect_write_config_dword_pcie); - - hose->cfg_addr = (unsigned int *)cfg_addr; - hose->cfg_data = (unsigned char *)cfg_data; -} - -#endif /* CONFIG_PCI */ diff --git a/drivers/Makefile b/drivers/Makefile index 48fd4eaade0..fa2e86fd20f 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -52,7 +52,7 @@ COBJS = 3c589.o 5701rls.o ali512x.o ata_piix.o atmel_usart.o \ ks8695eth.o \ pxa_pcmcia.o mpc8xx_pcmcia.o tqm8xx_pcmcia.o \ rpx_pcmcia.o \ - fsl_i2c.o + fsl_i2c.o fsl_pci_init.o SRCS := $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/drivers/ahci.c b/drivers/ahci.c index 8ceff00925f..ccd4d71e8ae 100644 --- a/drivers/ahci.c +++ b/drivers/ahci.c @@ -253,7 +253,8 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent) static int ahci_init_one(pci_dev_t pdev) { - u32 iobase, vendor; + u32 iobase; + u16 vendor; int rc; memset((void *)ataid, 0, sizeof(hd_driveid_t *) * AHCI_MAX_PORTS); diff --git a/drivers/fsl_pci_init.c b/drivers/fsl_pci_init.c new file mode 100644 index 00000000000..1d1f6df997a --- /dev/null +++ b/drivers/fsl_pci_init.c @@ -0,0 +1,180 @@ +/* + * Copyright 2007 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * Version 2 as published by the Free Software Foundation. + * + * 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 + */ +#define DEBUG +#include + +#ifdef CONFIG_FSL_PCI_INIT + +/* + * PCI/PCIE Controller initialization for mpc85xx/mpc86xx soc's + * + * Initialize controller and call the common driver/pci pci_hose_scan to + * scan for bridges and devices. + * + * Hose fields which need to be pre-initialized by board specific code: + * regions[] + * first_busno + * + * Fields updated: + * last_busno + */ + +#include +#include + +void pciauto_prescan_setup_bridge(struct pci_controller *hose, + pci_dev_t dev, int sub_bus); +void pciauto_postscan_setup_bridge(struct pci_controller *hose, + pci_dev_t dev, int sub_bus); + +void pciauto_config_init(struct pci_controller *hose); +void +fsl_pci_init(struct pci_controller *hose) +{ + u16 temp16; + u32 temp32; + int busno = hose->first_busno; + int enabled; + u16 ltssm; + u8 temp8; + int r; + int bridge; + volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) hose->cfg_addr; + pci_dev_t dev = PCI_BDF(busno,0,0); + + /* Initialize ATMU registers based on hose regions and flags */ + volatile pot_t *po=&pci->pot[1]; /* skip 0 */ + volatile pit_t *pi=&pci->pit[0]; /* ranges from: 3 to 1 */ + +#ifdef DEBUG + int neg_link_w; +#endif + + for (r=0; rregion_count; r++) { + if (hose->regions[r].flags & PCI_REGION_MEMORY) { /* inbound */ + pi->pitar = (hose->regions[r].bus_start >> 12) & 0x000fffff; + pi->piwbar = (hose->regions[r].phys_start >> 12) & 0x000fffff; + pi->piwbear = 0; + pi->piwar = PIWAR_EN | PIWAR_PF | PIWAR_LOCAL | + PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | + (__ilog2(hose->regions[r].size) - 1); + pi++; + } else { /* Outbound */ + po->powbar = (hose->regions[r].phys_start >> 12) & 0x000fffff; + po->potar = (hose->regions[r].bus_start >> 12) & 0x000fffff; + po->potear = 0; + if (hose->regions[r].flags & PCI_REGION_IO) + po->powar = POWAR_EN | POWAR_IO_READ | POWAR_IO_WRITE | + (__ilog2(hose->regions[r].size) - 1); + else + po->powar = POWAR_EN | POWAR_MEM_READ | POWAR_MEM_WRITE | + (__ilog2(hose->regions[r].size) - 1); + po++; + } + } + + pci_register_hose(hose); + pciauto_config_init(hose); /* grab pci_{mem,prefetch,io} */ + hose->current_busno = hose->first_busno; + + pci->pedr = 0xffffffff; /* Clear any errors */ + pci->peer = 0xffffffff; /* Enable Error Interupts */ + pci_hose_read_config_dword (hose, dev, PCI_DCR, &temp32); + temp32 |= 0xf000e; /* set URR, FER, NFER (but not CER) */ + pci_hose_write_config_dword(hose, dev, PCI_DCR, temp32); + + pci_hose_read_config_byte (hose, dev, PCI_HEADER_TYPE, &temp8); + bridge = temp8 & PCI_HEADER_TYPE_BRIDGE; /* Bridge, such as pcie */ + + if ( bridge ) { + + pci_hose_read_config_word(hose, dev, PCI_LTSSM, <ssm); + enabled = ltssm >= PCI_LTSSM_L0; + + if (!enabled) { + debug("....PCIE link error. Skipping scan." + "LTSSM=0x%02x\n", temp16); + hose->last_busno = hose->first_busno; + return; + } + + pci->pme_msg_det = 0xffffffff; + pci->pme_msg_int_en = 0xffffffff; +#ifdef DEBUG + pci_hose_read_config_word(hose, dev, PCI_LSR, &temp16); + neg_link_w = (temp16 & 0x3f0 ) >> 4; + debug("...PCIE LTSSM=0x%x, Negotiated link width=%d\n", + ltssm, neg_link_w); +#endif + hose->current_busno++; /* Start scan with secondary */ + pciauto_prescan_setup_bridge(hose, dev, hose->current_busno); + + } else { +#if 0 +/* done in pci_hose_config_device() */ + pci_hose_read_config_word(hose, dev, PCI_COMMAND, &temp16); + temp16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | + PCI_COMMAND_MEMORY | PCI_COMMAND_IO; + pci_hose_write_config_word(hose, dev, PCI_COMMAND, temp16); + pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff); + pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80); +#endif + } + + /* Call setup to allocate PCSRBAR window */ + pciauto_setup_device(hose, dev, 1, hose->pci_mem, + hose->pci_prefetch, hose->pci_io); + + printf (" Scanning PCI bus %02x\n", hose->current_busno); + hose->last_busno = pci_hose_scan_bus(hose,hose->current_busno); + + if ( bridge ) { /* update limit regs and subordinate busno */ + pciauto_postscan_setup_bridge(hose, dev, hose->last_busno); + } + + /* Clear all error indications */ + + if (pci->pme_msg_det && pci->pme_msg_det != 0xffffffff) { + debug("pci_fsl_init: pme_msg_det@%x=%x. Clearing\n", + &pci->pme_msg_det, pci->pme_msg_det); + pci->pme_msg_det = 0xffffffff; + } + + if (pci->pedr) { + debug("pci_fsl_init: pedr@%x=%x. Clearing\n", + &pci->pedr, pci->pedr); + pci->pedr = 0xffffffff; + } + + pci_hose_read_config_word (hose, dev, PCI_DSR, &temp16); + if (temp16) { + debug("pci_fsl_init: PCI_DSR@%x=%x. Clearing\n", + PCI_DSR, temp16); + pci_hose_write_config_word(hose, dev, + PCI_DSR, 0xffff); + } + + pci_hose_read_config_word (hose, dev, PCI_SEC_STATUS, &temp16); + if (temp16) { + debug("pci_fsl_init: PCI_SEC_STATUS@%x=%x. Clearing\n", + PCI_SEC_STATUS, temp16); + pci_hose_write_config_word(hose, dev, PCI_SEC_STATUS, 0xffff); + } +} + +#endif /* CONFIG_FSL_PCI */ diff --git a/include/asm-ppc/immap_fsl_pci.h b/include/asm-ppc/immap_fsl_pci.h new file mode 100644 index 00000000000..bd732b66889 --- /dev/null +++ b/include/asm-ppc/immap_fsl_pci.h @@ -0,0 +1,150 @@ +/* (C) Copyright 2007 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __IMMAP_85xx_fsl_pci__ +#define __IMMAP_85xx_fsl_pci__ + +/* + * Common PCI/PCIE Register structure for mpc85xx and mpc86xx + */ + +/* + * PCI Translation Registers + */ +typedef struct pci_outbound_window { + u32 potar; /* 0x00 - Address */ + u32 potear; /* 0x04 - Address Extended */ + u32 powbar; /* 0x08 - Window Base Address */ + u32 res1; + u32 powar; /* 0x10 - Window Attributes */ +#define POWAR_EN 0x80000000 +#define POWAR_IO_READ 0x00080000 +#define POWAR_MEM_READ 0x00040000 +#define POWAR_IO_WRITE 0x00008000 +#define POWAR_MEM_WRITE 0x00004000 + u32 res2[3]; +} pot_t; + +typedef struct pci_inbound_window { + u32 pitar; /* 0x00 - Address */ + u32 res1; + u32 piwbar; /* 0x08 - Window Base Address */ + u32 piwbear; /* 0x0c - Window Base Address Extended */ + u32 piwar; /* 0x10 - Window Attributes */ +#define PIWAR_EN 0x80000000 +#define PIWAR_PF 0x20000000 +#define PIWAR_LOCAL 0x00f00000 +#define PIWAR_READ_SNOOP 0x00050000 +#define PIWAR_WRITE_SNOOP 0x00005000 + u32 res2[3]; +} pit_t; + +/* PCI/PCI Express Registers */ +typedef struct ccsr_pci { + u32 cfg_addr; /* 0x000 - PCI Configuration Address Register */ + u32 cfg_data; /* 0x004 - PCI Configuration Data Register */ + u32 int_ack; /* 0x008 - PCI Interrupt Acknowledge Register */ + u32 out_comp_to; /* 0x00C - PCI Outbound Completion Timeout Register */ + u32 out_conf_to; /* 0x010 - PCI Configuration Timeout Register */ + u32 config; /* 0x014 - PCIE CONFIG Register */ + char res2[8]; + u32 pme_msg_det; /* 0x020 - PCIE PME & message detect register */ + u32 pme_msg_dis; /* 0x024 - PCIE PME & message disable register */ + u32 pme_msg_int_en; /* 0x028 - PCIE PME & message interrupt enable register */ + u32 pm_command; /* 0x02c - PCIE PM Command register */ + char res4[3016]; /* (- #xbf8 #x30)3016 */ + u32 block_rev1; /* 0xbf8 - PCIE Block Revision register 1 */ + u32 block_rev2; /* 0xbfc - PCIE Block Revision register 2 */ + + pot_t pot[5]; /* 0xc00 - 0xc9f Outbound ATMU's 0, 1, 2, 3, and 4 */ + u32 res5[64]; + pit_t pit[3]; /* 0xda0 - 0xdff Inbound ATMU's 3, 2, and 1 */ +#define PIT3 0 +#define PIT2 1 +#define PIT1 2 + +#if 0 + u32 potar0; /* 0xc00 - PCI Outbound Transaction Address Register 0 */ + u32 potear0; /* 0xc04 - PCI Outbound Translation Extended Address Register 0 */ + char res5[8]; + u32 powar0; /* 0xc10 - PCI Outbound Window Attributes Register 0 */ + char res6[12]; + u32 potar1; /* 0xc20 - PCI Outbound Transaction Address Register 1 */ + u32 potear1; /* 0xc24 - PCI Outbound Translation Extended Address Register 1 */ + u32 powbar1; /* 0xc28 - PCI Outbound Window Base Address Register 1 */ + char res7[4]; + u32 powar1; /* 0xc30 - PCI Outbound Window Attributes Register 1 */ + char res8[12]; + u32 potar2; /* 0xc40 - PCI Outbound Transaction Address Register 2 */ + u32 potear2; /* 0xc44 - PCI Outbound Translation Extended Address Register 2 */ + u32 powbar2; /* 0xc48 - PCI Outbound Window Base Address Register 2 */ + char res9[4]; + u32 powar2; /* 0xc50 - PCI Outbound Window Attributes Register 2 */ + char res10[12]; + u32 potar3; /* 0xc60 - PCI Outbound Transaction Address Register 3 */ + u32 potear3; /* 0xc64 - PCI Outbound Translation Extended Address Register 3 */ + u32 powbar3; /* 0xc68 - PCI Outbound Window Base Address Register 3 */ + char res11[4]; + u32 powar3; /* 0xc70 - PCI Outbound Window Attributes Register 3 */ + char res12[12]; + u32 potar4; /* 0xc80 - PCI Outbound Transaction Address Register 4 */ + u32 potear4; /* 0xc84 - PCI Outbound Translation Extended Address Register 4 */ + u32 powbar4; /* 0xc88 - PCI Outbound Window Base Address Register 4 */ + char res13[4]; + u32 powar4; /* 0xc90 - PCI Outbound Window Attributes Register 4 */ + char res14[268]; + u32 pitar3; /* 0xda0 - PCI Inbound Translation Address Register 3 */ + char res15[4]; + u32 piwbar3; /* 0xda8 - PCI Inbound Window Base Address Register 3 */ + u32 piwbear3; /* 0xdac - PCI Inbound Window Base Extended Address Register 3 */ + u32 piwar3; /* 0xdb0 - PCI Inbound Window Attributes Register 3 */ + char res16[12]; + u32 pitar2; /* 0xdc0 - PCI Inbound Translation Address Register 2 */ + char res17[4]; + u32 piwbar2; /* 0xdc8 - PCI Inbound Window Base Address Register 2 */ + u32 piwbear2; /* 0xdcc - PCI Inbound Window Base Extended Address Register 2 */ + u32 piwar2; /* 0xdd0 - PCI Inbound Window Attributes Register 2 */ + char res18[12]; + u32 pitar1; /* 0xde0 - PCI Inbound Translation Address Register 1 */ + char res19[4]; + u32 piwbar1; /* 0xde8 - PCI Inbound Window Base Address Register 1 */ + char res20[4]; + u32 piwar1; /* 0xdf0 - PCI Inbound Window Attributes Register 1 */ + char res21[12]; +#endif + u32 pedr; /* 0xe00 - PCI Error Detect Register */ + u32 pecdr; /* 0xe04 - PCI Error Capture Disable Register */ + u32 peer; /* 0xe08 - PCI Error Interrupt Enable Register */ + u32 peattrcr; /* 0xe0c - PCI Error Attributes Capture Register */ + u32 peaddrcr; /* 0xe10 - PCI Error Address Capture Register */ +/* u32 perr_disr * 0xe10 - PCIE Erorr Disable Register */ + u32 peextaddrcr; /* 0xe14 - PCI Error Extended Address Capture Register */ + u32 pedlcr; /* 0xe18 - PCI Error Data Low Capture Register */ + u32 pedhcr; /* 0xe1c - PCI Error Error Data High Capture Register */ + u32 gas_timr; /* 0xe20 - PCI Gasket Timer Register */ +/* u32 perr_cap_stat; * 0xe20 - PCIE Error Capture Status Register */ + char res22[4]; + u32 perr_cap0; /* 0xe28 - PCIE Error Capture Register 0 */ + u32 perr_cap1; /* 0xe2c - PCIE Error Capture Register 1 */ + u32 perr_cap2; /* 0xe30 - PCIE Error Capture Register 2 */ + u32 perr_cap3; /* 0xe34 - PCIE Error Capture Register 3 */ + char res23[456]; /* (- #x1000 #xe38) 456 */ +} ccsr_fsl_pci_t; + +#endif /*__IMMAP_fsl_pci__*/ diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h index 808c19f7673..5a511e53244 100644 --- a/include/configs/MPC8641HPCN.h +++ b/include/configs/MPC8641HPCN.h @@ -46,8 +46,10 @@ #define CFG_RESET_ADDRESS 0xfff00100 -/*#undef CONFIG_PCI*/ -#define CONFIG_PCI +#define CONFIG_PCI 1 /* Enable PCI/PCIE */ +#define CONFIG_PCI1 1 /* PCIE controler 1 (ULI bridge) */ +#define CONFIG_PCI2 1 /* PCIE controler 2 (slot) */ +#define CONFIG_FSL_PCI_INIT 1 /* Use common FSL init code */ #define CONFIG_TSEC_ENET /* tsec ethernet support */ #define CONFIG_ENV_OVERWRITE @@ -76,6 +78,9 @@ #define L2_ENABLE (L2CR_L2E) #ifndef CONFIG_SYS_CLK_FREQ +#ifndef __ASSEMBLY__ +extern unsigned long get_board_sys_clk(unsigned long dummy); +#endif #define CONFIG_SYS_CLK_FREQ get_board_sys_clk(0) #endif @@ -93,6 +98,9 @@ #define CFG_CCSRBAR 0xf8000000 /* relocated CCSRBAR */ #define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */ +#define CFG_PCI1_ADDR (CFG_CCSRBAR+0x8000) +#define CFG_PCI2_ADDR (CFG_CCSRBAR+0x9000) + /* * DDR Setup */ @@ -296,9 +304,9 @@ #define CFG_PCI1_MEM_BASE 0x80000000 #define CFG_PCI1_MEM_PHYS CFG_PCI1_MEM_BASE #define CFG_PCI1_MEM_SIZE 0x20000000 /* 512M */ -#define CFG_PCI1_IO_BASE 0xe2000000 -#define CFG_PCI1_IO_PHYS CFG_PCI1_IO_BASE -#define CFG_PCI1_IO_SIZE 0x1000000 /* 16M */ +#define CFG_PCI1_IO_BASE 0x00000000 +#define CFG_PCI1_IO_PHYS 0xe2000000 +#define CFG_PCI1_IO_SIZE 0x00100000 /* 1M */ /* PCI view of System Memory */ #define CFG_PCI_MEMORY_BUS 0x00000000 @@ -311,10 +319,10 @@ #define CFG_PCI2_MEM_BASE 0xa0000000 #define CFG_PCI2_MEM_PHYS CFG_PCI2_MEM_BASE -#define CFG_PCI2_MEM_SIZE 0x10000000 /* 256M */ -#define CFG_PCI2_IO_BASE 0xe3000000 -#define CFG_PCI2_IO_PHYS CFG_PCI2_IO_BASE -#define CFG_PCI2_IO_SIZE 0x1000000 /* 16M */ +#define CFG_PCI2_MEM_SIZE 0x20000000 /* 512M */ +#define CFG_PCI2_IO_BASE 0x00000000 +#define CFG_PCI2_IO_PHYS 0xe3000000 +#define CFG_PCI2_IO_SIZE 0x00100000 /* 1M */ #if defined(CONFIG_PCI) @@ -396,20 +404,20 @@ * 0xa000_0000 512M PCI-Express 2 Memory * Changed it for operating from 0xd0000000 */ -#define CFG_DBAT1L ( CFG_PCI1_MEM_BASE | BATL_PP_RW \ +#define CFG_DBAT1L ( CFG_PCI1_MEM_PHYS | BATL_PP_RW \ | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) -#define CFG_DBAT1U (CFG_PCI1_MEM_BASE | BATU_BL_256M | BATU_VS | BATU_VP) -#define CFG_IBAT1L (CFG_PCI1_MEM_BASE | BATL_PP_RW | BATL_CACHEINHIBIT) +#define CFG_DBAT1U (CFG_PCI1_MEM_PHYS | BATU_BL_1G | BATU_VS | BATU_VP) +#define CFG_IBAT1L (CFG_PCI1_MEM_PHYS | BATL_PP_RW | BATL_CACHEINHIBIT) #define CFG_IBAT1U CFG_DBAT1U /* * BAT2 512M Cache-inhibited, guarded * 0xc000_0000 512M RapidIO Memory */ -#define CFG_DBAT2L (CFG_RIO_MEM_BASE | BATL_PP_RW \ +#define CFG_DBAT2L (CFG_RIO_MEM_PHYS | BATL_PP_RW \ | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) -#define CFG_DBAT2U (CFG_RIO_MEM_BASE | BATU_BL_512M | BATU_VS | BATU_VP) -#define CFG_IBAT2L (CFG_RIO_MEM_BASE | BATL_PP_RW | BATL_CACHEINHIBIT) +#define CFG_DBAT2U (CFG_RIO_MEM_PHYS | BATU_BL_512M | BATU_VS | BATU_VP) +#define CFG_IBAT2L (CFG_RIO_MEM_PHYS | BATL_PP_RW | BATL_CACHEINHIBIT) #define CFG_IBAT2U CFG_DBAT2U /* @@ -428,10 +436,10 @@ * 0xe300_0000 16M PCI-Express 2 I/0 * Note that this is at 0xe0000000 */ -#define CFG_DBAT4L ( CFG_PCI1_IO_BASE | BATL_PP_RW \ +#define CFG_DBAT4L ( CFG_PCI1_IO_PHYS | BATL_PP_RW \ | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) -#define CFG_DBAT4U (CFG_PCI1_IO_BASE | BATU_BL_32M | BATU_VS | BATU_VP) -#define CFG_IBAT4L (CFG_PCI1_IO_BASE | BATL_PP_RW | BATL_CACHEINHIBIT) +#define CFG_DBAT4U (CFG_PCI1_IO_PHYS | BATU_BL_32M | BATU_VS | BATU_VP) +#define CFG_IBAT4L (CFG_PCI1_IO_PHYS | BATL_PP_RW | BATL_CACHEINHIBIT) #define CFG_IBAT4U CFG_DBAT4U /* diff --git a/include/pci.h b/include/pci.h index 7c9a0e34410..8e5dacc0df6 100644 --- a/include/pci.h +++ b/include/pci.h @@ -302,6 +302,12 @@ #define PCI_MAX_PCI_DEVICES 32 #define PCI_MAX_PCI_FUNCTIONS 8 +#define PCI_DCR 0x54 /* PCIe Device Control Register */ +#define PCI_DSR 0x56 /* PCIe Device Status Register */ +#define PCI_LSR 0x5e /* PCIe Link Status Register */ +#define PCI_LTSSM 0x404 /* PCIe Link Training, Status State Machine */ +#define PCI_LTSSM_L0 0x16 /* L0 state */ + /* Include the ID list */ #include -- cgit v1.3.1 From cfc7a7f5bb3273c9951173c788001d45118f141f Mon Sep 17 00:00:00 2001 From: Jon Loeliger Date: Thu, 2 Aug 2007 14:42:20 -0500 Subject: cpu/86xx fixes. Remove rev 1 fixes. Always set PICGCR_MODE. Enable machine check and provide board config option to set and handle SoC error interrupts. Include MSSSR0 in error message. Isolate a RAMBOOT bit of code with #ifdef CFG_RAMBOOT. Signed-off-by: Ed Swarthout Signed-off-by: Jon Loeliger --- cpu/mpc86xx/cpu_init.c | 4 +-- cpu/mpc86xx/interrupts.c | 51 ++++++++++++++------------ cpu/mpc86xx/start.S | 85 ++++++++------------------------------------ cpu/mpc86xx/traps.c | 8 +++-- include/asm-ppc/immap_86xx.h | 16 ++++++--- include/asm-ppc/processor.h | 3 +- 6 files changed, 65 insertions(+), 102 deletions(-) (limited to 'include/asm-ppc') diff --git a/cpu/mpc86xx/cpu_init.c b/cpu/mpc86xx/cpu_init.c index 4673d05e719..c8e46666949 100644 --- a/cpu/mpc86xx/cpu_init.c +++ b/cpu/mpc86xx/cpu_init.c @@ -104,8 +104,8 @@ void cpu_init_f(void) /* enable the timebase bit in HID0 */ set_hid0(get_hid0() | 0x4000000); - /* enable SYNCBE | ABE bits in HID1 */ - set_hid1(get_hid1() | 0x00000C00); + /* enable EMCP, SYNCBE | ABE bits in HID1 */ + set_hid1(get_hid1() | 0x80000C00); } /* diff --git a/cpu/mpc86xx/interrupts.c b/cpu/mpc86xx/interrupts.c index 08e0675fee4..d9f634fdab8 100644 --- a/cpu/mpc86xx/interrupts.c +++ b/cpu/mpc86xx/interrupts.c @@ -8,7 +8,7 @@ * (C) Copyright 2003 Motorola Inc. (MPC85xx port) * Xianghua Xiao (X.Xiao@motorola.com) * - * (C) Copyright 2004 Freescale Semiconductor. (MPC86xx Port) + * (C) Copyright 2004, 2007 Freescale Semiconductor. (MPC86xx Port) * Jeff Brown * Srikanth Srinivasan (srikanth.srinivasan@freescale.com) * @@ -80,25 +80,10 @@ int interrupt_init(void) { int ret; - /* - * The IRQ0 on Rev 2 is pulled high (low in Rev 1.x) to - * implement PEX10 errata. As INT is active high, it - * will cause core to take 0x500 interrupt. - * - * Due to the PIC's default pass through mode, as soon - * as interrupts are enabled (MSR[EE] = 1), an interrupt - * will be taken and u-boot will hang. This is due to a - * hardware change (per an errata fix) on new revisions - * of the board with Rev 2.x parts. - * - * Setting the PIC to mixed mode prevents the hang. - */ - if ((get_svr() & 0xf0) == 0x20) { - volatile immap_t *immr = (immap_t *)CFG_IMMR; - immr->im_pic.gcr = MPC86xx_PICGCR_RST; - while (immr->im_pic.gcr & MPC86xx_PICGCR_RST); - immr->im_pic.gcr = MPC86xx_PICGCR_MODE; - } + volatile immap_t *immr = (immap_t *)CFG_IMMR; + immr->im_pic.gcr = MPC86xx_PICGCR_RST; + while (immr->im_pic.gcr & MPC86xx_PICGCR_RST); + immr->im_pic.gcr = MPC86xx_PICGCR_MODE; /* call cpu specific function from $(CPU)/interrupts.c */ ret = interrupt_init_cpu(&decrementer_count); @@ -119,6 +104,30 @@ int interrupt_init(void) get_msr(), get_dec()); +#ifdef CONFIG_INTERRUPTS + volatile ccsr_pic_t *pic = &immr->im_pic; + + pic->iivpr1 = 0x810001; /* 50220 enable mcm interrupts */ + debug("iivpr1@%x = %x\n", &pic->iivpr1, pic->iivpr1); + + pic->iivpr2 = 0x810002; /* 50240 enable ddr interrupts */ + debug("iivpr2@%x = %x\n", &pic->iivpr2, pic->iivpr2); + + pic->iivpr3 = 0x810003; /* 50260 enable lbc interrupts */ + debug("iivpr3@%x = %x\n", &pic->iivpr3, pic->iivpr3); + +#if defined(CONFIG_PCI1) || defined(CONFIG_PCIE1) + pic->iivpr8 = 0x810008; /* enable pcie1 interrupts */ + debug("iivpr8@%x = %x\n", &pic->iivpr8, pic->iivpr8); +#endif +#if defined(CONFIG_PCI2) || defined(CONFIG_PCIE2) + pic->iivpr9 = 0x810009; /* enable pcie2 interrupts */ + debug("iivpr9@%x = %x\n", &pic->iivpr9, pic->iivpr9); +#endif + + pic->ctpr = 0; /* 40080 clear current task priority register */ +#endif + return 0; } @@ -158,8 +167,6 @@ void timer_interrupt(struct pt_regs *regs) timestamp++; - ppcDcbf((unsigned long)×tamp); - /* Restore Decrementer Count */ set_dec(decrementer_count); diff --git a/cpu/mpc86xx/start.S b/cpu/mpc86xx/start.S index 412745bdaea..c83310a3339 100644 --- a/cpu/mpc86xx/start.S +++ b/cpu/mpc86xx/start.S @@ -1,5 +1,5 @@ /* - * Copyright 2004 Freescale Semiconductor. + * Copyright 2004, 2007 Freescale Semiconductor. * Srikanth Srinivasan * * See file CREDITS for list of people who contributed to this @@ -44,11 +44,9 @@ #define CONFIG_IDENT_STRING "" #endif -/* We don't want the MMU yet. -*/ -#undef MSR_KERNEL -/* Machine Check and Recoverable Interr. */ -#define MSR_KERNEL ( MSR_ME | MSR_RI ) +/* + * Need MSR_DR | MSR_IR enabled to access I/O (printf) in exceptions + */ /* * Set up GOT: Global Offset Table @@ -195,17 +193,21 @@ boot_warm: bl secondary_cpu_setup #endif +1: +#ifdef CFG_RAMBOOT /* disable everything */ -1: li r0, 0 + li r0, 0 mtspr HID0, r0 sync mtmsr 0 +#endif + bl invalidate_bats sync #ifdef CFG_L2 /* init the L2 cache */ - addis r3, r0, L2_INIT@h + lis r3, L2_INIT@h ori r3, r3, L2_INIT@l mtspr l2cr, r3 /* invalidate the L2 cache */ @@ -241,69 +243,9 @@ in_flash: bl setup_ccsrbar #endif - - /* -- 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 - - /* Set DBCR[ERD_DIS] */ - lis r3,MCM_DBCR@ha - lwz r4,MCM_DBCR@l(r3) - oris r4, r4, 0x4000 - 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 */ - /* Setup OR0 (LALE FIX)*/ - lis r3, CFG_CCSRBAR@h - ori r3, r3, 0x5004 - li r4, 0x0FF3 - stw r4, 0(r3) - sync - - /* Setup LCRR */ - lis r3, CFG_CCSRBAR@h - ori r3, r3, 0x50D4 - lis r4, 0x8000 - ori r4, r4, 0x0002 - stw r4, 0(r3) - sync -#endif -#if 1 - /* make sure timer enabled in guts register too */ - lis r3, CFG_CCSRBAR@h - oris r3,r3, 0xE - ori r3,r3,0x0070 - lwz r4, 0(r3) - lis r5,0xFFFC - ori r5,r5,0x5FFF - and r4,r4,r5 - stw r4,0(r3) -#endif /* * Cache must be enabled here for stack-in-cache trick. * This means we need to enable the BATS. @@ -346,8 +288,6 @@ in_flash: #ifdef RUN_DIAG - /* Sri: Code to run the diagnostic automatically */ - /* Load PX_AUX register address in r4 */ lis r4, 0xf810 ori r4, r4, 0x6 @@ -392,6 +332,7 @@ diag_done: .globl invalidate_bats invalidate_bats: + li r0, 0 /* invalidate BATs */ mtspr IBAT0U, r0 mtspr IBAT1U, r0 @@ -1040,6 +981,7 @@ trap_init: mfmsr r7 li r8,MSR_IP andc r7,r7,r8 + ori r7,r7,MSR_ME /* Enable Machine Check */ mtmsr r7 mtlr r4 /* restore link register */ @@ -1224,8 +1166,9 @@ secondary_cpu_setup: sync isync - /*SYNCBE|ABE in HID1*/ + /* MCP|SYNCBE|ABE in HID1 */ mfspr r4, HID1 + oris r4, r4, 0x8000 ori r4, r4, 0x0C00 mtspr HID1, r4 sync diff --git a/cpu/mpc86xx/traps.c b/cpu/mpc86xx/traps.c index fab1975834e..c84bfbf6aaa 100644 --- a/cpu/mpc86xx/traps.c +++ b/cpu/mpc86xx/traps.c @@ -130,8 +130,11 @@ MachineCheckException(struct pt_regs *regs) printf("Machine check in kernel mode.\n"); printf("Caused by (from msr): "); printf("regs %p ", regs); - switch (regs->msr & 0x000F0000) { - case (0x80000000 >> 12): + switch ( regs->msr & 0x001F0000) { + case (0x80000000>>11): + printf("MSS error. MSSSR0: %08x\n", mfspr(SPRN_MSSSR0)); + break; + case (0x80000000>>12): printf("Machine check signal - probably due to mm fault\n" "with mmu off\n"); break; @@ -209,6 +212,7 @@ UnknownException(struct pt_regs *regs) if (debugger_exception_handler && (*debugger_exception_handler) (regs)) return; #endif + printf("UnknownException regs@%x\n", regs); printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", regs->nip, regs->msr, regs->trap); _exception(0, regs); diff --git a/include/asm-ppc/immap_86xx.h b/include/asm-ppc/immap_86xx.h index 0e3fc3403d5..169725b9236 100644 --- a/include/asm-ppc/immap_86xx.h +++ b/include/asm-ppc/immap_86xx.h @@ -1257,9 +1257,12 @@ typedef struct ccsr_gur { uint porpllsr; /* 0xe0000 - POR PLL ratio status register */ uint porbmsr; /* 0xe0004 - POR boot mode status register */ #define MPC86xx_PORBMSR_HA 0x00060000 +#define MPC85xx_PORBMSR_HA 0x00070000 uint porimpscr; /* 0xe0008 - POR I/O impedance status and control register */ uint pordevsr; /* 0xe000c - POR I/O device status regsiter */ -#define MPC86xx_PORDEVSR_IO_SEL 0x000F0000 +#define MPC86xx_PORDEVSR_IO_SEL 0x000F0000 +#define MPC85xx_PORDEVSR_IO_SEL 0x00380000 /* 85xx platform type */ +#define MPC86xx_PORDEVSR_CORE1TE 0x00000080 /* ASMP (Core1 addr trans) */ uint pordbgmsr; /* 0xe0010 - POR debug mode status register */ char res1[12]; uint gpporcr; /* 0xe0020 - General-purpose POR configuration register */ @@ -1273,8 +1276,11 @@ typedef struct ccsr_gur { uint pmuxcr; /* 0xe0060 - Alternate function signal multiplex control */ char res6[12]; uint devdisr; /* 0xe0070 - Device disable control */ -#define MPC86xx_DEVDISR_PCIEX1 0x80000000 -#define MPC86xx_DEVDISR_PCIEX2 0x40000000 +#define MPC86xx_DEVDISR_PCIEX1 0x80000000 +#define MPC86xx_DEVDISR_PCIEX2 0x40000000 +#define MPC86xx_DEVDISR_PCI1 0x80000000 +#define MPC86xx_DEVDISR_PCIE1 0x40000000 +#define MPC86xx_DEVDISR_PCIE2 0x20000000 char res7[12]; uint powmgtcsr; /* 0xe0080 - Power management status and control register */ char res8[12]; @@ -1282,7 +1288,9 @@ typedef struct ccsr_gur { char res9[12]; uint pvr; /* 0xe00a0 - Processor version register */ uint svr; /* 0xe00a4 - System version register */ - char res10[3416]; + char res10a[1880]; + uint clkdvdr; /* 0xe0800 - Clock Divide register */ + char res10b[1532]; uint clkocr; /* 0xe0e00 - Clock out select register */ char res11[12]; uint ddrdllcr; /* 0xe0e10 - DDR DLL control register */ diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h index 71e2e847a46..b806cc09f1f 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-ppc/processor.h @@ -464,7 +464,8 @@ #define ESR_ST 0x00800000 /* Store Operation */ #if defined(CONFIG_MPC86xx) -#define SPRN_MSSCRO 0x3f6 +#define SPRN_MSSCR0 0x3f6 +#define SPRN_MSSSR0 0x3f7 #endif -- cgit v1.3.1 From 2e4d94f1e3c2961428967a33b6ff2520568391b3 Mon Sep 17 00:00:00 2001 From: Ed Swarthout Date: Fri, 27 Jul 2007 01:50:45 -0500 Subject: fsl_pci_init cleanup. Do not enable normal errors created during probe (master abort, perr, and pcie Invalid Configuration access). Add CONFIG_PCI_NOSCAN board option to prevent bus scan. Signed-off-by: Ed Swarthout Acked-by: Andy Fleming --- drivers/fsl_pci_init.c | 46 +++++++++++++++------------------------------ include/asm-ppc/processor.h | 2 +- 2 files changed, 16 insertions(+), 32 deletions(-) (limited to 'include/asm-ppc') diff --git a/drivers/fsl_pci_init.c b/drivers/fsl_pci_init.c index 1d1f6df997a..1084dc6b787 100644 --- a/drivers/fsl_pci_init.c +++ b/drivers/fsl_pci_init.c @@ -15,7 +15,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ -#define DEBUG + #include #ifdef CONFIG_FSL_PCI_INIT @@ -93,7 +93,11 @@ fsl_pci_init(struct pci_controller *hose) hose->current_busno = hose->first_busno; pci->pedr = 0xffffffff; /* Clear any errors */ - pci->peer = 0xffffffff; /* Enable Error Interupts */ + pci->peer = ~0x20140; /* Enable All Error Interupts except + * - Master abort (pci) + * - Master PERR (pci) + * - ICCA (PCIe) + */ pci_hose_read_config_dword (hose, dev, PCI_DCR, &temp32); temp32 |= 0xf000e; /* set URR, FER, NFER (but not CER) */ pci_hose_write_config_dword(hose, dev, PCI_DCR, temp32); @@ -108,7 +112,7 @@ fsl_pci_init(struct pci_controller *hose) if (!enabled) { debug("....PCIE link error. Skipping scan." - "LTSSM=0x%02x\n", temp16); + "LTSSM=0x%02x\n", ltssm); hose->last_busno = hose->first_busno; return; } @@ -118,61 +122,41 @@ fsl_pci_init(struct pci_controller *hose) #ifdef DEBUG pci_hose_read_config_word(hose, dev, PCI_LSR, &temp16); neg_link_w = (temp16 & 0x3f0 ) >> 4; - debug("...PCIE LTSSM=0x%x, Negotiated link width=%d\n", + printf("...PCIE LTSSM=0x%x, Negotiated link width=%d\n", ltssm, neg_link_w); #endif hose->current_busno++; /* Start scan with secondary */ pciauto_prescan_setup_bridge(hose, dev, hose->current_busno); - } else { -#if 0 -/* done in pci_hose_config_device() */ - pci_hose_read_config_word(hose, dev, PCI_COMMAND, &temp16); - temp16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | - PCI_COMMAND_MEMORY | PCI_COMMAND_IO; - pci_hose_write_config_word(hose, dev, PCI_COMMAND, temp16); - pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff); - pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80); -#endif } /* Call setup to allocate PCSRBAR window */ pciauto_setup_device(hose, dev, 1, hose->pci_mem, hose->pci_prefetch, hose->pci_io); - +#ifndef CONFIG_PCI_NOSCAN printf (" Scanning PCI bus %02x\n", hose->current_busno); hose->last_busno = pci_hose_scan_bus(hose,hose->current_busno); if ( bridge ) { /* update limit regs and subordinate busno */ pciauto_postscan_setup_bridge(hose, dev, hose->last_busno); } +#else + hose->last_busno = hose->current_busno; +#endif /* Clear all error indications */ - if (pci->pme_msg_det && pci->pme_msg_det != 0xffffffff) { - debug("pci_fsl_init: pme_msg_det@%x=%x. Clearing\n", - &pci->pme_msg_det, pci->pme_msg_det); - pci->pme_msg_det = 0xffffffff; - } - - if (pci->pedr) { - debug("pci_fsl_init: pedr@%x=%x. Clearing\n", - &pci->pedr, pci->pedr); - pci->pedr = 0xffffffff; - } + pci->pme_msg_det = 0xffffffff; + pci->pedr = 0xffffffff; pci_hose_read_config_word (hose, dev, PCI_DSR, &temp16); if (temp16) { - debug("pci_fsl_init: PCI_DSR@%x=%x. Clearing\n", - PCI_DSR, temp16); pci_hose_write_config_word(hose, dev, - PCI_DSR, 0xffff); + PCI_DSR, 0xffff); } pci_hose_read_config_word (hose, dev, PCI_SEC_STATUS, &temp16); if (temp16) { - debug("pci_fsl_init: PCI_SEC_STATUS@%x=%x. Clearing\n", - PCI_SEC_STATUS, temp16); pci_hose_write_config_word(hose, dev, PCI_SEC_STATUS, 0xffff); } } diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h index b806cc09f1f..9be5a279e26 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-ppc/processor.h @@ -532,7 +532,7 @@ #define LR SPRN_LR #define MBAR SPRN_MBAR /* System memory base address */ #if defined(CONFIG_MPC86xx) -#define MSSCR0 SPRN_MSSCRO +#define MSSCR0 SPRN_MSSCR0 #endif #if defined(CONFIG_E500) || defined(CONFIG_MPC86xx) #define PIR SPRN_PIR -- cgit v1.3.1 From 61a21e980a7b9188424d04f1c265fdc5c21c7e85 Mon Sep 17 00:00:00 2001 From: Andy Fleming Date: Tue, 14 Aug 2007 01:34:21 -0500 Subject: 85xx start.S cleanup and exception support From: Ed Swarthout Support external interrupts from platform to eliminate system hangs. Define CONFIG_INTERRUPTS board configure option to enable. Enable ecm, ddr, lbc, and pci/pcie error interrupts in PIC. Remove extra cpu initialization redundant with hardware initialization. Whitespace cleanup. Define and use _START_OFFSET consistent with other processors using ppc_asm.tmpl Move additional code from .text to boot page to make room for exception vectors at start of image. Handle Machine Check, External and Critical exceptions. Fix e500 machine check error determination in traps.c TEXT_BASE can now be 0xfffc_0000 - which cuts binary image in half. Signed-off-by: Ed Swarthout Acked-by: Andy Fleming --- cpu/mpc85xx/interrupts.c | 33 +++ cpu/mpc85xx/start.S | 485 +++++++++++++++++++------------------------- cpu/mpc85xx/traps.c | 99 +++++++-- include/asm-ppc/processor.h | 3 + include/mpc85xx.h | 8 +- 5 files changed, 326 insertions(+), 302 deletions(-) (limited to 'include/asm-ppc') diff --git a/cpu/mpc85xx/interrupts.c b/cpu/mpc85xx/interrupts.c index dc246dca028..bf737d62286 100644 --- a/cpu/mpc85xx/interrupts.c +++ b/cpu/mpc85xx/interrupts.c @@ -89,6 +89,39 @@ int interrupt_init (void) mtspr(SPRN_TCR, TCR_PIE); set_dec (decrementer_count); set_msr (get_msr () | MSR_EE); + +#ifdef CONFIG_INTERRUPTS + volatile ccsr_pic_t *pic = &immr->im_pic; + + pic->iivpr1 = 0x810002; /* 50220 enable ecm interrupts */ + debug("iivpr1@%x = %x\n",&pic->iivpr1, pic->iivpr1); + + pic->iivpr2 = 0x810002; /* 50240 enable ddr interrupts */ + debug("iivpr2@%x = %x\n",&pic->iivpr2, pic->iivpr2); + + pic->iivpr3 = 0x810003; /* 50260 enable lbc interrupts */ + debug("iivpr3@%x = %x\n",&pic->iivpr3, pic->iivpr3); + +#ifdef CONFIG_PCI1 + pic->iivpr8 = 0x810008; /* enable pci1 interrupts */ + debug("iivpr8@%x = %x\n",&pic->iivpr8, pic->iivpr8); +#endif +#if defined(CONFIG_PCI2) || defined(CONFIG_PCIE2) + pic->iivpr9 = 0x810009; /* enable pci1 interrupts */ + debug("iivpr9@%x = %x\n",&pic->iivpr9, pic->iivpr9); +#endif +#ifdef CONFIG_PCIE1 + pic->iivpr10 = 0x81000a; /* enable pcie1 interrupts */ + debug("iivpr10@%x = %x\n",&pic->iivpr10, pic->iivpr10); +#endif +#ifdef CONFIG_PCIE3 + pic->iivpr11 = 0x81000b; /* enable pcie3 interrupts */ + debug("iivpr11@%x = %x\n",&pic->iivpr11, pic->iivpr11); +#endif + + pic->ctpr=0; /* 40080 clear current task priority register */ +#endif + return (0); } diff --git a/cpu/mpc85xx/start.S b/cpu/mpc85xx/start.S index 77c155c5bdc..9dfd38d6a0d 100644 --- a/cpu/mpc85xx/start.S +++ b/cpu/mpc85xx/start.S @@ -1,7 +1,6 @@ /* - * Copyright 2004 Freescale Semiconductor. + * Copyright 2004, 2007 Freescale Semiconductor. * Copyright (C) 2003 Motorola,Inc. - * Xianghua Xiao * * See file CREDITS for list of people who contributed to this * project. @@ -46,7 +45,7 @@ #endif #undef MSR_KERNEL -#define MSR_KERNEL ( MSR_ME ) /* Machine Check */ +#define MSR_KERNEL ( MSR_ME ) /* Machine Check */ /* * Set up GOT: Global Offset Table @@ -80,110 +79,37 @@ * */ - .section .bootpg,"ax" - .globl _start_e500 + .section .bootpg,"ax" + .globl _start_e500 _start_e500: - mfspr r0, PVR - lis r1, PVR_85xx_REV1@h - ori r1, r1, PVR_85xx_REV1@l - cmpw r0, r1 - bne 1f - /* Semi-bogus errata fixup for Rev 1 */ - li r0,0x2000 - mtspr 977,r0 +/* clear registers/arrays not reset by hardware */ - /* - * Before invalidating MMU L1/L2, read TLB1 Entry 0 and then - * write it back immediately to fixup a Rev 1 bug (Errata CPU4) - * for this initial TLB1 entry 0, otherwise the TLB1 entry 0 - * will be invalidated (incorrectly). - */ - lis r2,0x1000 - mtspr MAS0,r2 - tlbre - tlbwe - isync - -1: - /* - * Clear and set up some registers. - * Note: Some registers need strict synchronization by - * sync/mbar/msync/isync when being "mtspr". - * BookE: isync before PID,tlbivax,tlbwe - * BookE: isync after MSR,PID; msync_isync after tlbivax & tlbwe - * E500: msync,isync before L1CSR0 - * E500: isync after BBEAR,BBTAR,BUCSR,DBCR0,DBCR1,HID0,HID1, - * L1CSR0, L1CSR1, MAS[0,1,2,3,4,6],MMUCSR0, PID[0,1,2], - * SPEFCSR - */ - - /* invalidate d-cache */ - mfspr r0,L1CSR0 - ori r0,r0,0x0002 - msync - isync - mtspr L1CSR0,r0 - isync - - /* disable d-cache */ - li r0,0x0 - mtspr L1CSR0,r0 - - /* invalidate i-cache */ - mfspr r0,L1CSR1 - ori r0,r0,0x0002 - mtspr L1CSR1,r0 - isync - - /* disable i-cache */ - li r0,0x0 - mtspr L1CSR1,r0 - isync - - /* clear registers */ - li r0,0 - mtspr SRR0,r0 - mtspr SRR1,r0 - mtspr CSRR0,r0 - mtspr CSRR1,r0 - mtspr MCSRR0,r0 - mtspr MCSRR1,r0 - - mtspr ESR,r0 - mtspr MCSR,r0 - mtspr DEAR,r0 - - /* not needed and conflicts with some debuggers */ - /* mtspr DBCR0,r0 */ - mtspr DBCR1,r0 - mtspr DBCR2,r0 - /* not needed and conflicts with some debuggers */ - /* mtspr IAC1,r0 */ - /* mtspr IAC2,r0 */ - mtspr DAC1,r0 - mtspr DAC2,r0 + /* L1 */ + li r0,2 + mtspr L1CSR0,r0 /* invalidate d-cache */ + mtspr L1CSR1,r0 /* invalidate i-cache */ mfspr r1,DBSR mtspr DBSR,r1 /* Clear all valid bits */ - mtspr PID0,r0 - mtspr PID1,r0 - mtspr PID2,r0 - mtspr TCR,r0 + /* + * Enable L1 Caches early + * + */ - mtspr BUCSR,r0 /* disable branch prediction */ - mtspr MAS4,r0 - mtspr MAS6,r0 -#if defined(CONFIG_ENABLE_36BIT_PHYS) - mtspr MAS7,r0 -#endif + lis r2,L1CSR0_CPE@H /* enable parity */ + ori r2,r2,L1CSR0_DCE + mtspr L1CSR0,r2 /* enable L1 Dcache */ + isync + mtspr L1CSR1,r2 /* enable L1 Icache */ isync + msync /* Setup interrupt vectors */ lis r1,TEXT_BASE@h - mtspr IVPR, r1 + mtspr IVPR,r1 li r1,0x0100 mtspr IVOR0,r1 /* 0: Critical input */ @@ -217,26 +143,6 @@ _start_e500: li r1,0x0f00 mtspr IVOR15,r1 /* 15: Debug */ - /* - * Invalidate MMU L1/L2 - * - * Note: There is a fixup earlier for Errata CPU4 on - * Rev 1 parts that must precede this MMU invalidation. - */ - li r2, 0x001e - mtspr MMUCSR0, r2 - isync - - /* - * Invalidate all TLB0 entries. - */ - li r3,4 - li r4,0 - tlbivax r4,r3 - /* - * To avoid REV1 Errata CPU6 issues, make sure - * the instruction following tlbivax is not a store. - */ /* * After reset, CCSRBAR is located at CFG_CCSRBAR_DEFAULT, i.e. @@ -254,14 +160,14 @@ _start_e500: lwzu r4,0(r5) /* how many TLB1 entries we actually use */ mtctr r4 -0: lwzu r0,4(r5) - lwzu r1,4(r5) - lwzu r2,4(r5) - lwzu r3,4(r5) - mtspr MAS0,r0 - mtspr MAS1,r1 - mtspr MAS2,r2 - mtspr MAS3,r3 +0: lwzu r6,4(r5) + lwzu r7,4(r5) + lwzu r8,4(r5) + lwzu r9,4(r5) + mtspr MAS0,r6 + mtspr MAS1,r7 + mtspr MAS2,r8 + mtspr MAS3,r9 isync msync tlbwe @@ -271,22 +177,22 @@ _start_e500: 1: #if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR) /* Special sequence needed to update CCSRBAR itself */ - lis r4, CFG_CCSRBAR_DEFAULT@h - ori r4, r4, CFG_CCSRBAR_DEFAULT@l + lis r4,CFG_CCSRBAR_DEFAULT@h + ori r4,r4,CFG_CCSRBAR_DEFAULT@l - lis r5, CFG_CCSRBAR@h - ori r5, r5, CFG_CCSRBAR@l + lis r5,CFG_CCSRBAR@h + ori r5,r5,CFG_CCSRBAR@l srwi r6,r5,12 - stw r6, 0(r4) + stw r6,0(r4) isync - lis r5, 0xffff + lis r5,0xffff ori r5,r5,0xf000 - lwz r5, 0(r5) + lwz r5,0(r5) isync - lis r3, CFG_CCSRBAR@h - lwz r5, CFG_CCSRBAR@l(r3) + lis r3,CFG_CCSRBAR@h + lwz r5,CFG_CCSRBAR@l(r3) isync #endif @@ -300,8 +206,8 @@ _start_e500: 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 + li r2,0x0c28 /* the first pair is reserved for */ + li r1,0x0c30 /* boot-over-rio-or-pci */ 0: lwzu r4,4(r6) lwzu r3,4(r6) @@ -311,31 +217,6 @@ _start_e500: addi r1,r1,0x0020 bdnz 0b - /* Jump out the last 4K page and continue to 'normal' start */ -1: bl 3f - b _start - -3: li r0,0 - mtspr SRR1,r0 /* Keep things disabled for now */ - mflr r1 - mtspr SRR0,r1 - rfi - -/* - * r3 - 1st arg to board_init(): IMMP pointer - * r4 - 2nd arg to board_init(): boot flag - */ - .text - .long 0x27051956 /* U-BOOT Magic Number */ - .globl version_string -version_string: - .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" - .ascii CONFIG_IDENT_STRING, "\0" - - . = EXC_OFF_SYS_RESET - .globl _start -_start: /* Clear and set up some registers. */ li r0,0x0000 lis r1,0xffff @@ -354,17 +235,14 @@ _start: /* Enable Time Base and Select Time Base Clock */ lis r0,HID0_EMCP@h /* Enable machine check */ - ori r0,r0,0x4000 /* time base is processor clock */ #if defined(CONFIG_ENABLE_36BIT_PHYS) - ori r0,r0,0x0080 /* enable MAS7 updates */ + ori r0,r0,(HID0_TBEN|HID0_ENMAS7)@l /* Enable Timebase & MAS7 */ +#else + ori r0,r0,HID0_TBEN@l /* enable Timebase */ #endif mtspr HID0,r0 -#if defined(CONFIG_ADDR_STREAMING) - li r0,0x3000 -#else - li r0,0x1000 -#endif + li r0,(HID1_ASTME|HID1_ABE)@l /* Addr streaming & broadcast */ mtspr HID1,r0 /* Enable Branch Prediction */ @@ -382,35 +260,56 @@ _start: mtspr DBCR0,r0 #endif -/* L1 DCache is used for initial RAM */ - mfspr r2, L1CSR0 - ori r2, r2, 0x0003 - oris r2, r2, 0x0001 - mtspr L1CSR0, r2 /* enable/invalidate L1 Dcache */ + /* Jump out the last 4K page and continue to 'normal' start */ + bl 3f + b _start_cont + +3: li r0,0 + mtspr SRR1,r0 /* Keep things disabled for now */ + mflr r1 + mtspr SRR0,r1 + rfi isync + + .text + .globl _start +_start: + .long 0x27051956 /* U-BOOT Magic Number */ + .globl version_string +version_string: + .ascii U_BOOT_VERSION + .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii CONFIG_IDENT_STRING, "\0" + + .align 4 + .globl _start_cont +_start_cont: + +/* L1 DCache is used for initial RAM */ + /* Allocate Initial RAM in data cache. */ - lis r3, CFG_INIT_RAM_ADDR@h - ori r3, r3, CFG_INIT_RAM_ADDR@l - li r2, 512 /* 512*32=16K */ + lis r3,CFG_INIT_RAM_ADDR@h + ori r3,r3,CFG_INIT_RAM_ADDR@l + li r2,512 /* 512*32=16K */ mtctr r2 - li r0, 0 + li r0,0 1: - dcbz r0, r3 - dcbtls 0,r0, r3 - addi r3, r3, 32 + dcbz r0,r3 + dcbtls 0,r0,r3 + addi r3,r3,32 bdnz 1b #ifndef CFG_RAMBOOT /* Calculate absolute address in FLASH and jump there */ /*--------------------------------------------------------------*/ - lis r3, CFG_MONITOR_BASE@h - ori r3, r3, CFG_MONITOR_BASE@l - addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET + lis r3,CFG_MONITOR_BASE@h + ori r3,r3,CFG_MONITOR_BASE@l + addi r3,r3,in_flash - _start + _START_OFFSET mtlr r3 blr - + .global in_flash in_flash: #endif /* CFG_RAMBOOT */ @@ -424,26 +323,24 @@ in_flash: stwu r1,-8(r1) /* Save back chain and move SP */ lis r0,RESET_VECTOR@h /* Address of reset vector */ - ori r0,r0, RESET_VECTOR@l + ori r0,r0,RESET_VECTOR@l stwu r1,-8(r1) /* Save back chain and move SP */ stw r0,+12(r1) /* Save return addr (underflow vect) */ GET_GOT bl cpu_init_f - bl icache_enable bl board_init_f isync -/* --FIXME-- machine check with MCSRRn and rfmci */ - + . = EXC_OFF_SYS_RESET .globl _start_of_vectors _start_of_vectors: -#if 0 + /* Critical input. */ - CRIT_EXCEPTION(0x0100, CritcalInput, CritcalInputException) -#endif -/* Machine check --FIXME-- Should be MACH_EXCEPTION */ - CRIT_EXCEPTION(0x0200, MachineCheck, MachineCheckException) + CRIT_EXCEPTION(0x0100, CriticalInput, CritcalInputException) + +/* Machine check */ + MCK_EXCEPTION(0x200, MachineCheck, MachineCheckException) /* Data Storage exception. */ STD_EXCEPTION(0x0300, DataStorage, UnknownException) @@ -452,7 +349,7 @@ _start_of_vectors: STD_EXCEPTION(0x0400, InstStorage, UnknownException) /* External Interrupt exception. */ - STD_EXCEPTION(0x0500, ExtInterrupt, UnknownException) + STD_EXCEPTION(0x0500, ExtInterrupt, ExtIntException) /* Alignment exception. */ . = 0x0600 @@ -469,8 +366,8 @@ Alignment: mtlr r6 blrl .L_Alignment: - .long AlignmentException - _start + EXC_OFF_SYS_RESET - .long int_return - _start + EXC_OFF_SYS_RESET + .long AlignmentException - _start + _START_OFFSET + .long int_return - _start + _START_OFFSET /* Program check exception */ . = 0x0700 @@ -483,8 +380,8 @@ ProgramCheck: mtlr r6 blrl .L_ProgramCheck: - .long ProgramCheckException - _start + EXC_OFF_SYS_RESET - .long int_return - _start + EXC_OFF_SYS_RESET + .long ProgramCheckException - _start + _START_OFFSET + .long int_return - _start + _START_OFFSET /* No FPU on MPC85xx. This exception is not supposed to happen. */ @@ -496,23 +393,23 @@ ProgramCheck: * r3-... arguments */ SystemCall: - addis r11,r0,0 /* get functions table addr */ - ori r11,r11,0 /* Note: this code is patched in trap_init */ - addis r12,r0,0 /* get number of functions */ + addis r11,r0,0 /* get functions table addr */ + ori r11,r11,0 /* Note: this code is patched in trap_init */ + addis r12,r0,0 /* get number of functions */ ori r12,r12,0 - cmplw 0, r0, r12 + cmplw 0,r0,r12 bge 1f - rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */ + rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */ add r11,r11,r0 lwz r11,0(r11) - li r20,0xd00-4 /* Get stack pointer */ + li r20,0xd00-4 /* Get stack pointer */ lwz r12,0(r20) - subi r12,r12,12 /* Adjust stack pointer */ + subi r12,r12,12 /* Adjust stack pointer */ li r0,0xc00+_end_back-SystemCall - cmplw 0, r0, r12 /* Check stack overflow */ + cmplw 0,r0,r12 /* Check stack overflow */ bgt 1f stw r12,0(r20) @@ -570,7 +467,7 @@ _end_back: _end_of_vectors: - . = 0x2100 + . = . + (0x100 - ( . & 0xff )) /* align for debug */ /* * This code finishes saving the registers to the exception frame @@ -655,26 +552,58 @@ crit_return: REST_GPR(31, r1) lwz r2,_NIP(r1) /* Restore environment */ lwz r0,_MSR(r1) - mtspr 990,r2 /* SRR2 */ - mtspr 991,r0 /* SRR3 */ + mtspr SPRN_CSRR0,r2 + mtspr SPRN_CSRR1,r0 lwz r0,GPR0(r1) lwz r2,GPR2(r1) lwz r1,GPR1(r1) SYNC rfci +mck_return: + mfmsr r28 /* Disable interrupts */ + li r4,0 + ori r4,r4,MSR_EE + andc r28,r28,r4 + SYNC /* Some chip revs need this... */ + mtmsr r28 + SYNC + lwz r2,_CTR(r1) + lwz r0,_LINK(r1) + mtctr r2 + mtlr r0 + lwz r2,_XER(r1) + lwz r0,_CCR(r1) + mtspr XER,r2 + mtcrf 0xFF,r0 + REST_10GPRS(3, r1) + REST_10GPRS(13, r1) + REST_8GPRS(23, r1) + REST_GPR(31, r1) + lwz r2,_NIP(r1) /* Restore environment */ + lwz r0,_MSR(r1) + mtspr SPRN_MCSRR0,r2 + mtspr SPRN_MCSRR1,r0 + lwz r0,GPR0(r1) + lwz r2,GPR2(r1) + lwz r1,GPR1(r1) + SYNC + rfmci + /* Cache functions. */ invalidate_icache: mfspr r0,L1CSR1 - ori r0,r0,0x0002 + ori r0,r0,L1CSR1_ICFI + msync + isync mtspr L1CSR1,r0 isync - blr /* entire I cache */ + blr /* entire I cache */ invalidate_dcache: mfspr r0,L1CSR0 - ori r0,r0,0x0002 + ori r0,r0,L1CSR0_DCFI msync isync mtspr L1CSR0,r0 @@ -697,9 +626,9 @@ icache_enable: .globl icache_disable icache_disable: mfspr r0,L1CSR1 - lis r1,0xfffffffe@h - ori r1,r1,0xfffffffe@l - and r0,r0,r1 + lis r3,0 + ori r3,r3,L1CSR1_ICE + andc r0,r0,r3 mtspr L1CSR1,r0 isync blr @@ -707,7 +636,7 @@ icache_disable: .globl icache_status icache_status: mfspr r3,L1CSR1 - andi. r3,r3,1 + andi. r3,r3,L1CSR1_ICE blr .globl dcache_enable @@ -727,12 +656,10 @@ dcache_enable: .globl dcache_disable dcache_disable: - mfspr r0,L1CSR0 - lis r1,0xfffffffe@h - ori r1,r1,0xfffffffe@l - and r0,r0,r1 - msync - isync + mfspr r3,L1CSR0 + lis r4,0 + ori r4,r4,L1CSR0_DCE + andc r3,r3,r4 mtspr L1CSR0,r0 isync blr @@ -740,27 +667,27 @@ dcache_disable: .globl dcache_status dcache_status: mfspr r3,L1CSR0 - andi. r3,r3,1 + andi. r3,r3,L1CSR0_DCE blr .globl get_pir get_pir: - mfspr r3, PIR + mfspr r3,PIR blr .globl get_pvr get_pvr: - mfspr r3, PVR + mfspr r3,PVR blr .globl get_svr get_svr: - mfspr r3, SVR + mfspr r3,SVR blr .globl wr_tcr wr_tcr: - mtspr TCR, r3 + mtspr TCR,r3 blr /*------------------------------------------------------------------------------- */ @@ -913,16 +840,16 @@ ppcSync: */ .globl relocate_code relocate_code: - mr r1, r3 /* Set new stack pointer */ - mr r9, r4 /* Save copy of Init Data pointer */ - mr r10, r5 /* Save copy of Destination Address */ + mr r1,r3 /* Set new stack pointer */ + mr r9,r4 /* Save copy of Init Data pointer */ + mr r10,r5 /* Save copy of Destination Address */ - mr r3, r5 /* Destination Address */ - lis r4, CFG_MONITOR_BASE@h /* Source Address */ - ori r4, r4, CFG_MONITOR_BASE@l + 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) sub r5,r5,r4 - li r6, CFG_CACHELINE_SIZE /* Cache Line Size */ + li r6,CFG_CACHELINE_SIZE /* Cache Line Size */ /* * Fix GOT pointer: @@ -931,12 +858,12 @@ relocate_code: * * Offset: */ - sub r15, r10, r4 + sub r15,r10,r4 /* First our own GOT */ - add r14, r14, r15 + add r14,r14,r15 /* the the one used by the C code */ - add r30, r30, r15 + add r30,r30,r15 /* * Now relocate code @@ -997,10 +924,10 @@ relocate_code: * initialization, now running from RAM. */ - addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET + addi r0,r10,in_ram - _start + _START_OFFSET mtlr r0 blr /* NEVER RETURNS! */ - + .globl in_ram in_ram: /* @@ -1044,19 +971,19 @@ clear_bss: lwz r3,GOT(__bss_start) lwz r4,GOT(_end) - cmplw 0, r3, r4 + cmplw 0,r3,r4 beq 6f - li r0, 0 + li r0,0 5: - stw r0, 0(r3) - addi r3, r3, 4 - cmplw 0, r3, r4 + stw r0,0(r3) + addi r3,r3,4 + cmplw 0,r3,r4 bne 5b 6: - mr r3, r9 /* Init Data pointer */ - mr r4, r10 /* Destination Address */ + mr r3,r9 /* Init Data pointer */ + mr r4,r10 /* Destination Address */ bl board_init_r /* @@ -1067,52 +994,54 @@ clear_bss: */ .globl trap_init trap_init: - lwz r7, GOT(_start) - lwz r8, GOT(_end_of_vectors) + lwz r7,GOT(_start_of_vectors) + lwz r8,GOT(_end_of_vectors) - li r9, 0x100 /* reset vector always at 0x100 */ + li r9,0x100 /* reset vector always at 0x100 */ - cmplw 0, r7, r8 + cmplw 0,r7,r8 bgelr /* return if r7>=r8 - just in case */ mflr r4 /* save link register */ 1: - lwz r0, 0(r7) - stw r0, 0(r9) - addi r7, r7, 4 - addi r9, r9, 4 - cmplw 0, r7, r8 + lwz r0,0(r7) + stw r0,0(r9) + addi r7,r7,4 + addi r9,r9,4 + cmplw 0,r7,r8 bne 1b /* * relocate `hdlr' and `int_return' entries */ - li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET + li r7,.L_CriticalInput - _start + _START_OFFSET bl trap_reloc - li r7, .L_DataStorage - _start + EXC_OFF_SYS_RESET + li r7,.L_MachineCheck - _start + _START_OFFSET bl trap_reloc - li r7, .L_InstStorage - _start + EXC_OFF_SYS_RESET + li r7,.L_DataStorage - _start + _START_OFFSET bl trap_reloc - li r7, .L_ExtInterrupt - _start + EXC_OFF_SYS_RESET + li r7,.L_InstStorage - _start + _START_OFFSET bl trap_reloc - li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET + li r7,.L_ExtInterrupt - _start + _START_OFFSET bl trap_reloc - li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET + li r7,.L_Alignment - _start + _START_OFFSET bl trap_reloc - li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET + li r7,.L_ProgramCheck - _start + _START_OFFSET bl trap_reloc - li r7, .L_Decrementer - _start + EXC_OFF_SYS_RESET + li r7,.L_FPUnavailable - _start + _START_OFFSET bl trap_reloc - li r7, .L_IntervalTimer - _start + EXC_OFF_SYS_RESET - li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET + li r7,.L_Decrementer - _start + _START_OFFSET + bl trap_reloc + li r7,.L_IntervalTimer - _start + _START_OFFSET + li r8,_end_of_vectors - _start + _START_OFFSET 2: bl trap_reloc - addi r7, r7, 0x100 /* next exception vector */ - cmplw 0, r7, r8 + addi r7,r7,0x100 /* next exception vector */ + cmplw 0,r7,r8 blt 2b lis r7,0x0 - mtspr IVPR, r7 + mtspr IVPR,r7 mtlr r4 /* restore link register */ blr @@ -1121,13 +1050,13 @@ trap_init: * Function: relocate entries for one exception vector */ trap_reloc: - lwz r0, 0(r7) /* hdlr ... */ - add r0, r0, r3 /* ... += dest_addr */ - stw r0, 0(r7) + lwz r0,0(r7) /* hdlr ... */ + add r0,r0,r3 /* ... += dest_addr */ + stw r0,0(r7) - lwz r0, 4(r7) /* int_return ... */ - add r0, r0, r3 /* ... += dest_addr */ - stw r0, 4(r7) + lwz r0,4(r7) /* int_return ... */ + add r0,r0,r3 /* ... += dest_addr */ + stw r0,4(r7) blr @@ -1135,13 +1064,13 @@ trap_reloc: .globl unlock_ram_in_cache unlock_ram_in_cache: /* invalidate the INIT_RAM section */ - lis r3, (CFG_INIT_RAM_ADDR & ~31)@h - ori r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l - li r2,512 - mtctr r2 -1: icbi r0, r3 - dcbi r0, r3 - addi r3, r3, 32 + lis r3,(CFG_INIT_RAM_ADDR & ~31)@h + ori r3,r3,(CFG_INIT_RAM_ADDR & ~31)@l + li r4,512 + mtctr r4 +1: icbi r0,r3 + dcbi r0,r3 + addi r3,r3,32 bdnz 1b sync /* Wait for all icbi to complete on bus */ isync diff --git a/cpu/mpc85xx/traps.c b/cpu/mpc85xx/traps.c index 9cd621c3ac4..efc80c7aee7 100644 --- a/cpu/mpc85xx/traps.c +++ b/cpu/mpc85xx/traps.c @@ -1,6 +1,7 @@ /* * linux/arch/ppc/kernel/traps.c * + * Copyright 2007 Freescale Semiconductor. * Copyright (C) 2003 Motorola * Modified by Xianghua Xiao(x.xiao@motorola.com) * @@ -145,10 +146,13 @@ CritcalInputException(struct pt_regs *regs) panic("Critical Input Exception"); } +int machinecheck_count = 0; +int machinecheck_error = 0; void MachineCheckException(struct pt_regs *regs) { unsigned long fixup; + unsigned int mcsr, mcsrr0, mcsrr1, mcar; /* Probing PCI using config cycles cause this exception * when a device is not present. Catch it and return to @@ -159,34 +163,62 @@ MachineCheckException(struct pt_regs *regs) return; } + mcsrr0 = mfspr(SPRN_MCSRR0); + mcsrr1 = mfspr(SPRN_MCSRR1); + mcsr = mfspr(SPRN_MCSR); + mcar = mfspr(SPRN_MCAR); + + machinecheck_count++; + machinecheck_error=1; + #if defined(CONFIG_CMD_KGDB) if (debugger_exception_handler && (*debugger_exception_handler)(regs)) return; #endif printf("Machine check in kernel mode.\n"); - printf("Caused by (from msr): "); - printf("regs %p ",regs); - switch( regs->msr & 0x000F0000) { - case (0x80000000>>12): - printf("Machine check signal - probably due to mm fault\n" - "with mmu off\n"); - break; - case (0x80000000>>13): - printf("Transfer error ack signal\n"); - break; - case (0x80000000>>14): - printf("Data parity signal\n"); - break; - case (0x80000000>>15): - printf("Address parity signal\n"); - break; - default: - printf("Unknown values in msr\n"); - } + printf("Caused by (from mcsr): "); + printf("mcsr = 0x%08x\n", mcsr); + if (mcsr & 0x80000000) + printf("Machine check input pin\n"); + if (mcsr & 0x40000000) + printf("Instruction cache parity error\n"); + if (mcsr & 0x20000000) + printf("Data cache push parity error\n"); + if (mcsr & 0x10000000) + printf("Data cache parity error\n"); + if (mcsr & 0x00000080) + printf("Bus instruction address error\n"); + if (mcsr & 0x00000040) + printf("Bus Read address error\n"); + if (mcsr & 0x00000020) + printf("Bus Write address error\n"); + if (mcsr & 0x00000010) + printf("Bus Instruction data bus error\n"); + if (mcsr & 0x00000008) + printf("Bus Read data bus error\n"); + if (mcsr & 0x00000004) + printf("Bus Write bus error\n"); + if (mcsr & 0x00000002) + printf("Bus Instruction parity error\n"); + if (mcsr & 0x00000001) + printf("Bus Read parity error\n"); + show_regs(regs); + printf("MCSR=0x%08x \tMCSRR0=0x%08x \nMCSRR1=0x%08x \tMCAR=0x%08x\n", + mcsr, mcsrr0, mcsrr1, mcar); print_backtrace((unsigned long *)regs->gpr[1]); - panic("machine check"); + if (machinecheck_count > 10) { + panic("machine check count too high\n"); + } + + if (machinecheck_count > 1) { + regs->nip += 4; /* skip offending instruction */ + printf("Skipping current instr, Returning to 0x%08x\n", + regs->nip); + } else { + printf("Returning back to 0x%08x\n",regs->nip); + } } void @@ -253,6 +285,33 @@ UnknownException(struct pt_regs *regs) regs->nip, regs->msr, regs->trap); _exception(0, regs); } +void +ExtIntException(struct pt_regs *regs) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile ccsr_pic_t *pic = &immap->im_pic; + uint vect; + +#if defined(CONFIG_CMD_KGDB) + if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + return; +#endif + + printf("External Interrupt Exception at PC: %lx, SR: %lx, vector=%lx", + regs->nip, regs->msr, regs->trap); + vect = pic->iack0; + printf(" irq IACK0@%05x=%d\n",&pic->iack0,vect); + show_regs(regs); + print_backtrace((unsigned long *)regs->gpr[1]); + machinecheck_count++; +#ifdef EXTINT_NOSKIP + printf("Returning back to 0x%08x\n",regs->nip); +#else + regs->nip += 4; /* skip offending instruction */ + printf("Skipping current instr, Returning to 0x%08x\n",regs->nip); +#endif + +} void DebugException(struct pt_regs *regs) diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h index 9be5a279e26..0a160e2513a 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-ppc/processor.h @@ -217,12 +217,14 @@ #define HID0_DPM (1<<20) #define HID0_ICE (1< -- cgit v1.3.1 From 837f1ba05cfb248aba5ab8e1fb1bfeefa07d5962 Mon Sep 17 00:00:00 2001 From: Ed Swarthout Date: Fri, 27 Jul 2007 01:50:51 -0500 Subject: 8544ds PCIE support PCI1 LAW mapping should use CFG_PCI1_MEM_PHY and not _BASE address. Enable LBC and ECM errors and clear error registers. Add tftpflash env var to get uboot from tftp server and flash it. Add pci/pcie convenience env vars to display register space: "run pcie3regs" to see all pcie3 ccsr registers "run pcie3cfg" to see all cfg registers Whitespace cleanup and MPC8544DS.h Enable CONFIG_INTERRUPTS. Signed-off-by: Ed Swarthout Acked-by: Andy Fleming --- board/freescale/mpc8544ds/init.S | 6 +- board/freescale/mpc8544ds/mpc8544ds.c | 350 ++++++++++++++++++++++++++++++++++ include/asm-ppc/immap_85xx.h | 37 +++- include/configs/MPC8544DS.h | 135 +++++++------ 4 files changed, 468 insertions(+), 60 deletions(-) (limited to 'include/asm-ppc') diff --git a/board/freescale/mpc8544ds/init.S b/board/freescale/mpc8544ds/init.S index 296fee5e606..ea7d54dc302 100644 --- a/board/freescale/mpc8544ds/init.S +++ b/board/freescale/mpc8544ds/init.S @@ -52,8 +52,8 @@ */ #define entry_start \ - mflr r1 ; \ - bl 0f ; + mflr r1 ; \ + bl 0f ; #define entry_end \ 0: mflr r0 ; \ @@ -214,7 +214,7 @@ law_entry: .long 0 .long (LAWAR_TRGT_DDR | (LAWAR_SIZE & LAWAR_SIZE_128M)) & ~LAWAR_EN - .long (CFG_PCI1_MEM_BASE>>12) & 0xfffff + .long (CFG_PCI1_MEM_PHYS>>12) & 0xfffff .long LAWAR_EN | LAWAR_TRGT_PCI1 | (LAWAR_SIZE & LAWAR_SIZE_512M) .long (CFG_PCI1_IO_PHYS>>12) & 0xfffff diff --git a/board/freescale/mpc8544ds/mpc8544ds.c b/board/freescale/mpc8544ds/mpc8544ds.c index 4ff1da93017..8ddbb010119 100644 --- a/board/freescale/mpc8544ds/mpc8544ds.c +++ b/board/freescale/mpc8544ds/mpc8544ds.c @@ -22,8 +22,10 @@ #include #include +#include #include #include +#include #include #include @@ -51,12 +53,19 @@ int checkboard (void) { volatile immap_t *immap = (immap_t *) CFG_CCSRBAR; volatile ccsr_gur_t *gur = &immap->im_gur; + volatile ccsr_lbc_t *lbc = &immap->im_lbc; + volatile ccsr_local_ecm_t *ecm = &immap->im_local_ecm; if ((uint)&gur->porpllsr != 0xe00e0000) { printf("immap size error %x\n",&gur->porpllsr); } printf ("Board: MPC8544DS\n"); + lbc->ltesr = 0xffffffff; /* Clear LBC error interrupts */ + lbc->lteir = 0xffffffff; /* Enable LBC error interrupts */ + ecm->eedr = 0xffffffff; /* Clear ecm errors */ + ecm->eeer = 0xffffffff; /* Enable ecm errors */ + return 0; } @@ -118,6 +127,316 @@ testdram(void) } #endif +#ifdef CONFIG_PCI1 +static struct pci_controller pci1_hose; +#endif + +#ifdef CONFIG_PCIE1 +static struct pci_controller pcie1_hose; +#endif + +#ifdef CONFIG_PCIE2 +static struct pci_controller pcie2_hose; +#endif + +#ifdef CONFIG_PCIE3 +static struct pci_controller pcie3_hose; +#endif + +int first_free_busno=0; + +void +pci_init_board(void) +{ + volatile immap_t *immap = (immap_t *)CFG_IMMR; + volatile ccsr_gur_t *gur = &immap->im_gur; + uint devdisr = gur->devdisr; + uint io_sel = (gur->pordevsr & MPC85xx_PORDEVSR_IO_SEL) >> 19; + uint host_agent = (gur->porbmsr & MPC85xx_PORBMSR_HA) >> 16; + + debug (" pci_init_board: devdisr=%x, io_sel=%x, host_agent=%x\n", + devdisr, io_sel, host_agent); + + if (io_sel & 1) { + if (!(gur->pordevsr & MPC85xx_PORDEVSR_SGMII1_DIS)) + printf (" eTSEC1 is in sgmii mode.\n"); + if (!(gur->pordevsr & MPC85xx_PORDEVSR_SGMII3_DIS)) + printf (" eTSEC3 is in sgmii mode.\n"); + } + +#ifdef CONFIG_PCIE3 +{ + volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) CFG_PCIE3_ADDR; + extern void fsl_pci_init(struct pci_controller *hose); + struct pci_controller *hose = &pcie3_hose; + int pcie_ep = (host_agent == 3); + int pcie_configured = io_sel >= 1; + + if (pcie_configured && !(devdisr & MPC85xx_DEVDISR_PCIE)){ + printf ("\n PCIE3 connected to ULI as %s (base address %x)", + pcie_ep ? "End Point" : "Root Complex", + (uint)pci); + if (pci->pme_msg_det) { + pci->pme_msg_det = 0xffffffff; + debug (" with errors. Clearing. Now 0x%08x",pci->pme_msg_det); + } + printf ("\n"); + + /* inbound */ + pci_set_region(hose->regions + 0, + CFG_PCI_MEMORY_BUS, + CFG_PCI_MEMORY_PHYS, + CFG_PCI_MEMORY_SIZE, + PCI_REGION_MEM | PCI_REGION_MEMORY); + + /* outbound memory */ + pci_set_region(hose->regions + 1, + CFG_PCIE3_MEM_BASE, + CFG_PCIE3_MEM_PHYS, + CFG_PCIE3_MEM_SIZE, + PCI_REGION_MEM); + + /* outbound io */ + pci_set_region(hose->regions + 2, + CFG_PCIE3_IO_BASE, + CFG_PCIE3_IO_PHYS, + CFG_PCIE3_IO_SIZE, + PCI_REGION_IO); + + hose->region_count = 3; +#ifdef CFG_PCIE3_MEM_BASE2 + /* outbound memory */ + pci_set_region(hose->regions + 3, + CFG_PCIE3_MEM_BASE2, + CFG_PCIE3_MEM_PHYS2, + CFG_PCIE3_MEM_SIZE2, + PCI_REGION_MEM); + hose->region_count++; +#endif + hose->first_busno=first_free_busno; + pci_setup_indirect(hose, (int) &pci->cfg_addr, (int) &pci->cfg_data); + + fsl_pci_init(hose); + + first_free_busno=hose->last_busno+1; + printf (" PCIE3 on bus %02x - %02x\n", + hose->first_busno,hose->last_busno); + + } else { + printf (" PCIE3: disabled\n"); + } + + } +#else + gur->devdisr |= MPC85xx_DEVDISR_PCIE3; /* disable */ +#endif + +#ifdef CONFIG_PCIE1 + { + volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) CFG_PCIE1_ADDR; + extern void fsl_pci_init(struct pci_controller *hose); + struct pci_controller *hose = &pcie1_hose; + int pcie_ep = (host_agent == 5); + int pcie_configured = io_sel & 6; + + if (pcie_configured && !(devdisr & MPC85xx_DEVDISR_PCIE)){ + printf ("\n PCIE1 connected to Slot2 as %s (base address %x)", + pcie_ep ? "End Point" : "Root Complex", + (uint)pci); + if (pci->pme_msg_det) { + pci->pme_msg_det = 0xffffffff; + debug (" with errors. Clearing. Now 0x%08x",pci->pme_msg_det); + } + printf ("\n"); + + /* inbound */ + pci_set_region(hose->regions + 0, + CFG_PCI_MEMORY_BUS, + CFG_PCI_MEMORY_PHYS, + CFG_PCI_MEMORY_SIZE, + PCI_REGION_MEM | PCI_REGION_MEMORY); + + /* outbound memory */ + pci_set_region(hose->regions + 1, + CFG_PCIE1_MEM_BASE, + CFG_PCIE1_MEM_PHYS, + CFG_PCIE1_MEM_SIZE, + PCI_REGION_MEM); + + /* outbound io */ + pci_set_region(hose->regions + 2, + CFG_PCIE1_IO_BASE, + CFG_PCIE1_IO_PHYS, + CFG_PCIE1_IO_SIZE, + PCI_REGION_IO); + + hose->region_count = 3; +#ifdef CFG_PCIE1_MEM_BASE2 + /* outbound memory */ + pci_set_region(hose->regions + 3, + CFG_PCIE1_MEM_BASE2, + CFG_PCIE1_MEM_PHYS2, + CFG_PCIE1_MEM_SIZE2, + PCI_REGION_MEM); + hose->region_count++; +#endif + hose->first_busno=first_free_busno; + + pci_setup_indirect(hose, (int) &pci->cfg_addr, (int) &pci->cfg_data); + + fsl_pci_init(hose); + + first_free_busno=hose->last_busno+1; + printf(" PCIE1 on bus %02x - %02x\n", + hose->first_busno,hose->last_busno); + + } else { + printf (" PCIE1: disabled\n"); + } + + } +#else + gur->devdisr |= MPC85xx_DEVDISR_PCIE; /* disable */ +#endif + +#ifdef CONFIG_PCIE2 + { + volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) CFG_PCIE2_ADDR; + extern void fsl_pci_init(struct pci_controller *hose); + struct pci_controller *hose = &pcie2_hose; + int pcie_ep = (host_agent == 3); + int pcie_configured = io_sel & 4; + + if (pcie_configured && !(devdisr & MPC85xx_DEVDISR_PCIE)){ + printf ("\n PCIE2 connected to Slot 1 as %s (base address %x)", + pcie_ep ? "End Point" : "Root Complex", + (uint)pci); + if (pci->pme_msg_det) { + pci->pme_msg_det = 0xffffffff; + debug (" with errors. Clearing. Now 0x%08x",pci->pme_msg_det); + } + printf ("\n"); + + /* inbound */ + pci_set_region(hose->regions + 0, + CFG_PCI_MEMORY_BUS, + CFG_PCI_MEMORY_PHYS, + CFG_PCI_MEMORY_SIZE, + PCI_REGION_MEM | PCI_REGION_MEMORY); + + /* outbound memory */ + pci_set_region(hose->regions + 1, + CFG_PCIE2_MEM_BASE, + CFG_PCIE2_MEM_PHYS, + CFG_PCIE2_MEM_SIZE, + PCI_REGION_MEM); + + /* outbound io */ + pci_set_region(hose->regions + 2, + CFG_PCIE2_IO_BASE, + CFG_PCIE2_IO_PHYS, + CFG_PCIE2_IO_SIZE, + PCI_REGION_IO); + + hose->region_count = 3; +#ifdef CFG_PCIE2_MEM_BASE2 + /* outbound memory */ + pci_set_region(hose->regions + 3, + CFG_PCIE2_MEM_BASE2, + CFG_PCIE2_MEM_PHYS2, + CFG_PCIE2_MEM_SIZE2, + PCI_REGION_MEM); + hose->region_count++; +#endif + hose->first_busno=first_free_busno; + pci_setup_indirect(hose, (int) &pci->cfg_addr, (int) &pci->cfg_data); + + fsl_pci_init(hose); + first_free_busno=hose->last_busno+1; + printf (" PCIE2 on bus %02x - %02x\n", + hose->first_busno,hose->last_busno); + + } else { + printf (" PCIE2: disabled\n"); + } + + } +#else + gur->devdisr |= MPC85xx_DEVDISR_PCIE2; /* disable */ +#endif + + +#ifdef CONFIG_PCI1 +{ + volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) CFG_PCI1_ADDR; + extern void fsl_pci_init(struct pci_controller *hose); + struct pci_controller *hose = &pci1_hose; + + uint pci_agent = (host_agent == 6); + uint pci_speed = 66666000; /*get_clock_freq (); PCI PSPEED in [4:5] */ + uint pci_32 = 1; + uint pci_arb = gur->pordevsr & MPC85xx_PORDEVSR_PCI1_ARB; /* PORDEVSR[14] */ + uint pci_clk_sel = gur->porpllsr & MPC85xx_PORDEVSR_PCI1_SPD; /* PORPLLSR[16] */ + + + if (!(devdisr & MPC85xx_DEVDISR_PCI1)) { + printf ("\n PCI: %d bit, %s MHz, %s, %s, %s (base address %x)\n", + (pci_32) ? 32 : 64, + (pci_speed == 33333000) ? "33" : + (pci_speed == 66666000) ? "66" : "unknown", + pci_clk_sel ? "sync" : "async", + pci_agent ? "agent" : "host", + pci_arb ? "arbiter" : "external-arbiter", + (uint)pci + ); + + /* inbound */ + pci_set_region(hose->regions + 0, + CFG_PCI_MEMORY_BUS, + CFG_PCI_MEMORY_PHYS, + CFG_PCI_MEMORY_SIZE, + PCI_REGION_MEM | PCI_REGION_MEMORY); + + /* outbound memory */ + pci_set_region(hose->regions + 1, + CFG_PCI1_MEM_BASE, + CFG_PCI1_MEM_PHYS, + CFG_PCI1_MEM_SIZE, + PCI_REGION_MEM); + + /* outbound io */ + pci_set_region(hose->regions + 2, + CFG_PCI1_IO_BASE, + CFG_PCI1_IO_PHYS, + CFG_PCI1_IO_SIZE, + PCI_REGION_IO); + hose->region_count = 3; +#ifdef CFG_PCIE3_MEM_BASE2 + /* outbound memory */ + pci_set_region(hose->regions + 3, + CFG_PCIE3_MEM_BASE2, + CFG_PCIE3_MEM_PHYS2, + CFG_PCIE3_MEM_SIZE2, + PCI_REGION_MEM); + hose->region_count++; +#endif + hose->first_busno=first_free_busno; + pci_setup_indirect(hose, (int) &pci->cfg_addr, (int) &pci->cfg_data); + + fsl_pci_init(hose); + first_free_busno=hose->last_busno+1; + printf ("PCI on bus %02x - %02x\n", + hose->first_busno,hose->last_busno); + } else { + printf (" PCI: disabled\n"); + } +} +#else + gur->devdisr |= MPC85xx_DEVDISR_PCI1; /* disable */ +#endif +} + + int last_stage_init(void) { return 0; @@ -192,6 +511,37 @@ ft_board_setup(void *blob, bd_t *bd) ft_cpu_setup(blob, bd); + p = ft_get_prop(blob, "/memory/reg", &len); + if (p != NULL) { + *p++ = cpu_to_be32(bd->bi_memstart); + *p = cpu_to_be32(bd->bi_memsize); + } +#ifdef CONFIG_PCIE1 + p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@a000/bus-range", &len); + if (p != NULL) { + p[0] = 0; + p[1] = pcie1_hose.last_busno - pcie1_hose.first_busno; + debug("PCI@a000 first_busno=%d last_busno=%d\n",p[0],p[1]); + } +#endif +#ifdef CONFIG_PCIE2 + p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@9000/bus-range", &len); + if (p != NULL) { + p[0] = 0; + p[1] = pcie2_hose.last_busno - pcie2_hose.first_busno; + debug("PCI@9000 first_busno=%d last_busno=%d\n",p[0],p[1]); + } +#endif +#ifdef CONFIG_PCIE3 + p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@b000/bus-range", &len); + if (p != NULL) { + p[0] = 0; + p[1] = pcie3_hose.last_busno - pcie3_hose.first_busno;; + debug("PCI@b000 first_busno=%d last_busno=%d\n",p[0],p[1]); + } +#endif + ft_cpu_setup(blob, bd); + p = ft_get_prop(blob, "/memory/reg", &len); if (p != NULL) { *p++ = cpu_to_be32(bd->bi_memstart); diff --git a/include/asm-ppc/immap_85xx.h b/include/asm-ppc/immap_85xx.h index e002d2838e9..77f885daa67 100644 --- a/include/asm-ppc/immap_85xx.h +++ b/include/asm-ppc/immap_85xx.h @@ -1,6 +1,8 @@ /* * MPC85xx Internal Memory Map * + * Copyright 2007 Freescale Semiconductor. + * * Copyright(c) 2002,2003 Motorola Inc. * Xianghua Xiao (x.xiao@motorola.com) * @@ -1526,8 +1528,22 @@ typedef struct ccsr_rio { typedef struct ccsr_gur { uint porpllsr; /* 0xe0000 - POR PLL ratio status register */ uint porbmsr; /* 0xe0004 - POR boot mode status register */ +#define MPC85xx_PORBMSR_HA 0x00070000 uint porimpscr; /* 0xe0008 - POR I/O impedance status and control register */ uint pordevsr; /* 0xe000c - POR I/O device status regsiter */ +#define MPC85xx_PORDEVSR_SGMII1_DIS 0x20000000 +#define MPC85xx_PORDEVSR_SGMII2_DIS 0x10000000 +#define MPC85xx_PORDEVSR_SGMII3_DIS 0x08000000 +#define MPC85xx_PORDEVSR_SGMII4_DIS 0x04000000 +#define MPC85xx_PORDEVSR_IO_SEL 0x00380000 +#define MPC85xx_PORDEVSR_PCI2_ARB 0x00040000 +#define MPC85xx_PORDEVSR_PCI1_ARB 0x00020000 +#define MPC85xx_PORDEVSR_PCI1_PCI32 0x00010000 +#define MPC85xx_PORDEVSR_PCI1_SPD 0x00008000 +#define MPC85xx_PORDEVSR_PCI2_SPD 0x00004000 +#define MPC85xx_PORDEVSR_DRAM_RTYPE 0x00000060 +#define MPC85xx_PORDEVSR_RIO_CTLS 0x00000008 +#define MPC85xx_PORDEVSR_RIO_DEV_ID 0x00000007 uint pordbgmsr; /* 0xe0010 - POR debug mode status register */ char res1[12]; uint gpporcr; /* 0xe0020 - General-purpose POR configuration register */ @@ -1541,6 +1557,25 @@ typedef struct ccsr_gur { uint pmuxcr; /* 0xe0060 - Alternate function signal multiplex control */ char res6[12]; uint devdisr; /* 0xe0070 - Device disable control */ +#define MPC85xx_DEVDISR_PCI1 0x80000000 +#define MPC85xx_DEVDISR_PCI2 0x40000000 +#define MPC85xx_DEVDISR_PCIE 0x20000000 +#define MPC85xx_DEVDISR_LBC 0x08000000 +#define MPC85xx_DEVDISR_PCIE2 0x04000000 +#define MPC85xx_DEVDISR_PCIE3 0x02000000 +#define MPC85xx_DEVDISR_SEC 0x01000000 +#define MPC85xx_DEVDISR_SRIO 0x00080000 +#define MPC85xx_DEVDISR_RMSG 0x00040000 +#define MPC85xx_DEVDISR_DDR 0x00010000 +#define MPC85xx_DEVDISR_CPU 0x00008000 +#define MPC85xx_DEVDISR_TB 0x00004000 +#define MPC85xx_DEVDISR_DMA 0x00000400 +#define MPC85xx_DEVDISR_TSEC1 0x00000080 +#define MPC85xx_DEVDISR_TSEC2 0x00000040 +#define MPC85xx_DEVDISR_TSEC3 0x00000020 +#define MPC85xx_DEVDISR_TSEC4 0x00000010 +#define MPC85xx_DEVDISR_I2C 0x00000004 +#define MPC85xx_DEVDISR_DUART 0x00000002 char res7[12]; uint powmgtcsr; /* 0xe0080 - Power management status and control register */ char res8[12]; @@ -1562,7 +1597,7 @@ typedef struct ccsr_gur { uint ddrioovcr; /* 0xe0f24 - DDR IO Override Control */ uint res14; /* 0xe0f28 */ uint tsec34ioovcr; /* 0xe0f2c - eTSEC 3/4 IO override control */ - char res15[61651]; + char res15[61648]; /* 0xe0f30 to 0xefffff */ } ccsr_gur_t; #define PORDEVSR_PCI (0x00800000) /* PCI Mode */ diff --git a/include/configs/MPC8544DS.h b/include/configs/MPC8544DS.h index d0f94a3e220..32934e15506 100644 --- a/include/configs/MPC8544DS.h +++ b/include/configs/MPC8544DS.h @@ -34,14 +34,14 @@ #define CONFIG_MPC8544 1 #define CONFIG_MPC8544DS 1 -#undef CONFIG_PCI /* Enable PCI/PCIE */ -#undef CONFIG_PCI1 /* PCI controller 1 */ -#undef CONFIG_PCIE1 /* PCIE controler 1 (slot 1) */ -#undef CONFIG_PCIE2 /* PCIE controler 2 (slot 2) */ -#undef CONFIG_PCIE3 /* PCIE controler 3 (ULI bridge) */ -#undef CONFIG_FSL_PCI_INIT /* Use common FSL init code */ - -#define CONFIG_TSEC_ENET /* tsec ethernet support */ +#define CONFIG_PCI 1 /* Enable PCI/PCIE */ +#define CONFIG_PCI1 1 /* PCI controller 1 */ +#define CONFIG_PCIE1 1 /* PCIE controler 1 (slot 1) */ +#define CONFIG_PCIE2 1 /* PCIE controler 2 (slot 2) */ +#define CONFIG_PCIE3 1 /* PCIE controler 3 (ULI bridge) */ +#define CONFIG_FSL_PCI_INIT 1 /* Use common FSL init code */ + +#define CONFIG_TSEC_ENET /* tsec ethernet support */ #define CONFIG_ENV_OVERWRITE #define CONFIG_SPD_EEPROM /* Use SPD EEPROM for DDR setup */ #undef CONFIG_DDR_DLL @@ -52,6 +52,7 @@ #define CONFIG_MEM_INIT_VALUE 0xDeadBeef #define CONFIG_DDR_ECC_CMD +#define CONFIG_INTERRUPTS /* enable pci, srio, ddr interrupts */ /* * When initializing flash, if we cannot find the manufacturer ID, @@ -70,7 +71,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); /* * These can be toggled for performance analysis, otherwise use default. */ -#define CONFIG_L2_CACHE /* toggle L2 cache */ +#define CONFIG_L2_CACHE /* toggle L2 cache */ #define CONFIG_BTB /* toggle branch predition */ #define CONFIG_ADDR_STREAMING /* toggle addr streaming */ #define CONFIG_CLEAR_LAW0 /* Clear LAW0 in cpu_init_r */ @@ -86,13 +87,13 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define CFG_MEMTEST_START 0x00200000 /* memtest works on */ #define CFG_MEMTEST_END 0x00400000 #define CFG_ALT_MEMTEST -#define CONFIG_PANIC_HANG /* do not reset board on panic */ +#define CONFIG_PANIC_HANG /* do not reset board on panic */ /* * Base addresses -- Note these are effective addresses where the * actual resources get mapped (not physical addresses) */ -#define CFG_CCSRBAR_DEFAULT 0xff700000 /* CCSRBAR Default */ +#define CFG_CCSRBAR_DEFAULT 0xff700000 /* CCSRBAR Default */ #define CFG_CCSRBAR 0xe0000000 /* relocated CCSRBAR */ #define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */ @@ -344,7 +345,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define CONFIG_SATA_ULI5288 #define CFG_SCSI_MAX_SCSI_ID 4 #define CFG_SCSI_MAX_LUN 1 -#define CFG_SCSI_MAX_DEVICE (CFG_SCSI_MAX_SCSI_ID * CFG_SCSI_MAX_LUN) +#define CFG_SCSI_MAX_DEVICE (CFG_SCSI_MAX_SCSI_ID * CFG_SCSI_MAX_LUN) #define CFG_SCSI_MAXDEVICE CFG_SCSI_MAX_DEVICE #endif /* SCSCI */ @@ -354,7 +355,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #if defined(CONFIG_TSEC_ENET) #ifndef CONFIG_NET_MULTI -#define CONFIG_NET_MULTI 1 +#define CONFIG_NET_MULTI 1 #endif #define CONFIG_MII 1 /* MII PHY management */ @@ -365,6 +366,10 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define CONFIG_TSEC3_NAME "eTSEC3" #undef CONFIG_MPC85XX_FEC +#define CONFIG_TSEC_TBI 1 /* enable internal TBI phy */ +#define CONFIG_SGMII_RISER +#define TSEC1_SGMII_PHY_ADDR_OFFSET 0x1c /* sgmii phy base */ + #define TSEC1_PHY_ADDR 0 #define TSEC3_PHY_ADDR 1 @@ -374,7 +379,6 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define CONFIG_ETHPRIME "eTSEC1" #define CONFIG_PHY_GIGE 1 /* Include GbE speed/duplex detection */ - #endif /* CONFIG_TSEC_ENET */ /* @@ -392,7 +396,6 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ #define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ - /* * BOOTP options */ @@ -415,6 +418,8 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define CONFIG_CMD_PCI #define CONFIG_CMD_BEDBUG #define CONFIG_CMD_NET + #define CONFIG_CMD_SCSI + #define CONFIG_CMD_EXT2 #endif @@ -441,10 +446,10 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); * have to be in the first 8 MB of memory, since this is * the maximum mapped by the Linux kernel during initialization. */ -#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux*/ +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux*/ /* Cache Configuration */ -#define CFG_DCACHE_SIZE 32768 +#define CFG_DCACHE_SIZE 32768 #define CFG_CACHELINE_SIZE 32 #if defined(CONFIG_CMD_KGDB) #define CFG_CACHELINE_SHIFT 5 /*log base 2 of the above value*/ @@ -482,7 +487,8 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define CONFIG_HOSTNAME 8544ds_unknown #define CONFIG_ROOTPATH /nfs/mpc85xx -#define CONFIG_BOOTFILE 8544ds_tmt/uImage.uboot +#define CONFIG_BOOTFILE 8544ds/uImage.uboot +#define CONFIG_UBOOTPATH 8544ds/u-boot.bin /* TFTP server */ #define CONFIG_SERVERIP 192.168.0.1 #define CONFIG_GATEWAYIP 192.168.0.1 @@ -491,7 +497,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define CONFIG_LOADADDR 1000000 /*default location for tftp and bootm*/ #define CONFIG_BOOTDELAY 10 /* -1 disables auto-boot */ -#undef CONFIG_BOOTARGS /* the boot command will set bootargs*/ +#undef CONFIG_BOOTARGS /* the boot command will set bootargs*/ #define CONFIG_BAUDRATE 115200 @@ -499,10 +505,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define PCIE_ENV \ "pciereg=md ${a}000 6; md ${a}020 4; md ${a}bf8 2; echo o;md ${a}c00 25;" \ "echo i; md ${a}da0 15; echo e;md ${a}e00 e; echo d; md ${a}f00 c\0" \ - "pcie1regs=setenv a e000a; run pciereg\0" \ - "pcie2regs=setenv a e0009; run pciereg\0" \ - "pcie3regs=setenv a e000b; run pciereg\0" \ - "pcieerr=md ${a}020 1; md ${a}e00;" \ + "pcieerr=md ${a}020 1; md ${a}e00 e;" \ "pci d.b $b.0 7 1; pci d.w $b.0 1e 1;" \ "pci d.w $b.0 56 1;" \ "pci d $b.0 104 1;pci d $b.0 110 1;pci d $b.0 130 1\0" \ @@ -511,12 +514,18 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); "pci w $b.0 104 ffffffff; pci w $b.0 110 ffffffff;" \ "pci w $b.0 130 ffffffff\0" \ "pciecfg=pci d $b.0 0 20; pci d $b.0 100 e; pci d $b.0 400 69\0" \ - "pcie1err=setenv a e000a; run pcieerr\0" \ - "pcie2err=setenv a e0009; run pcieerr\0" \ - "pcie3err=setenv a e000b; run pcieerr\0" \ - "pcie1errc=setenv a e000a; run pcieerrc\0" \ - "pcie2errc=setenv a e0009; run pcieerrc\0" \ - "pcie3errc=setenv a e000b; run pcieerrc\0" + "pcie1regs=setenv a e000a; run pciereg\0" \ + "pcie2regs=setenv a e0009; run pciereg\0" \ + "pcie3regs=setenv a e000b; run pciereg\0" \ + "pcie1cfg=setenv b 3; run pciecfg\0" \ + "pcie2cfg=setenv b 5; run pciecfg\0" \ + "pcie3cfg=setenv b 0; run pciecfg\0" \ + "pcie1err=setenv a e000a; setenv b 3; run pcieerr\0" \ + "pcie2err=setenv a e0009; setenv b 5; run pcieerr\0" \ + "pcie3err=setenv a e000b; setenv b 0; run pcieerr\0" \ + "pcie1errc=setenv a e000a; setenv b 3; run pcieerrc\0" \ + "pcie2errc=setenv a e0009; setenv b 5; run pcieerrc\0" \ + "pcie3errc=setenv a e000b; setenv b 0; run pcieerrc\0" #else #define PCIE_ENV "" #endif @@ -524,14 +533,14 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #if defined(CONFIG_PCI1) #define PCI_ENV \ "pcireg=md ${a}000 3; echo o;md ${a}c00 25; echo i; md ${a}da0 15;" \ - "echo e;md ${a}e00 9\0" \ + "echo e;md ${a}e00 9\0" \ "pci1regs=setenv a e0008; run pcireg\0" \ "pcierr=md ${a}e00 8; pci d.b $b.0 7 1; pci d.w $b.0 1e 1;" \ "pci d.w $b.0 56 1\0" \ - "pcierrc=mw ${a}e00 ffffffff; pci w.b $b.0 7 ff; pci w.w $b.0 1e ffff;" \ - "pci w.w $b.0 56 ffff\0" \ - "pci1err=setenv a e0008; run pcierr\0" \ - "pci1errc=setenv a e0008; run pcierrc\0" + "pcierrc=mw ${a}e00 ffffffff; mw ${a}e0c 0; pci w.b $b.0 7 ff;" \ + "pci w.w $b.0 1e ffff; pci w.w $b.0 56 ffff\0" \ + "pci1err=setenv a e0008; setenv b 7; run pcierr\0" \ + "pci1errc=setenv a e0008; setenv b 7; run pcierrc\0" #else #define PCI_ENV "" #endif @@ -551,25 +560,39 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define ENET_ENV "" #endif -#define CONFIG_EXTRA_ENV_SETTINGS \ - "netdev=eth0\0" \ +#define CONFIG_EXTRA_ENV_SETTINGS \ + "netdev=eth0\0" \ + "uboot=" MK_STR(CONFIG_UBOOTPATH) "\0" \ + "tftpflash=tftpboot $loadaddr $uboot; " \ + "protect off " MK_STR(TEXT_BASE) " +$filesize; " \ + "erase " MK_STR(TEXT_BASE) " +$filesize; " \ + "cp.b $loadaddr " MK_STR(TEXT_BASE) " $filesize; " \ + "protect on " MK_STR(TEXT_BASE) " +$filesize; " \ + "cmp.b $loadaddr " MK_STR(TEXT_BASE) " $filesize\0" \ "consoledev=ttyS0\0" \ "ramdiskaddr=2000000\0" \ - "ramdiskfile=8544ds_tmt/ramdisk.uboot\0" \ - "fdtaddr=400000\0" \ - "fdtfile=8544ds_tmt/mpc8544ds.dtb\0" \ - "eoi=mw e00400b0 0\0" \ - "iack=md e00400a0 1\0" \ + "ramdiskfile=8544ds/ramdisk.uboot\0" \ + "dtbaddr=c00000\0" \ + "dtbfile=8544ds/mpc8544ds.dtb\0" \ + "bdev=sda3\0" \ + "eoi=mw e00400b0 0\0" \ + "iack=md e00400a0 1\0" \ "ddrreg=md ${a}000 8; md ${a}080 8;md ${a}100 d; md ${a}140 4; md ${a}bf0 4;" \ "md ${a}e00 3; md ${a}e20 3; md ${a}e40 7; md ${a}f00 5\0" \ - "ddrregs=setenv a e0002; run ddrreg\0" \ + "ddrregs=setenv a e0002; run ddrreg\0" \ "gureg=md ${a}000 2c; md ${a}0b0 1; md ${a}0c0 1; md ${a}b20 3;" \ - "md ${a}e00 1; md ${a}e60 1; md ${a}ef0 15\0" \ - "guregs=setenv a e00e0; run gureg\0" \ + "md ${a}e00 1; md ${a}e60 1; md ${a}ef0 15\0" \ + "guregs=setenv a e00e0; run gureg\0" \ "ecmreg=md ${a}000 1; md ${a}010 1; md ${a}bf8 2; md ${a}e00 6\0" \ - "ecmregs=setenv a e0001; run ecmreg\0" \ - PCIE_ENV \ - PCI_ENV \ + "ecmregs=setenv a e0001; run ecmreg\0" \ + "lawregs=md e0000c08 4b\0" \ + "lbcregs=md e0005000 36\0" \ + "dma0regs=md e0021100 12\0" \ + "dma1regs=md e0021180 12\0" \ + "dma2regs=md e0021200 12\0" \ + "dma3regs=md e0021280 12\0" \ + PCIE_ENV \ + PCI_ENV \ ENET_ENV @@ -579,23 +602,23 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); "ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off " \ "console=$consoledev,$baudrate $othbootargs;" \ "tftp $loadaddr $bootfile;" \ - "tftp $fdtaddr $fdtfile;" \ - "bootm $loadaddr - $fdtaddr" + "tftp $dtbaddr $dtbfile;" \ + "bootm $loadaddr - $dtbaddr" -#define CONFIG_RAMBOOTCOMMAND \ +#define CONFIG_RAMBOOTCOMMAND \ "setenv bootargs root=/dev/ram rw " \ "console=$consoledev,$baudrate $othbootargs;" \ "tftp $ramdiskaddr $ramdiskfile;" \ "tftp $loadaddr $bootfile;" \ - "tftp $fdtaddr $fdtfile;" \ - "bootm $loadaddr $ramdiskaddr $fdtaddr" + "tftp $dtbaddr $dtbfile;" \ + "bootm $loadaddr $ramdiskaddr $dtbaddr" -#define CONFIG_BOOTCOMMAND \ - "setenv bootargs root=/dev/sda3 rw " \ +#define CONFIG_BOOTCOMMAND \ + "setenv bootargs root=/dev/$bdev rw " \ "console=$consoledev,$baudrate $othbootargs;" \ "tftp $loadaddr $bootfile;" \ - "tftp $fdtaddr $fdtfile;" \ - "bootm $loadaddr - $fdtaddr" + "tftp $dtbaddr $dtbfile;" \ + "bootm $loadaddr - $dtbaddr" #endif /* __CONFIG_H */ -- cgit v1.3.1 From c59e4091ffe0148398b9e9ff14a019ea038b7432 Mon Sep 17 00:00:00 2001 From: Haiying Wang Date: Tue, 19 Jun 2007 14:18:34 -0400 Subject: Add PCI support for MPC8568MDS board This patch is against u-boot-mpc85xx.git of www.denx.com Signed-off-by: Haiying Wang Signed-off-by: Ebony Zhu --- board/mpc8568mds/init.S | 48 +++++++++++++--------------------- board/mpc8568mds/mpc8568mds.c | 60 ++++++++++++++++++++++++++++++++++++++++--- include/asm-ppc/immap_85xx.h | 17 ++++++++++++ include/configs/MPC8568MDS.h | 11 +++++--- 4 files changed, 98 insertions(+), 38 deletions(-) (limited to 'include/asm-ppc') diff --git a/board/mpc8568mds/init.S b/board/mpc8568mds/init.S index 0d879821e33..972a7d42990 100644 --- a/board/mpc8568mds/init.S +++ b/board/mpc8568mds/init.S @@ -143,54 +143,42 @@ tlb1_entry: .long TLB1_MAS3(E500_TLB_RPN(CFG_FLASH_BASE), 0,0,0,0,0,1,0,1,0,1) /* - * TLBe 2: 256M Non-cacheable, guarded - * 0x80000000 256M PCI1 MEM + * TLBe 2: 1G Non-cacheable, guarded + * 0x80000000 512M PCI1 MEM + * 0xa0000000 512M PCIe MEM */ .long TLB1_MAS0(1, 2, 0) - .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_256M) + .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_1G) .long TLB1_MAS2(E500_TLB_EPN(CFG_PCI1_MEM_BASE), 0,0,0,0,1,0,1,0) .long TLB1_MAS3(E500_TLB_RPN(CFG_PCI1_MEM_BASE), 0,0,0,0,0,1,0,1,0,1) /* - * TLBe 3: 256M Non-cacheable, guarded - * 0xa0000000 256M PCIe Mem - */ - .long TLB1_MAS0(1, 3, 0) - .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_256M) - .long TLB1_MAS2(E500_TLB_EPN(CFG_PEX_MEM_BASE), 0,0,0,0,1,0,1,0) - .long TLB1_MAS3(E500_TLB_RPN(CFG_PEX_MEM_BASE), 0,0,0,0,0,1,0,1,0,1) - - /* - * TLBe 4: Reserved for future usage - */ - - /* - * TLBe 5: 64M Non-cacheable, guarded + * TLBe 3: 64M Non-cacheable, guarded * 0xe000_0000 1M CCSRBAR * 0xe200_0000 8M PCI1 IO * 0xe280_0000 8M PCIe IO */ - .long TLB1_MAS0(1, 5, 0) + .long TLB1_MAS0(1, 3, 0) .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_64M) .long TLB1_MAS2(E500_TLB_EPN(CFG_CCSRBAR), 0,0,0,0,1,0,1,0) .long TLB1_MAS3(E500_TLB_RPN(CFG_CCSRBAR), 0,0,0,0,0,1,0,1,0,1) /* - * TLBe 6: 64M Cacheable, non-guarded + * TLBe 4: 64M Cacheable, non-guarded * 0xf000_0000 64M LBC SDRAM */ - .long TLB1_MAS0(1, 6, 0) + .long TLB1_MAS0(1, 4, 0) .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_64M) .long TLB1_MAS2(E500_TLB_EPN(CFG_LBC_SDRAM_BASE), 0,0,0,0,0,0,0,0) .long TLB1_MAS3(E500_TLB_RPN(CFG_LBC_SDRAM_BASE), 0,0,0,0,0,1,0,1,0,1) /* - * TLBe 7: 256K Non-cacheable, guarded + * TLBe 5: 256K Non-cacheable, guarded * 0xf8000000 32K BCSR * 0xf8008000 32K PIB (CS4) * 0xf8010000 32K PIB (CS5) */ - .long TLB1_MAS0(1, 7, 0) + .long TLB1_MAS0(1, 5, 0) .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_256K) .long TLB1_MAS2(E500_TLB_EPN(CFG_BCSR_BASE), 0,0,0,0,1,0,1,0) .long TLB1_MAS3(E500_TLB_RPN(CFG_BCSR_BASE), 0,0,0,0,0,1,0,1,0,1) @@ -202,12 +190,12 @@ tlb1_entry: * LAW(Local Access Window) configuration: * *0) 0x0000_0000 0x7fff_ffff DDR 2G - *1) 0x8000_0000 0x9fff_ffff PCI1 MEM 256MB - *2) 0xa000_0000 0xbfff_ffff PCIe MEM 256MB - *5) 0xc000_0000 0xdfff_ffff SRIO 256MB + *1) 0x8000_0000 0x9fff_ffff PCI1 MEM 512MB + *2) 0xa000_0000 0xbfff_ffff PCIe MEM 512MB *-) 0xe000_0000 0xe00f_ffff CCSR 1M *3) 0xe200_0000 0xe27f_ffff PCI1 I/O 8M - *4) 0xe280_0000 0xe2ff_ffff PCIe I/0 8M + *4) 0xe280_0000 0xe2ff_ffff PCIe I/O 8M + *5) 0xc000_0000 0xdfff_ffff SRIO 512MB *6.a) 0xf000_0000 0xf3ff_ffff SDRAM 64MB *6.b) 0xf800_0000 0xf800_7fff BCSR 32KB *6.c) 0xf800_8000 0xf800_ffff PIB (CS4) 32KB @@ -226,20 +214,20 @@ tlb1_entry: #define LAWAR0 ((LAWAR_TRGT_IF_DDR | (LAWAR_SIZE & LAWAR_SIZE_128M)) & ~LAWAR_EN) #define LAWBAR1 ((CFG_PCI1_MEM_BASE>>12) & 0xfffff) -#define LAWAR1 (LAWAR_EN | LAWAR_TRGT_IF_PCI1 | (LAWAR_SIZE & LAWAR_SIZE_256M)) +#define LAWAR1 (LAWAR_EN | LAWAR_TRGT_IF_PCI1 | (LAWAR_SIZE & LAWAR_SIZE_512M)) #define LAWBAR2 ((CFG_PEX_MEM_BASE>>12) & 0xfffff) -#define LAWAR2 (LAWAR_EN | LAWAR_TRGT_IF_PEX | (LAWAR_SIZE & LAWAR_SIZE_256M)) +#define LAWAR2 (LAWAR_EN | LAWAR_TRGT_IF_PEX | (LAWAR_SIZE & LAWAR_SIZE_512M)) #define LAWBAR3 ((CFG_PCI1_IO_PHYS>>12) & 0xfffff) #define LAWAR3 (LAWAR_EN | LAWAR_TRGT_IF_PCI1 | (LAWAR_SIZE & LAWAR_SIZE_8M)) #define LAWBAR4 ((CFG_PEX_IO_PHYS>>12) & 0xfffff) -#define LAWAR4 (LAWAR_EN | LAWAR_TRGT_IF_PEX | (LAWAR_SIZE & LAWAR_SIZE_16M)) +#define LAWAR4 (LAWAR_EN | LAWAR_TRGT_IF_PEX | (LAWAR_SIZE & LAWAR_SIZE_8M)) #define LAWBAR5 ((CFG_SRIO_MEM_BASE>>12) & 0xfffff) -#define LAWAR5 (LAWAR_EN | LAWAR_TRGT_IF_RIO | (LAWAR_SIZE & LAWAR_SIZE_256M)) +#define LAWAR5 (LAWAR_EN | LAWAR_TRGT_IF_RIO | (LAWAR_SIZE & LAWAR_SIZE_512M)) /* LBC window - maps 256M. That's SDRAM, BCSR, PIBs, and Flash */ #define LAWBAR6 ((CFG_LBC_SDRAM_BASE>>12) & 0xfffff) diff --git a/board/mpc8568mds/mpc8568mds.c b/board/mpc8568mds/mpc8568mds.c index 9c7960d47e7..23caaec72f2 100644 --- a/board/mpc8568mds/mpc8568mds.c +++ b/board/mpc8568mds/mpc8568mds.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "bcsr.h" @@ -50,6 +51,15 @@ int board_early_init_f (void) enable_8568mds_duart(); enable_8568mds_flash_write(); +#ifdef CFG_I2C2_OFFSET + /* Enable I2C2_SCL and I2C2_SDA */ + volatile struct par_io *port_c; + port_c = (struct par_io*)(CFG_IMMR + 0xe0140); + port_c->cpdir2 |= 0x0f000000; + port_c->cppar2 &= ~0x0f000000; + port_c->cppar2 |= 0x0a000000; +#endif + return 0; } @@ -269,20 +279,62 @@ static struct pci_config_table pci_mpc8568mds_config_table[] = { #endif static struct pci_controller hose[] = { + { #ifndef CONFIG_PCI_PNP - { config_table: pci_mpc8568mds_config_table,}, -#endif -#ifdef CONFIG_MPC85XX_PCI2 - {}, + config_table: pci_mpc8568mds_config_table, #endif + } }; #endif /* CONFIG_PCI */ +/* + * pib_init() -- Initialize the PCA9555 IO expander on the PIB board + */ +void +pib_init(void) +{ + u8 val8, orig_i2c_bus; + /* + * Assign PIB PMC2/3 to PCI bus + */ + + /*switch temporarily to I2C bus #2 */ + orig_i2c_bus = i2c_get_bus_num(); + i2c_set_bus_num(1); + + val8 = 0x00; + i2c_write(0x23, 0x6, 1, &val8, 1); + i2c_write(0x23, 0x7, 1, &val8, 1); + val8 = 0xff; + i2c_write(0x23, 0x2, 1, &val8, 1); + i2c_write(0x23, 0x3, 1, &val8, 1); + + val8 = 0x00; + i2c_write(0x26, 0x6, 1, &val8, 1); + val8 = 0x34; + i2c_write(0x26, 0x7, 1, &val8, 1); + val8 = 0xf9; + i2c_write(0x26, 0x2, 1, &val8, 1); + val8 = 0xff; + i2c_write(0x26, 0x3, 1, &val8, 1); + + val8 = 0x00; + i2c_write(0x27, 0x6, 1, &val8, 1); + i2c_write(0x27, 0x7, 1, &val8, 1); + val8 = 0xff; + i2c_write(0x27, 0x2, 1, &val8, 1); + val8 = 0xef; + i2c_write(0x27, 0x3, 1, &val8, 1); + + asm("eieio"); +} + void pci_init_board(void) { #ifdef CONFIG_PCI + pib_init(); pci_mpc85xx_init(&hose); #endif } diff --git a/include/asm-ppc/immap_85xx.h b/include/asm-ppc/immap_85xx.h index 77f885daa67..3d4816f3a99 100644 --- a/include/asm-ppc/immap_85xx.h +++ b/include/asm-ppc/immap_85xx.h @@ -1522,6 +1522,17 @@ typedef struct ccsr_rio { char res58[60176]; } ccsr_rio_t; +/* Quick Engine Block Pin Muxing Registers (0xe_0100 - 0xe_01bf) */ +typedef struct par_io { + uint cpodr; /* 0x100 */ + uint cpdat; /* 0x104 */ + uint cpdir1; /* 0x108 */ + uint cpdir2; /* 0x10c */ + uint cppar1; /* 0x110 */ + uint cppar2; /* 0x114 */ + char res[8]; +}par_io_t; + /* * Global Utilities Register Block(0xe_0000-0xf_ffff) */ @@ -1585,7 +1596,13 @@ typedef struct ccsr_gur { uint svr; /* 0xe00a4 - System version register */ char res10a[8]; uint rstcr; /* 0xe00b0 - Reset control register */ +#ifdef MPC8568 + char res10b[76]; + par_io_t qe_par_io[7]; /* 0xe0100 - 0xe01bf */ + char res10c[3136]; +#else char res10b[3404]; +#endif uint clkocr; /* 0xe0e00 - Clock out select register */ char res11[12]; uint ddrdllcr; /* 0xe0e10 - DDR DLL control register */ diff --git a/include/configs/MPC8568MDS.h b/include/configs/MPC8568MDS.h index eef168c252d..5bc953adc42 100644 --- a/include/configs/MPC8568MDS.h +++ b/include/configs/MPC8568MDS.h @@ -33,7 +33,7 @@ #define CONFIG_MPC8568 1 /* MPC8568 specific */ #define CONFIG_MPC8568MDS 1 /* MPC8568MDS board specific */ -#undef CONFIG_PCI +#define CONFIG_PCI #define CONFIG_TSEC_ENET /* tsec ethernet support */ #define CONFIG_ENV_OVERWRITE #define CONFIG_SPD_EEPROM /* Use SPD EEPROM for DDR setup*/ @@ -306,11 +306,14 @@ extern unsigned long get_clock_freq(void); #define CONFIG_FSL_I2C /* Use FSL common I2C driver */ #define CONFIG_HARD_I2C /* I2C with hardware support*/ #undef CONFIG_SOFT_I2C /* I2C bit-banged */ +#define CONFIG_I2C_MULTI_BUS +#define CONFIG_I2C_CMD_TREE #define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ -#define CFG_I2C_EEPROM_ADDR 0x57 +#define CFG_I2C_EEPROM_ADDR 0x52 #define CFG_I2C_SLAVE 0x7F -#define CFG_I2C_NOPROBES {0x69} /* Don't probe these addrs */ +#define CFG_I2C_NOPROBES {0,0x69} /* Don't probe these addrs */ #define CFG_I2C_OFFSET 0x3000 +#define CFG_I2C2_OFFSET 0x3100 /* * General PCI @@ -318,7 +321,7 @@ extern unsigned long get_clock_freq(void); */ #define CFG_PCI1_MEM_BASE 0x80000000 #define CFG_PCI1_MEM_PHYS CFG_PCI1_MEM_BASE -#define CFG_PCI1_MEM_SIZE 0x10000000 /* 256M */ +#define CFG_PCI1_MEM_SIZE 0x20000000 /* 512M */ #define CFG_PCI1_IO_BASE 0x00000000 #define CFG_PCI1_IO_PHYS 0xe2000000 #define CFG_PCI1_IO_SIZE 0x00800000 /* 8M */ -- cgit v1.3.1 From da9d4610d76e52c4d20a8f3d8433439a7fcf5b71 Mon Sep 17 00:00:00 2001 From: Andy Fleming Date: Tue, 14 Aug 2007 00:14:25 -0500 Subject: Add support for UEC to 8568 Signed-off-by: Haiying Wang Signed-off-by: Andy Fleming --- Makefile | 3 ++ board/mpc8568mds/bcsr.c | 7 ++++ board/mpc8568mds/bcsr.h | 1 + board/mpc8568mds/mpc8568mds.c | 61 ++++++++++++++++++++++++++++++- cpu/mpc85xx/Makefile | 2 +- cpu/mpc85xx/cpu.c | 24 +++++++++++- cpu/mpc85xx/cpu_init.c | 33 +++++++++++++++++ cpu/mpc85xx/qe_io.c | 85 +++++++++++++++++++++++++++++++++++++++++++ drivers/qe/uec.c | 27 +++++++++----- drivers/qe/uec.h | 1 + drivers/qe/uec_phy.c | 14 +++---- drivers/qe/uec_phy.h | 6 +-- include/asm-ppc/global_data.h | 8 ++-- include/asm-ppc/immap_qe.h | 20 +++++++++- include/configs/MPC8568MDS.h | 56 ++++++++++++++++++++++++---- 15 files changed, 313 insertions(+), 35 deletions(-) create mode 100644 cpu/mpc85xx/qe_io.c (limited to 'include/asm-ppc') diff --git a/Makefile b/Makefile index f51688961b3..a5698cf7c95 100644 --- a/Makefile +++ b/Makefile @@ -212,6 +212,9 @@ LIBS += drivers/nand_legacy/libnand_legacy.a ifeq ($(CPU),mpc83xx) LIBS += drivers/qe/qe.a endif +ifeq ($(CPU),mpc85xx) +LIBS += drivers/qe/qe.a +endif LIBS += drivers/sk98lin/libsk98lin.a LIBS += post/libpost.a post/drivers/libpostdrivers.a LIBS += $(shell if [ -d post/lib_$(ARCH) ]; then echo \ diff --git a/board/mpc8568mds/bcsr.c b/board/mpc8568mds/bcsr.c index 2e2e8cd18fa..aae0f98e038 100644 --- a/board/mpc8568mds/bcsr.c +++ b/board/mpc8568mds/bcsr.c @@ -47,3 +47,10 @@ void disable_8568mds_flash_write() bcsr[9] &= ~(0x01); } + +void enable_8568mds_qe_mdio() +{ + u8 *bcsr = (u8 *)(CFG_BCSR); + + bcsr[7] |= 0x01; +} diff --git a/board/mpc8568mds/bcsr.h b/board/mpc8568mds/bcsr.h index 8d4cb2f1412..aefd9bf54d3 100644 --- a/board/mpc8568mds/bcsr.h +++ b/board/mpc8568mds/bcsr.h @@ -95,5 +95,6 @@ void enable_8568mds_duart(void); void enable_8568mds_flash_write(void); void disable_8568mds_flash_write(void); +void enable_8568mds_qe_mdio(void); #endif /* __BCSR_H_ */ diff --git a/board/mpc8568mds/mpc8568mds.c b/board/mpc8568mds/mpc8568mds.c index 23caaec72f2..818ff138a99 100644 --- a/board/mpc8568mds/mpc8568mds.c +++ b/board/mpc8568mds/mpc8568mds.c @@ -28,9 +28,65 @@ #include #include #include +#include #include "bcsr.h" +const qe_iop_conf_t qe_iop_conf_tab[] = { + /* GETH1 */ + {4, 10, 1, 0, 2}, /* TxD0 */ + {4, 9, 1, 0, 2}, /* TxD1 */ + {4, 8, 1, 0, 2}, /* TxD2 */ + {4, 7, 1, 0, 2}, /* TxD3 */ + {4, 23, 1, 0, 2}, /* TxD4 */ + {4, 22, 1, 0, 2}, /* TxD5 */ + {4, 21, 1, 0, 2}, /* TxD6 */ + {4, 20, 1, 0, 2}, /* TxD7 */ + {4, 15, 2, 0, 2}, /* RxD0 */ + {4, 14, 2, 0, 2}, /* RxD1 */ + {4, 13, 2, 0, 2}, /* RxD2 */ + {4, 12, 2, 0, 2}, /* RxD3 */ + {4, 29, 2, 0, 2}, /* RxD4 */ + {4, 28, 2, 0, 2}, /* RxD5 */ + {4, 27, 2, 0, 2}, /* RxD6 */ + {4, 26, 2, 0, 2}, /* RxD7 */ + {4, 11, 1, 0, 2}, /* TX_EN */ + {4, 24, 1, 0, 2}, /* TX_ER */ + {4, 16, 2, 0, 2}, /* RX_DV */ + {4, 30, 2, 0, 2}, /* RX_ER */ + {4, 17, 2, 0, 2}, /* RX_CLK */ + {4, 19, 1, 0, 2}, /* GTX_CLK */ + {1, 31, 2, 0, 3}, /* GTX125 */ + + /* GETH2 */ + {5, 10, 1, 0, 2}, /* TxD0 */ + {5, 9, 1, 0, 2}, /* TxD1 */ + {5, 8, 1, 0, 2}, /* TxD2 */ + {5, 7, 1, 0, 2}, /* TxD3 */ + {5, 23, 1, 0, 2}, /* TxD4 */ + {5, 22, 1, 0, 2}, /* TxD5 */ + {5, 21, 1, 0, 2}, /* TxD6 */ + {5, 20, 1, 0, 2}, /* TxD7 */ + {5, 15, 2, 0, 2}, /* RxD0 */ + {5, 14, 2, 0, 2}, /* RxD1 */ + {5, 13, 2, 0, 2}, /* RxD2 */ + {5, 12, 2, 0, 2}, /* RxD3 */ + {5, 29, 2, 0, 2}, /* RxD4 */ + {5, 28, 2, 0, 2}, /* RxD5 */ + {5, 27, 2, 0, 3}, /* RxD6 */ + {5, 26, 2, 0, 2}, /* RxD7 */ + {5, 11, 1, 0, 2}, /* TX_EN */ + {5, 24, 1, 0, 2}, /* TX_ER */ + {5, 16, 2, 0, 2}, /* RX_DV */ + {5, 30, 2, 0, 2}, /* RX_ER */ + {5, 17, 2, 0, 2}, /* RX_CLK */ + {5, 19, 1, 0, 2}, /* GTX_CLK */ + {1, 31, 2, 0, 3}, /* GTX125 */ + {4, 6, 3, 0, 2}, /* MDIO */ + {4, 5, 1, 0, 2}, /* MDC */ + {0, 0, 0, 0, QE_IOP_TAB_END}, /* END of table */ +}; + #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) extern void ddr_enable_ecc(unsigned int dram_size); @@ -50,6 +106,9 @@ int board_early_init_f (void) enable_8568mds_duart(); enable_8568mds_flash_write(); +#if defined(CONFIG_QE) && !defined(CONFIG_eTSEC_MDIO_BUS) + enable_8568mds_qe_mdio(); +#endif #ifdef CFG_I2C2_OFFSET /* Enable I2C2_SCL and I2C2_SDA */ @@ -335,6 +394,6 @@ pci_init_board(void) { #ifdef CONFIG_PCI pib_init(); - pci_mpc85xx_init(&hose); + pci_mpc85xx_init(hose); #endif } diff --git a/cpu/mpc85xx/Makefile b/cpu/mpc85xx/Makefile index ff67dcdd353..32091fa4e1d 100644 --- a/cpu/mpc85xx/Makefile +++ b/cpu/mpc85xx/Makefile @@ -30,7 +30,7 @@ LIB = $(obj)lib$(CPU).a START = start.o resetvec.o COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o \ - pci.o serial_scc.o commproc.o ether_fcc.o spd_sdram.o + pci.o serial_scc.o commproc.o ether_fcc.o spd_sdram.o qe_io.o SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/mpc85xx/cpu.c b/cpu/mpc85xx/cpu.c index 1d791c9b9b3..08e04685f59 100644 --- a/cpu/mpc85xx/cpu.c +++ b/cpu/mpc85xx/cpu.c @@ -280,7 +280,7 @@ ft_cpu_setup(void *blob, bd_t *bd) if (p != NULL) *p = cpu_to_be32(clock); -#if defined(CONFIG_TSEC1) +#if defined(CONFIG_HAS_ETH0) p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/mac-address", &len); if (p) memcpy(p, bd->bi_enetaddr, 6); @@ -308,6 +308,17 @@ ft_cpu_setup(void *blob, bd_t *bd) p = ft_get_prop(blob, "/" OF_SOC "/ethernet@26000/local-mac-address", &len); if (p) memcpy(p, bd->bi_enet2addr, 6); + +#ifdef CONFIG_UEC_ETH + p = ft_get_prop(blob, "/" OF_QE "/ucc@2000/mac-address", &len); + if (p) + memcpy(p, bd->bi_enet2addr, 6); + + p = ft_get_prop(blob, "/" OF_QE "/ucc@2000/local-mac-address", &len); + if (p) + memcpy(p, bd->bi_enet2addr, 6); + +#endif #endif #if defined(CONFIG_HAS_ETH3) @@ -318,6 +329,17 @@ ft_cpu_setup(void *blob, bd_t *bd) p = ft_get_prop(blob, "/" OF_SOC "/ethernet@27000/local-mac-address", &len); if (p) memcpy(p, bd->bi_enet3addr, 6); + +#ifdef CONFIG_UEC_ETH + p = ft_get_prop(blob, "/" OF_QE "/ucc@3000/mac-address", &len); + if (p) + memcpy(p, bd->bi_enet3addr, 6); + + p = ft_get_prop(blob, "/" OF_QE "/ucc@3000/local-mac-address", &len); + if (p) + memcpy(p, bd->bi_enet3addr, 6); + +#endif #endif } diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c index c7fe130ee0e..7b9961013c0 100644 --- a/cpu/mpc85xx/cpu_init.c +++ b/cpu/mpc85xx/cpu_init.c @@ -34,6 +34,29 @@ DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_QE +extern qe_iop_conf_t qe_iop_conf_tab[]; +extern void qe_config_iopin(u8 port, u8 pin, int dir, + int open_drain, int assign); +extern void qe_init(uint qe_base); +extern void qe_reset(void); + +static void config_qe_ioports(void) +{ + u8 port, pin; + int dir, open_drain, assign; + int i; + + for (i = 0; qe_iop_conf_tab[i].assign != QE_IOP_TAB_END; i++) { + port = qe_iop_conf_tab[i].port; + pin = qe_iop_conf_tab[i].pin; + dir = qe_iop_conf_tab[i].dir; + open_drain = qe_iop_conf_tab[i].open_drain; + assign = qe_iop_conf_tab[i].assign; + qe_config_iopin(port, pin, dir, open_drain, assign); + } +} +#endif #ifdef CONFIG_CPM2 static void config_8560_ioports (volatile immap_t * immr) @@ -181,6 +204,11 @@ void cpu_init_f (void) #if defined(CONFIG_CPM2) m8560_cpm_reset(); #endif +#ifdef CONFIG_QE + /* Config QE ioports */ + config_qe_ioports(); +#endif + } @@ -262,6 +290,11 @@ int cpu_init_r(void) #else printf("L2 cache: disabled\n"); #endif +#ifdef CONFIG_QE + uint qe_base = CFG_IMMR + 0x00080000; /* QE immr base */ + qe_init(qe_base); + qe_reset(); +#endif return 0; } diff --git a/cpu/mpc85xx/qe_io.c b/cpu/mpc85xx/qe_io.c new file mode 100644 index 00000000000..8878bc53193 --- /dev/null +++ b/cpu/mpc85xx/qe_io.c @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2006 Freescale Semiconductor, Inc. + * + * Dave Liu + * based on source code of Shlomi Gridish + * + * 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 "asm/errno.h" +#include "asm/io.h" +#include "asm/immap_85xx.h" + +#if defined(CONFIG_QE) +#define NUM_OF_PINS 32 +void qe_config_iopin(u8 port, u8 pin, int dir, int open_drain, int assign) +{ + u32 pin_2bit_mask; + u32 pin_2bit_dir; + u32 pin_2bit_assign; + u32 pin_1bit_mask; + u32 tmp_val; + volatile immap_t *im = (volatile immap_t *)CFG_IMMR; + volatile par_io_t *par_io = (volatile par_io_t *) + &(im->im_gur.qe_par_io); + + /* Caculate pin location and 2bit mask and dir */ + pin_2bit_mask = (u32)(0x3 << (NUM_OF_PINS-(pin%(NUM_OF_PINS/2)+1)*2)); + pin_2bit_dir = (u32)(dir << (NUM_OF_PINS-(pin%(NUM_OF_PINS/2)+1)*2)); + + /* Setup the direction */ + tmp_val = (pin > (NUM_OF_PINS/2) - 1) ? \ + in_be32(&par_io[port].cpdir2) : + in_be32(&par_io[port].cpdir1); + + if (pin > (NUM_OF_PINS/2) -1) { + out_be32(&par_io[port].cpdir2, ~pin_2bit_mask & tmp_val); + out_be32(&par_io[port].cpdir2, pin_2bit_dir | tmp_val); + } else { + out_be32(&par_io[port].cpdir1, ~pin_2bit_mask & tmp_val); + out_be32(&par_io[port].cpdir1, pin_2bit_dir | tmp_val); + } + + /* Calculate pin location for 1bit mask */ + pin_1bit_mask = (u32)(1 << (NUM_OF_PINS - (pin+1))); + + /* Setup the open drain */ + tmp_val = in_be32(&par_io[port].cpodr); + if (open_drain) + out_be32(&par_io[port].cpodr, pin_1bit_mask | tmp_val); + else + out_be32(&par_io[port].cpodr, ~pin_1bit_mask & tmp_val); + + /* Setup the assignment */ + tmp_val = (pin > (NUM_OF_PINS/2) - 1) ? + in_be32(&par_io[port].cppar2): + in_be32(&par_io[port].cppar1); + pin_2bit_assign = (u32)(assign + << (NUM_OF_PINS - (pin%(NUM_OF_PINS/2)+1)*2)); + + /* Clear and set 2 bits mask */ + if (pin > (NUM_OF_PINS/2) - 1) { + out_be32(&par_io[port].cppar2, ~pin_2bit_mask & tmp_val); + out_be32(&par_io[port].cppar2, pin_2bit_assign | tmp_val); + } else { + out_be32(&par_io[port].cppar1, ~pin_2bit_mask & tmp_val); + out_be32(&par_io[port].cppar1, pin_2bit_assign | tmp_val); + } +} + +#endif /* CONFIG_QE */ diff --git a/drivers/qe/uec.c b/drivers/qe/uec.c index c416a67c832..89a72798232 100644 --- a/drivers/qe/uec.c +++ b/drivers/qe/uec.c @@ -391,17 +391,17 @@ static int uec_set_mac_if_mode(uec_private_t *uec, enet_interface_e if_mode) return 0; } -static int init_mii_management_configuration(uec_t *uec_regs) +static int init_mii_management_configuration(uec_mii_t *uec_mii_regs) { uint timeout = 0x1000; u32 miimcfg = 0; - miimcfg = in_be32(&uec_regs->miimcfg); + miimcfg = in_be32(&uec_mii_regs->miimcfg); miimcfg |= MIIMCFG_MNGMNT_CLC_DIV_INIT_VALUE; - out_be32(&uec_regs->miimcfg, miimcfg); + out_be32(&uec_mii_regs->miimcfg, miimcfg); /* Wait until the bus is free */ - while ((in_be32(&uec_regs->miimcfg) & MIIMIND_BUSY) && timeout--); + while ((in_be32(&uec_mii_regs->miimcfg) & MIIMIND_BUSY) && timeout--); if (timeout <= 0) { printf("%s: The MII Bus is stuck!", __FUNCTION__); return -ETIMEDOUT; @@ -413,13 +413,13 @@ static int init_mii_management_configuration(uec_t *uec_regs) static int init_phy(struct eth_device *dev) { uec_private_t *uec; - uec_t *uec_regs; + uec_mii_t *umii_regs; struct uec_mii_info *mii_info; struct phy_info *curphy; int err; uec = (uec_private_t *)dev->priv; - uec_regs = uec->uec_regs; + umii_regs = uec->uec_mii_regs; uec->oldlink = 0; uec->oldspeed = 0; @@ -451,19 +451,19 @@ static int init_phy(struct eth_device *dev) mii_info->mii_id = uec->uec_info->phy_address; mii_info->dev = dev; - mii_info->mdio_read = &read_phy_reg; - mii_info->mdio_write = &write_phy_reg; + mii_info->mdio_read = &uec_read_phy_reg; + mii_info->mdio_write = &uec_write_phy_reg; uec->mii_info = mii_info; - if (init_mii_management_configuration(uec_regs)) { + if (init_mii_management_configuration(umii_regs)) { printf("%s: The MII Bus is stuck!", dev->name); err = -1; goto bus_fail; } /* get info for this PHY */ - curphy = get_phy_info(uec->mii_info); + curphy = uec_get_phy_info(uec->mii_info); if (!curphy) { printf("%s: No PHY found", dev->name); err = -1; @@ -989,6 +989,13 @@ static int uec_startup(uec_private_t *uec) /* Setup MAC interface mode */ uec_set_mac_if_mode(uec, uec_info->enet_interface); + /* Setup MII management base */ +#ifndef CONFIG_eTSEC_MDIO_BUS + uec->uec_mii_regs = (uec_mii_t *)(&uec_regs->miimcfg); +#else + uec->uec_mii_regs = (uec_mii_t *) CONFIG_MIIM_ADDRESS; +#endif + /* Setup MII master clock source */ qe_set_mii_clk_src(uec_info->uf_info.ucc_num); diff --git a/drivers/qe/uec.h b/drivers/qe/uec.h index 04950264b89..c384055cebf 100644 --- a/drivers/qe/uec.h +++ b/drivers/qe/uec.h @@ -675,6 +675,7 @@ typedef struct uec_private { ucc_fast_private_t *uccf; struct eth_device *dev; uec_t *uec_regs; + uec_mii_t *uec_mii_regs; /* enet init command parameter */ uec_init_cmd_pram_t *p_init_enet_param; u32 init_enet_param_offset; diff --git a/drivers/qe/uec_phy.c b/drivers/qe/uec_phy.c index 76fd38896a8..ca6faa6ef4e 100644 --- a/drivers/qe/uec_phy.c +++ b/drivers/qe/uec_phy.c @@ -60,14 +60,14 @@ void phy_write (struct uec_mii_info *mii_info, u16 regnum, u16 val); /* Write value to the PHY for this device to the register at regnum, */ /* waiting until the write is done before it returns. All PHY */ /* configuration has to be done through the TSEC1 MIIM regs */ -void write_phy_reg (struct eth_device *dev, int mii_id, int regnum, int value) +void uec_write_phy_reg (struct eth_device *dev, int mii_id, int regnum, int value) { uec_private_t *ugeth = (uec_private_t *) dev->priv; - uec_t *ug_regs; + uec_mii_t *ug_regs; enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; u32 tmp_reg; - ug_regs = ugeth->uec_regs; + ug_regs = ugeth->uec_mii_regs; /* Stop the MII management read cycle */ out_be32 (&ug_regs->miimcom, 0); @@ -87,15 +87,15 @@ void write_phy_reg (struct eth_device *dev, int mii_id, int regnum, int value) /* Reads from register regnum in the PHY for device dev, */ /* returning the value. Clears miimcom first. All PHY */ /* configuration has to be done through the TSEC1 MIIM regs */ -int read_phy_reg (struct eth_device *dev, int mii_id, int regnum) +int uec_read_phy_reg (struct eth_device *dev, int mii_id, int regnum) { uec_private_t *ugeth = (uec_private_t *) dev->priv; - uec_t *ug_regs; + uec_mii_t *ug_regs; enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; u32 tmp_reg; u16 value; - ug_regs = ugeth->uec_regs; + ug_regs = ugeth->uec_mii_regs; /* Setting up the MII Mangement Address Register */ tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg; @@ -521,7 +521,7 @@ void phy_write (struct uec_mii_info *mii_info, u16 regnum, u16 val) /* Use the PHY ID registers to determine what type of PHY is attached * to device dev. return a struct phy_info structure describing that PHY */ -struct phy_info *get_phy_info (struct uec_mii_info *mii_info) +struct phy_info *uec_get_phy_info (struct uec_mii_info *mii_info) { u16 phy_reg; u32 phy_ID; diff --git a/drivers/qe/uec_phy.h b/drivers/qe/uec_phy.h index 9bd926ddd5a..e59a940e0dd 100644 --- a/drivers/qe/uec_phy.h +++ b/drivers/qe/uec_phy.h @@ -249,10 +249,10 @@ struct phy_info { void (*close) (struct uec_mii_info * mii_info); }; -struct phy_info *get_phy_info (struct uec_mii_info *mii_info); -void write_phy_reg (struct eth_device *dev, int mii_id, int regnum, +struct phy_info *uec_get_phy_info (struct uec_mii_info *mii_info); +void uec_write_phy_reg (struct eth_device *dev, int mii_id, int regnum, int value); -int read_phy_reg (struct eth_device *dev, int mii_id, int regnum); +int uec_read_phy_reg (struct eth_device *dev, int mii_id, int regnum); void mii_clear_phy_interrupt (struct uec_mii_info *mii_info); void mii_configure_phy_interrupt (struct uec_mii_info *mii_info, u32 interrupts); diff --git a/include/asm-ppc/global_data.h b/include/asm-ppc/global_data.h index bbaeb3f575f..1f1583a9231 100644 --- a/include/asm-ppc/global_data.h +++ b/include/asm-ppc/global_data.h @@ -71,16 +71,16 @@ typedef struct global_data { u32 lclk_clk; u32 ddr_clk; u32 pci_clk; +#if defined(CONFIG_MPC8360) + u32 ddr_sec_clk; +#endif /* CONFIG_MPC8360 */ +#endif #if defined(CONFIG_QE) u32 qe_clk; u32 brg_clk; uint mp_alloc_base; uint mp_alloc_top; #endif /* CONFIG_QE */ -#if defined (CONFIG_MPC8360) - u32 ddr_sec_clk; -#endif /* CONFIG_MPC8360 */ -#endif #if defined(CONFIG_MPC5xxx) unsigned long ipb_clk; unsigned long pci_clk; diff --git a/include/asm-ppc/immap_qe.h b/include/asm-ppc/immap_qe.h index 950b9497f8a..a16a6d3fc5f 100644 --- a/include/asm-ppc/immap_qe.h +++ b/include/asm-ppc/immap_qe.h @@ -281,6 +281,17 @@ typedef struct ucc_slow { u8 res4[0x200 - 0x091]; } __attribute__ ((packed)) ucc_slow_t; +typedef struct ucc_mii_mng { + u32 miimcfg; /* MII management configuration reg */ + u32 miimcom; /* MII management command reg */ + u32 miimadd; /* MII management address reg */ + u32 miimcon; /* MII management control reg */ + u32 miimstat; /* MII management status reg */ + u32 miimind; /* MII management indication reg */ + u32 ifctl; /* interface control reg */ + u32 ifstat; /* interface statux reg */ +} __attribute__ ((packed))uec_mii_t; + typedef struct ucc_ethernet { u32 maccfg1; /* mac configuration reg. 1 */ u32 maccfg2; /* mac configuration reg. 2 */ @@ -540,14 +551,21 @@ typedef struct qe_immap { u8 res14[0x300]; u8 res15[0x3A00]; u8 res16[0x8000]; /* 0x108000 - 0x110000 */ +#if defined(CONFIG_MPC8568) + u8 muram[0x10000]; /* 0x1_0000 - 0x2_0000 Multi-user RAM */ + u8 res17[0x20000]; /* 0x2_0000 - 0x4_0000 */ +#else u8 muram[0xC000]; /* 0x110000 - 0x11C000 Multi-user RAM */ u8 res17[0x24000]; /* 0x11C000 - 0x140000 */ u8 res18[0xC0000]; /* 0x140000 - 0x200000 */ +#endif } __attribute__ ((packed)) qe_map_t; extern qe_map_t *qe_immr; -#if defined(CONFIG_MPC8360) +#if defined(CONFIG_MPC8568) +#define QE_MURAM_SIZE 0x10000UL +#elif defined(CONFIG_MPC8360) #define QE_MURAM_SIZE 0xc000UL #elif defined(CONFIG_MPC832X) #define QE_MURAM_SIZE 0x4000UL diff --git a/include/configs/MPC8568MDS.h b/include/configs/MPC8568MDS.h index 5bc953adc42..dc9cb1ff545 100644 --- a/include/configs/MPC8568MDS.h +++ b/include/configs/MPC8568MDS.h @@ -28,20 +28,21 @@ /* High Level Configuration Options */ #define CONFIG_BOOKE 1 /* BOOKE */ -#define CONFIG_E500 1 /* BOOKE e500 family */ +#define CONFIG_E500 1 /* BOOKE e500 family */ #define CONFIG_MPC85xx 1 /* MPC8540/60/55/41/48/68 */ #define CONFIG_MPC8568 1 /* MPC8568 specific */ #define CONFIG_MPC8568MDS 1 /* MPC8568MDS board specific */ #define CONFIG_PCI #define CONFIG_TSEC_ENET /* tsec ethernet support */ +#undef CONFIG_QE /* Enable QE */ #define CONFIG_ENV_OVERWRITE #define CONFIG_SPD_EEPROM /* Use SPD EEPROM for DDR setup*/ #define CONFIG_DDR_DLL /* possible DLL fix needed */ /*#define CONFIG_DDR_2T_TIMING Sets the 2T timing bit */ /*#define CONFIG_DDR_ECC*/ /* only for ECC DDR module */ -/*#define CONFIG_ECC_INIT_VIA_DDRCONTROLLER*/ /* DDR controller or DMA? */ +/*#define CONFIG_ECC_INIT_VIA_DDRCONTROLLER*/ /* DDR controller or DMA? */ #define CONFIG_MEM_INIT_VALUE 0xDeadBeef @@ -297,6 +298,7 @@ extern unsigned long get_clock_freq(void); #define OF_CPU "PowerPC,8568@0" #define OF_SOC "soc8568@e0000000" +#define OF_QE "qe@e0080000" #define OF_TBCLK (bd->bi_busfreq / 8) #define OF_STDOUT_PATH "/soc8568@e0000000/serial@4600" @@ -311,7 +313,7 @@ extern unsigned long get_clock_freq(void); #define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ #define CFG_I2C_EEPROM_ADDR 0x52 #define CFG_I2C_SLAVE 0x7F -#define CFG_I2C_NOPROBES {0,0x69} /* Don't probe these addrs */ +#define CFG_I2C_NOPROBES {{0,0x69}} /* Don't probe these addrs */ #define CFG_I2C_OFFSET 0x3000 #define CFG_I2C2_OFFSET 0x3100 @@ -340,6 +342,44 @@ extern unsigned long get_clock_freq(void); #define CONFIG_NET_MULTI #define CONFIG_PCI_PNP /* do pci plug-and-play */ +#ifdef CONFIG_QE +/* + * QE UEC ethernet configuration + */ +#define CONFIG_UEC_ETH +#ifndef CONFIG_TSEC_ENET +#define CONFIG_ETHPRIME "Freescale GETH" +#endif +#define CONFIG_PHY_MODE_NEED_CHANGE +#define CONFIG_eTSEC_MDIO_BUS + +#ifdef CONFIG_eTSEC_MDIO_BUS +#define CONFIG_MIIM_ADDRESS 0xE0024520 +#endif + +#define CONFIG_UEC_ETH1 /* GETH1 */ + +#ifdef CONFIG_UEC_ETH1 +#define CFG_UEC1_UCC_NUM 0 /* UCC1 */ +#define CFG_UEC1_RX_CLK QE_CLK_NONE +#define CFG_UEC1_TX_CLK QE_CLK16 +#define CFG_UEC1_ETH_TYPE GIGA_ETH +#define CFG_UEC1_PHY_ADDR 7 +#define CFG_UEC1_INTERFACE_MODE ENET_1000_GMII +#endif + +#define CONFIG_UEC_ETH2 /* GETH2 */ + +#ifdef CONFIG_UEC_ETH2 +#define CFG_UEC2_UCC_NUM 1 /* UCC2 */ +#define CFG_UEC2_RX_CLK QE_CLK_NONE +#define CFG_UEC2_TX_CLK QE_CLK16 +#define CFG_UEC2_ETH_TYPE GIGA_ETH +#define CFG_UEC2_PHY_ADDR 1 +#define CFG_UEC2_INTERFACE_MODE ENET_1000_GMII +#endif +#endif /* CONFIG_QE */ + #undef CONFIG_EEPRO100 #undef CONFIG_TULIP @@ -348,13 +388,12 @@ extern unsigned long get_clock_freq(void); #endif /* CONFIG_PCI */ - -#if defined(CONFIG_TSEC_ENET) - #ifndef CONFIG_NET_MULTI #define CONFIG_NET_MULTI 1 #endif +#if defined(CONFIG_TSEC_ENET) + #define CONFIG_MII 1 /* MII PHY management */ #define CONFIG_TSEC1 1 #define CONFIG_TSEC1_NAME "eTSEC0" @@ -460,12 +499,15 @@ extern unsigned long get_clock_freq(void); */ /* The mac addresses for all ethernet interface */ -#if defined(CONFIG_TSEC_ENET) +#if defined(CONFIG_TSEC_ENET) || defined(CONFIG_UEC_ETH) +#define CONFIG_HAS_ETH0 #define CONFIG_ETHADDR 00:E0:0C:00:00:FD #define CONFIG_HAS_ETH1 #define CONFIG_ETH1ADDR 00:E0:0C:00:01:FD #define CONFIG_HAS_ETH2 #define CONFIG_ETH2ADDR 00:E0:0C:00:02:FD +#define CONFIG_HAS_ETH3 +#define CONFIG_ETH3ADDR 00:E0:0C:00:03:FD #endif #define CONFIG_IPADDR 192.168.1.253 -- cgit v1.3.1