Implemented support for MPC8548CDS board.
Added DDR II support based on SPD values for MPC85xx boards.
This roll-up patch also includes bugfies for the previously
published patches:
DDRII CPO, pre eTSEC, 8548 LBIU, Andy's TSEC, eTSEC 3&4 I/O
======================================================================
Changes for U-Boot 1.1.3:
======================================================================
+* Patch by Jon Loeliger, 2005-05-05
+ Implemented support for MPC8548CDS board.
+ Added DDR II support based on SPD values for MPC85xx boards.
+ This roll-up patch also includes bugfies for the previously
+ published patches:
+ DDRII CPO, pre eTSEC, 8548 LBIU, Andy's TSEC, eTSEC 3&4 I/O
+
* Patch by Jon Loeliger, 2005-Feb-10
Add config option CONFIG_HAS_FEC calling out 8540 FEC features.
#########################################################################
LIST_85xx=" \
- MPC8540ADS MPC8541CDS MPC8555CDS MPC8560ADS \
- PM854 sbc8540 sbc8560 stxgp3 \
- TQM8540 \
+
+ MPC8540ADS MPC8541CDS MPC8548CDS MPC8555CDS \
+ MPC8560ADS PM854 sbc8540 sbc8560 \
+ stxgp3 TQM8540 \
"
#########################################################################
MPC8541CDS_config: unconfig
@./mkconfig $(@:_config=) ppc mpc85xx mpc8541cds cds
+MPC8548CDS_config: unconfig
+ @./mkconfig $(@:_config=) ppc mpc85xx mpc8548cds cds
+
MPC8555CDS_config: unconfig
@./mkconfig $(@:_config=) ppc mpc85xx mpc8555cds cds
#include "../common/cadmus.h"
#include "../common/eeprom.h"
-#if defined(CONFIG_DDR_ECC)
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
extern void ddr_enable_ecc(unsigned int dram_size);
#endif
#endif
dram_size = spd_sdram();
-#if defined(CONFIG_DDR_ECC)
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
/*
* Initialize and enable DDR ECC.
*/
--- /dev/null
+#
+# Copyright 2004 Freescale Semiconductor.
+# (C) Copyright 2001
+# 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 = lib$(BOARD).a
+
+OBJS := $(BOARD).o \
+ ../common/cadmus.o \
+ ../common/eeprom.o
+
+SOBJS := init.o
+
+$(LIB): $(OBJS) $(SOBJS)
+ $(AR) crv $@ $(OBJS)
+
+clean:
+ rm -f $(OBJS) $(SOBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+-include .depend
+
+#########################################################################
--- /dev/null
+#
+# Copyright 2004 Freescale Semiconductor.
+#
+# 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
+#
+
+#
+# mpc8548cds board
+#
+TEXT_BASE = 0xfff80000
+
+PLATFORM_CPPFLAGS += -DCONFIG_E500=1
+PLATFORM_CPPFLAGS += -DCONFIG_MPC85xx=1
+PLATFORM_CPPFLAGS += -DCONFIG_MPC8548=1
--- /dev/null
+/*
+ * Copyright 2004 Freescale Semiconductor.
+ * Copyright 2002,2003, Motorola Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+#include <asm/cache.h>
+#include <asm/mmu.h>
+#include <config.h>
+#include <mpc85xx.h>
+
+
+/*
+ * TLB0 and TLB1 Entries
+ *
+ * Out of reset, TLB1's Entry 0 maps the highest 4K for CCSRBAR.
+ * However, CCSRBAR is then relocated to CFG_CCSRBAR right after
+ * these TLB entries are established.
+ *
+ * The TLB entries for DDR are dynamically setup in spd_sdram()
+ * and use TLB1 Entries 8 through 15 as needed according to the
+ * size of DDR memory.
+ *
+ * MAS0: tlbsel, esel, nv
+ * MAS1: valid, iprot, tid, ts, tsize
+ * MAS2: epn, sharen, x0, x1, w, i, m, g, e
+ * MAS3: rpn, u0-u3, ux, sx, uw, sw, ur, sr
+ */
+
+#define entry_start \
+ mflr r1 ; \
+ bl 0f ;
+
+#define entry_end \
+0: mflr r0 ; \
+ mtlr r1 ; \
+ blr ;
+
+
+ .section .bootpg, "ax"
+ .globl tlb1_entry
+tlb1_entry:
+ entry_start
+
+ /*
+ * Number of TLB0 and TLB1 entries in the following table
+ */
+ .long 13
+
+#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR)
+ /*
+ * TLB0 4K Non-cacheable, guarded
+ * 0xff700000 4K Initial CCSRBAR mapping
+ *
+ * This ends up at a TLB0 Index==0 entry, and must not collide
+ * with other TLB0 Entries.
+ */
+ .long TLB1_MAS0(0, 0, 0)
+ .long TLB1_MAS1(1, 0, 0, 0, 0)
+ .long TLB1_MAS2(E500_TLB_EPN(CFG_CCSRBAR_DEFAULT), 0,0,0,0,1,0,1,0)
+ .long TLB1_MAS3(E500_TLB_RPN(CFG_CCSRBAR_DEFAULT), 0,0,0,0,0,1,0,1,0,1)
+#else
+#error("Update the number of table entries in tlb1_entry")
+#endif
+
+ /*
+ * TLB0 16K Cacheable, non-guarded
+ * 0xd001_0000 16K Temporary Global data for initialization
+ *
+ * Use four 4K TLB0 entries. These entries must be cacheable
+ * as they provide the bootstrap memory before the memory
+ * controler and real memory have been configured.
+ *
+ * These entries end up at TLB0 Indicies 0x10, 0x14, 0x18 and 0x1c,
+ * and must not collide with other TLB0 entries.
+ */
+ .long TLB1_MAS0(0, 0, 0)
+ .long TLB1_MAS1(1, 0, 0, 0, 0)
+ .long TLB1_MAS2(E500_TLB_EPN(CFG_INIT_RAM_ADDR),
+ 0,0,0,0,0,0,0,0)
+ .long TLB1_MAS3(E500_TLB_RPN(CFG_INIT_RAM_ADDR),
+ 0,0,0,0,0,1,0,1,0,1)
+
+ .long TLB1_MAS0(0, 0, 0)
+ .long TLB1_MAS1(1, 0, 0, 0, 0)
+ .long TLB1_MAS2(E500_TLB_EPN(CFG_INIT_RAM_ADDR + 4 * 1024),
+ 0,0,0,0,0,0,0,0)
+ .long TLB1_MAS3(E500_TLB_RPN(CFG_INIT_RAM_ADDR + 4 * 1024),
+ 0,0,0,0,0,1,0,1,0,1)
+
+ .long TLB1_MAS0(0, 0, 0)
+ .long TLB1_MAS1(1, 0, 0, 0, 0)
+ .long TLB1_MAS2(E500_TLB_EPN(CFG_INIT_RAM_ADDR + 8 * 1024),
+ 0,0,0,0,0,0,0,0)
+ .long TLB1_MAS3(E500_TLB_RPN(CFG_INIT_RAM_ADDR + 8 * 1024),
+ 0,0,0,0,0,1,0,1,0,1)
+
+ .long TLB1_MAS0(0, 0, 0)
+ .long TLB1_MAS1(1, 0, 0, 0, 0)
+ .long TLB1_MAS2(E500_TLB_EPN(CFG_INIT_RAM_ADDR + 12 * 1024),
+ 0,0,0,0,0,0,0,0)
+ .long TLB1_MAS3(E500_TLB_RPN(CFG_INIT_RAM_ADDR + 12 * 1024),
+ 0,0,0,0,0,1,0,1,0,1)
+
+
+ /*
+ * TLB 0: 16M Non-cacheable, guarded
+ * 0xff000000 16M FLASH
+ * Out of reset this entry is only 4K.
+ */
+ .long TLB1_MAS0(1, 0, 0)
+ .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_16M)
+ .long TLB1_MAS2(E500_TLB_EPN(CFG_FLASH_BASE), 0,0,0,0,1,0,1,0)
+ .long TLB1_MAS3(E500_TLB_RPN(CFG_FLASH_BASE), 0,0,0,0,0,1,0,1,0,1)
+
+ /*
+ * TLB 1: 256M Non-cacheable, guarded
+ * 0x80000000 256M PCI1 MEM First half
+ */
+ .long TLB1_MAS0(1, 1, 0)
+ .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_256M)
+ .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)
+
+ /*
+ * TLB 2: 256M Non-cacheable, guarded
+ * 0x90000000 256M PCI1 MEM Second half
+ */
+ .long TLB1_MAS0(1, 2, 0)
+ .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_256M)
+ .long TLB1_MAS2(E500_TLB_EPN(CFG_PCI1_MEM_BASE + 0x10000000),
+ 0,0,0,0,1,0,1,0)
+ .long TLB1_MAS3(E500_TLB_RPN(CFG_PCI1_MEM_BASE + 0x10000000),
+ 0,0,0,0,0,1,0,1,0,1)
+
+ /*
+ * TLB 3: 256M Non-cacheable, guarded
+ * 0xa0000000 256M PCI2 MEM First half
+ */
+ .long TLB1_MAS0(1, 3, 0)
+ .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_256M)
+ .long TLB1_MAS2(E500_TLB_EPN(CFG_PCI2_MEM_BASE), 0,0,0,0,1,0,1,0)
+ .long TLB1_MAS3(E500_TLB_RPN(CFG_PCI2_MEM_BASE), 0,0,0,0,0,1,0,1,0,1)
+
+ /*
+ * TLB 4: 256M Non-cacheable, guarded
+ * 0xb0000000 256M PCI2 MEM Second half
+ */
+ .long TLB1_MAS0(1, 4, 0)
+ .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_256M)
+ .long TLB1_MAS2(E500_TLB_EPN(CFG_PCI2_MEM_BASE + 0x10000000),
+ 0,0,0,0,1,0,1,0)
+ .long TLB1_MAS3(E500_TLB_RPN(CFG_PCI2_MEM_BASE + 0x10000000),
+ 0,0,0,0,0,1,0,1,0,1)
+
+ /*
+ * TLB 5: 64M Non-cacheable, guarded
+ * 0xe000_0000 1M CCSRBAR
+ * 0xe200_0000 16M PCI1 IO
+ * 0xe300_0000 16M PCI2 IO
+ */
+ .long TLB1_MAS0(1, 5, 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)
+
+ /*
+ * TLB 6: 64M Cacheable, non-guarded
+ * 0xf000_0000 64M LBC SDRAM
+ */
+ .long TLB1_MAS0(1, 6, 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)
+
+ /*
+ * TLB 7: 1M Non-cacheable, guarded
+ * 0xf8000000 1M CADMUS registers
+ */
+ .long TLB1_MAS0(1, 7, 0)
+ .long TLB1_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_1M)
+ .long TLB1_MAS2(E500_TLB_EPN(CADMUS_BASE_ADDR), 0,0,0,0,1,0,1,0)
+ .long TLB1_MAS3(E500_TLB_RPN(CADMUS_BASE_ADDR), 0,0,0,0,0,1,0,1,0,1)
+
+ entry_end
+
+/*
+ * LAW(Local Access Window) configuration:
+ *
+ * 0x0000_0000 0x7fff_ffff DDR 2G
+ * 0x8000_0000 0x9fff_ffff PCI1 MEM 512M
+ * 0xa000_0000 0xbfff_ffff PCI2 MEM 512M
+ * 0xe000_0000 0xe000_ffff CCSR 1M
+ * 0xe200_0000 0xe2ff_ffff PCI1 IO 16M
+ * 0xe300_0000 0xe3ff_ffff PCI2 IO 16M
+ * 0xf000_0000 0xf7ff_ffff SDRAM 128M
+ * 0xf800_0000 0xf80f_ffff NVRAM/CADMUS (*) 1M
+ * 0xff00_0000 0xff7f_ffff FLASH (2nd bank) 8M
+ * 0xff80_0000 0xffff_ffff FLASH (boot bank) 8M
+ *
+ * Notes:
+ * CCSRBAR and L2-as-SRAM don't need a configured Local Access Window.
+ * If flash is 8M at default position (last 8M), no LAW needed.
+ *
+ * The defines below are 1-off of the actual LAWAR0 usage.
+ * So LAWAR3 define uses the LAWAR4 register in the ECM.
+ */
+
+#define LAWBAR0 0
+#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_512M))
+
+#define LAWBAR2 ((CFG_PCI2_MEM_BASE>>12) & 0xfffff)
+#define LAWAR2 (LAWAR_EN | LAWAR_TRGT_IF_PCI2 | (LAWAR_SIZE & LAWAR_SIZE_512M))
+
+#define LAWBAR3 ((CFG_PCI1_IO_BASE>>12) & 0xfffff)
+#define LAWAR3 (LAWAR_EN | LAWAR_TRGT_IF_PCI1 | (LAWAR_SIZE & LAWAR_SIZE_16M))
+
+#define LAWBAR4 ((CFG_PCI2_IO_BASE>>12) & 0xfffff)
+#define LAWAR4 (LAWAR_EN | LAWAR_TRGT_IF_PCI2 | (LAWAR_SIZE & LAWAR_SIZE_16M))
+
+/* LBC window - maps 256M 0xf0000000 -> 0xffffffff */
+#define LAWBAR5 ((CFG_LBC_SDRAM_BASE>>12) & 0xfffff)
+#define LAWAR5 (LAWAR_EN | LAWAR_TRGT_IF_LBC | (LAWAR_SIZE & LAWAR_SIZE_256M))
+
+ .section .bootpg, "ax"
+ .globl law_entry
+
+law_entry:
+ entry_start
+ .long 6
+ .long LAWBAR0,LAWAR0,LAWBAR1,LAWAR1,LAWBAR2,LAWAR2,LAWBAR3,LAWAR3
+ .long LAWBAR4,LAWAR4,LAWBAR5,LAWAR5
+ entry_end
--- /dev/null
+/*
+ * Copyright 2004 Freescale Semiconductor.
+ *
+ * (C) Copyright 2002 Scott McNutt <smcnutt@artesyncp.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <pci.h>
+#include <asm/processor.h>
+#include <asm/immap_85xx.h>
+#include <spd.h>
+
+#include "../common/cadmus.h"
+#include "../common/eeprom.h"
+
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+extern void ddr_enable_ecc(unsigned int dram_size);
+#endif
+
+extern long int spd_sdram(void);
+
+void local_bus_init(void);
+void sdram_init(void);
+
+int board_early_init_f (void)
+{
+ return 0;
+}
+
+int checkboard (void)
+{
+ volatile immap_t *immap = (immap_t *) CFG_CCSRBAR;
+ volatile ccsr_gur_t *gur = &immap->im_gur;
+
+ /* PCI slot in USER bits CSR[6:7] by convention. */
+ uint pci_slot = get_pci_slot ();
+
+ uint pci_dual = get_pci_dual (); /* PCI DUAL in CM_PCI[3] */
+ uint pci1_32 = gur->pordevsr & 0x10000; /* PORDEVSR[15] */
+ uint pci1_clk_sel = gur->porpllsr & 0x8000; /* PORPLLSR[16] */
+ uint pci2_clk_sel = gur->porpllsr & 0x4000; /* PORPLLSR[17] */
+
+ uint pci1_speed = get_clock_freq (); /* PCI PSPEED in [4:5] */
+
+ uint cpu_board_rev = get_cpu_board_revision ();
+
+ printf ("Board: CDS Version 0x%02x, PCI Slot %d\n",
+ get_board_version (), pci_slot);
+
+ printf ("CPU Board Revision %d.%d (0x%04x)\n",
+ MPC85XX_CPU_BOARD_MAJOR (cpu_board_rev),
+ MPC85XX_CPU_BOARD_MINOR (cpu_board_rev), cpu_board_rev);
+
+ printf (" PCI1: %d bit, %s MHz, %s\n",
+ (pci1_32) ? 32 : 64,
+ (pci1_speed == 33000000) ? "33" :
+ (pci1_speed == 66000000) ? "66" : "unknown",
+ pci1_clk_sel ? "sync" : "async");
+
+ if (pci_dual) {
+ printf (" PCI2: 32 bit, 66 MHz, %s\n",
+ pci2_clk_sel ? "sync" : "async");
+ } else {
+ printf (" PCI2: disabled\n");
+ }
+
+ /*
+ * Initialize local bus.
+ */
+ local_bus_init ();
+
+
+ /*
+ * Hack TSEC 3 and 4 IO voltages.
+ */
+ gur->tsec34ioovcr = 0xe7e0; /* 1110 0111 1110 0xxx */
+
+ return 0;
+}
+
+long int
+initdram(int board_type)
+{
+ long dram_size = 0;
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+
+ puts("Initializing\n");
+
+#if defined(CONFIG_DDR_DLL)
+ {
+ /*
+ * Work around to stabilize DDR DLL MSYNC_IN.
+ * Errata DDR9 seems to have been fixed.
+ * This is now the workaround for Errata DDR11:
+ * Override DLL = 1, Course Adj = 1, Tap Select = 0
+ */
+
+ volatile ccsr_gur_t *gur= &immap->im_gur;
+
+ gur->ddrdllcr = 0x81000000;
+ asm("sync;isync;msync");
+ udelay(200);
+ }
+#endif
+ dram_size = spd_sdram();
+
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+ /*
+ * Initialize and enable DDR ECC.
+ */
+ ddr_enable_ecc(dram_size);
+#endif
+ /*
+ * SDRAM Initialization
+ */
+ sdram_init();
+
+ puts(" DDR: ");
+ return dram_size;
+}
+
+/*
+ * Initialize Local Bus
+ */
+void
+local_bus_init(void)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile ccsr_gur_t *gur = &immap->im_gur;
+ volatile ccsr_lbc_t *lbc = &immap->im_lbc;
+
+ uint clkdiv;
+ uint lbc_hz;
+ sys_info_t sysinfo;
+
+ get_sys_info(&sysinfo);
+ clkdiv = (lbc->lcrr & 0x0f) * 2;
+ lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv;
+
+ gur->lbiuiplldcr1 = 0x00078080;
+ if (clkdiv == 16) {
+ gur->lbiuiplldcr0 = 0x7c0f1bf0;
+ } else if (clkdiv == 8) {
+ gur->lbiuiplldcr0 = 0x6c0f1bf0;
+ } else if (clkdiv == 4) {
+ gur->lbiuiplldcr0 = 0x5c0f1bf0;
+ }
+
+ lbc->lcrr |= 0x00030000;
+
+ asm("sync;isync;msync");
+}
+
+/*
+ * Initialize SDRAM memory on the Local Bus.
+ */
+void
+sdram_init(void)
+{
+#if defined(CFG_OR2_PRELIM) && defined(CFG_BR2_PRELIM)
+
+ uint idx;
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile ccsr_lbc_t *lbc = &immap->im_lbc;
+ uint *sdram_addr = (uint *)CFG_LBC_SDRAM_BASE;
+ uint cpu_board_rev;
+ uint lsdmr_common;
+
+ puts(" SDRAM: ");
+
+ print_size (CFG_LBC_SDRAM_SIZE * 1024 * 1024, "\n");
+
+ /*
+ * Setup SDRAM Base and Option Registers
+ */
+ lbc->or2 = CFG_OR2_PRELIM;
+ asm("msync");
+
+ lbc->br2 = CFG_BR2_PRELIM;
+ asm("msync");
+
+ lbc->lbcr = CFG_LBC_LBCR;
+ asm("msync");
+
+
+ lbc->lsrt = CFG_LBC_LSRT;
+ lbc->mrtpr = CFG_LBC_MRTPR;
+ asm("msync");
+
+ /*
+ * MPC8548 uses "new" 15-16 style addressing.
+ */
+ cpu_board_rev = get_cpu_board_revision();
+ lsdmr_common = CFG_LBC_LSDMR_COMMON;
+ lsdmr_common |= CFG_LBC_LSDMR_BSMA1516;
+
+ /*
+ * Issue PRECHARGE ALL command.
+ */
+ lbc->lsdmr = lsdmr_common | CFG_LBC_LSDMR_OP_PCHALL;
+ asm("sync;msync");
+ *sdram_addr = 0xff;
+ ppcDcbf((unsigned long) sdram_addr);
+ udelay(100);
+
+ /*
+ * Issue 8 AUTO REFRESH commands.
+ */
+ for (idx = 0; idx < 8; idx++) {
+ lbc->lsdmr = lsdmr_common | CFG_LBC_LSDMR_OP_ARFRSH;
+ asm("sync;msync");
+ *sdram_addr = 0xff;
+ ppcDcbf((unsigned long) sdram_addr);
+ udelay(100);
+ }
+
+ /*
+ * Issue 8 MODE-set command.
+ */
+ lbc->lsdmr = lsdmr_common | CFG_LBC_LSDMR_OP_MRW;
+ asm("sync;msync");
+ *sdram_addr = 0xff;
+ ppcDcbf((unsigned long) sdram_addr);
+ udelay(100);
+
+ /*
+ * Issue NORMAL OP command.
+ */
+ lbc->lsdmr = lsdmr_common | CFG_LBC_LSDMR_OP_NORMAL;
+ asm("sync;msync");
+ *sdram_addr = 0xff;
+ ppcDcbf((unsigned long) sdram_addr);
+ udelay(200); /* Overkill. Must wait > 200 bus cycles */
+
+#endif /* enable SDRAM init */
+}
+
+#if defined(CFG_DRAM_TEST)
+int
+testdram(void)
+{
+ uint *pstart = (uint *) CFG_MEMTEST_START;
+ uint *pend = (uint *) CFG_MEMTEST_END;
+ uint *p;
+
+ printf("Testing DRAM from 0x%08x to 0x%08x\n",
+ CFG_MEMTEST_START,
+ CFG_MEMTEST_END);
+
+ printf("DRAM test phase 1:\n");
+ for (p = pstart; p < pend; p++)
+ *p = 0xaaaaaaaa;
+
+ for (p = pstart; p < pend; p++) {
+ if (*p != 0xaaaaaaaa) {
+ printf ("DRAM test fails at: %08x\n", (uint) p);
+ return 1;
+ }
+ }
+
+ printf("DRAM test phase 2:\n");
+ for (p = pstart; p < pend; p++)
+ *p = 0x55555555;
+
+ for (p = pstart; p < pend; p++) {
+ if (*p != 0x55555555) {
+ printf ("DRAM test fails at: %08x\n", (uint) p);
+ return 1;
+ }
+ }
+
+ printf("DRAM test passed.\n");
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_PCI)
+
+/*
+ * Initialize PCI Devices, report devices found.
+ */
+
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_mpc85xxcds_config_table[] = {
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ PCI_IDSEL_NUMBER, PCI_ANY_ID,
+ pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
+ PCI_ENET0_MEMADDR,
+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
+ } },
+ { }
+};
+#endif
+
+static struct pci_controller hose = {
+#ifndef CONFIG_PCI_PNP
+ config_table: pci_mpc85xxcds_config_table,
+#endif
+};
+
+#endif /* CONFIG_PCI */
+
+void
+pci_init_board(void)
+{
+#ifdef CONFIG_PCI
+ extern void pci_mpc85xx_init(struct pci_controller *hose);
+
+ pci_mpc85xx_init(&hose);
+#endif
+}
--- /dev/null
+/*
+ * Copyright 2004 Freescale Semiconductor.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ .resetvec 0xFFFFFFFC :
+ {
+ *(.resetvec)
+ } = 0xffff
+
+ .bootpg 0xFFFFF000 :
+ {
+ cpu/mpc85xx/start.o (.bootpg)
+ board/cds/mpc8548cds/init.o (.bootpg)
+ } = 0xffff
+
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ cpu/mpc85xx/start.o (.text)
+ board/cds/mpc8548cds/init.o (.text)
+ cpu/mpc85xx/traps.o (.text)
+ cpu/mpc85xx/interrupts.o (.text)
+ cpu/mpc85xx/cpu_init.o (.text)
+ cpu/mpc85xx/cpu.o (.text)
+ cpu/mpc85xx/tsec.o (.text)
+ cpu/mpc85xx/speed.o (.text)
+ cpu/mpc85xx/pci.o (.text)
+ common/dlmalloc.o (.text)
+ lib_generic/crc32.o (.text)
+ lib_ppc/extable.o (.text)
+ lib_generic/zlib.o (.text)
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ }
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x00FF) & 0xFFFFFF00;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+ __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(256);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(256);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
#include "../common/cadmus.h"
#include "../common/eeprom.h"
-#if defined(CONFIG_DDR_ECC)
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
extern void ddr_enable_ecc(unsigned int dram_size);
#endif
#endif
dram_size = spd_sdram();
-#if defined(CONFIG_DDR_ECC)
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
/*
* Initialize and enable DDR ECC.
*/
#include <asm/immap_85xx.h>
#include <spd.h>
-#if defined(CONFIG_DDR_ECC)
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
extern void ddr_enable_ecc(unsigned int dram_size);
#endif
dram_size = fixed_sdram ();
#endif
-#if defined(CONFIG_DDR_ECC)
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
/*
* Initialize and enable DDR ECC.
*/
#include <spd.h>
#include <miiphy.h>
-#if defined(CONFIG_DDR_ECC)
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
extern void ddr_enable_ecc(unsigned int dram_size);
#endif
dram_size = fixed_sdram ();
#endif
-#if defined(CONFIG_DDR_ECC)
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
/*
* Initialize and enable DDR ECC.
*/
uint lcrr; /* local bus clock ratio register */
uint clkdiv; /* clock divider portion of lcrr */
uint pvr, svr;
+ uint fam;
uint ver;
uint major, minor;
case SVR_8560:
puts("8560");
break;
+ case SVR_8548:
+ puts("8548");
+ break;
+ case SVR_8548_E:
+ puts("8548_E");
+ break;
default:
puts("Unknown");
break;
printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr);
pvr = get_pvr();
+ fam = PVR_FAM(pvr);
ver = PVR_VER(pvr);
major = PVR_MAJ(pvr);
minor = PVR_MIN(pvr);
printf("Core: ");
- switch (ver) {
- case PVR_VER(PVR_85xx):
+ switch (fam) {
+ case PVR_FAM(PVR_85xx):
puts("E500");
break;
default:
get_sys_info(&sysinfo);
- puts("Clocks Configuration:\n");
+ puts("Clock Configuration:\n");
printf(" CPU:%4lu MHz, ", sysinfo.freqProcessor / 1000000);
printf("CCB:%4lu MHz,\n", sysinfo.freqSystemBus / 1000000);
printf(" DDR:%4lu MHz, ", sysinfo.freqSystemBus / 2000000);
#endif
clkdiv = lcrr & 0x0f;
if (clkdiv == 2 || clkdiv == 4 || clkdiv == 8) {
+#ifdef CONFIG_MPC8548
+ /*
+ * Yes, the entire PQ38 family use the same
+ * bit-representation for twice the clock divider values.
+ */
+ clkdiv *= 2;
+#endif
printf("LBC:%4lu MHz\n",
sysinfo.freqSystemBus / 1000000 / clkdiv);
} else {
#endif
}
+
/*
- * We initialize L2 as cache here.
+ * Initialize L2 as cache.
+ *
+ * The newer 8548, etc, parts have twice as much cache, but
+ * use the same bit-encoding as the older 8555, etc, parts.
+ *
+ * FIXME: Use PVR_VER(pvr) == 1 test here instead of SVR_VER()?
*/
-int cpu_init_r (void)
+
+int cpu_init_r(void)
{
#if defined(CONFIG_L2_CACHE)
- volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile ccsr_l2cache_t *l2cache = &immap->im_l2cache;
- volatile uint temp;
+ volatile uint cache_ctl;
+ uint svr, ver;
+
+ svr = get_svr();
+ ver = SVR_VER(svr);
asm("msync;isync");
- temp = l2cache->l2ctl;
- temp &= 0x30000000;
- switch ( temp ) {
+ cache_ctl = l2cache->l2ctl;
+
+ switch (cache_ctl & 0x30000000) {
case 0x20000000:
- printf ("L2 cache 256KB:");
+ if (ver == SVR_8548 || ver == SVR_8548_E) {
+ printf ("L2 cache 512KB:");
+ } else {
+ printf ("L2 cache 256KB:");
+ }
break;
case 0x00000000:
case 0x10000000:
case 0x30000000:
default:
- printf ("L2 cache unknown size. Check the silicon!\n");
+ printf ("L2 cache unknown size (0x%08x)\n", cache_ctl);
return -1;
}
asm("msync;isync");
l2cache->l2ctl = 0x68000000; /* invalidate */
- temp = l2cache->l2ctl;
+ cache_ctl = l2cache->l2ctl;
asm("msync;isync");
+
l2cache->l2ctl = 0xa8000000; /* enable 256KB L2 cache */
- temp = l2cache->l2ctl;
+ cache_ctl = l2cache->l2ctl;
asm("msync;isync");
- printf("enabled\n");
+ printf(" enabled\n");
#else
- printf("L2: disabled.\n");
+ printf("L2 cache: disabled\n");
#endif
return 0;
#include <spd.h>
#include <asm/mmu.h>
-#if defined(CONFIG_DDR_ECC)
-extern void dma_init (void);
+
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+extern void dma_init(void);
extern uint dma_check(void);
-extern int dma_xfer (void *dest, uint count, void *src);
+extern int dma_xfer(void *dest, uint count, void *src);
#endif
#ifdef CONFIG_SPD_EEPROM
#define CFG_READ_SPD i2c_read
#endif
+static unsigned int setup_laws_and_tlbs(unsigned int memsize);
+
+
/*
* Convert picoseconds into clock cycles (rounding up if needed).
*/
return clks;
}
+
+/*
+ * Calculate the Density of each Physical Rank.
+ * Returned size is in bytes.
+ *
+ * Study these table from Byte 31 of JEDEC SPD Spec.
+ *
+ * DDR I DDR II
+ * Bit Size Size
+ * --- ----- ------
+ * 7 high 512MB 512MB
+ * 6 256MB 256MB
+ * 5 128MB 128MB
+ * 4 64MB 16GB
+ * 3 32MB 8GB
+ * 2 16MB 4GB
+ * 1 2GB 2GB
+ * 0 low 1GB 1GB
+ *
+ * Reorder Table to be linear by stripping the bottom
+ * 2 or 5 bits off and shifting them up to the top.
+ */
+
+unsigned int
+compute_banksize(unsigned int mem_type, unsigned char row_dens)
+{
+ unsigned int bsize;
+
+ if (mem_type == SPD_MEMTYPE_DDR) {
+ /* Bottom 2 bits up to the top. */
+ bsize = ((row_dens >> 2) | ((row_dens & 3) << 6)) << 24;
+ debug("DDR: DDR I rank density = 0x%08x\n", bsize);
+ } else {
+ /* Bottom 5 bits up to the top. */
+ bsize = ((row_dens >> 5) | ((row_dens & 31) << 3)) << 27;
+ debug("DDR: DDR II rank density = 0x%08x\n", bsize);
+ }
+ return bsize;
+}
+
+
+/*
+ * Convert a two-nibble BCD value into a cycle time.
+ * While the spec calls for nano-seconds, picos are returned.
+ *
+ * This implements the tables for bytes 9, 23 and 25 for both
+ * DDR I and II. No allowance for distinguishing the invalid
+ * fields absent for DDR I yet present in DDR II is made.
+ * (That is, cycle times of .25, .33, .66 and .75 ns are
+ * allowed for both DDR II and I.)
+ */
+
unsigned int
-banksize(unsigned char row_dens)
+convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val)
{
- return ((row_dens >> 2) | ((row_dens & 3) << 6)) << 24;
+ /*
+ * Table look up the lower nibble, allow DDR I & II.
+ */
+ unsigned int tenths_ps[16] = {
+ 0,
+ 100,
+ 200,
+ 300,
+ 400,
+ 500,
+ 600,
+ 700,
+ 800,
+ 900,
+ 250,
+ 330, /* FIXME: Is 333 better/valid? */
+ 660, /* FIXME: Is 667 better/valid? */
+ 750,
+ 0, /* undefined */
+ 0 /* undefined */
+ };
+
+ unsigned int whole_ns = (spd_val & 0xF0) >> 4;
+ unsigned int tenth_ns = spd_val & 0x0F;
+ unsigned int ps = whole_ns * 1000 + tenths_ps[tenth_ns];
+
+ return ps;
}
+
long int
spd_sdram(void)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile ccsr_ddr_t *ddr = &immap->im_ddr;
- volatile ccsr_local_ecm_t *ecm = &immap->im_local_ecm;
+ volatile ccsr_gur_t *gur = &immap->im_gur;
spd_eeprom_t spd;
- unsigned tmp, tmp1;
+ unsigned int n_ranks;
+ unsigned int rank_density;
+ unsigned int odt_rd_cfg, odt_wr_cfg;
+ unsigned int odt_cfg, mode_odt_enable;
+ unsigned int dqs_cfg;
+ unsigned char twr_clk, twtr_clk, twr_auto_clk;
+ unsigned int tCKmin_ps, tCKmax_ps;
+ unsigned int max_data_rate, effective_data_rate;
+ unsigned int busfreq;
+ unsigned sdram_cfg;
unsigned int memsize;
- unsigned int tlb_size;
- unsigned int law_size;
- unsigned char caslat;
- unsigned int ram_tlb_index;
- unsigned int ram_tlb_address;
+ unsigned char caslat, caslat_ctrl;
+ unsigned int trfc, trfc_clk, trfc_low, trfc_high;
+ unsigned int trcd_clk;
+ unsigned int trtp_clk;
+ unsigned char cke_min_clk;
+ unsigned char add_lat;
+ unsigned char wr_lat;
+ unsigned char wr_data_delay;
+ unsigned char four_act;
+ unsigned char cpo;
+ unsigned char burst_len;
+ unsigned int mode_caslat;
+ unsigned char sdram_type;
+ unsigned char d_init;
- CFG_READ_SPD(SPD_EEPROM_ADDRESS, 0, 1, (uchar *) & spd, sizeof (spd));
+ /*
+ * Read SPD information.
+ */
+ CFG_READ_SPD(SPD_EEPROM_ADDRESS, 0, 1, (uchar *) &spd, sizeof(spd));
- if (spd.nrows > 2) {
- puts("DDR:Only two chip selects are supported on ADS.\n");
+ /*
+ * Check for supported memory module types.
+ */
+ if (spd.mem_type != SPD_MEMTYPE_DDR &&
+ spd.mem_type != SPD_MEMTYPE_DDR2) {
+ printf("Unable to locate DDR I or DDR II module.\n"
+ " Fundamental memory type is 0x%0x\n",
+ spd.mem_type);
return 0;
}
- if (spd.nrow_addr < 12
- || spd.nrow_addr > 14
- || spd.ncol_addr < 8
- || spd.ncol_addr > 11) {
- puts("DDR:Row or Col number unsupported.\n");
+ /*
+ * These test gloss over DDR I and II differences in interpretation
+ * of bytes 3 and 4, but irrelevantly. Multiple asymmetric banks
+ * are not supported on DDR I; and not encoded on DDR II.
+ *
+ * Also note that the 8548 controller can support:
+ * 12 <= nrow <= 16
+ * and
+ * 8 <= ncol <= 11 (still, for DDR)
+ * 6 <= ncol <= 9 (for FCRAM)
+ */
+ if (spd.nrow_addr < 12 || spd.nrow_addr > 14) {
+ printf("DDR: Unsupported number of Row Addr lines: %d.\n",
+ spd.nrow_addr);
+ return 0;
+ }
+ if (spd.ncol_addr < 8 || spd.ncol_addr > 11) {
+ printf("DDR: Unsupported number of Column Addr lines: %d.\n",
+ spd.ncol_addr);
return 0;
}
- ddr->cs0_bnds = (banksize(spd.row_dens) >> 24) - 1;
- ddr->cs0_config = ( 1 << 31
- | (spd.nrow_addr - 12) << 8
- | (spd.ncol_addr - 8) );
- debug("\n");
- debug("cs0_bnds = 0x%08x\n",ddr->cs0_bnds);
- debug("cs0_config = 0x%08x\n",ddr->cs0_config);
-
- if (spd.nrows == 2) {
- ddr->cs1_bnds = ( (banksize(spd.row_dens) >> 8)
- | ((banksize(spd.row_dens) >> 23) - 1) );
- ddr->cs1_config = ( 1<<31
- | (spd.nrow_addr-12) << 8
- | (spd.ncol_addr-8) );
- debug("cs1_bnds = 0x%08x\n",ddr->cs1_bnds);
- debug("cs1_config = 0x%08x\n",ddr->cs1_config);
+ /*
+ * Determine the number of physical banks controlled by
+ * different Chip Select signals. This is not quite the
+ * same as the number of DIMM modules on the board. Feh.
+ */
+ if (spd.mem_type == SPD_MEMTYPE_DDR) {
+ n_ranks = spd.nrows;
+ } else {
+ n_ranks = (spd.nrows & 0x7) + 1;
}
- if (spd.mem_type != 0x07) {
- puts("No DDR module found!\n");
+ debug("DDR: number of ranks = %d\n", n_ranks);
+
+ if (n_ranks > 2) {
+ printf("DDR: Only 2 chip selects are supported: %d\n",
+ n_ranks);
return 0;
}
/*
- * Figure out memory size in Megabytes.
+ * Adjust DDR II IO voltage biasing. It just makes it work.
*/
- memsize = spd.nrows * banksize(spd.row_dens) / 0x100000;
+ if (spd.mem_type == SPD_MEMTYPE_DDR2) {
+ gur->ddrioovcr = (0
+ | 0x80000000 /* Enable */
+ | 0x10000000 /* VSEL to 1.8V */
+ );
+ }
/*
- * First supported LAW size is 16M, at LAWAR_SIZE_16M == 23. Fnord.
+ * Determine the size of each Rank in bytes.
*/
- law_size = 19 + __ilog2(memsize);
+ rank_density = compute_banksize(spd.mem_type, spd.row_dens);
+
/*
- * Determine size of each TLB1 entry.
+ * Eg: Bounds: 0x0000_0000 to 0x0f000_0000 first 256 Meg
*/
- switch (memsize) {
- case 16:
- case 32:
- tlb_size = BOOKE_PAGESZ_16M;
- break;
- case 64:
- case 128:
- tlb_size = BOOKE_PAGESZ_64M;
- break;
- case 256:
- case 512:
- case 1024:
- case 2048:
- tlb_size = BOOKE_PAGESZ_256M;
- break;
- default:
- puts("DDR: only 16M,32M,64M,128M,256M,512M,1G and 2G DDR I are supported.\n");
- return 0;
- break;
- }
+ ddr->cs0_bnds = (rank_density >> 24) - 1;
/*
- * Configure DDR TLB1 entries.
- * Starting at TLB1 8, use no more than 8 TLB1 entries.
+ * ODT configuration recommendation from DDR Controller Chapter.
*/
- ram_tlb_index = 8;
- ram_tlb_address = (unsigned int)CFG_DDR_SDRAM_BASE;
- while (ram_tlb_address < (memsize * 1024 * 1024)
- && ram_tlb_index < 16) {
- mtspr(MAS0, TLB1_MAS0(1, ram_tlb_index, 0));
- mtspr(MAS1, TLB1_MAS1(1, 1, 0, 0, tlb_size));
- mtspr(MAS2, TLB1_MAS2(E500_TLB_EPN(ram_tlb_address),
- 0, 0, 0, 0, 0, 0, 0, 0));
- mtspr(MAS3, TLB1_MAS3(E500_TLB_RPN(ram_tlb_address),
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 1));
- asm volatile("isync;msync;tlbwe;isync");
+ odt_rd_cfg = 0; /* Never assert ODT */
+ odt_wr_cfg = 0; /* Never assert ODT */
+ if (spd.mem_type == SPD_MEMTYPE_DDR2) {
+ odt_wr_cfg = 1; /* Assert ODT on writes to CS0 */
+#if 0
+ /* FIXME: How to determine the number of dimm modules? */
+ if (n_dimm_modules == 2) {
+ odt_rd_cfg = 1; /* Assert ODT on reads to CS0 */
+ }
+#endif
+ }
- debug("DDR:MAS0=0x%08x\n", TLB1_MAS0(1, ram_tlb_index, 0));
- debug("DDR:MAS1=0x%08x\n", TLB1_MAS1(1, 1, 0, 0, tlb_size));
- debug("DDR:MAS2=0x%08x\n",
- TLB1_MAS2(E500_TLB_EPN(ram_tlb_address),
- 0, 0, 0, 0, 0, 0, 0, 0));
- debug("DDR:MAS3=0x%08x\n",
- TLB1_MAS3(E500_TLB_RPN(ram_tlb_address),
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 1));
+ ddr->cs0_config = ( 1 << 31
+ | (odt_rd_cfg << 20)
+ | (odt_wr_cfg << 16)
+ | (spd.nrow_addr - 12) << 8
+ | (spd.ncol_addr - 8) );
+ debug("\n");
+ debug("DDR: cs0_bnds = 0x%08x\n", ddr->cs0_bnds);
+ debug("DDR: cs0_config = 0x%08x\n", ddr->cs0_config);
- ram_tlb_address += (0x1000 << ((tlb_size - 1) * 2));
- ram_tlb_index++;
+ if (n_ranks == 2) {
+ /*
+ * Eg: Bounds: 0x0f00_0000 to 0x1e0000_0000, second 256 Meg
+ */
+ ddr->cs1_bnds = ( (rank_density >> 8)
+ | ((rank_density >> (24 - 1)) - 1) );
+ ddr->cs1_config = ( 1<<31
+ | (odt_rd_cfg << 20)
+ | (odt_wr_cfg << 16)
+ | (spd.nrow_addr - 12) << 8
+ | (spd.ncol_addr - 8) );
+ debug("DDR: cs1_bnds = 0x%08x\n", ddr->cs1_bnds);
+ debug("DDR: cs1_config = 0x%08x\n", ddr->cs1_config);
}
+
/*
- * Set up LAWBAR for all of DDR.
+ * Find the largest CAS by locating the highest 1 bit
+ * in the spd.cas_lat field. Translate it to a DDR
+ * controller field value:
+ *
+ * CAS Lat DDR I DDR II Ctrl
+ * Clocks SPD Bit SPD Bit Value
+ * ------- ------- ------- -----
+ * 1.0 0 0001
+ * 1.5 1 0010
+ * 2.0 2 2 0011
+ * 2.5 3 0100
+ * 3.0 4 3 0101
+ * 3.5 5 0110
+ * 4.0 4 0111
+ * 4.5 1000
+ * 5.0 5 1001
*/
- ecm->lawbar1 = ((CFG_DDR_SDRAM_BASE>>12) & 0xfffff);
- ecm->lawar1 = (LAWAR_EN | LAWAR_TRGT_IF_DDR | (LAWAR_SIZE & law_size));
- debug("DDR:LAWBAR1=0x%08x\n", ecm->lawbar1);
- debug("DDR:LARAR1=0x%08x\n", ecm->lawar1);
-
- /*
- * find the largest CAS
- */
- if(spd.cas_lat & 0x40) {
- caslat = 7;
- } else if (spd.cas_lat & 0x20) {
- caslat = 6;
- } else if (spd.cas_lat & 0x10) {
- caslat = 5;
- } else if (spd.cas_lat & 0x08) {
- caslat = 4;
- } else if (spd.cas_lat & 0x04) {
- caslat = 3;
- } else if (spd.cas_lat & 0x02) {
- caslat = 2;
- } else if (spd.cas_lat & 0x01) {
- caslat = 1;
- } else {
- puts("DDR:no valid CAS Latency information.\n");
+ caslat = __ilog2(spd.cas_lat);
+ if ((spd.mem_type == SPD_MEMTYPE_DDR)
+ && (caslat > 5)) {
+ printf("DDR I: Invalid SPD CAS Latency: 0x%x.\n", spd.cas_lat);
+ return 0;
+
+ } else if (spd.mem_type == SPD_MEMTYPE_DDR2
+ && (caslat < 2 || caslat > 5)) {
+ printf("DDR II: Invalid SPD CAS Latency: 0x%x.\n",
+ spd.cas_lat);
return 0;
}
+ debug("DDR: caslat SPD bit is %d\n", caslat);
+
+ /*
+ * Calculate the Maximum Data Rate based on the Minimum Cycle time.
+ * The SPD clk_cycle field (tCKmin) is measured in tenths of
+ * nanoseconds and represented as BCD.
+ */
+ tCKmin_ps = convert_bcd_tenths_to_cycle_time_ps(spd.clk_cycle);
+ debug("DDR: tCKmin = %d ps\n", tCKmin_ps);
+
+ /*
+ * Double-data rate, scaled 1000 to picoseconds, and back down to MHz.
+ */
+ max_data_rate = 2 * 1000 * 1000 / tCKmin_ps;
+ debug("DDR: Module max data rate = %d Mhz\n", max_data_rate);
+
- tmp = 20000 / (((spd.clk_cycle & 0xF0) >> 4) * 10
- + (spd.clk_cycle & 0x0f));
- debug("DDR:Module maximum data rate is: %dMhz\n", tmp);
+ /*
+ * Adjust the CAS Latency to allow for bus speeds that
+ * are slower than the DDR module.
+ */
+ busfreq = get_bus_freq(0) / 1000000; /* MHz */
- tmp1 = get_bus_freq(0) / 1000000;
- if (tmp1 < 230 && tmp1 >= 90 && tmp >= 230) {
- /* 90~230 range, treated as DDR 200 */
- if (spd.clk_cycle3 == 0xa0)
+ effective_data_rate = max_data_rate;
+ if (busfreq < 90) {
+ /* DDR rate out-of-range */
+ puts("DDR: platform frequency is not fit for DDR rate\n");
+ return 0;
+
+ } else if (90 <= busfreq && busfreq < 230 && max_data_rate >= 230) {
+ /*
+ * busfreq 90~230 range, treated as DDR 200.
+ */
+ effective_data_rate = 200;
+ if (spd.clk_cycle3 == 0xa0) /* 10 ns */
caslat -= 2;
- else if(spd.clk_cycle2 == 0xa0)
+ else if (spd.clk_cycle2 == 0xa0)
caslat--;
- } else if (tmp1 < 280 && tmp1 >= 230 && tmp >= 280) {
- /* 230-280 range, treated as DDR 266 */
- if (spd.clk_cycle3 == 0x75)
+
+ } else if (230 <= busfreq && busfreq < 280 && max_data_rate >= 280) {
+ /*
+ * busfreq 230~280 range, treated as DDR 266.
+ */
+ effective_data_rate = 266;
+ if (spd.clk_cycle3 == 0x75) /* 7.5 ns */
caslat -= 2;
else if (spd.clk_cycle2 == 0x75)
caslat--;
- } else if (tmp1 < 350 && tmp1 >= 280 && tmp >= 350) {
- /* 280~350 range, treated as DDR 333 */
- if (spd.clk_cycle3 == 0x60)
+
+ } else if (280 <= busfreq && busfreq < 350 && max_data_rate >= 350) {
+ /*
+ * busfreq 280~350 range, treated as DDR 333.
+ */
+ effective_data_rate = 333;
+ if (spd.clk_cycle3 == 0x60) /* 6.0 ns */
caslat -= 2;
else if (spd.clk_cycle2 == 0x60)
caslat--;
- } else if (tmp1 < 90 || tmp1 >= 350) {
- /* DDR rate out-of-range */
- puts("DDR:platform frequency is not fit for DDR rate\n");
+
+ } else if (350 <= busfreq && busfreq < 460 && max_data_rate >= 460) {
+ /*
+ * busfreq 350~460 range, treated as DDR 400.
+ */
+ effective_data_rate = 400;
+ if (spd.clk_cycle3 == 0x50) /* 5.0 ns */
+ caslat -= 2;
+ else if (spd.clk_cycle2 == 0x50)
+ caslat--;
+
+ } else if (460 <= busfreq && busfreq < 560 && max_data_rate >= 560) {
+ /*
+ * busfreq 460~560 range, treated as DDR 533.
+ */
+ effective_data_rate = 533;
+ if (spd.clk_cycle3 == 0x3D) /* 3.75 ns */
+ caslat -= 2;
+ else if (spd.clk_cycle2 == 0x3D)
+ caslat--;
+
+ } else if (560 <= busfreq && busfreq < 700 && max_data_rate >= 700) {
+ /*
+ * busfreq 560~700 range, treated as DDR 667.
+ */
+ effective_data_rate = 667;
+ if (spd.clk_cycle3 == 0x30) /* 3.0 ns */
+ caslat -= 2;
+ else if (spd.clk_cycle2 == 0x30)
+ caslat--;
+
+ } else if (700 <= busfreq) {
+ /*
+ * DDR rate out-of-range
+ */
+ printf("DDR: Bus freq %d MHz is not fit for DDR rate %d MHz\n",
+ busfreq, max_data_rate);
return 0;
}
+
/*
- * note: caslat must also be programmed into ddr->sdram_mode
- * register.
- *
- * note: WRREC(Twr) and WRTORD(Twtr) are not in SPD,
- * use conservative value here.
+ * Convert caslat clocks to DDR controller value.
+ * Force caslat_ctrl to be DDR Controller field-sized.
+ */
+ if (spd.mem_type == SPD_MEMTYPE_DDR) {
+ caslat_ctrl = (caslat + 1) & 0x07;
+ } else {
+ caslat_ctrl = (2 * caslat - 1) & 0x0f;
+ }
+
+ debug("DDR: effective data rate is %d MHz\n", effective_data_rate);
+ debug("DDR: caslat SPD bit is %d, controller field is 0x%x\n",
+ caslat, caslat_ctrl);
+
+ /*
+ * Timing Config 0.
+ * Avoid writing for DDR I. The new PQ38 DDR controller
+ * dreams up non-zero default values to be backwards compatible.
*/
+ if (spd.mem_type == SPD_MEMTYPE_DDR2) {
+ unsigned char taxpd_clk = 8; /* By the book. */
+ unsigned char tmrd_clk = 2; /* By the book. */
+ unsigned char act_pd_exit = 2; /* Empirical? */
+ unsigned char pre_pd_exit = 6; /* Empirical? */
+
+ ddr->timing_cfg_0 = (0
+ | ((act_pd_exit & 0x7) << 20) /* ACT_PD_EXIT */
+ | ((pre_pd_exit & 0x7) << 16) /* PRE_PD_EXIT */
+ | ((taxpd_clk & 0xf) << 8) /* ODT_PD_EXIT */
+ | ((tmrd_clk & 0xf) << 0) /* MRS_CYC */
+ );
+#if 0
+ ddr->timing_cfg_0 |= 0xaa000000; /* extra cycles */
+#endif
+ debug("DDR: timing_cfg_0 = 0x%08x\n", ddr->timing_cfg_0);
+
+ } else {
+#if 0
+ /*
+ * Force extra cycles with 0xaa bits.
+ * Incidentally supply the dreamt-up backwards compat value!
+ */
+ ddr->timing_cfg_0 = 0x00110105; /* backwards compat value */
+ ddr->timing_cfg_0 |= 0xaa000000; /* extra cycles */
+ debug("DDR: HACK timing_cfg_0 = 0x%08x\n", ddr->timing_cfg_0);
+#endif
+ }
+
+
+ /*
+ * Some Timing Config 1 values now.
+ * Sneak Extended Refresh Recovery in here too.
+ */
+
+ /*
+ * For DDR I, WRREC(Twr) and WRTORD(Twtr) are not in SPD,
+ * use conservative value.
+ * For DDR II, they are bytes 36 and 37, in quarter nanos.
+ */
+
+ if (spd.mem_type == SPD_MEMTYPE_DDR) {
+ twr_clk = 3; /* Clocks */
+ twtr_clk = 1; /* Clocks */
+ } else {
+ twr_clk = picos_to_clk(spd.twr * 250);
+ twtr_clk = picos_to_clk(spd.twtr * 250);
+ }
+
+ /*
+ * Calculate Trfc, in picos.
+ * DDR I: Byte 42 straight up in ns.
+ * DDR II: Byte 40 and 42 swizzled some, in ns.
+ */
+ if (spd.mem_type == SPD_MEMTYPE_DDR) {
+ trfc = spd.trfc * 1000; /* up to ps */
+ } else {
+ unsigned int byte40_table_ps[8] = {
+ 0,
+ 250,
+ 330,
+ 500,
+ 660,
+ 750,
+ 0,
+ 0
+ };
+
+ trfc = (((spd.trctrfc_ext & 0x1) * 256) + spd.trfc) * 1000
+ + byte40_table_ps[(spd.trctrfc_ext >> 1) & 0x7];
+ }
+ trfc_clk = picos_to_clk(trfc);
+
+ /*
+ * Trcd, Byte 29, from quarter nanos to ps and clocks.
+ */
+ trcd_clk = picos_to_clk(spd.trcd * 250) & 0x7;
+
+ /*
+ * Convert trfc_clk to DDR controller fields. DDR I should
+ * fit in the REFREC field (16-19) of TIMING_CFG_1, but the
+ * 8548 controller has an extended REFREC field of three bits.
+ * The controller automatically adds 8 clocks to this value,
+ * so preadjust it down 8 first before splitting it up.
+ */
+ trfc_low = (trfc_clk - 8) & 0xf;
+ trfc_high = ((trfc_clk - 8) >> 4) & 0x3;
+
+ /*
+ * Sneak in some Extended Refresh Recovery.
+ */
+ ddr->ext_refrec = (trfc_high << 16);
+ debug("DDR: ext_refrec = 0x%08x\n", ddr->ext_refrec);
+
ddr->timing_cfg_1 =
- (((picos_to_clk(spd.trp * 250) & 0x07) << 28 ) |
- ((picos_to_clk(spd.tras * 1000) & 0x0f ) << 24 ) |
- ((picos_to_clk(spd.trcd * 250) & 0x07) << 20 ) |
- ((caslat & 0x07) << 16 ) |
- (((picos_to_clk(spd.sset[6] * 1000) - 8) & 0x0f) << 12 ) |
- ( 0x300 ) |
- ((picos_to_clk(spd.trrd * 250) & 0x07) << 4) | 1);
+ (0
+ | ((picos_to_clk(spd.trp * 250) & 0x07) << 28) /* PRETOACT */
+ | ((picos_to_clk(spd.tras * 1000) & 0x0f ) << 24) /* ACTTOPRE */
+ | (trcd_clk << 20) /* ACTTORW */
+ | (caslat_ctrl << 16) /* CASLAT */
+ | (trfc_low << 12) /* REFEC */
+ | ((twr_clk & 0x07) << 8) /* WRRREC */
+ | ((picos_to_clk(spd.trrd * 250) & 0x07) << 4) /* ACTTOACT */
+ | ((twtr_clk & 0x07) << 0) /* WRTORD */
+ );
- ddr->timing_cfg_2 = 0x00000800;
+ debug("DDR: timing_cfg_1 = 0x%08x\n", ddr->timing_cfg_1);
- debug("DDR:timing_cfg_1=0x%08x\n", ddr->timing_cfg_1);
- debug("DDR:timing_cfg_2=0x%08x\n", ddr->timing_cfg_2);
/*
- * Only DDR I is supported
- * DDR I and II have different mode-register-set definition
+ * Timing_Config_2
+ * Was: 0x00000800;
*/
- /* burst length is always 4 */
- switch(caslat) {
- case 2:
- ddr->sdram_mode = 0x52; /* 1.5 */
- break;
- case 3:
- ddr->sdram_mode = 0x22; /* 2.0 */
- break;
- case 4:
- ddr->sdram_mode = 0x62; /* 2.5 */
- break;
- case 5:
- ddr->sdram_mode = 0x32; /* 3.0 */
- break;
- default:
- puts("DDR:only CAS Latency 1.5, 2.0, 2.5, 3.0 is supported.\n");
- return 0;
+ /*
+ * Additive Latency
+ * For DDR I, 0.
+ * For DDR II, with ODT enabled, use "a value" less than ACTTORW,
+ * which comes from Trcd, and also note that:
+ * add_lat + caslat must be >= 4
+ */
+ add_lat = 0;
+ if (spd.mem_type == SPD_MEMTYPE_DDR2
+ && (odt_wr_cfg || odt_rd_cfg)
+ && (caslat < 4)) {
+ add_lat = 4 - caslat;
+ if (add_lat > trcd_clk) {
+ add_lat = trcd_clk - 1;
+ }
}
- debug("DDR:sdram_mode=0x%08x\n", ddr->sdram_mode);
- switch(spd.refresh) {
- case 0x00:
- case 0x80:
- tmp = picos_to_clk(15625000);
- break;
- case 0x01:
- case 0x81:
- tmp = picos_to_clk(3900000);
- break;
- case 0x02:
- case 0x82:
- tmp = picos_to_clk(7800000);
- break;
- case 0x03:
- case 0x83:
- tmp = picos_to_clk(31300000);
- break;
- case 0x04:
- case 0x84:
- tmp = picos_to_clk(62500000);
- break;
- case 0x05:
- case 0x85:
- tmp = picos_to_clk(125000000);
- break;
- default:
- tmp = 0x512;
- break;
+ /*
+ * Write Data Delay
+ * Historically 0x2 == 4/8 clock delay.
+ * Empirically, 0x3 == 6/8 clock delay is suggested for DDR I 266.
+ */
+ wr_data_delay = 3;
+
+ /*
+ * Write Latency
+ * Read to Precharge
+ * Minimum CKE Pulse Width.
+ * Four Activate Window
+ */
+ if (spd.mem_type == SPD_MEMTYPE_DDR) {
+ /*
+ * This is a lie. It should really be 1, but if it is
+ * set to 1, bits overlap into the old controller's
+ * otherwise unused ACSM field. If we leave it 0, then
+ * the HW will magically treat it as 1 for DDR 1. Oh Yea.
+ */
+ wr_lat = 0;
+
+ trtp_clk = 2; /* By the book. */
+ cke_min_clk = 1; /* By the book. */
+ four_act = 1; /* By the book. */
+
+ } else {
+ wr_lat = caslat - 1;
+
+ /* Convert SPD value from quarter nanos to picos. */
+ trtp_clk = picos_to_clk(spd.trtp * 250);
+
+ cke_min_clk = 3; /* By the book. */
+ four_act = picos_to_clk(37500); /* By the book. 1k pages? */
+ }
+
+ /*
+ * Empirically set ~MCAS-to-preamble override for DDR 2.
+ * Your milage will vary.
+ */
+ cpo = 0;
+ if (spd.mem_type == SPD_MEMTYPE_DDR2) {
+ if (effective_data_rate == 266 || effective_data_rate == 333) {
+ cpo = 0x7; /* READ_LAT + 5/4 */
+ } else if (effective_data_rate == 400) {
+ cpo = 0x9; /* READ_LAT + 7/4 */
+ } else {
+ /* Pure speculation */
+ cpo = 0xb;
+ }
+ }
+
+ ddr->timing_cfg_2 = (0
+ | ((add_lat & 0x7) << 28) /* ADD_LAT */
+ | ((cpo & 0x1f) << 23) /* CPO */
+ | ((wr_lat & 0x7) << 19) /* WR_LAT */
+ | ((trtp_clk & 0x7) << 13) /* RD_TO_PRE */
+ | ((wr_data_delay & 0x7) << 10) /* WR_DATA_DELAY */
+ | ((cke_min_clk & 0x7) << 6) /* CKE_PLS */
+ | ((four_act & 0x1f) << 0) /* FOUR_ACT */
+ );
+
+ debug("DDR: timing_cfg_2 = 0x%08x\n", ddr->timing_cfg_2);
+
+
+ /*
+ * Determine the Mode Register Set.
+ *
+ * This is nominally part specific, but it appears to be
+ * consistent for all DDR I devices, and for all DDR II devices.
+ *
+ * caslat must be programmed
+ * burst length is always 4
+ * burst type is sequential
+ *
+ * For DDR I:
+ * operating mode is "normal"
+ *
+ * For DDR II:
+ * other stuff
+ */
+
+ mode_caslat = 0;
+
+ /*
+ * Table lookup from DDR I or II Device Operation Specs.
+ */
+ if (spd.mem_type == SPD_MEMTYPE_DDR) {
+ if (1 <= caslat && caslat <= 4) {
+ unsigned char mode_caslat_table[4] = {
+ 0x5, /* 1.5 clocks */
+ 0x2, /* 2.0 clocks */
+ 0x6, /* 2.5 clocks */
+ 0x3 /* 3.0 clocks */
+ };
+ mode_caslat = mode_caslat_table[caslat - 1];
+ } else {
+ puts("DDR I: Only CAS Latencies of 1.5, 2.0, "
+ "2.5 and 3.0 clocks are supported.\n");
+ return 0;
+ }
+
+ } else {
+ if (2 <= caslat && caslat <= 5) {
+ mode_caslat = caslat;
+ } else {
+ puts("DDR II: Only CAS Latencies of 2.0, 3.0, "
+ "4.0 and 5.0 clocks are supported.\n");
+ return 0;
+ }
+ }
+
+ /*
+ * Encoded Burst Lenght of 4.
+ */
+ burst_len = 2; /* Fiat. */
+
+ if (spd.mem_type == SPD_MEMTYPE_DDR) {
+ twr_auto_clk = 0; /* Historical */
+ } else {
+ /*
+ * Determine tCK max in picos. Grab tWR and convert to picos.
+ * Auto-precharge write recovery is:
+ * WR = roundup(tWR_ns/tCKmax_ns).
+ *
+ * Ponder: Is twr_auto_clk different than twr_clk?
+ */
+ tCKmax_ps = convert_bcd_tenths_to_cycle_time_ps(spd.tckmax);
+ twr_auto_clk = (spd.twr * 250 + tCKmax_ps - 1) / tCKmax_ps;
+ }
+
+
+ /*
+ * Mode Reg in bits 16 ~ 31,
+ * Extended Mode Reg 1 in bits 0 ~ 15.
+ */
+ mode_odt_enable = 0x0; /* Default disabled */
+ if (odt_wr_cfg || odt_rd_cfg) {
+ /*
+ * Bits 6 and 2 in Extended MRS(1)
+ * Bit 2 == 0x04 == 75 Ohm, with 2 DIMM modules.
+ * Bit 6 == 0x40 == 150 Ohm, with 1 DIMM module.
+ */
+ mode_odt_enable = 0x40; /* 150 Ohm */
}
+ ddr->sdram_mode =
+ (0
+ | (add_lat << (16 + 3)) /* Additive Latency in EMRS1 */
+ | (mode_odt_enable << 16) /* ODT Enable in EMRS1 */
+ | (twr_auto_clk << 9) /* Write Recovery Autopre */
+ | (mode_caslat << 4) /* caslat */
+ | (burst_len << 0) /* Burst length */
+ );
+
+ debug("DDR: sdram_mode = 0x%08x\n", ddr->sdram_mode);
+
+
+ /*
+ * Clear EMRS2 and EMRS3.
+ */
+ ddr->sdram_mode_2 = 0;
+ debug("DDR: sdram_mode_2 = 0x%08x\n", ddr->sdram_mode_2);
+
+
/*
- * Set BSTOPRE to 0x100 for page mode
- * If auto-charge is used, set BSTOPRE = 0
+ * Determine Refresh Rate. Ignore self refresh bit on DDR I.
+ * Table from SPD Spec, Byte 12, converted to picoseconds and
+ * filled in with "default" normal values.
*/
- ddr->sdram_interval = ((tmp & 0x3fff) << 16) | 0x100;
- debug("DDR:sdram_interval=0x%08x\n", ddr->sdram_interval);
+ {
+ unsigned int refresh_clk;
+ unsigned int refresh_time_ns[8] = {
+ 15625000, /* 0 Normal 1.00x */
+ 3900000, /* 1 Reduced .25x */
+ 7800000, /* 2 Extended .50x */
+ 31300000, /* 3 Extended 2.00x */
+ 62500000, /* 4 Extended 4.00x */
+ 125000000, /* 5 Extended 8.00x */
+ 15625000, /* 6 Normal 1.00x filler */
+ 15625000, /* 7 Normal 1.00x filler */
+ };
+
+ refresh_clk = picos_to_clk(refresh_time_ns[spd.refresh & 0x7]);
+
+ /*
+ * Set BSTOPRE to 0x100 for page mode
+ * If auto-charge is used, set BSTOPRE = 0
+ */
+ ddr->sdram_interval =
+ (0
+ | (refresh_clk & 0x3fff) << 16
+ | 0x100
+ );
+ debug("DDR: sdram_interval = 0x%08x\n", ddr->sdram_interval);
+ }
/*
* Is this an ECC DDR chip?
+ * But don't mess with it if the DDR controller will init mem.
*/
-#if defined(CONFIG_DDR_ECC)
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
if (spd.config == 0x02) {
ddr->err_disable = 0x0000000d;
ddr->err_sbe = 0x00ff0000;
}
- debug("DDR:err_disable=0x%08x\n", ddr->err_disable);
- debug("DDR:err_sbe=0x%08x\n", ddr->err_sbe);
+ debug("DDR: err_disable = 0x%08x\n", ddr->err_disable);
+ debug("DDR: err_sbe = 0x%08x\n", ddr->err_sbe);
#endif
- asm("sync;isync;msync");
+ asm("sync;isync;msync");
udelay(500);
-#ifdef MPC85xx_DDR_SDRAM_CLK_CNTL
- /* Setup the clock control (8555 and later)
- * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1
- * SDRAM_CLK_CNTL[5-7] = Clock Adjust == 3 (3/4 cycle late)
+ /*
+ * SDRAM Cfg 2
+ */
+
+ /*
+ * When ODT is enabled, Chap 9 suggests asserting ODT to
+ * internal IOs only during reads.
+ */
+ odt_cfg = 0;
+ if (odt_rd_cfg | odt_wr_cfg) {
+ odt_cfg = 0x2; /* ODT to IOs during reads */
+ }
+
+ /*
+ * Try to use differential DQS with DDR II.
*/
- ddr->sdram_clk_cntl = 0x83000000;
+ if (spd.mem_type == SPD_MEMTYPE_DDR) {
+ dqs_cfg = 0; /* No Differential DQS for DDR I */
+ } else {
+ dqs_cfg = 0x1; /* Differential DQS for DDR II */
+ }
+
+#if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+ /*
+ * Use the DDR controller to auto initialize memory.
+ */
+ d_init = 1;
+ ddr->sdram_data_init = CONFIG_MEM_INIT_VALUE;
+ debug("DDR: ddr_data_init = 0x%08x\n", ddr->sdram_data_init);
+#else
+ /*
+ * Memory will be initialized via DMA, or not at all.
+ */
+ d_init = 0;
+#endif
+
+ ddr->sdram_cfg_2 = (0
+ | (dqs_cfg << 26) /* Differential DQS */
+ | (odt_cfg << 21) /* ODT */
+ | (d_init << 4) /* D_INIT auto init DDR */
+ );
+
+ debug("DDR: sdram_cfg_2 = 0x%08x\n", ddr->sdram_cfg_2);
+
+
+#ifdef MPC85xx_DDR_SDRAM_CLK_CNTL
+ {
+ unsigned char clk_adjust;
+
+ /*
+ * Setup the clock control.
+ * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1
+ * SDRAM_CLK_CNTL[5-7] = Clock Adjust
+ * 0110 3/4 cycle late
+ * 0111 7/8 cycle late
+ */
+ if (spd.mem_type == SPD_MEMTYPE_DDR) {
+ clk_adjust = 0x6;
+ } else {
+ clk_adjust = 0x7;
+ }
+
+ ddr->sdram_clk_cntl = (0
+ | 0x80000000
+ | (clk_adjust << 23)
+ );
+ debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr->sdram_clk_cntl);
+ }
#endif
/*
- * Figure out the settings for the sdram_cfg register. Build up
- * the entire register in 'tmp' before writing since the write into
- * the register will actually enable the memory controller, and all
- * settings must be done before enabling.
+ * Figure out the settings for the sdram_cfg register.
+ * Build up the entire register in 'sdram_cfg' before writing
+ * since the write into the register will actually enable the
+ * memory controller; all settings must be done before enabling.
*
* sdram_cfg[0] = 1 (ddr sdram logic enable)
* sdram_cfg[1] = 1 (self-refresh-enable)
- * sdram_cfg[6:7] = 2 (SDRAM type = DDR SDRAM)
+ * sdram_cfg[5:7] = (SDRAM type = DDR SDRAM)
+ * 010 DDR 1 SDRAM
+ * 011 DDR 2 SDRAM
*/
- tmp = 0xc2000000;
+ sdram_type = (spd.mem_type == SPD_MEMTYPE_DDR) ? 2 : 3;
+ sdram_cfg = (0
+ | (1 << 31) /* Enable */
+ | (1 << 30) /* Self refresh */
+ | (sdram_type << 24) /* SDRAM type */
+ );
/*
* sdram_cfg[3] = RD_EN - registered DIMM enable
* A value of 0x26 indicates micron registered DIMMS (micron.com)
*/
- if (spd.mod_attr == 0x26) {
- tmp |= 0x10000000;
+ if (spd.mem_type == SPD_MEMTYPE_DDR && spd.mod_attr == 0x26) {
+ sdram_cfg |= 0x10000000; /* RD_EN */
}
#if defined(CONFIG_DDR_ECC)
* If the user wanted ECC (enabled via sdram_cfg[2])
*/
if (spd.config == 0x02) {
- tmp |= 0x20000000;
+ sdram_cfg |= 0x20000000; /* ECC_EN */
}
#endif
/*
* Enable 2T timing by setting sdram_cfg[16].
*/
- tmp |= 0x8000;
+ sdram_cfg |= 0x8000; /* 2T_EN */
#endif
}
}
- ddr->sdram_cfg = tmp;
+ /*
+ * 200 painful micro-seconds must elapse between
+ * the DDR clock setup and the DDR config enable.
+ */
+ udelay(200);
+
+ /*
+ * Go!
+ */
+ ddr->sdram_cfg = sdram_cfg;
asm("sync;isync;msync");
udelay(500);
- debug("DDR:sdram_cfg=0x%08x\n", ddr->sdram_cfg);
+ debug("DDR: sdram_cfg = 0x%08x\n", ddr->sdram_cfg);
+
+
+#if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+ /*
+ * Poll until memory is initialized.
+ * 512 Meg at 400 might hit this 200 times or so.
+ */
+ while ((ddr->sdram_cfg_2 & (d_init << 4)) != 0) {
+ udelay(1000);
+ }
+#endif
+
+
+ /*
+ * Figure out memory size in Megabytes.
+ */
+ memsize = n_ranks * rank_density / 0x100000;
+
+ /*
+ * Establish Local Access Window and TLB mappings for DDR memory.
+ */
+ memsize = setup_laws_and_tlbs(memsize);
+ if (memsize == 0) {
+ return 0;
+ }
return memsize * 1024 * 1024;
}
+
+
+/*
+ * Setup Local Access Window and TLB1 mappings for the requested
+ * amount of memory. Returns the amount of memory actually mapped
+ * (usually the original request size), or 0 on error.
+ */
+
+static unsigned int
+setup_laws_and_tlbs(unsigned int memsize)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile ccsr_local_ecm_t *ecm = &immap->im_local_ecm;
+ unsigned int tlb_size;
+ unsigned int law_size;
+ unsigned int ram_tlb_index;
+ unsigned int ram_tlb_address;
+
+ /*
+ * Determine size of each TLB1 entry.
+ */
+ switch (memsize) {
+ case 16:
+ case 32:
+ tlb_size = BOOKE_PAGESZ_16M;
+ break;
+ case 64:
+ case 128:
+ tlb_size = BOOKE_PAGESZ_64M;
+ break;
+ case 256:
+ case 512:
+ case 1024:
+ case 2048:
+ tlb_size = BOOKE_PAGESZ_256M;
+ break;
+ default:
+ puts("DDR: only 16M,32M,64M,128M,256M,512M,1G and 2G are supported.\n");
+
+ /*
+ * The memory was not able to be mapped.
+ */
+ return 0;
+ break;
+ }
+
+ /*
+ * Configure DDR TLB1 entries.
+ * Starting at TLB1 8, use no more than 8 TLB1 entries.
+ */
+ ram_tlb_index = 8;
+ ram_tlb_address = (unsigned int)CFG_DDR_SDRAM_BASE;
+ while (ram_tlb_address < (memsize * 1024 * 1024)
+ && ram_tlb_index < 16) {
+ mtspr(MAS0, TLB1_MAS0(1, ram_tlb_index, 0));
+ mtspr(MAS1, TLB1_MAS1(1, 1, 0, 0, tlb_size));
+ mtspr(MAS2, TLB1_MAS2(E500_TLB_EPN(ram_tlb_address),
+ 0, 0, 0, 0, 0, 0, 0, 0));
+ mtspr(MAS3, TLB1_MAS3(E500_TLB_RPN(ram_tlb_address),
+ 0, 0, 0, 0, 0, 1, 0, 1, 0, 1));
+ asm volatile("isync;msync;tlbwe;isync");
+
+ debug("DDR: MAS0=0x%08x\n", TLB1_MAS0(1, ram_tlb_index, 0));
+ debug("DDR: MAS1=0x%08x\n", TLB1_MAS1(1, 1, 0, 0, tlb_size));
+ debug("DDR: MAS2=0x%08x\n",
+ TLB1_MAS2(E500_TLB_EPN(ram_tlb_address),
+ 0, 0, 0, 0, 0, 0, 0, 0));
+ debug("DDR: MAS3=0x%08x\n",
+ TLB1_MAS3(E500_TLB_RPN(ram_tlb_address),
+ 0, 0, 0, 0, 0, 1, 0, 1, 0, 1));
+
+ ram_tlb_address += (0x1000 << ((tlb_size - 1) * 2));
+ ram_tlb_index++;
+ }
+
+
+ /*
+ * First supported LAW size is 16M, at LAWAR_SIZE_16M == 23. Fnord.
+ */
+ law_size = 19 + __ilog2(memsize);
+
+ /*
+ * Set up LAWBAR for all of DDR.
+ */
+ ecm->lawbar1 = ((CFG_DDR_SDRAM_BASE >> 12) & 0xfffff);
+ ecm->lawar1 = (LAWAR_EN
+ | LAWAR_TRGT_IF_DDR
+ | (LAWAR_SIZE & law_size));
+ debug("DDR: LAWBAR1=0x%08x\n", ecm->lawbar1);
+ debug("DDR: LARAR1=0x%08x\n", ecm->lawar1);
+
+ /*
+ * Confirm that the requested amount of memory was mapped.
+ */
+ return memsize;
+}
+
#endif /* CONFIG_SPD_EEPROM */
-#if defined(CONFIG_DDR_ECC)
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+
/*
* Initialize all of memory for ECC, then enable errors.
*/
+
void
ddr_enable_ecc(unsigned int dram_size)
{
if (((unsigned int)p & 0x1f) == 0) {
ppcDcbz((unsigned long) p);
}
- *p = (unsigned int)0xdeadbeef;
+ *p = (unsigned int)CONFIG_MEM_INIT_VALUE;
if (((unsigned int)p & 0x1c) == 0x1c) {
ppcDcbf((unsigned long) p);
}
/*
* Enable errors for ECC.
*/
+ debug("DMA DDR: err_disable = 0x%08x\n", ddr->err_disable);
ddr->err_disable = 0x00000000;
asm("sync;isync;msync");
+ debug("DMA DDR: err_disable = 0x%08x\n", ddr->err_disable);
}
-#endif /* CONFIG_DDR_ECC */
+
+#endif /* CONFIG_DDR_ECC && ! CONFIG_ECC_INIT_VIA_DDRCONTROLLER */
mtspr BUCSR,r0 /* disable branch prediction */
mtspr MAS4,r0
mtspr MAS6,r0
+#if defined(CONFIG_ENABLE_36BIT_PHYS)
+ mtspr MAS7,r0
+#endif
isync
/* Setup interrupt vectors */
/* 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 */
+#endif
mtspr HID0,r0
#if defined(CONFIG_ADDR_STREAMING)
struct tsec_info_struct {
unsigned int phyaddr;
- unsigned int gigabit;
+ u32 flags;
unsigned int phyregidx;
};
* phyaddr - The address of the PHY which is attached to
* the given device.
*
- * gigabit - This variable indicates whether the device
- * supports gigabit speed ethernet
+ * flags - This variable indicates whether the device
+ * supports gigabit speed ethernet, and whether it should be
+ * in reduced mode.
*
* phyregidx - This variable specifies which ethernet device
* controls the MII Management registers which are connected
*/
static struct tsec_info_struct tsec_info[] = {
#ifdef CONFIG_MPC85XX_TSEC1
- {TSEC1_PHY_ADDR, 1, TSEC1_PHYIDX},
+ {TSEC1_PHY_ADDR, TSEC_GIGABIT, TSEC1_PHYIDX},
#else
{ 0, 0, 0},
#endif
#ifdef CONFIG_MPC85XX_TSEC2
- {TSEC2_PHY_ADDR, 1, TSEC2_PHYIDX},
+ {TSEC2_PHY_ADDR, TSEC_GIGABIT, TSEC2_PHYIDX},
#else
{ 0, 0, 0},
#endif
#ifdef CONFIG_MPC85XX_FEC
{FEC_PHY_ADDR, 0, FEC_PHYIDX},
#else
+# ifdef CONFIG_MPC85XX_TSEC3
+ {TSEC3_PHY_ADDR, TSEC_GIGABIT | TSEC_REDUCED, TSEC3_PHYIDX},
+# else
{ 0, 0, 0},
+# endif
+# ifdef CONFIG_MPC85XX_TSEC4
+ {TSEC4_PHY_ADDR, TSEC_REDUCED, TSEC4_PHYIDX},
+# else
+ { 0, 0, 0},
+# endif
#endif
};
-#define MAXCONTROLLERS 3
+#define MAXCONTROLLERS (4)
static int relocated = 0;
/* Initialize device structure. Returns success if PHY
* initialization succeeded (i.e. if it recognizes the PHY)
*/
-int tsec_initialize(bd_t *bis, int index)
+int tsec_initialize(bd_t *bis, int index, char *devname)
{
struct eth_device* dev;
int i;
tsec_info[index].phyregidx*TSEC_SIZE);
priv->phyaddr = tsec_info[index].phyaddr;
- priv->gigabit = tsec_info[index].gigabit;
+ priv->flags = tsec_info[index].flags;
- sprintf(dev->name, "ENET%d", index);
+ sprintf(dev->name, devname);
dev->iobase = 0;
dev->priv = priv;
dev->init = tsec_init;
/* For 10/100, the value is slightly different */
uint mii_cr_init(uint mii_reg, struct tsec_private *priv)
{
- if(priv->gigabit)
+ if(priv->flags & TSEC_GIGABIT)
return MIIM_CONTROL_INIT;
else
return MIIM_CR_INIT;
return MIIM_CIS8204_SLEDCON_INIT;
}
+uint mii_cis8204_setmode(uint mii_reg, struct tsec_private *priv)
+{
+ if (priv->flags & TSEC_REDUCED)
+ return MIIM_CIS8204_EPHYCON_INIT | MIIM_CIS8204_EPHYCON_RGMII;
+ else
+ return MIIM_CIS8204_EPHYCON_INIT;
+}
/* Initialized required registers to appropriate values, zeroing
* those we don't care about (unless zero is bad, in which case,
case 10:
regs->maccfg2 = ((regs->maccfg2&~(MACCFG2_IF))
| MACCFG2_MII);
+
+ /* If We're in reduced mode, we
+ * need to say whether we're 10
+ * or 100 MB. */
+ if ((priv->speed == 100)
+ && (priv->flags & TSEC_REDUCED))
+ regs->ecntrl |= ECNTRL_R100;
+ else
+ regs->ecntrl &= ~(ECNTRL_R100);
break;
default:
printf("%s: Speed was bad\n", dev->name);
/* Configure some basic stuff */
{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
{MIIM_CIS8204_SLED_CON, MIIM_CIS8204_SLEDCON_INIT, &mii_cis8204_fixled},
- {MIIM_CIS8204_EPHY_CON, MIIM_CIS8204_EPHYCON_INIT, NULL},
+ {MIIM_CIS8204_EPHY_CON, MIIM_CIS8204_EPHYCON_INIT, &mii_cis8204_setmode},
{miim_end,}
},
(struct phy_cmd[]) { /* startup */
#define ECNTRL_INIT_SETTINGS 0x00001000
#define ECNTRL_TBI_MODE 0x00000020
+#define ECNTRL_R100 0x00000008
#define miim_end -2
#define miim_read -1
/* Cicada 8204 Extended PHY Control Register 1 */
#define MIIM_CIS8204_EPHY_CON 0x17
#define MIIM_CIS8204_EPHYCON_INIT 0x0006
+#define MIIM_CIS8204_EPHYCON_RGMII 0x1000
/* Cicada 8204 Serial LED Control Register */
#define MIIM_CIS8204_SLED_CON 0x1b
uint resc00[256];
} tsec_t;
+#define TSEC_GIGABIT (1)
+
+/* This flag currently only has
+ * meaning if we're using the eTSEC */
+#define TSEC_REDUCED (1 << 1)
+
struct tsec_private {
volatile tsec_t *regs;
volatile tsec_t *phyregs;
struct phy_info *phyinfo;
uint phyaddr;
- uint gigabit;
+ u32 flags;
uint link;
uint duplexity;
uint speed;
CONFIG_DDR_ECC only for ECC DDR module
CONFIG_DDR_DLL DLL fix on some ADS boards needed for more
stability.
+ CONFIG_HAS_FEC If an FEC is on chip, set to 1, else 0.
Other than the above definitions, the rest in the config files are
straightforward.
4.4 Reflash U-boot Image using U-boot
- => tftp 10000 u-boot.bin
- => protect off fff80000 ffffffff
- => erase fff80000 ffffffff
- => cp.b 10000 fff80000 80000
+ tftp 10000 u-boot.bin
+ protect off fff80000 ffffffff
+ erase fff80000 ffffffff
+ cp.b 10000 fff80000 80000
4.5 Reflash U-Boot with a BDI-2000
SW4=10001000
-CPU Card Switches
------------------
+8555/41 CPU Card Switches
+-------------------------
Most switches on the CPU Card should not be changed. However, the
frequency can be changed by setting SW3:
SW4=11111110
+8548 CPU Card Switches
+----------------------
+And, just to be confusing, in this set of switches:
+
+ ON = 1
+ OFF = 0
+
+Default
+ SW1=11111101
+ SW2=10011111
+ SW3=11001000 (8X) (2:1)
+ SW4=11110011
+
+ SW3=X000XXXX == CORE:CCB 4:1
+ X001XXXX == CORE:CCB 9:2
+ X010XXXX == CORE:CCB 1:1
+ X011XXXX == CORE:CCB 3:2
+ X100XXXX == CORE:CCB 2:1
+ X101XXXX == CORE:CCB 5:2
+ X110XXXX == CORE:CCB 3:1
+ X111XXXX == CORE:CCB 7:2
+ XXXX0000 == CCB:SYSCLK 16:1
+ XXXX0001 == RESERVED
+ XXXX0010 == CCB:SYSCLK 2:1
+ XXXX0011 == CCB:SYSCLK 3:1
+ XXXX0100 == CCB:SYSCLK 4:1
+ XXXX0101 == CCB:SYSCLK 5:1
+ XXXX0110 == CCB:SYSCLK 6:1
+ XXXX0111 == RESERVED
+ XXXX1000 == CCB:SYSCLK 8:1
+ XXXX1001 == CCB:SYSCLK 9:1
+ XXXX1010 == CCB:SYSCLK 10:1
+ XXXX1011 == RESERVED
+ XXXX1100 == CCB:SYSCLK 12:1
+ XXXX1101 == CCB:SYSCLK 20:1
+ XXXX1110 == RESERVED
+ XXXX1111 == RESERVED
+
+
eDINK Info
----------
uint cs1_config; /* 0x2084 - DDR Chip Select Configuration */
uint cs2_config; /* 0x2088 - DDR Chip Select Configuration */
uint cs3_config; /* 0x208c - DDR Chip Select Configuration */
- char res5[120];
+ char res5[112];
+ uint ext_refrec; /* 0x2100 - DDR SDRAM Extended Refresh Recovery */
+ uint timing_cfg_0; /* 0x2104 - DDR SDRAM Timing Configuration Register 0 */
uint timing_cfg_1; /* 0x2108 - DDR SDRAM Timing Configuration Register 1 */
uint timing_cfg_2; /* 0x210c - DDR SDRAM Timing Configuration Register 2 */
uint sdram_cfg; /* 0x2110 - DDR SDRAM Control Configuration */
- char res6[4];
+ uint sdram_cfg_2; /* 0x2114 - DDR SDRAM Control Configuration 2 */
uint sdram_mode; /* 0x2118 - DDR SDRAM Mode Configuration */
- char res7[8];
+ uint sdram_mode_2; /* 0x211c - DDR SDRAM Mode Configuration 2*/
+ uint sdram_md_cntl; /* 0x2120 - DDR SDRAM Mode Control */
uint sdram_interval; /* 0x2124 - DDR SDRAM Interval Configuration */
-#ifdef MPC85xx_DDR_SDRAM_CLK_CNTL
- char res7_5[8];
+ uint sdram_data_init; /* 0x2128 - DDR SDRAM Data initialization */
+ char res6[4];
uint sdram_clk_cntl; /* 0x2130 - DDR SDRAM Clock Control */
- char res8[3276];
-#else
- char res8[3288];
-#endif
+ char res7[20];
+ uint init_address; /* 0x2148 - DDR training initialization address */
+ uint init_ext_address; /* 0x214C - DDR training initialization extended address */
+ char res8_1[2728];
+ uint ip_rev1; /* 0x2BF8 - DDR IP Block Revision 1 */
+ uint ip_rev2; /* 0x2BFC - DDR IP Block Revision 2 */
+ char res8_2[512];
uint data_err_inject_hi; /* 0x2e00 - DDR Memory Data Path Error Injection Mask High */
uint data_err_inject_lo; /* 0x2e04 - DDR Memory Data Path Error Injection Mask Low */
uint ecc_err_inject; /* 0x2e08 - DDR Memory Data Path Error Injection Mask ECC */
} ccsr_ddr_t;
+
+
/* I2C Registers(0x3000-0x4000) */
typedef struct ccsr_i2c {
#if defined(CONFIG_MPC8540) \
|| defined(CONFIG_MPC8541) \
+ || defined(CONFIG_MPC8548) \
|| defined(CONFIG_MPC8555)
/* DUART Registers(0x4000-0x5000) */
typedef struct ccsr_duart {
uint ddrdllcr; /* 0xe0e10 - DDR DLL control register */
char res12[12];
uint lbcdllcr; /* 0xe0e20 - LBC DLL control register */
- char res13[61915];
+ char res13[248];
+ uint lbiuiplldcr0; /* 0xe0f1c -- LBIU PLL Debug Reg 0 */
+ uint lbiuiplldcr1; /* 0xe0f20 -- LBIU PLL Debug Reg 1 */
+ uint ddrioovcr; /* 0xe0f24 - DDR IO Override Control */
+ uint res14; /* 0xe0f28 */
+ uint tsec34ioovcr; /* 0xe0f2c - eTSEC 3/4 IO override control */
+ char res15[61651];
} ccsr_gur_t;
typedef struct immap {
#define SPRN_MAS4 0x274 /* MMU Assist Register 4 */
#define SPRN_MAS5 0x275 /* MMU Assist Register 5 */
#define SPRN_MAS6 0x276 /* MMU Assist Register 6 */
+#define SPRN_MAS7 0x3B0 /* MMU Assist Register 7 */
#define SPRN_IVOR32 0x210 /* Interrupt Vector Offset Register 32 */
#define SPRN_IVOR33 0x211 /* Interrupt Vector Offset Register 33 */
#define MAS4 SPRN_MAS4
#define MAS5 SPRN_MAS5
#define MAS6 SPRN_MAS6
+#define MAS7 SPRN_MAS7
/* Device Control Registers */
#define SVR_8560 0x8070
#define SVR_8555 0x8079
#define SVR_8541 0x807A
+#define SVR_8548 0x8031
+#define SVR_8548_E 0x8039
/* I am just adding a single entry for 8260 boards. I think we may be
#define CONFIG_TSEC_ENET /* tsec ethernet support */
#define CONFIG_ENV_OVERWRITE
#define CONFIG_SPD_EEPROM /* Use SPD EEPROM for DDR setup*/
-#define CONFIG_DDR_ECC /* only for ECC DDR module */
#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_MEM_INIT_VALUE 0xDeadBeef
+
/*
* sysclk for MPC85xx
#define CONFIG_MII 1 /* MII PHY management */
#define CONFIG_MPC85XX_TSEC1 1
+#define CONFIG_MPC85XX_TSEC1_NAME "TSEC0"
#define CONFIG_MPC85XX_TSEC2 1
+#define CONFIG_MPC85XX_TSEC2_NAME "TSEC1"
#define TSEC1_PHY_ADDR 0
#define TSEC2_PHY_ADDR 1
#define TSEC1_PHYIDX 0
#if CONFIG_HAS_FEC
#define CONFIG_MPC85XX_FEC 1
+#define CONFIG_MPC85XX_FEC_NAME "FEC"
#define FEC_PHY_ADDR 3
#define FEC_PHYIDX 0
#endif
-#define CONFIG_ETHPRIME "MOTO ENET0"
+/* Options are: TSEC[0-1], FEC */
+#define CONFIG_ETHPRIME "TSEC0"
#endif /* CONFIG_TSEC_ENET */
#define CONFIG_TSEC_ENET /* tsec ethernet support */
#define CONFIG_ENV_OVERWRITE
#define CONFIG_SPD_EEPROM /* Use SPD EEPROM for DDR setup*/
-#define CONFIG_DDR_ECC /* only for ECC DDR module */
#define CONFIG_DDR_DLL /* possible DLL fix needed */
-#define CONFIG_DDR_2T_TIMING /* Sets the 2T timing bit */
+#undef CONFIG_DDR_2T_TIMING /* Sets the 2T timing bit */
+
+#define CONFIG_DDR_ECC /* only for ECC DDR module */
+#define CONFIG_MEM_INIT_VALUE 0xDeadBeef
+
/*
* When initializing flash, if we cannot find the manufacturer ID,
#define CONFIG_MII 1 /* MII PHY management */
#define CONFIG_MPC85XX_TSEC1 1
+#define CONFIG_MPC85XX_TSEC1_NAME "TSEC0"
#define CONFIG_MPC85XX_TSEC2 1
+#define CONFIG_MPC85XX_TSEC2_NAME "TSEC1"
#undef CONFIG_MPC85XX_FEC
#define TSEC1_PHY_ADDR 0
#define TSEC2_PHY_ADDR 1
#define TSEC1_PHYIDX 0
#define TSEC2_PHYIDX 0
#define FEC_PHYIDX 0
-#define CONFIG_ETHPRIME "MOTO ENET0"
+
+/* Options are: TSEC[0-1] */
+#define CONFIG_ETHPRIME "TSEC0"
#endif /* CONFIG_TSEC_ENET */
--- /dev/null
+/*
+ * Copyright 2004 Freescale Semiconductor.
+ *
+ * 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
+ */
+
+/*
+ * mpc8548cds board configuration file
+ *
+ * Please refer to doc/README.mpc85xxcds for more info.
+ *
+ */
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/* High Level Configuration Options */
+#define CONFIG_BOOKE 1 /* BOOKE */
+#define CONFIG_E500 1 /* BOOKE e500 family */
+#define CONFIG_MPC85xx 1 /* MPC8540/60/55/41/48 */
+#define CONFIG_MPC8548 1 /* MPC8548 specific */
+#define CONFIG_MPC8548CDS 1 /* MPC8548CDS board specific */
+
+#undef CONFIG_PCI
+#define CONFIG_TSEC_ENET /* tsec ethernet support */
+#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_MEM_INIT_VALUE 0xDeadBeef
+
+
+/*
+ * When initializing flash, if we cannot find the manufacturer ID,
+ * assume this is the AMD flash associated with the CDS board.
+ * This allows booting from a promjet.
+ */
+#define CONFIG_ASSUME_AMD_FLASH
+
+#define MPC85xx_DDR_SDRAM_CLK_CNTL /* 85xx has clock control reg */
+
+#ifndef __ASSEMBLY__
+extern unsigned long get_clock_freq(void);
+#endif
+#define CONFIG_SYS_CLK_FREQ get_clock_freq() /* sysclk for MPC85xx */
+
+/*
+ * These can be toggled for performance analysis, otherwise use default.
+ */
+#define CONFIG_L2_CACHE /* toggle L2 cache */
+#define CONFIG_BTB /* toggle branch predition */
+#define CONFIG_ADDR_STREAMING /* toggle addr streaming */
+
+/*
+ * Only possible on E500 Version 2 or newer cores.
+ */
+#define CONFIG_ENABLE_36BIT_PHYS 1
+
+
+#define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_pre_init */
+
+#undef CFG_DRAM_TEST /* memory test, takes time */
+#define CFG_MEMTEST_START 0x00200000 /* memtest works on */
+#define CFG_MEMTEST_END 0x00400000
+
+/*
+ * 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 0xe0000000 /* relocated CCSRBAR */
+#define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */
+
+/*
+ * DDR Setup
+ */
+#define CFG_DDR_SDRAM_BASE 0x00000000 /* DDR is system memory*/
+#define CFG_SDRAM_BASE CFG_DDR_SDRAM_BASE
+
+#define SPD_EEPROM_ADDRESS 0x51 /* DDR DIMM */
+
+/*
+ * Make sure required options are set
+ */
+#ifndef CONFIG_SPD_EEPROM
+#error ("CONFIG_SPD_EEPROM is required")
+#endif
+
+#undef CONFIG_CLOCKS_IN_MHZ
+
+
+/*
+ * Local Bus Definitions
+ */
+
+/*
+ * FLASH on the Local Bus
+ * Two banks, 8M each, using the CFI driver.
+ * Boot from BR0/OR0 bank at 0xff00_0000
+ * Alternate BR1/OR1 bank at 0xff80_0000
+ *
+ * BR0, BR1:
+ * Base address 0 = 0xff00_0000 = BR0[0:16] = 1111 1111 0000 0000 0
+ * Base address 1 = 0xff80_0000 = BR1[0:16] = 1111 1111 1000 0000 0
+ * Port Size = 16 bits = BRx[19:20] = 10
+ * Use GPCM = BRx[24:26] = 000
+ * Valid = BRx[31] = 1
+ *
+ * 0 4 8 12 16 20 24 28
+ * 1111 1111 1000 0000 0001 0000 0000 0001 = ff801001 BR0
+ * 1111 1111 0000 0000 0001 0000 0000 0001 = ff001001 BR1
+ *
+ * OR0, OR1:
+ * Addr Mask = 8M = ORx[0:16] = 1111 1111 1000 0000 0
+ * Reserved ORx[17:18] = 11, confusion here?
+ * CSNT = ORx[20] = 1
+ * ACS = half cycle delay = ORx[21:22] = 11
+ * SCY = 6 = ORx[24:27] = 0110
+ * TRLX = use relaxed timing = ORx[29] = 1
+ * EAD = use external address latch delay = OR[31] = 1
+ *
+ * 0 4 8 12 16 20 24 28
+ * 1111 1111 1000 0000 0110 1110 0110 0101 = ff806e65 ORx
+ */
+
+#define CFG_FLASH_BASE 0xff000000 /* start of FLASH 8M */
+
+#define CFG_BR0_PRELIM 0xff801001
+#define CFG_BR1_PRELIM 0xff001001
+
+#define CFG_OR0_PRELIM 0xff806e65
+#define CFG_OR1_PRELIM 0xff806e65
+
+#define CFG_FLASH_BANKS_LIST {0xff800000, CFG_FLASH_BASE}
+#define CFG_MAX_FLASH_BANKS 2 /* number of banks */
+#define CFG_MAX_FLASH_SECT 128 /* sectors per device */
+#undef CFG_FLASH_CHECKSUM
+#define CFG_FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */
+
+#define CFG_MONITOR_BASE TEXT_BASE /* start of monitor */
+
+#define CFG_FLASH_CFI_DRIVER
+#define CFG_FLASH_CFI
+#define CFG_FLASH_EMPTY_INFO
+
+
+/*
+ * SDRAM on the Local Bus
+ */
+#define CFG_LBC_SDRAM_BASE 0xf0000000 /* Localbus SDRAM */
+#define CFG_LBC_SDRAM_SIZE 64 /* LBC SDRAM is 64MB */
+
+/*
+ * Base Register 2 and Option Register 2 configure SDRAM.
+ * The SDRAM base address, CFG_LBC_SDRAM_BASE, is 0xf0000000.
+ *
+ * For BR2, need:
+ * Base address of 0xf0000000 = BR[0:16] = 1111 0000 0000 0000 0
+ * port-size = 32-bits = BR2[19:20] = 11
+ * no parity checking = BR2[21:22] = 00
+ * SDRAM for MSEL = BR2[24:26] = 011
+ * Valid = BR[31] = 1
+ *
+ * 0 4 8 12 16 20 24 28
+ * 1111 0000 0000 0000 0001 1000 0110 0001 = f0001861
+ *
+ * FIXME: CFG_LBC_SDRAM_BASE should be masked and OR'ed into
+ * FIXME: the top 17 bits of BR2.
+ */
+
+#define CFG_BR2_PRELIM 0xf0001861
+
+/*
+ * The SDRAM size in MB, CFG_LBC_SDRAM_SIZE, is 64.
+ *
+ * For OR2, need:
+ * 64MB mask for AM, OR2[0:7] = 1111 1100
+ * XAM, OR2[17:18] = 11
+ * 9 columns OR2[19-21] = 010
+ * 13 rows OR2[23-25] = 100
+ * EAD set for extra time OR[31] = 1
+ *
+ * 0 4 8 12 16 20 24 28
+ * 1111 1100 0000 0000 0110 1001 0000 0001 = fc006901
+ */
+
+#define CFG_OR2_PRELIM 0xfc006901
+
+#define CFG_LBC_LCRR 0x00030004 /* LB clock ratio reg */
+#define CFG_LBC_LBCR 0x00000000 /* LB config reg */
+#define CFG_LBC_LSRT 0x20000000 /* LB sdram refresh timer */
+#define CFG_LBC_MRTPR 0x00000000 /* LB refresh timer prescal*/
+
+/*
+ * LSDMR masks
+ */
+#define CFG_LBC_LSDMR_RFEN (1 << (31 - 1))
+#define CFG_LBC_LSDMR_BSMA1516 (3 << (31 - 10))
+#define CFG_LBC_LSDMR_BSMA1617 (4 << (31 - 10))
+#define CFG_LBC_LSDMR_RFCR16 (7 << (31 - 16))
+#define CFG_LBC_LSDMR_PRETOACT7 (7 << (31 - 19))
+#define CFG_LBC_LSDMR_ACTTORW7 (7 << (31 - 22))
+#define CFG_LBC_LSDMR_ACTTORW6 (6 << (31 - 22))
+#define CFG_LBC_LSDMR_BL8 (1 << (31 - 23))
+#define CFG_LBC_LSDMR_WRC4 (0 << (31 - 27))
+#define CFG_LBC_LSDMR_CL3 (3 << (31 - 31))
+
+#define CFG_LBC_LSDMR_OP_NORMAL (0 << (31 - 4))
+#define CFG_LBC_LSDMR_OP_ARFRSH (1 << (31 - 4))
+#define CFG_LBC_LSDMR_OP_SRFRSH (2 << (31 - 4))
+#define CFG_LBC_LSDMR_OP_MRW (3 << (31 - 4))
+#define CFG_LBC_LSDMR_OP_PRECH (4 << (31 - 4))
+#define CFG_LBC_LSDMR_OP_PCHALL (5 << (31 - 4))
+#define CFG_LBC_LSDMR_OP_ACTBNK (6 << (31 - 4))
+#define CFG_LBC_LSDMR_OP_RWINV (7 << (31 - 4))
+
+/*
+ * Common settings for all Local Bus SDRAM commands.
+ * At run time, either BSMA1516 (for CPU 1.1)
+ * or BSMA1617 (for CPU 1.0) (old)
+ * is OR'ed in too.
+ */
+#define CFG_LBC_LSDMR_COMMON ( CFG_LBC_LSDMR_RFCR16 \
+ | CFG_LBC_LSDMR_PRETOACT7 \
+ | CFG_LBC_LSDMR_ACTTORW7 \
+ | CFG_LBC_LSDMR_BL8 \
+ | CFG_LBC_LSDMR_WRC4 \
+ | CFG_LBC_LSDMR_CL3 \
+ | CFG_LBC_LSDMR_RFEN \
+ )
+
+/*
+ * The CADMUS registers are connected to CS3 on CDS.
+ * The new memory map places CADMUS at 0xf8000000.
+ *
+ * For BR3, need:
+ * Base address of 0xf8000000 = BR[0:16] = 1111 1000 0000 0000 0
+ * port-size = 8-bits = BR[19:20] = 01
+ * no parity checking = BR[21:22] = 00
+ * GPMC for MSEL = BR[24:26] = 000
+ * Valid = BR[31] = 1
+ *
+ * 0 4 8 12 16 20 24 28
+ * 1111 1000 0000 0000 0000 1000 0000 0001 = f8000801
+ *
+ * For OR3, need:
+ * 1 MB mask for AM, OR[0:16] = 1111 1111 1111 0000 0
+ * disable buffer ctrl OR[19] = 0
+ * CSNT OR[20] = 1
+ * ACS OR[21:22] = 11
+ * XACS OR[23] = 1
+ * SCY 15 wait states OR[24:27] = 1111 max is suboptimal but safe
+ * SETA OR[28] = 0
+ * TRLX OR[29] = 1
+ * EHTR OR[30] = 1
+ * EAD extra time OR[31] = 1
+ *
+ * 0 4 8 12 16 20 24 28
+ * 1111 1111 1111 0000 0000 1111 1111 0111 = fff00ff7
+ */
+
+#define CADMUS_BASE_ADDR 0xf8000000
+#define CFG_BR3_PRELIM 0xf8000801
+#define CFG_OR3_PRELIM 0xfff00ff7
+
+#define CONFIG_L1_INIT_RAM
+#define CFG_INIT_RAM_LOCK 1
+#define CFG_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */
+#define CFG_INIT_RAM_END 0x4000 /* End of used area in RAM */
+
+#define CFG_GBL_DATA_SIZE 128 /* 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_LEN (256 * 1024) /* Reserve 256 kB for Mon */
+#define CFG_MALLOC_LEN (128 * 1024) /* Reserved for malloc */
+
+/* Serial Port */
+#define CONFIG_CONS_INDEX 2
+#undef CONFIG_SERIAL_SOFTWARE_FIFO
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+#define CFG_NS16550_REG_SIZE 1
+#define CFG_NS16550_CLK get_bus_freq(0)
+
+#define CFG_BAUDRATE_TABLE \
+ {300, 600, 1200, 2400, 4800, 9600, 19200, 38400,115200}
+
+#define CFG_NS16550_COM1 (CFG_CCSRBAR+0x4500)
+#define CFG_NS16550_COM2 (CFG_CCSRBAR+0x4600)
+
+/* 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 /* I2C bit-banged */
+#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */
+#define CFG_I2C_EEPROM_ADDR 0x57
+#define CFG_I2C_SLAVE 0x7F
+#define CFG_I2C_NOPROBES {0x69} /* Don't probe these addrs */
+
+/*
+ * General PCI
+ * Addresses are mapped 1-1.
+ */
+#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_PCI2_MEM_BASE 0xa0000000
+#define CFG_PCI2_MEM_PHYS CFG_PCI2_MEM_BASE
+#define CFG_PCI2_MEM_SIZE 0x20000000 /* 512M */
+#define CFG_PCI2_IO_BASE 0xe3000000
+#define CFG_PCI2_IO_PHYS CFG_PCI2_IO_BASE
+#define CFG_PCI2_IO_SIZE 0x1000000 /* 16M */
+
+
+#if defined(CONFIG_PCI)
+
+#define CONFIG_NET_MULTI
+#define CONFIG_PCI_PNP /* do pci plug-and-play */
+
+#undef CONFIG_EEPRO100
+#undef CONFIG_TULIP
+
+#if !defined(CONFIG_PCI_PNP)
+ #define PCI_ENET0_IOADDR 0xe0000000
+ #define PCI_ENET0_MEMADDR 0xe0000000
+ #define PCI_IDSEL_NUMBER 0x0c /*slot0->3(IDSEL)=12->15*/
+#endif
+
+#undef CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */
+#define CFG_PCI_SUBSYS_VENDORID 0x1057 /* Motorola */
+
+#endif /* CONFIG_PCI */
+
+
+#if defined(CONFIG_TSEC_ENET)
+
+#ifndef CONFIG_NET_MULTI
+#define CONFIG_NET_MULTI 1
+#endif
+
+#define CONFIG_MII 1 /* MII PHY management */
+#define CONFIG_MPC85XX_TSEC1 1
+#define CONFIG_MPC85XX_TSEC1_NAME "eTSEC0"
+#define CONFIG_MPC85XX_TSEC2 1
+#define CONFIG_MPC85XX_TSEC2_NAME "eTSEC1"
+#define CONFIG_MPC85XX_TSEC3 1
+#define CONFIG_MPC85XX_TSEC3_NAME "eTSEC2"
+#define CONFIG_MPC85XX_TSEC4 1
+#define CONFIG_MPC85XX_TSEC4_NAME "eTSEC3"
+#undef CONFIG_MPC85XX_FEC
+
+#define TSEC1_PHY_ADDR 0
+#define TSEC2_PHY_ADDR 1
+#define TSEC3_PHY_ADDR 2
+#define TSEC4_PHY_ADDR 3
+#define FEC_PHY_ADDR 3
+
+#define TSEC1_PHYIDX 0
+#define TSEC2_PHYIDX 0
+#define TSEC3_PHYIDX 0
+#define TSEC4_PHYIDX 0
+#define FEC_PHYIDX 0
+
+/* Options are: eTSEC[0-3] */
+#define CONFIG_ETHPRIME "eTSEC0"
+
+#endif /* CONFIG_TSEC_ENET */
+
+/*
+ * Environment
+ */
+#define CFG_ENV_IS_IN_FLASH 1
+#define CFG_ENV_ADDR (CFG_MONITOR_BASE + 0x40000)
+#define CFG_ENV_SECT_SIZE 0x40000 /* 256K(one sector) for env */
+#define CFG_ENV_SIZE 0x2000
+
+#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_PING \
+ | CFG_CMD_I2C \
+ | CFG_CMD_MII)
+#else
+#define CONFIG_COMMANDS (CONFIG_CMD_DFL \
+ | CFG_CMD_PING \
+ | CFG_CMD_I2C \
+ | CFG_CMD_MII)
+#endif
+#include <cmd_confdefs.h>
+
+#undef CONFIG_WATCHDOG /* watchdog disabled */
+
+/*
+ * 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
+
+/*
+ * 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 to run kgdb serial port */
+#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */
+#endif
+
+/*
+ * Environment Configuration
+ */
+
+/* The mac addresses for all ethernet interface */
+#if defined(CONFIG_TSEC_ENET)
+#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
+#endif
+
+#define CONFIG_IPADDR 192.168.1.253
+
+#define CONFIG_HOSTNAME unknown
+#define CONFIG_ROOTPATH /nfsroot
+#define CONFIG_BOOTFILE your.uImage
+
+#define CONFIG_SERVERIP 192.168.1.1
+#define CONFIG_GATEWAYIP 192.168.1.1
+#define CONFIG_NETMASK 255.255.255.0
+
+#define CONFIG_LOADADDR 200000 /*default location for tftp and bootm*/
+
+#define CONFIG_BOOTDELAY 10 /* -1 disables auto-boot */
+#undef CONFIG_BOOTARGS /* the boot command will set bootargs*/
+
+#define CONFIG_BAUDRATE 115200
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "netdev=eth0\0" \
+ "consoledev=ttyS1\0" \
+ "ramdiskaddr=400000\0" \
+ "ramdiskfile=your.ramdisk.u-boot\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;" \
+ "bootm $loadaddr"
+
+#define CONFIG_RAMBOOTCOMMAND \
+ "setenv bootargs root=/dev/ram rw " \
+ "console=$consoledev,$baudrate $othbootargs;" \
+ "tftp $ramdiskaddr $ramdiskfile;" \
+ "tftp $loadaddr $bootfile;" \
+ "bootm $loadaddr $ramdiskaddr"
+
+#define CONFIG_BOOTCOMMAND CONFIG_NFSBOOTCOMMAND
+
+#endif /* __CONFIG_H */
#define CONFIG_TSEC_ENET /* tsec ethernet support */
#define CONFIG_ENV_OVERWRITE
#define CONFIG_SPD_EEPROM /* Use SPD EEPROM for DDR setup*/
-#define CONFIG_DDR_ECC /* only for ECC DDR module */
#define CONFIG_DDR_DLL /* possible DLL fix needed */
-#define CONFIG_DDR_2T_TIMING /* Sets the 2T timing bit */
+#undef CONFIG_DDR_2T_TIMING /* Sets the 2T timing bit */
+
+#define CONFIG_DDR_ECC /* only for ECC DDR module */
+#define CONFIG_MEM_INIT_VALUE 0xDeadBeef
+
/*
* When initializing flash, if we cannot find the manufacturer ID,
#define CONFIG_MII 1 /* MII PHY management */
#define CONFIG_MPC85XX_TSEC1 1
+#define CONFIG_MPC85XX_TSEC1_NAME "TSEC0"
#define CONFIG_MPC85XX_TSEC2 1
+#define CONFIG_MPC85XX_TSEC2_NAME "TSEC1"
#undef CONFIG_MPC85XX_FEC
#define TSEC1_PHY_ADDR 0
#define TSEC2_PHY_ADDR 1
#define TSEC1_PHYIDX 0
#define TSEC2_PHYIDX 0
#define FEC_PHYIDX 0
-#define CONFIG_ETHPRIME "MOTO ENET0"
+
+/* Options are: TSEC[0-1] */
+#define CONFIG_ETHPRIME "TSEC0"
#endif /* CONFIG_TSEC_ENET */
#undef CONFIG_ETHER_ON_FCC /* cpm FCC ethernet support */
#define CONFIG_ENV_OVERWRITE
#define CONFIG_SPD_EEPROM /* Use SPD EEPROM for DDR setup*/
-#define CONFIG_DDR_ECC /* only for ECC DDR module */
#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_MEM_INIT_VALUE 0xDeadBeef
+
/*
* sysclk for MPC85xx
#define CONFIG_MII 1 /* MII PHY management */
#define CONFIG_MPC85XX_TSEC1 1
+#define CONFIG_MPC85XX_TSEC1_NAME "TSEC0"
#define CONFIG_MPC85XX_TSEC2 1
+#define CONFIG_MPC85XX_TSEC2_NAME "TSEC1"
#undef CONFIG_MPC85XX_FEC
#define TSEC1_PHY_ADDR 0
#define TSEC2_PHY_ADDR 1
#define TSEC1_PHYIDX 0
#define TSEC2_PHYIDX 0
-#define CONFIG_ETHPRIME "MOTO ENET0"
+
+/* Options are: TSEC[0-1] */
+#define CONFIG_ETHPRIME "TSEC0"
#elif defined(CONFIG_ETHER_ON_FCC) /* CPM FCC Ethernet */
#define CONFIG_TSEC_ENET /* tsec ethernet support */
#define CONFIG_ENV_OVERWRITE
#undef CONFIG_SPD_EEPROM /* do not use SPD EEPROM for DDR setup*/
-#define CONFIG_DDR_ECC /* only for ECC DDR module */
#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_MEM_INIT_VALUE 0xDeadBeef
+
/*
* sysclk for MPC85xx
#define CONFIG_MII 1 /* MII PHY management */
#define CONFIG_MPC85XX_TSEC1 1
+#define CONFIG_MPC85XX_TSEC1_NAME "TSEC0"
#define CONFIG_MPC85XX_TSEC2 1
+#define CONFIG_MPC85XX_TSEC2_NAME "TSEC1"
#define TSEC1_PHY_ADDR 2
#define TSEC2_PHY_ADDR 3
#define TSEC1_PHYIDX 0
#define TSEC2_PHYIDX 0
#define CONFIG_MPC85XX_FEC 1
+#define CONFIG_MPC85XX_FEC_NAME "FEC"
#define FEC_PHY_ADDR 1
#define FEC_PHYIDX 0
-#define CONFIG_ETHPRIME "MOTO ENET0"
+/* Options are: TSEC[0-1] */
+#define CONFIG_ETHPRIME "TSEC0"
#define CONFIG_HAS_ETH1 1
#define CONFIG_HAS_ETH2 1
#if defined(CONFIG_TSEC_ENET) /* TSEC Ethernet port */
- #define CONFIG_NET_MULTI 1
- #define CONFIG_PHY_BCM5421S /* GigaBit Ether PHY */
- #define CONFIG_MII 1 /* MII PHY management */
- #define CONFIG_PHY_ADDR 25 /* PHY address */
+# define CONFIG_NET_MULTI 1
+# define CONFIG_MPC85xx_TSEC1
+# define CONFIG_MPC85xx_TSEC1_NAME "TSEC0"
+# define CONFIG_MII 1 /* MII PHY management */
+# define TSEC1_PHY_ADDR 25
+# define TSEC1_PHYIDX 0
+/* Options are: TSEC0 */
+# define CONFIG_ETHPRIME "TSEC0"
#elif defined(CONFIG_ETHER_ON_FCC) /* CPM FCC Ethernet */
#if defined(CONFIG_TSEC_ENET) /* TSEC Ethernet port */
- #define CONFIG_NET_MULTI 1
- #define CONFIG_PHY_BCM5421S /* GigaBit Ether PHY */
- #define CONFIG_MII 1 /* MII PHY management */
- #define CONFIG_PHY_ADDR 25 /* PHY address */
+# define CONFIG_NET_MULTI 1
+# define CONFIG_MII 1 /* MII PHY management */
+# define CONFIG_MPC85xx_TSEC1
+# define CONFIG_MPC85xx_TSEC1_NAME "TSEC0"
+# define TSEC1_PHY_ADDR 25
+# define TSEC1_PHYIDX 0
+/* Options are: TSEC0 */
+# define CONFIG_ETHPRIME "TSEC0"
#elif defined(CONFIG_ETHER_ON_FCC) /* CPM FCC Ethernet */
#define CONFIG_MII 1 /* MII PHY management */
#define CONFIG_MPC85XX_TSEC1 1
+#define CONFIG_MPC85XX_TSEC1_NAME "TSEC0"
#define CONFIG_MPC85XX_TSEC2 1
+#define CONFIG_MPC85XX_TSEC2_NAME "TSEC1"
#define TSEC1_PHY_ADDR 0
#define TSEC2_PHY_ADDR 1
#define TSEC1_PHYIDX 0
#define TSEC2_PHYIDX 0
#define CONFIG_MPC85XX_FEC 1
+#define CONFIG_MPC85XX_FEC_NAME "FEC"
#define FEC_PHY_ADDR 2
#define FEC_PHYIDX 0
#define CONFIG_HAS_ETH1
#define CONFIG_HAS_ETH2
-#define CONFIG_ETHPRIME "ENET1"
+/* Options are TSEC[0-1], FEC */
+#define CONFIG_ETHPRIME "TSEC1"
#endif /* CONFIG_TSEC_ENET */
#define CONFIG_MII 1 /* MII PHY management */
#define CONFIG_MPC85XX_TSEC2 1
+#define CONFIG_MPC85XX_TSEC2_NAME "TSEC1"
#define TSEC2_PHY_ADDR 1
#define TSEC2_PHYIDX 0
#define CFG_CPMFCR_RAMTYPE 0
#define CFG_FCC_PSMR (FCC_PSMR_FDE | FCC_PSMR_LPB)
-#define CONFIG_ETHPRIME "ENET1"
+#define CONFIG_ETHPRIME "TSEC1"
/*
* Environment
#if defined(CONFIG_TSEC_ENET) /* TSEC Ethernet port */
- #define CONFIG_NET_MULTI 1
- #define CONFIG_PHY_BCM5421S 1 /* GigaBit Ether PHY */
- #define CONFIG_MII 1 /* MII PHY management */
- #define CONFIG_PHY_ADDR 25 /* PHY address */
+# define CONFIG_NET_MULTI 1
+# define CONFIG_MII 1 /* MII PHY management */
+# define CONFIG_MPC85xx_TSEC1
+# define CONFIG_MPC85xx_TSEC1_NAME "TSEC0"
+# define TSEC1_PHY_ADDR 25
+# define TSEC1_PHYIDX 0
+/* Options are: TSEC0 */
+# define CONFIG_ETHPRIME "TSEC0"
#elif defined(CONFIG_ETHER_ON_FCC) /* CPM FCC Ethernet */
#define CONFIG_MII 1 /* MII PHY management */
#define CONFIG_MPC85XX_TSEC1 1
+#define CONFIG_MPC85XX_TSEC1_NAME "TSEC0"
#define CONFIG_MPC85XX_TSEC2 1
+#define CONFIG_MPC85XX_TSEC2_NAME "TSEC1"
#undef CONFIG_MPS85XX_FEC
#define TSEC1_PHY_ADDR 2
#define TSEC2_PHY_ADDR 4
#define TSEC1_PHYIDX 0
#define TSEC2_PHYIDX 0
-#define CONFIG_ETHPRIME "MOTO ENET0"
+#define CONFIG_ETHPRIME "TSEC0"
#elif defined(CONFIG_ETHER_ON_FCC) /* CPM FCC Ethernet */
#define _SPD_H_
typedef struct spd_eeprom_s {
- unsigned char info_size; /* # of bytes written into serial memory */
- unsigned char chip_size; /* Total # of bytes of SPD memory device */
- unsigned char mem_type; /* Fundamental memory type (FPM, EDO, SDRAM...) */
- unsigned char nrow_addr; /* # of Row Addresses on this assembly */
- unsigned char ncol_addr; /* # of Column Addresses on this assembly */
- unsigned char nrows; /* # of Module Rows on this assembly */
- unsigned char dataw_lsb; /* Data Width of this assembly */
- unsigned char dataw_msb; /* ... Data Width continuation */
- unsigned char voltage; /* Voltage interface standard of this assembly */
- unsigned char clk_cycle; /* SDRAM Cycle time at CL=X */
- unsigned char clk_access; /* SDRAM Access from Clock at CL=X */
- unsigned char config; /* DIMM Configuration type (non-parity, ECC) */
- unsigned char refresh; /* Refresh Rate/Type */
- unsigned char primw; /* Primary SDRAM Width */
- unsigned char ecw; /* Error Checking SDRAM width */
- unsigned char min_delay; /* Min Clock Delay for Back to Back Random Address */
- unsigned char burstl; /* Burst Lengths Supported */
- unsigned char nbanks; /* # of Banks on Each SDRAM Device */
- unsigned char cas_lat; /* CAS# Latencies Supported */
- unsigned char cs_lat; /* CS# Latency */
- unsigned char write_lat; /* Write Latency (also called Write Recovery time) */
- unsigned char mod_attr; /* SDRAM Module Attributes */
- unsigned char dev_attr; /* SDRAM Device Attributes */
- unsigned char clk_cycle2; /* Min SDRAM Cycle time at CL=X-1 */
- unsigned char clk_access2; /* SDRAM Access from Clock at CL=X-1 */
- unsigned char clk_cycle3; /* Min SDRAM Cycle time at CL=X-2 */
- unsigned char clk_access3; /* Max SDRAM Access from Clock at CL=X-2 */
- unsigned char trp; /* Min Row Precharge Time (tRP) */
- unsigned char trrd; /* Min Row Active to Row Active (tRRD) */
- unsigned char trcd; /* Min RAS to CAS Delay (tRCD) */
- unsigned char tras; /* Minimum RAS Pulse Width (tRAS) */
- unsigned char row_dens; /* Density of each row on module */
- unsigned char ca_setup; /* Command and Address signal input setup time */
- unsigned char ca_hold; /* Command and Address signal input hold time */
- unsigned char data_setup; /* Data signal input setup time */
- unsigned char data_hold; /* Data signal input hold time */
- unsigned char sset[26]; /* Superset Information (may be used in future) */
- unsigned char spd_rev; /* SPD Data Revision Code */
- unsigned char cksum; /* Checksum for bytes 0-62 */
- unsigned char mid[8]; /* Manufacturer's JEDEC ID code per JEP-108E */
- unsigned char mloc; /* Manufacturing Location */
- unsigned char mpart[18]; /* Manufacturer's Part Number */
- unsigned char rev[2]; /* Revision Code */
- unsigned char mdate[2]; /* Manufacturing Date */
- unsigned char sernum[4]; /* Assembly Serial Number */
- unsigned char mspec[27]; /* Manufacturer Specific Data */
- unsigned char freq; /* Intel specification frequency */
- unsigned char intel_cas; /* Intel Specification CAS# Latency support */
+ unsigned char info_size; /* 0 # bytes written into serial memory */
+ unsigned char chip_size; /* 1 Total # bytes of SPD memory device */
+ unsigned char mem_type; /* 2 Fundamental memory type */
+ unsigned char nrow_addr; /* 3 # of Row Addresses on this assembly */
+ unsigned char ncol_addr; /* 4 # of Column Addrs on this assembly */
+ unsigned char nrows; /* 5 # of Module Rows on this assembly */
+ unsigned char dataw_lsb; /* 6 Data Width of this assembly */
+ unsigned char dataw_msb; /* 7 ... Data Width continuation */
+ unsigned char voltage; /* 8 Voltage intf std of this assembly */
+ unsigned char clk_cycle; /* 9 SDRAM Cycle time at CL=X */
+ unsigned char clk_access; /* 10 SDRAM Access from Clock at CL=X */
+ unsigned char config; /* 11 DIMM Configuration type */
+ unsigned char refresh; /* 12 Refresh Rate/Type */
+ unsigned char primw; /* 13 Primary SDRAM Width */
+ unsigned char ecw; /* 14 Error Checking SDRAM width */
+ unsigned char min_delay; /* 15 for Back to Back Random Address */
+ unsigned char burstl; /* 16 Burst Lengths Supported */
+ unsigned char nbanks; /* 17 # of Banks on Each SDRAM Device */
+ unsigned char cas_lat; /* 18 CAS# Latencies Supported */
+ unsigned char cs_lat; /* 19 CS# Latency */
+ unsigned char write_lat; /* 20 Write Latency (aka Write Recovery) */
+ unsigned char mod_attr; /* 21 SDRAM Module Attributes */
+ unsigned char dev_attr; /* 22 SDRAM Device Attributes */
+ unsigned char clk_cycle2; /* 23 Min SDRAM Cycle time at CL=X-1 */
+ unsigned char clk_access2; /* 24 SDRAM Access from Clock at CL=X-1 */
+ unsigned char clk_cycle3; /* 25 Min SDRAM Cycle time at CL=X-2 */
+ unsigned char clk_access3; /* 26 Max Access from Clock at CL=X-2 */
+ unsigned char trp; /* 27 Min Row Precharge Time (tRP)*/
+ unsigned char trrd; /* 28 Min Row Active to Row Active (tRRD) */
+ unsigned char trcd; /* 29 Min RAS to CAS Delay (tRCD) */
+ unsigned char tras; /* 30 Minimum RAS Pulse Width (tRAS) */
+ unsigned char row_dens; /* 31 Density of each row on module */
+ unsigned char ca_setup; /* 32 Cmd + Addr signal input setup time */
+ unsigned char ca_hold; /* 33 Cmd and Addr signal input hold time */
+ unsigned char data_setup; /* 34 Data signal input setup time */
+ unsigned char data_hold; /* 35 Data signal input hold time */
+ unsigned char twr; /* 36 Write Recovery time tWR */
+ unsigned char twtr; /* 37 Int write to read delay tWTR */
+ unsigned char trtp; /* 38 Int read to precharge delay tRTP */
+ unsigned char mem_probe; /* 39 Mem analysis probe characteristics */
+ unsigned char trctrfc_ext; /* 40 Extensions to trc and trfc */
+ unsigned char trc; /* 41 Min Active to Auto refresh time tRC */
+ unsigned char trfc; /* 42 Min Auto to Active period tRFC */
+ unsigned char tckmax; /* 43 Max device cycle time tCKmax */
+ unsigned char tdqsq; /* 44 Max DQS to DQ skew */
+ unsigned char tqhs; /* 45 Max Read DataHold skew tQHS */
+ unsigned char pll_relock; /* 46 PLL Relock time */
+ unsigned char res[15]; /* 47-xx IDD in SPD and Reserved space */
+ unsigned char spd_rev; /* 62 SPD Data Revision Code */
+ unsigned char cksum; /* 63 Checksum for bytes 0-62 */
+ unsigned char mid[8]; /* 64 Mfr's JEDEC ID code per JEP-108E */
+ unsigned char mloc; /* 72 Manufacturing Location */
+ unsigned char mpart[18]; /* 73 Manufacturer's Part Number */
+ unsigned char rev[2]; /* 91 Revision Code */
+ unsigned char mdate[2]; /* 93 Manufacturing Date */
+ unsigned char sernum[4]; /* 95 Assembly Serial Number */
+ unsigned char mspec[27]; /* 99 Manufacturer Specific Data */
+
+ /*
+ * Open for Customer Use starting with byte 128.
+ */
+ unsigned char freq; /* 128 Intel spec: frequency */
+ unsigned char intel_cas; /* 129 Intel spec: CAS# Latency support */
} spd_eeprom_t;
+
+/*
+ * Byte 2 Fundamental Memory Types.
+ */
+#define SPD_MEMTYPE_FPM (0x01)
+#define SPD_MEMTYPE_EDO (0x02)
+#define SPD_MEMTYPE_PIPE_NIBBLE (0x03)
+#define SPD_MEMTYPE_SDRAM (0x04)
+#define SPD_MEMTYPE_ROM (0x05)
+#define SPD_MEMTYPE_SGRAM (0x06)
+#define SPD_MEMTYPE_DDR (0x07)
+#define SPD_MEMTYPE_DDR2 (0x08)
+
+
#endif /* _SPD_H_ */
+
extern int rtl8169_initialize(bd_t*);
extern int scc_initialize(bd_t*);
extern int skge_initialize(bd_t*);
-extern int tsec_initialize(bd_t*, int);
+extern int tsec_initialize(bd_t*, int, char *);
static struct eth_device *eth_devices, *eth_current;
skge_initialize(bis);
#endif
#if defined(CONFIG_MPC85XX_TSEC1)
- tsec_initialize(bis, 0);
+ tsec_initialize(bis, 0, CONFIG_MPC85XX_TSEC1_NAME);
#endif
#if defined(CONFIG_MPC85XX_TSEC2)
- tsec_initialize(bis, 1);
+ tsec_initialize(bis, 1, CONFIG_MPC85XX_TSEC2_NAME);
#endif
#if defined(CONFIG_MPC85XX_FEC)
- tsec_initialize(bis, 2);
+ tsec_initialize(bis, 2, CONFIG_MPC85XX_FEC_NAME);
+#else
+# if defined(CONFIG_MPC85XX_TSEC3)
+ tsec_initialize(bis, 2, CONFIG_MPC85XX_TSEC3_NAME);
+# endif
+# if defined(CONFIG_MPC85XX_TSEC4)
+ tsec_initialize(bis, 3, CONFIG_MPC85XX_TSEC4_NAME);
+# endif
#endif
#if defined(CONFIG_AU1X00)
au1x00_enet_initialize(bis);