[U-Boot-Users] [PATCH 3/6 part 1] mpc8360epb board support
Jiang Bo-r61859
tanya.jiang at freescale.com
Thu Aug 17 14:05:15 CEST 2006
Subject: [PATCH] mpc8360epb board support
---
board/mpc8360epb/Makefile | 45 +++
board/mpc8360epb/config.mk | 26 ++
board/mpc8360epb/mpc8360epb.c | 579
+++++++++++++++++++++++++++++++++++++++++
board/mpc8360epb/pci.c | 302 +++++++++++++++++++++
board/mpc8360epb/u-boot.lds | 123 +++++++++
5 files changed, 1075 insertions(+), 0 deletions(-)
create mode 100644 board/mpc8360epb/Makefile
create mode 100644 board/mpc8360epb/config.mk
create mode 100644 board/mpc8360epb/mpc8360epb.c
create mode 100644 board/mpc8360epb/pci.c
create mode 100644 board/mpc8360epb/u-boot.lds
078f14f4c929af05403d420ec18c6ae896c9ae23
diff --git a/board/mpc8360epb/Makefile b/board/mpc8360epb/Makefile
new file mode 100644
index 0000000..7e47c67
--- /dev/null
+++ b/board/mpc8360epb/Makefile
@@ -0,0 +1,45 @@
+#
+# Copyright (C) 2006 Freescale Semiconductor, Inc.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = lib$(BOARD).a
+
+OBJS := $(BOARD).o pci.o
+
+$(LIB): $(OBJS) $(SOBJS)
+ $(AR) crv $@ $(OBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+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
+
+#######################################################################
##
diff --git a/board/mpc8360epb/config.mk b/board/mpc8360epb/config.mk
new file mode 100644
index 0000000..f740db3
--- /dev/null
+++ b/board/mpc8360epb/config.mk
@@ -0,0 +1,26 @@
+# Copyright (C) 2006 Freescale Semiconductor, Inc.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+#
+# MPC8360EPB
+#
+
+TEXT_BASE = 0xFEF00000
diff --git a/board/mpc8360epb/mpc8360epb.c
b/board/mpc8360epb/mpc8360epb.c
new file mode 100644
index 0000000..ff23040
--- /dev/null
+++ b/board/mpc8360epb/mpc8360epb.c
@@ -0,0 +1,579 @@
+/*
+ * Copyright (C) 2006 Freescale Semiconductor, Inc.
+ *
+ * Author: Mandy Lavi (mandy.lavi at freescale.com)
+ *
+ * Modifier: Xiaobo Xie <r63061 at freescale.com> & Dave Liu
<r63238 at freescale.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <common.h>
+#include <ioports.h>
+#include <mpc83xx.h>
+#include <i2c.h>
+#include <spd.h>
+#include <miiphy.h>
+#include <command.h>
+#if defined(CONFIG_PCI)
+#include <pci.h>
+#endif
+#if defined(CONFIG_SPD_EEPROM)
+#include <spd_sdram.h>
+#else
+#include <asm/mmu.h>
+#endif
+
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC)
+extern void ddr_enable_ecc(unsigned int dram_size);
+#endif
+
+int fixed_sdram(void);
+void sdram_init(void);
+
+int board_early_init_f(void)
+{
+ volatile u8 *bcsr = (volatile u8 *)CFG_BCSR;
+
+ /* Enable flash write */
+ bcsr[0xa] &= ~0x04;
+
+ return 0;
+}
+
+long int initdram(int board_type)
+{
+ volatile immap_t *im = (immap_t *) CFG_IMMRBAR;
+ u32 msize = 0;
+
+ if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im)
+ return -1;
+
+ /* DDR SDRAM - Main SODIMM */
+ im->sysconf.ddrlaw[0].bar = CFG_DDR_BASE & LAWBAR_BAR;
+#if defined(CONFIG_SPD_EEPROM)
+ msize = spd_sdram();
+#else
+ msize = fixed_sdram();
+#endif
+
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC)
+ /*
+ * Initialize DDR ECC byte
+ */
+ ddr_enable_ecc(msize * 1024 * 1024);
+#endif
+ /*
+ * Initialize SDRAM if it is on local bus.
+ */
+ sdram_init();
+ puts(" DDR RAM: ");
+ /* return total bus SDRAM size(bytes) -- DDR */
+ return (msize * 1024 * 1024);
+}
+
+#if !defined(CONFIG_SPD_EEPROM)
+/**********************************************************************
***
+ * fixed sdram init -- doesn't use serial presence detect.
+
************************************************************************
/
+int fixed_sdram(void)
+{
+ volatile immap_t *im = (immap_t *) CFG_IMMRBAR;
+ u32 msize = 0;
+ u32 ddr_size;
+ u32 ddr_size_log2;
+
+ msize = CFG_DDR_SIZE;
+ for (ddr_size = msize << 20, ddr_size_log2 = 0;
+ (ddr_size > 1); ddr_size = ddr_size >> 1,
ddr_size_log2++) {
+ if (ddr_size & 1) {
+ return -1;
+ }
+ }
+ im->sysconf.ddrlaw[0].ar =
+ LAWAR_EN | ((ddr_size_log2 - 1) & LAWAR_SIZE);
+#if (CFG_DDR_SIZE != 256)
+#warning Currenly any ddr size other than 256 is not supported
+#endif
+ im->ddr.csbnds[0].csbnds = 0x00000007;
+ im->ddr.csbnds[1].csbnds = 0x0008000f;
+
+ im->ddr.cs_config[0] = CFG_DDR_CONFIG;
+ im->ddr.cs_config[1] = CFG_DDR_CONFIG;
+
+ im->ddr.timing_cfg_1 = CFG_DDR_TIMING_1;
+ im->ddr.timing_cfg_2 = CFG_DDR_TIMING_2;
+ im->ddr.sdram_cfg = CFG_DDR_CONTROL;
+
+ im->ddr.sdram_mode = CFG_DDR_MODE;
+ im->ddr.sdram_interval = CFG_DDR_INTERVAL;
+ udelay(200);
+ im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN;
+
+ return msize;
+}
+#endif /*!CFG_SPD_EEPROM */
+
+int checkboard(void)
+{
+ puts("Board: Freescale MPC8360EPB\n");
+ return 0;
+}
+
+/*
+if MPC8360EPB is soldered with SDRAM
+*/
+#if defined(CFG_BR2_PRELIM) \
+ && defined(CFG_OR2_PRELIM) \
+ && defined(CFG_LBLAWBAR2_PRELIM) \
+ && defined(CFG_LBLAWAR2_PRELIM)
+/*
+ * Initialize SDRAM memory on the Local Bus.
+ */
+
+void sdram_init(void)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMRBAR;
+ volatile lbus83xx_t *lbc = &immap->lbus;
+ uint *sdram_addr = (uint *) CFG_LBC_SDRAM_BASE;
+
+ puts("\n SDRAM on Local Bus: ");
+ print_size(CFG_LBC_SDRAM_SIZE * 1024 * 1024, "\n");
+ /*
+ * Setup SDRAM Base and Option Registers, already done in
cpu_init.c
+ */
+ /*setup mtrpt, lsrt and lbcr for LB bus */
+ lbc->lbcr = CFG_LBC_LBCR;
+ lbc->mrtpr = CFG_LBC_MRTPR;
+ lbc->lsrt = CFG_LBC_LSRT;
+ asm("sync");
+
+ /*
+ * Configure the SDRAM controller Machine Mode Register.
+ */
+ lbc->lsdmr = CFG_LBC_LSDMR_5; /* 0x40636733; normal operation
*/
+ lbc->lsdmr = CFG_LBC_LSDMR_1; /*0x68636733;precharge all the
banks */
+ asm("sync");
+ *sdram_addr = 0xff;
+ udelay(100);
+
+ lbc->lsdmr = CFG_LBC_LSDMR_2; /*0x48636733;auto refresh */
+ asm("sync");
+ /*1 times*/
+ *sdram_addr = 0xff;
+ udelay(100);
+ /*2 times*/
+ *sdram_addr = 0xff;
+ udelay(100);
+ /*3 times*/
+ *sdram_addr = 0xff;
+ udelay(100);
+ /*4 times*/
+ *sdram_addr = 0xff;
+ udelay(100);
+ /*5 times*/
+ *sdram_addr = 0xff;
+ udelay(100);
+ /*6 times*/
+ *sdram_addr = 0xff;
+ udelay(100);
+ /*7 times*/
+ *sdram_addr = 0xff;
+ udelay(100);
+ /*8 times*/
+ *sdram_addr = 0xff;
+ udelay(100);
+
+ /*0x58636733;mode register write operation */
+ lbc->lsdmr = CFG_LBC_LSDMR_4;
+ asm("sync");
+ *(sdram_addr + 0xcc) = 0xff;
+ udelay(100);
+
+ /*0x40636733;normal operation */
+ lbc->lsdmr = CFG_LBC_LSDMR_5 | 0x40000000;
+ asm("sync");
+ *sdram_addr = 0xff;
+ udelay(100);
+}
+#else
+void sdram_init(void)
+{
+ puts("SDRAM on Local Bus is NOT available!\n");
+}
+#endif
+
+#if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD)
+/*
+ * ECC user commands
+ */
+void ecc_print_status(void)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMRBAR;
+ volatile ddr83xx_t *ddr = &immap->ddr;
+
+ printf("\nECC mode: %s\n\n",
+ (ddr->sdram_cfg & SDRAM_CFG_ECC_EN) ? "ON" : "OFF");
+
+ /* Interrupts */
+ printf("Memory Error Interrupt Enable:\n");
+ printf(" Multiple-Bit Error Interrupt Enable: %d\n",
+ (ddr->err_int_en & ECC_ERR_INT_EN_MBEE) ? 1 : 0);
+ printf(" Single-Bit Error Interrupt Enable: %d\n",
+ (ddr->err_int_en & ECC_ERR_INT_EN_SBEE) ? 1 : 0);
+ printf(" Memory Select Error Interrupt Enable: %d\n\n",
+ (ddr->err_int_en & ECC_ERR_INT_EN_MSEE) ? 1 : 0);
+
+ /* Error disable */
+ printf("Memory Error Disable:\n");
+ printf(" Multiple-Bit Error Disable: %d\n",
+ (ddr->err_disable & ECC_ERROR_DISABLE_MBED) ? 1 : 0);
+ printf(" Sinle-Bit Error Disable: %d\n",
+ (ddr->err_disable & ECC_ERROR_DISABLE_SBED) ? 1 : 0);
+ printf(" Memory Select Error Disable: %d\n\n",
+ (ddr->err_disable & ECC_ERROR_DISABLE_MSED) ? 1 : 0);
+
+ /* Error injection */
+ printf("Memory Data Path Error Injection Mask High/Low: %08lx
%08lx\n",
+ ddr->data_err_inject_hi, ddr->data_err_inject_lo);
+
+ printf("Memory Data Path Error Injection Mask ECC:\n");
+ printf(" ECC Mirror Byte: %d\n",
+ (ddr->ecc_err_inject & ECC_ERR_INJECT_EMB) ? 1 : 0);
+ printf(" ECC Injection Enable: %d\n",
+ (ddr->ecc_err_inject & ECC_ERR_INJECT_EIEN) ? 1 : 0);
+ printf(" ECC Error Injection Mask: 0x%02x\n\n",
+ ddr->ecc_err_inject & ECC_ERR_INJECT_EEIM);
+
+ /* SBE counter/threshold */
+ printf("Memory Single-Bit Error Management (0..255):\n");
+ printf(" Single-Bit Error Threshold: %d\n",
+ (ddr->err_sbe & ECC_ERROR_MAN_SBET) >>
ECC_ERROR_MAN_SBET_SHIFT);
+ printf(" Single-Bit Error Counter: %d\n\n",
+ (ddr->err_sbe & ECC_ERROR_MAN_SBEC) >>
ECC_ERROR_MAN_SBEC_SHIFT);
+
+ /* Error detect */
+ printf("Memory Error Detect:\n");
+ printf(" Multiple Memory Errors: %d\n",
+ (ddr->err_detect & ECC_ERROR_DETECT_MME) ? 1 : 0);
+ printf(" Multiple-Bit Error: %d\n",
+ (ddr->err_detect & ECC_ERROR_DETECT_MBE) ? 1 : 0);
+ printf(" Single-Bit Error: %d\n",
+ (ddr->err_detect & ECC_ERROR_DETECT_SBE) ? 1 : 0);
+ printf(" Memory Select Error: %d\n\n",
+ (ddr->err_detect & ECC_ERROR_DETECT_MSE) ? 1 : 0);
+
+ /* Capture data */
+ printf("Memory Error Address Capture: 0x%08lx\n",
ddr->capture_address);
+ printf("Memory Data Path Read Capture High/Low: %08lx %08lx\n",
+ ddr->capture_data_hi, ddr->capture_data_lo);
+ printf("Memory Data Path Read Capture ECC: 0x%02x\n\n",
+ ddr->capture_ecc & CAPTURE_ECC_ECE);
+
+ printf("Memory Error Attributes Capture:\n");
+ printf(" Data Beat Number: %d\n",
+ (ddr->capture_attributes & ECC_CAPT_ATTR_BNUM) >>
+ ECC_CAPT_ATTR_BNUM_SHIFT);
+ printf(" Transaction Size: %d\n",
+ (ddr->capture_attributes & ECC_CAPT_ATTR_TSIZ) >>
+ ECC_CAPT_ATTR_TSIZ_SHIFT);
+ printf(" Transaction Source: %d\n",
+ (ddr->capture_attributes & ECC_CAPT_ATTR_TSRC) >>
+ ECC_CAPT_ATTR_TSRC_SHIFT);
+ printf(" Transaction Type: %d\n",
+ (ddr->capture_attributes & ECC_CAPT_ATTR_TTYP) >>
+ ECC_CAPT_ATTR_TTYP_SHIFT);
+ printf(" Error Information Valid: %d\n\n",
+ ddr->capture_attributes & ECC_CAPT_ATTR_VLD);
+}
+
+int do_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMRBAR;
+ volatile ddr83xx_t *ddr = &immap->ddr;
+ volatile u32 val;
+ u64 *addr;
+ u32 count;
+ register u64 *i;
+ u32 ret[2];
+ u32 pattern[2];
+ u32 writeback[2];
+
+ pattern[0] = 0xfedcba98UL;
+ pattern[1] = 0x76543210UL;
+
+ writeback[0] = 0x01234567UL;
+ writeback[1] = 0x89abcdefUL;
+
+ if (argc > 4) {
+ printf("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ }
+
+ if (argc == 2) {
+ if (strcmp(argv[1], "status") == 0) {
+ ecc_print_status();
+ return 0;
+ } else if (strcmp(argv[1], "captureclear") == 0) {
+ ddr->capture_address = 0;
+ ddr->capture_data_hi = 0;
+ ddr->capture_data_lo = 0;
+ ddr->capture_ecc = 0;
+ ddr->capture_attributes = 0;
+ return 0;
+ }
+ }
+ if (argc == 3) {
+ if (strcmp(argv[1], "sbecnt") == 0) {
+ val = simple_strtoul(argv[2], NULL, 10);
+ if (val > 255) {
+ printf("Incorrect Counter value, "
+ "should be 0..255\n");
+ return 1;
+ }
+
+ val = (val << ECC_ERROR_MAN_SBEC_SHIFT);
+ val |= (ddr->err_sbe & ECC_ERROR_MAN_SBET);
+
+ ddr->err_sbe = val;
+ return 0;
+ } else if (strcmp(argv[1], "sbethr") == 0) {
+ val = simple_strtoul(argv[2], NULL, 10);
+ if (val > 255) {
+ printf("Incorrect Counter value, "
+ "should be 0..255\n");
+ return 1;
+ }
+
+ val = (val << ECC_ERROR_MAN_SBET_SHIFT);
+ val |= (ddr->err_sbe & ECC_ERROR_MAN_SBEC);
+
+ ddr->err_sbe = val;
+ return 0;
+ } else if (strcmp(argv[1], "errdisable") == 0) {
+ val = ddr->err_disable;
+
+ if (strcmp(argv[2], "+sbe") == 0) {
+ val |= ECC_ERROR_DISABLE_SBED;
+ } else if (strcmp(argv[2], "+mbe") == 0) {
+ val |= ECC_ERROR_DISABLE_MBED;
+ } else if (strcmp(argv[2], "+mse") == 0) {
+ val |= ECC_ERROR_DISABLE_MSED;
+ } else if (strcmp(argv[2], "+all") == 0) {
+ val |= (ECC_ERROR_DISABLE_SBED |
+ ECC_ERROR_DISABLE_MBED |
+ ECC_ERROR_DISABLE_MSED);
+ } else if (strcmp(argv[2], "-sbe") == 0) {
+ val &= ~ECC_ERROR_DISABLE_SBED;
+ } else if (strcmp(argv[2], "-mbe") == 0) {
+ val &= ~ECC_ERROR_DISABLE_MBED;
+ } else if (strcmp(argv[2], "-mse") == 0) {
+ val &= ~ECC_ERROR_DISABLE_MSED;
+ } else if (strcmp(argv[2], "-all") == 0) {
+ val &= ~(ECC_ERROR_DISABLE_SBED |
+ ECC_ERROR_DISABLE_MBED |
+ ECC_ERROR_DISABLE_MSED);
+ } else {
+ printf("Incorrect err_disable field\n");
+ return 1;
+ }
+
+ ddr->err_disable = val;
+ __asm__ __volatile__("sync");
+ __asm__ __volatile__("isync");
+ return 0;
+ } else if (strcmp(argv[1], "errdetectclr") == 0) {
+ val = ddr->err_detect;
+
+ if (strcmp(argv[2], "mme") == 0) {
+ val |= ECC_ERROR_DETECT_MME;
+ } else if (strcmp(argv[2], "sbe") == 0) {
+ val |= ECC_ERROR_DETECT_SBE;
+ } else if (strcmp(argv[2], "mbe") == 0) {
+ val |= ECC_ERROR_DETECT_MBE;
+ } else if (strcmp(argv[2], "mse") == 0) {
+ val |= ECC_ERROR_DETECT_MSE;
+ } else if (strcmp(argv[2], "all") == 0) {
+ val |= (ECC_ERROR_DETECT_MME |
+ ECC_ERROR_DETECT_MBE |
+ ECC_ERROR_DETECT_SBE |
+ ECC_ERROR_DETECT_MSE);
+ } else {
+ printf("Incorrect err_detect field\n");
+ return 1;
+ }
+
+ ddr->err_detect = val;
+ return 0;
+ } else if (strcmp(argv[1], "injectdatahi") == 0) {
+ val = simple_strtoul(argv[2], NULL, 16);
+
+ ddr->data_err_inject_hi = val;
+ return 0;
+ } else if (strcmp(argv[1], "injectdatalo") == 0) {
+ val = simple_strtoul(argv[2], NULL, 16);
+
+ ddr->data_err_inject_lo = val;
+ return 0;
+ } else if (strcmp(argv[1], "injectecc") == 0) {
+ val = simple_strtoul(argv[2], NULL, 16);
+ if (val > 0xff) {
+ printf("Incorrect ECC inject mask, "
+ "should be 0x00..0xff\n");
+ return 1;
+ }
+ val |= (ddr->ecc_err_inject &
~ECC_ERR_INJECT_EEIM);
+
+ ddr->ecc_err_inject = val;
+ return 0;
+ } else if (strcmp(argv[1], "inject") == 0) {
+ val = ddr->ecc_err_inject;
+
+ if (strcmp(argv[2], "en") == 0)
+ val |= ECC_ERR_INJECT_EIEN;
+ else if (strcmp(argv[2], "dis") == 0)
+ val &= ~ECC_ERR_INJECT_EIEN;
+ else
+ printf("Incorrect command\n");
+
+ ddr->ecc_err_inject = val;
+ __asm__ __volatile__("sync");
+ __asm__ __volatile__("isync");
+ return 0;
+ } else if (strcmp(argv[1], "mirror") == 0) {
+ val = ddr->ecc_err_inject;
+
+ if (strcmp(argv[2], "en") == 0)
+ val |= ECC_ERR_INJECT_EMB;
+ else if (strcmp(argv[2], "dis") == 0)
+ val &= ~ECC_ERR_INJECT_EMB;
+ else
+ printf("Incorrect command\n");
+
+ ddr->ecc_err_inject = val;
+ return 0;
+ }
+ }
+ if (argc == 4) {
+ if (strcmp(argv[1], "testdw") == 0) {
+ addr = (u64 *) simple_strtoul(argv[2], NULL,
16);
+ count = simple_strtoul(argv[3], NULL, 16);
+
+ if ((u32) addr % 8) {
+ printf("Address not alligned on "
+ "double word boundary\n");
+ return 1;
+ }
+ disable_interrupts();
+
+ for (i = addr; i < addr + count; i++) {
+
+ /* enable injects */
+ ddr->ecc_err_inject |=
ECC_ERR_INJECT_EIEN;
+ __asm__ __volatile__("sync");
+ __asm__ __volatile__("isync");
+
+ /* write memory location injecting
errors */
+ ppcDWstore((u32 *) i, pattern);
+
+ /* disable injects */
+ ddr->ecc_err_inject &=
~ECC_ERR_INJECT_EIEN;
+ __asm__ __volatile__("sync");
+ __asm__ __volatile__("isync");
+
+ /* read data, this generates ECC error
*/
+ ppcDWload((u32 *) i, ret);
+
+ /* re-initialize memory, double word
write the location again,
+ * generates new ECC code this time */
+ ppcDWstore((u32 *) i, writeback);
+ }
+ enable_interrupts();
+ return 0;
+ }
+ if (strcmp(argv[1], "testword") == 0) {
+ addr = (u64 *) simple_strtoul(argv[2], NULL,
16);
+ count = simple_strtoul(argv[3], NULL, 16);
+
+ if ((u32) addr % 8) {
+ printf("Address not alligned on "
+ "double word boundary\n");
+ return 1;
+ }
+ disable_interrupts();
+
+ for (i = addr; i < addr + count; i++) {
+
+ /* enable injects */
+ ddr->ecc_err_inject |=
ECC_ERR_INJECT_EIEN;
+ __asm__ __volatile__("sync");
+ __asm__ __volatile__("isync");
+
+ /* write memory location injecting
errors */
+ *(u32 *) i = 0xfedcba98UL;
+ __asm__ __volatile__("sync");
+
+ /* sub double word write,
+ * bus will read-modify-write,
+ * generates ECC error */
+ *((u32 *) i + 1) = 0x76543210UL;
+ __asm__ __volatile__("sync");
+
+ /* disable injects */
+ ddr->ecc_err_inject &=
~ECC_ERR_INJECT_EIEN;
+ __asm__ __volatile__("sync");
+ __asm__ __volatile__("isync");
+
+ /* re-initialize memory,
+ * double word write the location again,
+ * generates new ECC code this time */
+ ppcDWstore((u32 *) i, writeback);
+ }
+ enable_interrupts();
+ return 0;
+ }
+ }
+ printf("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+}
+
+U_BOOT_CMD(ecc, 4, 0, do_ecc,
+ "ecc - support for DDR ECC features\n",
+ "status - print out status info\n"
+ "ecc captureclear - clear capture regs data\n"
+ "ecc sbecnt <val> - set Single-Bit Error counter\n"
+ "ecc sbethr <val> - set Single-Bit Threshold\n"
+ "ecc errdisable <flag> - clear/set disable Memory Error
Disable, flag:\n"
+ " [-|+]sbe - Single-Bit Error\n"
+ " [-|+]mbe - Multiple-Bit Error\n"
+ " [-|+]mse - Memory Select Error\n"
+ " [-|+]all - all errors\n"
+ "ecc errdetectclr <flag> - clear Memory Error Detect,
flag:\n"
+ " mme - Multiple Memory Errors\n"
+ " sbe - Single-Bit Error\n"
+ " mbe - Multiple-Bit Error\n"
+ " mse - Memory Select Error\n"
+ " all - all errors\n"
+ "ecc injectdatahi <hi> - set Memory Data Path Error
Injection Mask High\n"
+ "ecc injectdatalo <lo> - set Memory Data Path Error
Injection Mask Low\n"
+ "ecc injectecc <ecc> - set ECC Error Injection Mask\n"
+ "ecc inject <en|dis> - enable/disable error injection\n"
+ "ecc mirror <en|dis> - enable/disable mirror byte\n"
+ "ecc testdw <addr> <cnt> - test mem region with double word
access:\n"
+ " - enables injects\n"
+ " - writes pattern injecting errors with double word
access\n"
+ " - disables injects\n"
+ " - reads pattern back with double word access, generates
error\n"
+ " - re-inits memory\n"
+ "ecc testword <addr> <cnt> - test mem region with word
access:\n"
+ " - enables injects\n"
+ " - writes pattern injecting errors with word access\n"
+ " - writes pattern with word access, generates error\n"
+ " - disables injects\n" " - re-inits memory");
+#endif /* if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD) */
diff --git a/board/mpc8360epb/pci.c b/board/mpc8360epb/pci.c
new file mode 100644
index 0000000..6634d44
--- /dev/null
+++ b/board/mpc8360epb/pci.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2006 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+/*
+ * PCI Configuration space access support for MPC83xx PCI Bridge
+ */
+#include <asm/mmu.h>
+#include <asm/io.h>
+#include <common.h>
+#include <pci.h>
+#include <i2c.h>
+
+#include <asm/i2c.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if defined(CONFIG_PCI)
+#define PCI_FUNCTION_CONFIG 0x44
+#define PCI_FUNCTION_CFG_LOCK 0x20
+
+/*
+ * Initialize PCI Devices, report devices found
+ */
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_mpc83xxads_config_table[] = {
+ {
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ pci_cfgfunc_config_device,
+ {PCI_ENET0_IOADDR,
+ PCI_ENET0_MEMADDR,
+ PCI_COMMON_MEMORY | PCI_COMMAND_MASTER}
+ },
+ {}
+}
+#endif
+static struct pci_controller hose[] = {
+ {
+#ifndef CONFIG_PCI_PNP
+ config_table:pci_mpc83xxads_config_table,
+#endif
+ },
+};
+
+/**********************************************************************
****
+ * pci_init_board()
+ *
+ * NOTICE: PCI2 is not currently supported
+ *
+ *********************************************************************/
+void pci_init_board(void)
+#ifdef CONFIG_PCISLAVE
+{
+ u16 reg16;
+ volatile immap_t *immr;
+ volatile law83xx_t *pci_law;
+ volatile pot83xx_t *pci_pot;
+ volatile pcictrl83xx_t *pci_ctrl;
+ volatile pciconf83xx_t *pci_conf;
+
+ immr = (immap_t *) CFG_IMMRBAR;
+ pci_law = immr->sysconf.pcilaw;
+ pci_pot = immr->ios.pot;
+ pci_ctrl = immr->pci_ctrl;
+ pci_conf = immr->pci_conf;
+ /*
+ * Configure PCI Inbound Translation Windows
+ */
+ pci_ctrl[0].pitar0 = 0x0;
+ pci_ctrl[0].pibar0 = 0x0;
+ pci_ctrl[0].piwar0 = PIWAR_EN | PIWAR_RTT_SNOOP |
+ PIWAR_WTT_SNOOP | PIWAR_IWS_4K;
+
+ pci_ctrl[0].pitar1 = 0x0;
+ pci_ctrl[0].pibar1 = 0x0;
+ pci_ctrl[0].piebar1 = 0x0;
+ pci_ctrl[0].piwar1 &= ~PIWAR_EN;
+
+ pci_ctrl[0].pitar2 = 0x0;
+ pci_ctrl[0].pibar2 = 0x0;
+ pci_ctrl[0].piebar2 = 0x0;
+ pci_ctrl[0].piwar2 &= ~PIWAR_EN;
+
+ hose[0].first_busno = 0;
+ hose[0].last_busno = 0xff;
+ pci_setup_indirect(&hose[0],
+ (CFG_IMMRBAR + 0x8300), (CFG_IMMRBAR +
0x8304));
+ reg16 = 0xff;
+
+ pci_hose_read_config_word(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_COMMAND, ®16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MEMORY;
+ pci_hose_write_config_word(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_COMMAND, reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ pci_hose_write_config_word(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_STATUS, 0xffff);
+ pci_hose_write_config_byte(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_LATENCY_TIMER, 0x80);
+
+ /*
+ * Unlock configuration lock in PCI function configuration
register.
+ */
+ pci_hose_read_config_word(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_FUNCTION_CONFIG, ®16);
+ reg16 &= ~(PCI_FUNCTION_CFG_LOCK);
+ pci_hose_write_config_word(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_FUNCTION_CONFIG, reg16);
+
+ printf("Enabled PCI 32bit Agent Mode\n");
+}
+#else
+{
+ volatile immap_t *immr;
+ volatile clk83xx_t *clk;
+ volatile law83xx_t *pci_law;
+ volatile pot83xx_t *pci_pot;
+ volatile pcictrl83xx_t *pci_ctrl;
+ volatile pciconf83xx_t *pci_conf;
+
+ u8 val8, ret;
+ u16 reg16;
+ u32 val32, tmp32;
+
+ immr = (immap_t *) CFG_IMMRBAR;
+ clk = (clk83xx_t *) & immr->clk;
+ pci_law = immr->sysconf.pcilaw;
+ pci_pot = immr->ios.pot;
+ pci_ctrl = immr->pci_ctrl;
+ pci_conf = immr->pci_conf;
+ /*
+ * Configure PCI controller and PCI_CLK_OUTPUT both in 66M mode
+ */
+ val32 = clk->occr;
+ udelay(2000);
+#if defined(PCI_66M)
+ clk->occr = OCCR_PCICOE0 | OCCR_PCICOE1 | OCCR_PCICOE2;
+ printf("PCI clock is 66MHz\n");
+#elif defined(PCI_33M)
+ clk->occr = OCCR_PCICOE0 | OCCR_PCICOE1 | OCCR_PCICOE2 |
+ OCCR_PCICD0 | OCCR_PCICD1 | OCCR_PCICD2 |
OCCR_PCICR;
+ printf("PCI clock is 33MHz\n");
+#else
+ clk->occr = OCCR_PCICOE0 | OCCR_PCICOE1 | OCCR_PCICOE2;
+ printf("PCI clock is 66MHz\n");
+#endif
+ udelay(2000);
+
+ /*
+ * Configure PCI Local Access Windows
+ */
+ pci_law[0].bar = CFG_PCI1_MEM_PHYS & LAWBAR_BAR;
+ pci_law[0].ar = LAWAR_EN | LAWAR_SIZE_1G;
+ pci_law[1].bar = CFG_PCI1_IO_PHYS & LAWBAR_BAR;
+ pci_law[1].ar = LAWAR_EN | LAWAR_SIZE_64M;
+
+ /*
+ * Configure PCI Outbound Translation Windows
+ */
+ pci_pot[0].potar = (CFG_PCI1_MEM_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[0].pobar = (CFG_PCI1_MEM_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[0].pocmr = POCMR_EN | (POCMR_CM_512M & POCMR_CM_MASK);
+
+ /* mapped to PCI1 IO space to local 0xD0000000 */
+ pci_pot[1].potar = (CFG_PCI1_IO_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[1].pobar = (CFG_PCI1_IO_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[1].pocmr = POCMR_EN | POCMR_IO | (POCMR_CM_64M &
POCMR_CM_MASK);
+ /*
+ * Configure PCI Inbound Translation Windows
+ */
+ pci_ctrl[0].pitar1 = (CFG_PCI_SLV_MEM_LOCAL >> 12) &
PITAR_TA_MASK;
+ pci_ctrl[0].pibar1 = (CFG_PCI_SLV_MEM_BUS >> 12) & PIBAR_MASK;
+ pci_ctrl[0].piebar1 = 0x0;
+ pci_ctrl[0].piwar1 =
+ PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP |
+ PIWAR_IWS_2G;
+
+ /*
+ * Assign PIB PMC slot to desired PCI bus
+ */
+ mpc83xx_i2c = (i2c_t *) (CFG_IMMRBAR + CFG_I2C2_OFFSET);
+ i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
+
+ val8 = 0;
+ ret = i2c_write(0x23, 0x6, 1, &val8, 1);
+ ret = i2c_write(0x23, 0x7, 1, &val8, 1);
+ val8 = 0xff;
+ ret = i2c_write(0x23, 0x2, 1, &val8, 1);
+ ret = i2c_write(0x23, 0x3, 1, &val8, 1);
+
+ val8 = 0;
+ ret = i2c_write(0x26, 0x6, 1, &val8, 1);
+ val8 = 0x34;
+ ret = i2c_write(0x26, 0x7, 1, &val8, 1);
+#if defined(PCI_64BIT)
+ val8 = 0xf4; /*PMC2<->PCI1 64bit */
+#elif defined(PCI_ALL_PCI1)
+ val8 = 0xf3; /*PMC1<->PCI1,PMC2<->PCI1,PMC3<->PCI1 32bit */
+#elif defined(PCI_ONE_PCI1)
+ val8 = 0xf9; /* PMC1<->PCI1,PMC2<->PCI2,PMC3<->PCI2 32bit */
+#elif defined(PCI_TWO_PCI1)
+ val8 = 0xf5; /* PMC1<->PCI1,PMC2<->PCI1,PMC3<->PCI2 32bit */
+#else
+ val8 = 0xf3;
+#endif
+ ret = i2c_write(0x26, 0x2, 1, &val8, 1);
+ val8 = 0xff;
+ ret = i2c_write(0x26, 0x3, 1, &val8, 1);
+
+ val8 = 0;
+ ret = i2c_write(0x27, 0x6, 1, &val8, 1);
+ ret = i2c_write(0x27, 0x7, 1, &val8, 1);
+ val8 = 0xff;
+ ret = i2c_write(0x27, 0x2, 1, &val8, 1);
+ val8 = 0xef;
+ ret = i2c_write(0x27, 0x3, 1, &val8, 1);
+ asm("eieio");
+
+ /*
+ * Release PCI RST Output signal
+ */
+ udelay(2000);
+ pci_ctrl[0].gcr = 1;
+ udelay(2000);
+
+ hose[0].first_busno = 0;
+ hose[0].last_busno = 0xff;
+
+ pci_set_region( hose[0].regions + 0,
+ CFG_PCI_SLV_MEM_LOCAL,
+ CFG_PCI_SLV_MEM_BUS,
+ CFG_PCI_SLV_MEM_SIZE,
+ PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+ pci_set_region( hose[0].regions + 1,
+ CFG_PCI1_MEM_BASE,
+ CFG_PCI1_MEM_PHYS,
+ CFG_PCI1_MEM_SIZE,
+ PCI_REGION_MEM);
+
+ pci_set_region( hose[0].regions + 2,
+ CFG_PCI1_IO_BASE,
+ CFG_PCI1_IO_PHYS,
+ CFG_PCI1_IO_SIZE,
+ PCI_REGION_IO);
+
+ hose[0].region_count = 3;
+
+ pci_setup_indirect(&hose[0],
+ (CFG_IMMRBAR + 0x8300),
+ (CFG_IMMRBAR + 0x8304));
+#define PCI_CLASS_BRIDGE 0x06
+ reg16 = 0xff;
+ tmp32 = 0xffff;
+ pci_hose_write_config_byte(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_CLASS_CODE, PCI_CLASS_BRIDGE);
+
+ pci_hose_read_config_word(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_COMMAND, ®16);
+
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER |
PCI_COMMAND_MEMORY;
+
+ pci_hose_write_config_word(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_COMMAND, reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ pci_hose_write_config_word(&hose[0], PCI_BDF(0, 0, 0),
PCI_STATUS,
+ 0xffff);
+ pci_hose_write_config_byte(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_LATENCY_TIMER, 0x80);
+
+#if defined(PCI_64BIT)
+ printf("PCI1 64bit on PMC2\n");
+#elif defined(PCI_ALL_PCI1)
+ printf("PCI1 32bit on PMC1 & PMC2 & PMC3\n");
+#elif defined(PCI_ONE_PCI1)
+ printf("PCI1 32bit on PMC1,PCI2 32bit on PMC2 & PMC3\n");
+#else
+ printf("PCI1 32bit on PMC1 & PMC2 & PMC3 in default\n");
+#endif
+
+ /*
+ * Hose scan.
+ */
+ pci_register_hose(hose);
+ hose->last_busno = pci_hose_scan(hose);
+}
+#endif /* CONFIG_PCISLAVE */
+#endif /* CONFIG_PCI */
diff --git a/board/mpc8360epb/u-boot.lds b/board/mpc8360epb/u-boot.lds
new file mode 100644
index 0000000..937c87a
--- /dev/null
+++ b/board/mpc8360epb/u-boot.lds
@@ -0,0 +1,123 @@
+/*
+ * (C) Copyright 2006
+ * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ cpu/mpc83xx/start.o (.text)
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ . = ALIGN(16);
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ *(.eh_frame)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x0FFF) & 0xFFFFF000;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+ __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+
+ . = .;
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(4096);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(4096);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
+ENTRY(_start)
--
1.3.GIT
More information about the U-Boot
mailing list