summaryrefslogtreecommitdiffstats
path: root/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'cpu')
-rw-r--r--cpu/arm720t/lpc2292/Makefile50
-rw-r--r--cpu/arm720t/lpc2292/flash.c249
-rw-r--r--cpu/arm720t/lpc2292/iap_entry.S7
-rw-r--r--cpu/arm720t/lpc2292/mmc.c157
-rw-r--r--cpu/arm720t/lpc2292/mmc_hw.c233
-rw-r--r--cpu/arm720t/lpc2292/mmc_hw.h29
-rw-r--r--cpu/arm720t/lpc2292/spi.c40
-rw-r--r--cpu/microblaze/Makefile2
-rwxr-xr-x[-rw-r--r--]cpu/microblaze/cache.c17
-rw-r--r--cpu/microblaze/dcache.S68
-rw-r--r--cpu/microblaze/disable_int.S46
-rw-r--r--cpu/microblaze/enable_int.S38
-rw-r--r--cpu/microblaze/exception.c10
-rw-r--r--cpu/microblaze/icache.S69
-rwxr-xr-x[-rw-r--r--]cpu/microblaze/interrupts.c30
-rwxr-xr-x[-rw-r--r--]cpu/microblaze/irq.S7
-rw-r--r--cpu/microblaze/start.S33
-rw-r--r--cpu/microblaze/timer.c4
-rw-r--r--cpu/mpc5xxx/cpu_init.c8
-rw-r--r--cpu/mpc5xxx/fec.c7
-rw-r--r--cpu/mpc83xx/Makefile2
-rw-r--r--cpu/mpc83xx/cpu.c39
-rw-r--r--cpu/mpc83xx/pci.c192
-rw-r--r--cpu/mpc83xx/spd_sdram.c11
-rw-r--r--cpu/mpc83xx/speed.c78
-rw-r--r--cpu/ppc4xx/44x_spd_ddr.c341
-rw-r--r--cpu/ppc4xx/44x_spd_ddr2.c7
-rw-r--r--cpu/ppc4xx/cpu.c8
-rw-r--r--cpu/ppc4xx/ndfc.c82
-rw-r--r--cpu/ppc4xx/start.S295
30 files changed, 1565 insertions, 594 deletions
diff --git a/cpu/arm720t/lpc2292/Makefile b/cpu/arm720t/lpc2292/Makefile
new file mode 100644
index 0000000..240f1e3
--- /dev/null
+++ b/cpu/arm720t/lpc2292/Makefile
@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2000-2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(SOC).a
+
+COBJS = flash.o mmc.o mmc_hw.o spi.o
+SOBJS = $(obj)iap_entry.o
+
+SRCS := $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS) $(SOBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+# this MUST be compiled as thumb code!
+$(SOBJS):
+ $(CC) $(AFLAGS) -march=armv4t -c -o $(SOBJS) iap_entry.S
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/arm720t/lpc2292/flash.c b/cpu/arm720t/lpc2292/flash.c
new file mode 100644
index 0000000..e5c8697
--- /dev/null
+++ b/cpu/arm720t/lpc2292/flash.c
@@ -0,0 +1,249 @@
+/*
+ * (C) Copyright 2006 Embedded Artists AB <www.embeddedartists.com>
+ *
+ * Modified to remove all but the IAP-command related code by
+ * Gary Jennejohn <garyj@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/arch/hardware.h>
+
+/* IAP commands use 32 bytes at the top of CPU internal sram, we
+ use 512 bytes below that */
+#define COPY_BUFFER_LOCATION 0x40003de0
+
+#define IAP_LOCATION 0x7ffffff1
+#define IAP_CMD_PREPARE 50
+#define IAP_CMD_COPY 51
+#define IAP_CMD_ERASE 52
+#define IAP_CMD_CHECK 53
+#define IAP_CMD_ID 54
+#define IAP_CMD_VERSION 55
+#define IAP_CMD_COMPARE 56
+
+#define IAP_RET_CMD_SUCCESS 0
+
+static unsigned long command[5];
+static unsigned long result[2];
+
+extern void iap_entry(unsigned long * command, unsigned long * result);
+
+/*-----------------------------------------------------------------------
+ *
+ */
+static int get_flash_sector(flash_info_t * info, ulong flash_addr)
+{
+ int i;
+
+ for(i = 1; i < (info->sector_count); i++) {
+ if (flash_addr < (info->start[i]))
+ break;
+ }
+
+ return (i-1);
+}
+
+/*-----------------------------------------------------------------------
+ * This function assumes that flash_addr is aligned on 512 bytes boundary
+ * in flash. This function also assumes that prepare have been called
+ * for the sector in question.
+ */
+int lpc2292_copy_buffer_to_flash(flash_info_t * info, ulong flash_addr)
+{
+ int first_sector;
+ int last_sector;
+
+ first_sector = get_flash_sector(info, flash_addr);
+ last_sector = get_flash_sector(info, flash_addr + 512 - 1);
+
+ /* prepare sectors for write */
+ command[0] = IAP_CMD_PREPARE;
+ command[1] = first_sector;
+ command[2] = last_sector;
+ iap_entry(command, result);
+ if (result[0] != IAP_RET_CMD_SUCCESS) {
+ printf("IAP prepare failed\n");
+ return ERR_PROG_ERROR;
+ }
+
+ command[0] = IAP_CMD_COPY;
+ command[1] = flash_addr;
+ command[2] = COPY_BUFFER_LOCATION;
+ command[3] = 512;
+ command[4] = CFG_SYS_CLK_FREQ >> 10;
+ iap_entry(command, result);
+ if (result[0] != IAP_RET_CMD_SUCCESS) {
+ printf("IAP copy failed\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int lpc2292_flash_erase (flash_info_t * info, int s_first, int s_last)
+{
+ int flag;
+ int prot;
+ int sect;
+
+ prot = 0;
+ for (sect = s_first; sect <= s_last; ++sect) {
+ if (info->protect[sect]) {
+ prot++;
+ }
+ }
+ if (prot)
+ return ERR_PROTECTED;
+
+
+ flag = disable_interrupts();
+
+ printf ("Erasing %d sectors starting at sector %2d.\n"
+ "This make take some time ... ",
+ s_last - s_first + 1, s_first);
+
+ command[0] = IAP_CMD_PREPARE;
+ command[1] = s_first;
+ command[2] = s_last;
+ iap_entry(command, result);
+ if (result[0] != IAP_RET_CMD_SUCCESS) {
+ printf("IAP prepare failed\n");
+ return ERR_PROTECTED;
+ }
+
+ command[0] = IAP_CMD_ERASE;
+ command[1] = s_first;
+ command[2] = s_last;
+ command[3] = CFG_SYS_CLK_FREQ >> 10;
+ iap_entry(command, result);
+ if (result[0] != IAP_RET_CMD_SUCCESS) {
+ printf("IAP erase failed\n");
+ return ERR_PROTECTED;
+ }
+
+ if (flag)
+ enable_interrupts();
+
+ return ERR_OK;
+}
+
+int lpc2292_write_buff (flash_info_t * info, uchar * src, ulong addr,
+ ulong cnt)
+{
+ int first_copy_size;
+ int last_copy_size;
+ int first_block;
+ int last_block;
+ int nbr_mid_blocks;
+ uchar memmap_value;
+ ulong i;
+ uchar* src_org;
+ uchar* dst_org;
+ int ret = ERR_OK;
+
+ src_org = src;
+ dst_org = (uchar*)addr;
+
+ first_block = addr / 512;
+ last_block = (addr + cnt) / 512;
+ nbr_mid_blocks = last_block - first_block - 1;
+
+ first_copy_size = 512 - (addr % 512);
+ last_copy_size = (addr + cnt) % 512;
+
+ debug("\ncopy first block: (1) %lX -> %lX 0x200 bytes, "
+ "(2) %lX -> %lX 0x%X bytes, (3) %lX -> %lX 0x200 bytes\n",
+ (ulong)(first_block * 512),
+ (ulong)COPY_BUFFER_LOCATION,
+ (ulong)src,
+ (ulong)(COPY_BUFFER_LOCATION + 512 - first_copy_size),
+ first_copy_size,
+ (ulong)COPY_BUFFER_LOCATION,
+ (ulong)(first_block * 512));
+
+ /* copy first block */
+ memcpy((void*)COPY_BUFFER_LOCATION,
+ (void*)(first_block * 512), 512);
+ memcpy((void*)(COPY_BUFFER_LOCATION + 512 - first_copy_size),
+ src, first_copy_size);
+ lpc2292_copy_buffer_to_flash(info, first_block * 512);
+ src += first_copy_size;
+ addr += first_copy_size;
+
+ /* copy middle blocks */
+ for (i = 0; i < nbr_mid_blocks; i++) {
+ debug("copy middle block: %lX -> %lX 512 bytes, "
+ "%lX -> %lX 512 bytes\n",
+ (ulong)src,
+ (ulong)COPY_BUFFER_LOCATION,
+ (ulong)COPY_BUFFER_LOCATION,
+ (ulong)addr);
+
+ memcpy((void*)COPY_BUFFER_LOCATION, src, 512);
+ lpc2292_copy_buffer_to_flash(info, addr);
+ src += 512;
+ addr += 512;
+ }
+
+
+ if (last_copy_size > 0) {
+ debug("copy last block: (1) %lX -> %lX 0x200 bytes, "
+ "(2) %lX -> %lX 0x%X bytes, (3) %lX -> %lX x200 bytes\n",
+ (ulong)(last_block * 512),
+ (ulong)COPY_BUFFER_LOCATION,
+ (ulong)src,
+ (ulong)(COPY_BUFFER_LOCATION),
+ last_copy_size,
+ (ulong)COPY_BUFFER_LOCATION,
+ (ulong)addr);
+
+ /* copy last block */
+ memcpy((void*)COPY_BUFFER_LOCATION,
+ (void*)(last_block * 512), 512);
+ memcpy((void*)COPY_BUFFER_LOCATION,
+ src, last_copy_size);
+ lpc2292_copy_buffer_to_flash(info, addr);
+ }
+
+ /* verify write */
+ memmap_value = GET8(MEMMAP);
+
+ disable_interrupts();
+
+ PUT8(MEMMAP, 01); /* we must make sure that initial 64
+ bytes are taken from flash when we
+ do the compare */
+
+ for (i = 0; i < cnt; i++) {
+ if (*dst_org != *src_org){
+ printf("Write failed. Byte %lX differs\n", i);
+ ret = ERR_PROG_ERROR;
+ break;
+ }
+ dst_org++;
+ src_org++;
+ }
+
+ PUT8(MEMMAP, memmap_value);
+ enable_interrupts();
+
+ return ret;
+}
diff --git a/cpu/arm720t/lpc2292/iap_entry.S b/cpu/arm720t/lpc2292/iap_entry.S
new file mode 100644
index 0000000..c31d519
--- /dev/null
+++ b/cpu/arm720t/lpc2292/iap_entry.S
@@ -0,0 +1,7 @@
+IAP_ADDRESS: .word 0x7FFFFFF1
+
+.globl iap_entry
+iap_entry:
+ ldr r2, IAP_ADDRESS
+ bx r2
+ mov pc, lr
diff --git a/cpu/arm720t/lpc2292/mmc.c b/cpu/arm720t/lpc2292/mmc.c
new file mode 100644
index 0000000..fd7f149
--- /dev/null
+++ b/cpu/arm720t/lpc2292/mmc.c
@@ -0,0 +1,157 @@
+/*
+ * 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 <config.h>
+#include <common.h>
+#include <mmc.h>
+#include <asm/errno.h>
+#include <asm/arch/hardware.h>
+#include <part.h>
+#include <fat.h>
+#include "mmc_hw.h"
+#include <asm/arch/spi.h>
+
+#ifdef CONFIG_MMC
+
+#undef MMC_DEBUG
+
+static block_dev_desc_t mmc_dev;
+
+/* these are filled out by a call to mmc_hw_get_parameters */
+static int hw_size; /* in kbytes */
+static int hw_nr_sects;
+static int hw_sect_size; /* in bytes */
+
+block_dev_desc_t * mmc_get_dev(int dev)
+{
+ return (block_dev_desc_t *)(&mmc_dev);
+}
+
+unsigned long mmc_block_read(int dev,
+ unsigned long start,
+ lbaint_t blkcnt,
+ void *buffer)
+{
+ unsigned long rc = 0;
+ unsigned char *p = (unsigned char *)buffer;
+ unsigned long i;
+ unsigned long addr = start;
+
+#ifdef MMC_DEBUG
+ printf("mmc_block_read: start=%lu, blkcnt=%lu\n", start,
+ (unsigned long)blkcnt);
+#endif
+
+ for(i = 0; i < (unsigned long)blkcnt; i++) {
+#ifdef MMC_DEBUG
+ printf("mmc_read_sector: addr=%lu, buffer=%p\n", addr, p);
+#endif
+ (void)mmc_read_sector(addr, p);
+ rc++;
+ addr++;
+ p += hw_sect_size;
+ }
+
+ return rc;
+}
+
+/*-----------------------------------------------------------------------------
+ * Read hardware paramterers (sector size, size, number of sectors)
+ */
+static int mmc_hw_get_parameters(void)
+{
+ unsigned char csddata[16];
+ unsigned int sizemult;
+ unsigned int size;
+
+ mmc_read_csd(csddata);
+ hw_sect_size = 1<<(csddata[5] & 0x0f);
+ size = ((csddata[6]&0x03)<<10)+(csddata[7]<<2)+(csddata[8]&0xc0);
+ sizemult = ((csddata[10] & 0x80)>>7)+((csddata[9] & 0x03)<<1);
+ hw_nr_sects = (size+1)*(1<<(sizemult+2));
+ hw_size = hw_nr_sects*hw_sect_size/1024;
+
+#ifdef MMC_DEBUG
+ printf("mmc_hw_get_parameters: hw_sect_size=%d, hw_nr_sects=%d, "
+ "hw_size=%d\n", hw_sect_size, hw_nr_sects, hw_size);
+#endif
+
+ return 0;
+}
+
+int mmc_init(int verbose)
+{
+ int ret = -ENODEV;
+
+ if (verbose)
+ printf("mmc_init\n");
+
+ spi_init();
+ /* this meeds to be done twice */
+ mmc_hw_init();
+ udelay(1000);
+ mmc_hw_init();
+
+ mmc_hw_get_parameters();
+
+ mmc_dev.if_type = IF_TYPE_MMC;
+ mmc_dev.part_type = PART_TYPE_DOS;
+ mmc_dev.dev = 0;
+ mmc_dev.lun = 0;
+ mmc_dev.type = 0;
+ mmc_dev.blksz = hw_sect_size;
+ mmc_dev.lba = hw_nr_sects;
+ sprintf((char*)mmc_dev.vendor, "Unknown vendor");
+ sprintf((char*)mmc_dev.product, "Unknown product");
+ sprintf((char*)mmc_dev.revision, "N/A");
+ mmc_dev.removable = 0; /* should be true??? */
+ mmc_dev.block_read = mmc_block_read;
+
+ fat_register_device(&mmc_dev, 1);
+
+ ret = 0;
+
+ return ret;
+}
+
+int mmc_write(uchar * src, ulong dst, int size)
+{
+#ifdef MMC_DEBUG
+ printf("mmc_write: src=%p, dst=%lu, size=%u\n", src, dst, size);
+#endif
+ /* Since mmc2info always returns 0 this function will never be called */
+ return 0;
+}
+
+int mmc_read(ulong src, uchar * dst, int size)
+{
+#ifdef MMC_DEBUG
+ printf("mmc_read: src=%lu, dst=%p, size=%u\n", src, dst, size);
+#endif
+ /* Since mmc2info always returns 0 this function will never be called */
+ return 0;
+}
+
+int mmc2info(ulong addr)
+{
+ /* This function is used by cmd_cp to determine if source or destination
+ address resides on MMC-card or not. We do not support copy to and from
+ MMC-card so we always return 0. */
+ return 0;
+}
+
+#endif /* CONFIG_MMC */
diff --git a/cpu/arm720t/lpc2292/mmc_hw.c b/cpu/arm720t/lpc2292/mmc_hw.c
new file mode 100644
index 0000000..b4dc4a6
--- /dev/null
+++ b/cpu/arm720t/lpc2292/mmc_hw.c
@@ -0,0 +1,233 @@
+/*
+ This code was original written by Ulrich Radig and modified by
+ Embedded Artists AB (www.embeddedartists.com).
+
+ 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 <config.h>
+#include <common.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/spi.h>
+
+#define MMC_Enable() PUT32(IO1CLR, 1l << 22)
+#define MMC_Disable() PUT32(IO1SET, 1l << 22)
+#define mmc_spi_cfg() spi_set_clock(8); spi_set_cfg(0, 1, 0);
+
+static unsigned char Write_Command_MMC (unsigned char *CMD);
+static void MMC_Read_Block(unsigned char *CMD, unsigned char *Buffer,
+ unsigned short int Bytes);
+
+/* initialize the hardware */
+int mmc_hw_init(void)
+{
+ unsigned long a;
+ unsigned short int Timeout = 0;
+ unsigned char b;
+ unsigned char CMD[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x95};
+
+ /* set-up GPIO and SPI */
+ (*((volatile unsigned long *)PINSEL2)) &= ~(1l << 3); /* clear bit 3 */
+ (*((volatile unsigned long *)IO1DIR)) |= (1l << 22); /* set bit 22 (output) */
+
+ MMC_Disable();
+
+ spi_lock();
+ spi_set_clock(248);
+ spi_set_cfg(0, 1, 0);
+ MMC_Enable();
+
+ /* waste some time */
+ for(a=0; a < 20000; a++)
+ asm("nop");
+
+ /* Put the MMC/SD-card into SPI-mode */
+ for (b = 0; b < 10; b++) /* Sends min 74+ clocks to the MMC/SD-card */
+ spi_write(0xff);
+
+ /* Sends command CMD0 to MMC/SD-card */
+ while (Write_Command_MMC(CMD) != 1) {
+ if (Timeout++ > 200) {
+ MMC_Disable();
+ spi_unlock();
+ return(1); /* Abort with command 1 (return 1) */
+ }
+ }
+ /* Sends Command CMD1 an MMC/SD-card */
+ Timeout = 0;
+ CMD[0] = 0x41;/* Command 1 */
+ CMD[5] = 0xFF;
+
+ while (Write_Command_MMC(CMD) != 0) {
+ if (Timeout++ > 200) {
+ MMC_Disable();
+ spi_unlock();
+ return (2); /* Abort with command 2 (return 2) */
+ }
+ }
+
+ MMC_Disable();
+ spi_unlock();
+
+ return 0;
+}
+
+/* ############################################################################
+ Sends a command to the MMC/SD-card
+ ######################################################################### */
+static unsigned char Write_Command_MMC (unsigned char *CMD)
+{
+ unsigned char a, tmp = 0xff;
+ unsigned short int Timeout = 0;
+
+ MMC_Disable();
+ spi_write(0xFF);
+ MMC_Enable();
+
+ for (a = 0; a < 0x06; a++)
+ spi_write(*CMD++);
+
+ while (tmp == 0xff) {
+ tmp = spi_read();
+ if (Timeout++ > 5000)
+ break;
+ }
+
+ return (tmp);
+}
+
+/* ############################################################################
+ Routine to read the CID register from the MMC/SD-card (16 bytes)
+ ######################################################################### */
+void MMC_Read_Block(unsigned char *CMD, unsigned char *Buffer, unsigned short
+ int Bytes)
+{
+ unsigned short int a;
+
+ spi_lock();
+ mmc_spi_cfg();
+ MMC_Enable();
+
+ if (Write_Command_MMC(CMD) != 0) {
+ MMC_Disable();
+ spi_unlock();
+ return;
+ }
+
+ while (spi_read() != 0xfe) {};
+ for (a = 0; a < Bytes; a++)
+ *Buffer++ = spi_read();
+
+ /* Read the CRC-byte */
+ spi_read(); /* CRC - byte is discarded */
+ spi_read(); /* CRC - byte is discarded */
+ /* set MMC_Chip_Select to high (MMC/SD-card Inaktiv) */
+ MMC_Disable();
+ spi_unlock();
+
+ return;
+}
+
+/* ############################################################################
+ Routine to read a block (512 bytes) from the MMC/SD-card
+ ######################################################################### */
+unsigned char mmc_read_sector (unsigned long addr,unsigned char *Buffer)
+{
+ /* Command 16 to read aBlocks from the MMC/SD - caed */
+ unsigned char CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
+
+ /* The addres on the MMC/SD-card is in bytes,
+ addr is transformed from blocks to bytes and the result is
+ placed into the command */
+
+ addr = addr << 9; /* addr = addr * 512 */
+
+ CMD[1] = ((addr & 0xFF000000) >> 24);
+ CMD[2] = ((addr & 0x00FF0000) >> 16);
+ CMD[3] = ((addr & 0x0000FF00) >> 8 );
+
+ MMC_Read_Block(CMD, Buffer, 512);
+
+ return (0);
+}
+
+/* ############################################################################
+ Routine to write a block (512 byte) to the MMC/SD-card
+ ######################################################################### */
+unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer)
+{
+ unsigned char tmp, a;
+ unsigned short int b;
+ /* Command 24 to write a block to the MMC/SD - card */
+ unsigned char CMD[] = {0x58, 0x00, 0x00, 0x00, 0x00, 0xFF};
+
+ /* The addres on the MMC/SD-card is in bytes,
+ addr is transformed from blocks to bytes and the result is
+ placed into the command */
+
+ addr = addr << 9; /* addr = addr * 512 */
+
+ CMD[1] = ((addr & 0xFF000000) >> 24);
+ CMD[2] = ((addr & 0x00FF0000) >> 16);
+ CMD[3] = ((addr & 0x0000FF00) >> 8 );
+
+ spi_lock();
+ mmc_spi_cfg();
+ MMC_Enable();
+
+ /* Send command CMD24 to the MMC/SD-card (Write 1 Block/512 Bytes) */
+ tmp = Write_Command_MMC(CMD);
+ if (tmp != 0) {
+ MMC_Disable();
+ spi_unlock();
+ return(tmp);
+ }
+
+ /* Do a short delay and send a clock-pulse to the MMC/SD-card */
+ for (a = 0; a < 100; a++)
+ spi_read();
+
+ /* Send a start byte to the MMC/SD-card */
+ spi_write(0xFE);
+
+ /* Write the block (512 bytes) to the MMC/SD-card */
+ for (b = 0; b < 512; b++)
+ spi_write(*Buffer++);
+
+ /* write the CRC-Byte */
+ spi_write(0xFF); /* write a dummy CRC */
+ spi_write(0xFF); /* CRC code is not used */
+
+ /* Wait for MMC/SD-card busy */
+ while (spi_read() != 0xff) {};
+
+ /* set MMC_Chip_Select to high (MMC/SD-card inactive) */
+ MMC_Disable();
+ spi_unlock();
+ return (0);
+}
+
+/* #########################################################################
+ Routine to read the CSD register from the MMC/SD-card (16 bytes)
+ ######################################################################### */
+unsigned char mmc_read_csd (unsigned char *Buffer)
+{
+ /* Command to read the CSD register */
+ unsigned char CMD[] = {0x49, 0x00, 0x00, 0x00, 0x00, 0xFF};
+
+ MMC_Read_Block(CMD, Buffer, 16);
+
+ return (0);
+}
diff --git a/cpu/arm720t/lpc2292/mmc_hw.h b/cpu/arm720t/lpc2292/mmc_hw.h
new file mode 100644
index 0000000..3687dbf
--- /dev/null
+++ b/cpu/arm720t/lpc2292/mmc_hw.h
@@ -0,0 +1,29 @@
+/*
+ This module implements a linux character device driver for the 24c256 chip.
+ Copyright (C) 2006 Embedded Artists AB (www.embeddedartists.com)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _MMC_HW_
+#define _MMC_HW_
+
+unsigned char mmc_read_csd(unsigned char *Buffer);
+unsigned char mmc_read_sector (unsigned long addr,
+ unsigned char *Buffer);
+unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer);
+int mmc_hw_init(void);
+
+#endif /* _MMC_HW_ */
diff --git a/cpu/arm720t/lpc2292/spi.c b/cpu/arm720t/lpc2292/spi.c
new file mode 100644
index 0000000..d296bda
--- /dev/null
+++ b/cpu/arm720t/lpc2292/spi.c
@@ -0,0 +1,40 @@
+/*
+ This module implements an interface to the SPI on the lpc22xx.
+ Copyright (C) 2006 Embedded Artists AB (www.embeddedartists.com)
+
+ 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 <config.h>
+#include <common.h>
+#include <asm/errno.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/spi.h>
+
+unsigned long spi_flags;
+unsigned char spi_idle = 0x00;
+
+int spi_init(void)
+{
+ unsigned long pinsel0_value;
+
+ /* activate spi pins */
+ pinsel0_value = GET32(PINSEL0);
+ pinsel0_value &= ~(0xFFl << 8);
+ pinsel0_value |= (0x55l << 8);
+ PUT32(PINSEL0, pinsel0_value);
+
+ return 0;
+}
diff --git a/cpu/microblaze/Makefile b/cpu/microblaze/Makefile
index db1afa5..9d54201 100644
--- a/cpu/microblaze/Makefile
+++ b/cpu/microblaze/Makefile
@@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(CPU).a
START = start.o
-SOBJS = dcache.o icache.o irq.o disable_int.o enable_int.o
+SOBJS = irq.o
COBJS = cpu.o interrupts.o cache.o exception.o timer.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/cpu/microblaze/cache.c b/cpu/microblaze/cache.c
index fc388eb..4f36a84 100644..100755
--- a/cpu/microblaze/cache.c
+++ b/cpu/microblaze/cache.c
@@ -23,6 +23,7 @@
*/
#include <common.h>
+#include <asm/asm.h>
#if (CONFIG_COMMANDS & CFG_CMD_CACHE)
@@ -45,4 +46,20 @@ int icache_status (void)
__asm__ __volatile__ ("and %0,%0,%1"::"r" (i), "r" (mask):"memory");
return i;
}
+
+void icache_enable (void) {
+ MSRSET(0x20);
+}
+
+void icache_disable(void) {
+ MSRCLR(0x20);
+}
+
+void dcache_enable (void) {
+ MSRSET(0x80);
+}
+
+void dcache_disable(void) {
+ MSRCLR(0x80);
+}
#endif
diff --git a/cpu/microblaze/dcache.S b/cpu/microblaze/dcache.S
deleted file mode 100644
index eaf9671..0000000
--- a/cpu/microblaze/dcache.S
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * (C) Copyright 2007 Michal Simek
- *
- * Michal SIMEK <monstr@monstr.eu>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
- .text
- .globl dcache_enable
- .ent dcache_enable
- .align 2
-dcache_enable:
- /* Make space on stack for a temporary */
- addi r1, r1, -4
- /* Save register r12 */
- swi r12, r1, 0
- /* Read the MSR register */
- mfs r12, rmsr
- /* Set the instruction enable bit */
- ori r12, r12, 0x80
- /* Save the MSR register */
- mts rmsr, r12
- /* Load register r12 */
- lwi r12, r1, 0
- /* Return */
- rtsd r15, 8
- /* Update stack in the delay slot */
- addi r1, r1, 4
- .end dcache_enable
-
- .text
- .globl dcache_disable
- .ent dcache_disable
- .align 2
-dcache_disable:
- /* Make space on stack for a temporary */
- addi r1, r1, -4
- /* Save register r12 */
- swi r12, r1, 0
- /* Read the MSR register */
- mfs r12, rmsr
- /* Clear the data cache enable bit */
- andi r12, r12, ~0x80
- /* Save the MSR register */
- mts rmsr, r12
- /* Load register r12 */
- lwi r12, r1, 0
- /* Return */
- rtsd r15, 8
- /* Update stack in the delay slot */
- addi r1, r1, 4
- .end dcache_disable
diff --git a/cpu/microblaze/disable_int.S b/cpu/microblaze/disable_int.S
deleted file mode 100644
index aecd795..0000000
--- a/cpu/microblaze/disable_int.S
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * (C) Copyright 2007 Michal Simek
- *
- * Michal SIMEK <monstr@monstr.eu>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
- .text
- .globl microblaze_disable_interrupts
- .ent microblaze_disable_interrupts
- .align 2
-microblaze_disable_interrupts:
- #Make space on stack for a temporary
- addi r1, r1, -4
- #Save register r12
- swi r12, r1, 0
- #Read the MSR register
- mfs r12, rmsr
- #Clear the interrupt enable bit
- andi r12, r12, ~2
- #Save the MSR register
- mts rmsr, r12
- #Load register r12
- lwi r12, r1, 0
- #Return
- rtsd r15, 8
- #Update stack in the delay slot
- addi r1, r1, 4
- .end microblaze_disable_interrupts
diff --git a/cpu/microblaze/enable_int.S b/cpu/microblaze/enable_int.S
deleted file mode 100644
index c096c6c..0000000
--- a/cpu/microblaze/enable_int.S
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * (C) Copyright 2007 Michal Simek
- *
- * Michal SIMEK <monstrmonstr.eu>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
- .text
- .globl microblaze_enable_interrupts
- .ent microblaze_enable_interrupts
- .align 2
-microblaze_enable_interrupts:
- addi r1, r1, -4
- swi r12, r1, 0
- mfs r12, rmsr
- ori r12, r12, 2
- mts rmsr, r12
- lwi r12, r1, 0
- rtsd r15, 8
- addi r1, r1, 4
- .end microblaze_enable_interrupts
diff --git a/cpu/microblaze/exception.c b/cpu/microblaze/exception.c
index b135acb..d76b05a 100644
--- a/cpu/microblaze/exception.c
+++ b/cpu/microblaze/exception.c
@@ -23,15 +23,16 @@
*/
#include <common.h>
+#include <asm/asm.h>
void _hw_exception_handler (void)
{
int address = 0;
int state = 0;
/* loading address of exception EAR */
- __asm__ __volatile ("mfs %0,rear"::"r" (address):"memory");
+ MFS (address, rear);
/* loading excetpion state register ESR */
- __asm__ __volatile ("mfs %0,resr"::"r" (state):"memory");
+ MFS (state, resr);
printf ("Hardware exception at 0x%x address\n", address);
switch (state & 0x1f) { /* mask on exception cause */
case 0x1:
@@ -49,6 +50,11 @@ void _hw_exception_handler (void)
case 0x5:
puts ("Divide by zero exception\n");
break;
+#ifdef MICROBLAZE_V5
+ case 0x1000:
+ puts ("Exception in delay slot\n");
+ break;
+#endif
default:
puts ("Undefined cause\n");
break;
diff --git a/cpu/microblaze/icache.S b/cpu/microblaze/icache.S
deleted file mode 100644
index 25940d1..0000000
--- a/cpu/microblaze/icache.S
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * (C) Copyright 2007 Michal Simek
- *
- * Michal SIMEK <monstr@monstr.eu>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
- .text
- .globl icache_enable
- .ent icache_enable
- .align 2
-icache_enable:
- /* Make space on stack for a temporary */
- addi r1, r1, -4
- /* Save register r12 */
- swi r12, r1, 0
- /* Read the MSR register */
- mfs r12, rmsr
- /* Set the instruction enable bit */
- ori r12, r12, 0x20
- /* Save the MSR register */
- mts rmsr, r12
- /* Load register r12 */
- lwi r12, r1, 0
- /* Return */
- rtsd r15, 8
- /* Update stack in the delay slot */
- addi r1, r1, 4
- .end icache_enable
-
- .text
- .globl icache_disable
- .ent icache_disable
- .align 2
-icache_disable:
- /* Make space on stack for a temporary */
- addi r1, r1, -4
- /* Save register r12 */
- swi r12, r1, 0
- /* Read the MSR register */
- mfs r12, rmsr
- /* Clear the instruction enable bit */
- andi r12, r12, ~0x20
- /* Save the MSR register */
- mts rmsr, r12
- /* Load register r12 */
- lwi r12, r1, 0
- /* Return */
- rtsd r15, 8
- /* Update stack in the delay slot */
- addi r1, r1, 4
- .end icache_disable
diff --git a/cpu/microblaze/interrupts.c b/cpu/microblaze/interrupts.c
index 2db847c..b61153f 100644..100755
--- a/cpu/microblaze/interrupts.c
+++ b/cpu/microblaze/interrupts.c
@@ -27,6 +27,7 @@
#include <common.h>
#include <command.h>
#include <asm/microblaze_intc.h>
+#include <asm/asm.h>
#undef DEBUG_INT
@@ -35,12 +36,12 @@ extern void microblaze_enable_interrupts (void);
void enable_interrupts (void)
{
- microblaze_enable_interrupts ();
+ MSRSET(0x2);
}
int disable_interrupts (void)
{
- microblaze_disable_interrupts ();
+ MSRCLR(0x2);
return 0;
}
@@ -48,6 +49,10 @@ int disable_interrupts (void)
#ifdef CFG_TIMER_0
extern void timer_init (void);
#endif
+#ifdef CFG_FSL_2
+extern void fsl_init2 (void);
+#endif
+
static struct irq_action vecs[CFG_INTC_0_NUM];
@@ -106,7 +111,6 @@ void install_interrupt_handler (int irq, interrupt_handler_t * hdlr, void *arg)
act->count = 0;
enable_one_interrupt (irq);
} else { /* disable */
-
act->handler = (interrupt_handler_t *) def_hdlr;
act->arg = (void *)irq;
disable_one_interrupt (irq);
@@ -141,18 +145,22 @@ int interrupts_init (void)
#ifdef CFG_TIMER_0
timer_init ();
#endif
+#ifdef CFG_FSL_2
+ fsl_init2 ();
+#endif
enable_interrupts ();
return 0;
}
void interrupt_handler (void)
{
- int irqs;
- irqs = (intc->isr & intc->ier); /* find active interrupt */
-
+ int irqs = (intc->isr & intc->ier); /* find active interrupt */
+ int i = 1;
#ifdef DEBUG_INT
+ int value;
printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier,
intc->iar, intc->mer);
+ R14(value);
printf ("Interrupt handler on %x line, r14 %x\n", irqs, value);
#endif
struct irq_action *act = vecs;
@@ -165,15 +173,19 @@ void interrupt_handler (void)
#endif
act->handler (act->arg);
act->count++;
+ intc->iar = i;
+ return;
}
irqs >>= 1;
act++;
+ i <<= 1;
}
- intc->iar = 0xFFFFFFFF; /* erase all events */
-#ifdef DEBUG
+
+#ifdef DEBUG_INT
printf ("Dump INTC reg, isr %x, ier %x, iar %x, mer %x\n", intc->isr,
intc->ier, intc->iar, intc->mer);
- printf ("Interrupt handler on %x line, r14\n", irqs);
+ R14(value);
+ printf ("Interrupt handler on %x line, r14 %x\n", irqs, value);
#endif
}
#endif
diff --git a/cpu/microblaze/irq.S b/cpu/microblaze/irq.S
index a4e3fbf..e1fc190 100644..100755
--- a/cpu/microblaze/irq.S
+++ b/cpu/microblaze/irq.S
@@ -23,6 +23,7 @@
*/
#include <config.h>
+#include <asm/asm.h>
.text
.global _interrupt_handler
_interrupt_handler:
@@ -151,6 +152,11 @@ _interrupt_handler:
addi r1, r1, 4
/* enable_interrupt */
+#ifdef XILINX_USE_MSR_INSTR
+ msrset r0, 2
+#else
+ /* FIXME unstable in stressed mode - two irqs */
+ nop
addi r1, r1, -4
swi r12, r1, 0
mfs r12, rmsr
@@ -159,6 +165,7 @@ _interrupt_handler:
lwi r12, r1, 0
addi r1, r1, 4
nop
+#endif
bra r14
nop
nop
diff --git a/cpu/microblaze/start.S b/cpu/microblaze/start.S
index ca3befc..3c027ff 100644
--- a/cpu/microblaze/start.S
+++ b/cpu/microblaze/start.S
@@ -117,3 +117,36 @@ clear_bss:
3: /* jumping to board_init */
brai board_init
1: bri 1b
+
+/*
+ * Read 16bit little endian
+ */
+ .text
+ .global in16
+ .ent in16
+ .align 2
+in16: lhu r3, r0, r5
+ bslli r4, r3, 8
+ bsrli r3, r3, 8
+ andi r4, r4, 0xffff
+ or r3, r3, r4
+ rtsd r15, 8
+ sext16 r3, r3
+ .end in16
+
+/*
+ * Write 16bit little endian
+ * first parameter(r5) - address, second(r6) - short value
+ */
+ .text
+ .global out16
+ .ent out16
+ .align 2
+out16: bslli r3, r6, 8
+ bsrli r6, r6, 8
+ andi r3, r3, 0xffff
+ or r3, r3, r6
+ sh r3, r0, r5
+ rtsd r15, 8
+ or r0, r0, r0
+ .end out16
diff --git a/cpu/microblaze/timer.c b/cpu/microblaze/timer.c
index be4fd57..ab1cb12 100644
--- a/cpu/microblaze/timer.c
+++ b/cpu/microblaze/timer.c
@@ -24,6 +24,7 @@
#include <common.h>
#include <asm/microblaze_timer.h>
+#include <asm/microblaze_intc.h>
volatile int timestamp = 0;
@@ -44,9 +45,6 @@ void set_timer (ulong t)
#ifdef CFG_INTC_0
#ifdef CFG_TIMER_0
-extern void install_interrupt_handler (int irq, interrupt_handler_t * hdlr,
- void *arg);
-
microblaze_timer_t *tmr = (microblaze_timer_t *) (CFG_TIMER_0_ADDR);
void timer_isr (void *arg)
diff --git a/cpu/mpc5xxx/cpu_init.c b/cpu/mpc5xxx/cpu_init.c
index 7e65821..d744030 100644
--- a/cpu/mpc5xxx/cpu_init.c
+++ b/cpu/mpc5xxx/cpu_init.c
@@ -156,21 +156,21 @@ void cpu_init_f (void)
*(vu_long *)(MPC5XXX_XLBARB + 0x40) |= (1 << 15);
*(vu_long *)(MPC5XXX_XLBARB + 0x70) = CFG_SDRAM_BASE | 0x1d;
-# if defined(CFG_IPBSPEED_133)
+# if defined(CFG_IPBCLK_EQUALS_XLBCLK)
/* Motorola reports IPB should better run at 133 MHz. */
*(vu_long *)MPC5XXX_ADDECR |= 1;
/* pci_clk_sel = 0x02, ipb_clk_sel = 0x00; */
addecr = *(vu_long *)MPC5XXX_CDM_CFG;
addecr &= ~0x103;
-# if defined(CFG_PCISPEED_66)
+# if defined(CFG_PCICLK_EQUALS_IPBCLK_DIV2)
/* pci_clk_sel = 0x01 -> IPB_CLK/2 */
addecr |= 0x01;
# else
/* pci_clk_sel = 0x02 -> XLB_CLK/4 = IPB_CLK/4 */
addecr |= 0x02;
-# endif /* CFG_PCISPEED_66 */
+# endif /* CFG_PCICLK_EQUALS_IPBCLK_DIV2 */
*(vu_long *)MPC5XXX_CDM_CFG = addecr;
-# endif /* CFG_IPBSPEED_133 */
+# endif /* CFG_IPBCLK_EQUALS_XLBCLK */
/* Configure the XLB Arbiter */
*(vu_long *)MPC5XXX_XLBARB_MPRIEN = 0xff;
*(vu_long *)MPC5XXX_XLBARB_MPRIVAL = 0x11111111;
diff --git a/cpu/mpc5xxx/fec.c b/cpu/mpc5xxx/fec.c
index e59bd85..8136366 100644
--- a/cpu/mpc5xxx/fec.c
+++ b/cpu/mpc5xxx/fec.c
@@ -428,6 +428,13 @@ static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis)
*/
fec->eth->imask = 0x00000000;
+/*
+ * In original Promess-provided code PHY initialization is disabled with the
+ * following comment: "Phy initialization is DISABLED for now. There was a
+ * problem with running 100 Mbps on PRO board". Thus we temporarily disable
+ * PHY initialization for the Motion-PRO board, until a proper fix is found.
+ */
+
if (fec->xcv_type != SEVENWIRE) {
/*
* Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
diff --git a/cpu/mpc83xx/Makefile b/cpu/mpc83xx/Makefile
index 4b9dcc8..bb96f77 100644
--- a/cpu/mpc83xx/Makefile
+++ b/cpu/mpc83xx/Makefile
@@ -29,7 +29,7 @@ LIB = $(obj)lib$(CPU).a
START = start.o
COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o \
- spd_sdram.o qe_io.o
+ spd_sdram.o qe_io.o pci.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c
index e934ba6..e078f27 100644
--- a/cpu/mpc83xx/cpu.c
+++ b/cpu/mpc83xx/cpu.c
@@ -52,13 +52,26 @@ int checkcpu(void)
immr = (immap_t *)CFG_IMMR;
- if ((pvr & 0xFFFF0000) != PVR_83xx) {
- puts("Not MPC83xx Family!!!\n");
- return -1;
+ puts("CPU: ");
+
+ switch (pvr & 0xffff0000) {
+ case PVR_E300C1:
+ printf("e300c1, ");
+ break;
+
+ case PVR_E300C2:
+ printf("e300c2, ");
+ break;
+
+ case PVR_E300C3:
+ printf("e300c3, ");
+ break;
+
+ default:
+ printf("Unknown core, ");
}
spridr = immr->sysconf.spridr;
- puts("CPU: ");
switch(spridr) {
case SPR_8349E_REV10:
case SPR_8349E_REV11:
@@ -124,6 +137,18 @@ int checkcpu(void)
case SPR_8321_REV11:
puts("MPC8321, ");
break;
+ case SPR_8311_REV10:
+ puts("MPC8311, ");
+ break;
+ case SPR_8311E_REV10:
+ puts("MPC8311E, ");
+ break;
+ case SPR_8313_REV10:
+ puts("MPC8313, ");
+ break;
+ case SPR_8313E_REV10:
+ puts("MPC8313E, ");
+ break;
default:
puts("Rev: Unknown revision number.\nWarning: Unsupported cpu revision!\n");
return 0;
@@ -133,10 +158,12 @@ int checkcpu(void)
/* Multiple revisons of 834x processors may have the same SPRIDR value.
* So use PVR to identify the revision number.
*/
- printf("Rev: %02x at %s MHz\n", PVR_MAJ(pvr)<<4 | PVR_MIN(pvr), strmhz(buf, clock));
+ printf("Rev: %02x at %s MHz", PVR_MAJ(pvr)<<4 | PVR_MIN(pvr), strmhz(buf, clock));
#else
- printf("Rev: %02x at %s MHz\n", spridr & 0x0000FFFF, strmhz(buf, clock));
+ printf("Rev: %02x at %s MHz", spridr & 0x0000FFFF, strmhz(buf, clock));
#endif
+ printf(", CSB: %4d MHz\n", gd->csb_clk / 1000000);
+
return 0;
}
diff --git a/cpu/mpc83xx/pci.c b/cpu/mpc83xx/pci.c
new file mode 100644
index 0000000..785d612
--- /dev/null
+++ b/cpu/mpc83xx/pci.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) Freescale Semiconductor, Inc. 2007
+ *
+ * Author: Scott Wood <scottwood@freescale.com>,
+ * with some bits from older board-specific PCI initialization.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <pci.h>
+#include <ft_build.h>
+#include <asm/mpc8349_pci.h>
+
+#ifdef CONFIG_83XX_GENERIC_PCI
+#define MAX_BUSES 2
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct pci_controller pci_hose[MAX_BUSES];
+static int pci_num_buses;
+
+static void pci_init_bus(int bus, struct pci_region *reg)
+{
+ volatile immap_t *immr = (volatile immap_t *)CFG_IMMR;
+ volatile pot83xx_t *pot = immr->ios.pot;
+ volatile pcictrl83xx_t *pci_ctrl = &immr->pci_ctrl[bus];
+ struct pci_controller *hose = &pci_hose[bus];
+ u32 dev;
+ u16 reg16;
+ int i;
+
+ if (bus == 1)
+ pot += 3;
+
+ /* Setup outbound translation windows */
+ for (i = 0; i < 3; i++, reg++, pot++) {
+ if (reg->size == 0)
+ break;
+
+ hose->regions[i] = *reg;
+ hose->region_count++;
+
+ pot->potar = reg->bus_start >> 12;
+ pot->pobar = reg->phys_start >> 12;
+ pot->pocmr = ~(reg->size - 1) >> 12;
+
+ if (reg->flags & PCI_REGION_IO)
+ pot->pocmr |= POCMR_IO;
+#ifdef CONFIG_83XX_PCI_STREAMING
+ else if (reg->flags & PCI_REGION_PREFETCH)
+ pot->pocmr |= POCMR_SE;
+#endif
+
+ if (bus == 1)
+ pot->pocmr |= POCMR_DST;
+
+ pot->pocmr |= POCMR_EN;
+ }
+
+ /* Point inbound translation at RAM */
+ pci_ctrl->pitar1 = 0;
+ pci_ctrl->pibar1 = 0;
+ pci_ctrl->piebar1 = 0;
+ pci_ctrl->piwar1 = PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP |
+ PIWAR_WTT_SNOOP | (__ilog2(gd->ram_size) - 1);
+
+ i = hose->region_count++;
+ hose->regions[i].bus_start = 0;
+ hose->regions[i].phys_start = 0;
+ hose->regions[i].size = gd->ram_size;
+ hose->regions[i].flags = PCI_REGION_MEM | PCI_REGION_MEMORY;
+
+ hose->first_busno = 0;
+ hose->last_busno = 0xff;
+
+ pci_setup_indirect(hose, CFG_IMMR + 0x8300 + bus * 0x80,
+ CFG_IMMR + 0x8304 + bus * 0x80);
+
+ pci_register_hose(hose);
+
+ /*
+ * Write to Command register
+ */
+ reg16 = 0xff;
+ dev = PCI_BDF(hose->first_busno, 0, 0);
+ pci_hose_read_config_word(hose, dev, PCI_COMMAND, &reg16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
+ pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
+ pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
+
+#ifdef CONFIG_PCI_SCAN_SHOW
+ printf("PCI: Bus Dev VenId DevId Class Int\n");
+#endif
+ /*
+ * Hose scan.
+ */
+ hose->last_busno = pci_hose_scan(hose);
+}
+
+/*
+ * The caller must have already set OCCR, and the PCI_LAW BARs
+ * must have been set to cover all of the requested regions.
+ *
+ * If fewer than three regions are requested, then the region
+ * list is terminated with a region of size 0.
+ */
+void mpc83xx_pci_init(int num_buses, struct pci_region **reg, int warmboot)
+{
+ volatile immap_t *immr = (volatile immap_t *)CFG_IMMR;
+ int i;
+
+ if (num_buses > MAX_BUSES) {
+ printf("%d PCI buses requsted, %d supported\n",
+ num_buses, MAX_BUSES);
+
+ num_buses = MAX_BUSES;
+ }
+
+ pci_num_buses = num_buses;
+
+ /*
+ * Release PCI RST Output signal.
+ * Power on to RST high must be at least 100 ms as per PCI spec.
+ * On warm boots only 1 ms is required.
+ */
+ udelay(warmboot ? 1000 : 100000);
+
+ for (i = 0; i < num_buses; i++)
+ immr->pci_ctrl[i].gcr = 1;
+
+ /*
+ * RST high to first config access must be at least 2^25 cycles
+ * as per PCI spec. This could be cut in half if we know we're
+ * running at 66MHz. This could be insufficiently long if we're
+ * running the PCI bus at significantly less than 33MHz.
+ */
+ udelay(1020000);
+
+ for (i = 0; i < num_buses; i++)
+ pci_init_bus(i, reg[i]);
+}
+
+#ifdef CONFIG_OF_FLAT_TREE
+void ft_pci_setup(void *blob, bd_t *bd)
+{
+ u32 *p;
+ int len;
+
+ if (pci_num_buses < 1)
+ return;
+
+ p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8500/bus-range", &len);
+ if (p) {
+ p[0] = pci_hose[0].first_busno;
+ p[1] = pci_hose[0].last_busno;
+ }
+
+ if (pci_num_buses < 2)
+ return;
+
+ p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8600/bus-range", &len);
+ if (p) {
+ p[0] = pci_hose[1].first_busno;
+ p[1] = pci_hose[1].last_busno;
+ }
+}
+#endif /* CONFIG_OF_FLAT_TREE */
+
+#endif /* CONFIG_83XX_GENERIC_PCI */
diff --git a/cpu/mpc83xx/spd_sdram.c b/cpu/mpc83xx/spd_sdram.c
index d9b8753..647813f 100644
--- a/cpu/mpc83xx/spd_sdram.c
+++ b/cpu/mpc83xx/spd_sdram.c
@@ -58,8 +58,8 @@ picos_to_clk(int picos)
int clks;
ddr_bus_clk = gd->ddr_clk >> 1;
- clks = picos / ((1000000000 / ddr_bus_clk) * 1000);
- if (picos % ((1000000000 / ddr_bus_clk) * 1000) != 0)
+ clks = picos / (1000000000 / (ddr_bus_clk / 1000));
+ if (picos % (1000000000 / (ddr_bus_clk / 1000)) != 0)
clks++;
return clks;
@@ -624,7 +624,7 @@ long int spd_sdram()
| (1 << (16 + 10)) /* DQS Differential disable */
| (add_lat << (16 + 3)) /* Additive Latency in EMRS1 */
| (mode_odt_enable << 16) /* ODT Enable in EMRS1 */
- | ((twr_clk >> 1) << 9) /* Write Recovery Autopre */
+ | ((twr_clk - 1) << 9) /* Write Recovery Autopre */
| (caslat << 4) /* caslat */
| (burstlen << 0) /* Burst length */
);
@@ -693,11 +693,6 @@ long int spd_sdram()
#ifdef CFG_DDR_SDRAM_CLK_CNTL /* Optional platform specific value */
ddr->sdram_clk_cntl = CFG_DDR_SDRAM_CLK_CNTL;
-#else
- /* SS_EN = 0, source synchronous disable
- * CLK_ADJST = 0, MCK/MCK# is launched aligned with addr/cmd
- */
- ddr->sdram_clk_cntl = 0x00000000;
#endif
debug("DDR:sdram_clk_cntl=0x%08x\n", ddr->sdram_clk_cntl);
diff --git a/cpu/mpc83xx/speed.c b/cpu/mpc83xx/speed.c
index c759930..bf30616 100644
--- a/cpu/mpc83xx/speed.c
+++ b/cpu/mpc83xx/speed.c
@@ -25,6 +25,7 @@
#include <common.h>
#include <mpc83xx.h>
+#include <command.h>
#include <asm/processor.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -99,12 +100,14 @@ int get_clocks(void)
u32 lcrr;
u32 csb_clk;
-#if defined(CONFIG_MPC834X)
+#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X)
u32 tsec1_clk;
u32 tsec2_clk;
- u32 usbmph_clk;
u32 usbdr_clk;
#endif
+#ifdef CONFIG_MPC834X
+ u32 usbmph_clk;
+#endif
u32 core_clk;
u32 i2c1_clk;
#if !defined(CONFIG_MPC832X)
@@ -148,7 +151,7 @@ int get_clocks(void)
sccr = im->clk.sccr;
-#if defined(CONFIG_MPC834X)
+#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X)
switch ((sccr & SCCR_TSEC1CM) >> SCCR_TSEC1CM_SHIFT) {
case 0:
tsec1_clk = 0;
@@ -167,6 +170,26 @@ int get_clocks(void)
return -4;
}
+ switch ((sccr & SCCR_USBDRCM) >> SCCR_USBDRCM_SHIFT) {
+ case 0:
+ usbdr_clk = 0;
+ break;
+ case 1:
+ usbdr_clk = csb_clk;
+ break;
+ case 2:
+ usbdr_clk = csb_clk / 2;
+ break;
+ case 3:
+ usbdr_clk = csb_clk / 3;
+ break;
+ default:
+ /* unkown SCCR_USBDRCM value */
+ return -8;
+ }
+#endif
+
+#if defined(CONFIG_MPC834X)
switch ((sccr & SCCR_TSEC2CM) >> SCCR_TSEC2CM_SHIFT) {
case 0:
tsec2_clk = 0;
@@ -205,24 +228,6 @@ int get_clocks(void)
return -7;
}
- switch ((sccr & SCCR_USBDRCM) >> SCCR_USBDRCM_SHIFT) {
- case 0:
- usbdr_clk = 0;
- break;
- case 1:
- usbdr_clk = csb_clk;
- break;
- case 2:
- usbdr_clk = csb_clk / 2;
- break;
- case 3:
- usbdr_clk = csb_clk / 3;
- break;
- default:
- /* unkown SCCR_USBDRCM value */
- return -8;
- }
-
if (usbmph_clk != 0 && usbdr_clk != 0 && usbmph_clk != usbdr_clk) {
/* if USB MPH clock is not disabled and
* USB DR clock is not disabled then
@@ -230,8 +235,16 @@ int get_clocks(void)
*/
return -9;
}
+#elif defined(CONFIG_MPC831X)
+ tsec2_clk = tsec1_clk;
+
+ if (!(sccr & SCCR_TSEC1ON))
+ tsec1_clk = 0;
+ if (!(sccr & SCCR_TSEC2ON))
+ tsec2_clk = 0;
#endif
-#if defined(CONFIG_MPC8360) || defined(CONFIG_MPC832X)
+
+#if !defined(CONFIG_MPC834X)
i2c1_clk = csb_clk;
#endif
#if !defined(CONFIG_MPC832X)
@@ -314,12 +327,14 @@ int get_clocks(void)
#endif
gd->csb_clk = csb_clk;
-#if defined(CONFIG_MPC834X)
+#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X)
gd->tsec1_clk = tsec1_clk;
gd->tsec2_clk = tsec2_clk;
- gd->usbmph_clk = usbmph_clk;
gd->usbdr_clk = usbdr_clk;
#endif
+#if defined(CONFIG_MPC834X)
+ gd->usbmph_clk = usbmph_clk;
+#endif
gd->core_clk = core_clk;
gd->i2c1_clk = i2c1_clk;
#if !defined(CONFIG_MPC832X)
@@ -351,11 +366,11 @@ ulong get_bus_freq(ulong dummy)
return gd->csb_clk;
}
-int print_clock_conf(void)
+int do_clocks (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
printf("Clock configuration:\n");
- printf(" Coherent System Bus: %4d MHz\n", gd->csb_clk / 1000000);
printf(" Core: %4d MHz\n", gd->core_clk / 1000000);
+ printf(" Coherent System Bus: %4d MHz\n", gd->csb_clk / 1000000);
#if defined(CONFIG_MPC8360) || defined(CONFIG_MPC832X)
printf(" QE: %4d MHz\n", gd->qe_clk / 1000000);
printf(" BRG: %4d MHz\n", gd->brg_clk / 1000000);
@@ -371,11 +386,18 @@ int print_clock_conf(void)
#if !defined(CONFIG_MPC832X)
printf(" I2C2: %4d MHz\n", gd->i2c2_clk / 1000000);
#endif
-#if defined(CONFIG_MPC834X)
+#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X)
printf(" TSEC1: %4d MHz\n", gd->tsec1_clk / 1000000);
printf(" TSEC2: %4d MHz\n", gd->tsec2_clk / 1000000);
- printf(" USB MPH: %4d MHz\n", gd->usbmph_clk / 1000000);
printf(" USB DR: %4d MHz\n", gd->usbdr_clk / 1000000);
#endif
+#if defined(CONFIG_MPC834X)
+ printf(" USB MPH: %4d MHz\n", gd->usbmph_clk / 1000000);
+#endif
return 0;
}
+
+U_BOOT_CMD(clocks, 1, 0, do_clocks,
+ "clocks - print clock configuration\n",
+ " clocks\n"
+);
diff --git a/cpu/ppc4xx/44x_spd_ddr.c b/cpu/ppc4xx/44x_spd_ddr.c
index 10b4c18..c500d3f 100644
--- a/cpu/ppc4xx/44x_spd_ddr.c
+++ b/cpu/ppc4xx/44x_spd_ddr.c
@@ -20,7 +20,7 @@
* Jun Gu, Artesyn Technology, jung@artesyncp.com
* Support for AMCC 440 based on OpenBIOS draminit.c from IBM.
*
- * (C) Copyright 2005
+ * (C) Copyright 2005-2007
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* See file CREDITS for list of people who contributed to this
@@ -42,6 +42,11 @@
* MA 02111-1307 USA
*/
+/* define DEBUG for debugging output (obviously ;-)) */
+#if 0
+#define DEBUG
+#endif
+
#include <common.h>
#include <asm/processor.h>
#include <i2c.h>
@@ -246,25 +251,6 @@
#define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE /* disable caching on SDRAM */
#endif
-const unsigned long test[NUMMEMTESTS][NUMMEMWORDS] = {
- {0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
- 0xFFFFFFFF, 0xFFFFFFFF},
- {0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
- 0x00000000, 0x00000000},
- {0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
- 0x55555555, 0x55555555},
- {0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
- 0xAAAAAAAA, 0xAAAAAAAA},
- {0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
- 0x5A5A5A5A, 0x5A5A5A5A},
- {0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
- 0xA5A5A5A5, 0xA5A5A5A5},
- {0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
- 0x55AA55AA, 0x55AA55AA},
- {0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
- 0xAA55AA55, 0xAA55AA55}
-};
-
/* bank_parms is used to sort the bank sizes by descending order */
struct bank_param {
unsigned long cr;
@@ -278,46 +264,37 @@ extern unsigned char cfg_simulate_spd_eeprom[128];
#endif
void program_tlb(u32 start, u32 size, u32 tlb_word2_i_value);
-unsigned char spd_read(uchar chip, uint addr);
-
-void get_spd_info(unsigned long* dimm_populated,
- unsigned char* iic0_dimm_addr,
- unsigned long num_dimm_banks);
-
-void check_mem_type
-(unsigned long* dimm_populated,
- unsigned char* iic0_dimm_addr,
- unsigned long num_dimm_banks);
-
-void check_volt_type
-(unsigned long* dimm_populated,
- unsigned char* iic0_dimm_addr,
- unsigned long num_dimm_banks);
-
-void program_cfg0(unsigned long* dimm_populated,
- unsigned char* iic0_dimm_addr,
- unsigned long num_dimm_banks);
-
-void program_cfg1(unsigned long* dimm_populated,
- unsigned char* iic0_dimm_addr,
- unsigned long num_dimm_banks);
-
-void program_rtr (unsigned long* dimm_populated,
- unsigned char* iic0_dimm_addr,
- unsigned long num_dimm_banks);
-
-void program_tr0 (unsigned long* dimm_populated,
- unsigned char* iic0_dimm_addr,
- unsigned long num_dimm_banks);
-
-void program_tr1 (void);
-
-void program_ecc (unsigned long num_bytes);
+static unsigned char spd_read(uchar chip, uint addr);
+static void get_spd_info(unsigned long *dimm_populated,
+ unsigned char *iic0_dimm_addr,
+ unsigned long num_dimm_banks);
+static void check_mem_type(unsigned long *dimm_populated,
+ unsigned char *iic0_dimm_addr,
+ unsigned long num_dimm_banks);
+static void check_volt_type(unsigned long *dimm_populated,
+ unsigned char *iic0_dimm_addr,
+ unsigned long num_dimm_banks);
+static void program_cfg0(unsigned long *dimm_populated,
+ unsigned char *iic0_dimm_addr,
+ unsigned long num_dimm_banks);
+static void program_cfg1(unsigned long *dimm_populated,
+ unsigned char *iic0_dimm_addr,
+ unsigned long num_dimm_banks);
+static void program_rtr(unsigned long *dimm_populated,
+ unsigned char *iic0_dimm_addr,
+ unsigned long num_dimm_banks);
+static void program_tr0(unsigned long *dimm_populated,
+ unsigned char *iic0_dimm_addr,
+ unsigned long num_dimm_banks);
+static void program_tr1(void);
+
+#ifdef CONFIG_DDR_ECC
+static void program_ecc(unsigned long num_bytes);
+#endif
-unsigned
-long program_bxcr(unsigned long* dimm_populated,
- unsigned char* iic0_dimm_addr,
- unsigned long num_dimm_banks);
+static unsigned long program_bxcr(unsigned long *dimm_populated,
+ unsigned char *iic0_dimm_addr,
+ unsigned long num_dimm_banks);
/*
* This function is reading data from the DIMM module EEPROM over the SPD bus
@@ -328,7 +305,6 @@ long program_bxcr(unsigned long* dimm_populated,
* BUG: Don't handle ECC memory
* BUG: A few values in the TR register is currently hardcoded
*/
-
long int spd_sdram(void) {
unsigned char iic0_dimm_addr[] = SPD_EEPROM_ADDRESS;
unsigned long dimm_populated[sizeof(iic0_dimm_addr)];
@@ -421,9 +397,8 @@ long int spd_sdram(void) {
*/
while (1) {
mfsdram(mem_mcsts, mcsts);
- if ((mcsts & SDRAM_MCSTS_MRSC) != 0) {
+ if ((mcsts & SDRAM_MCSTS_MRSC) != 0)
break;
- }
}
/*
@@ -431,14 +406,17 @@ long int spd_sdram(void) {
*/
program_tr1();
+#ifdef CONFIG_DDR_ECC
/*
- * if ECC is enabled, initialize parity bits
+ * If ecc is enabled, initialize the parity bits.
*/
+ program_ecc(total_size);
+#endif
return total_size;
}
-unsigned char spd_read(uchar chip, uint addr)
+static unsigned char spd_read(uchar chip, uint addr)
{
unsigned char data[2];
@@ -460,9 +438,9 @@ unsigned char spd_read(uchar chip, uint addr)
return 0;
}
-void get_spd_info(unsigned long* dimm_populated,
- unsigned char* iic0_dimm_addr,
- unsigned long num_dimm_banks)
+static void get_spd_info(unsigned long *dimm_populated,
+ unsigned char *iic0_dimm_addr,
+ unsigned long num_dimm_banks)
{
unsigned long dimm_num;
unsigned long dimm_found;
@@ -480,14 +458,10 @@ void get_spd_info(unsigned long* dimm_populated,
if ((num_of_bytes != 0) && (total_size != 0)) {
dimm_populated[dimm_num] = TRUE;
dimm_found = TRUE;
-#if 0
- printf("DIMM slot %lu: populated\n", dimm_num);
-#endif
+ debug("DIMM slot %lu: populated\n", dimm_num);
} else {
dimm_populated[dimm_num] = FALSE;
-#if 0
- printf("DIMM slot %lu: Not populated\n", dimm_num);
-#endif
+ debug("DIMM slot %lu: Not populated\n", dimm_num);
}
}
@@ -497,9 +471,9 @@ void get_spd_info(unsigned long* dimm_populated,
}
}
-void check_mem_type(unsigned long* dimm_populated,
- unsigned char* iic0_dimm_addr,
- unsigned long num_dimm_banks)
+static void check_mem_type(unsigned long *dimm_populated,
+ unsigned char *iic0_dimm_addr,
+ unsigned long num_dimm_banks)
{
unsigned long dimm_num;
unsigned char dimm_type;
@@ -509,9 +483,7 @@ void check_mem_type(unsigned long* dimm_populated,
dimm_type = spd_read(iic0_dimm_addr[dimm_num], 2);
switch (dimm_type) {
case 7:
-#if 0
- printf("DIMM slot %lu: DDR SDRAM detected\n", dimm_num);
-#endif
+ debug("DIMM slot %lu: DDR SDRAM detected\n", dimm_num);
break;
default:
printf("ERROR: Unsupported DIMM detected in slot %lu.\n",
@@ -525,10 +497,9 @@ void check_mem_type(unsigned long* dimm_populated,
}
}
-
-void check_volt_type(unsigned long* dimm_populated,
- unsigned char* iic0_dimm_addr,
- unsigned long num_dimm_banks)
+static void check_volt_type(unsigned long *dimm_populated,
+ unsigned char *iic0_dimm_addr,
+ unsigned long num_dimm_banks)
{
unsigned long dimm_num;
unsigned long voltage_type;
@@ -541,18 +512,16 @@ void check_volt_type(unsigned long* dimm_populated,
dimm_num);
hang();
} else {
-#if 0
- printf("DIMM %lu voltage level supported.\n", dimm_num);
-#endif
+ debug("DIMM %lu voltage level supported.\n", dimm_num);
}
break;
}
}
}
-void program_cfg0(unsigned long* dimm_populated,
- unsigned char* iic0_dimm_addr,
- unsigned long num_dimm_banks)
+static void program_cfg0(unsigned long *dimm_populated,
+ unsigned char *iic0_dimm_addr,
+ unsigned long num_dimm_banks)
{
unsigned long dimm_num;
unsigned long cfg0;
@@ -640,9 +609,9 @@ void program_cfg0(unsigned long* dimm_populated,
mtsdram(mem_cfg0, cfg0);
}
-void program_cfg1(unsigned long* dimm_populated,
- unsigned char* iic0_dimm_addr,
- unsigned long num_dimm_banks)
+static void program_cfg1(unsigned long *dimm_populated,
+ unsigned char *iic0_dimm_addr,
+ unsigned long num_dimm_banks)
{
unsigned long cfg1;
mfsdram(mem_cfg1, cfg1);
@@ -658,9 +627,9 @@ void program_cfg1(unsigned long* dimm_populated,
mtsdram(mem_cfg1, cfg1);
}
-void program_rtr (unsigned long* dimm_populated,
- unsigned char* iic0_dimm_addr,
- unsigned long num_dimm_banks)
+static void program_rtr(unsigned long *dimm_populated,
+ unsigned char *iic0_dimm_addr,
+ unsigned long num_dimm_banks)
{
unsigned long dimm_num;
unsigned long bus_period_x_10;
@@ -676,7 +645,6 @@ void program_rtr (unsigned long* dimm_populated,
get_sys_info(&sys_info);
bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10);
-
for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
if (dimm_populated[dimm_num] == TRUE) {
refresh_rate_type = 0x7F & spd_read(iic0_dimm_addr[dimm_num], 12);
@@ -719,9 +687,9 @@ void program_rtr (unsigned long* dimm_populated,
mtsdram(mem_rtr, sdram_rtr);
}
-void program_tr0 (unsigned long* dimm_populated,
- unsigned char* iic0_dimm_addr,
- unsigned long num_dimm_banks)
+static void program_tr0(unsigned long *dimm_populated,
+ unsigned char *iic0_dimm_addr,
+ unsigned long num_dimm_banks)
{
unsigned long dimm_num;
unsigned long tr0;
@@ -1001,13 +969,73 @@ void program_tr0 (unsigned long* dimm_populated,
break;
}
-#if 0
- printf("tr0: %x\n", tr0);
-#endif
+ debug("tr0: %x\n", tr0);
mtsdram(mem_tr0, tr0);
}
-void program_tr1 (void)
+static int short_mem_test(void)
+{
+ unsigned long i, j;
+ unsigned long bxcr_num;
+ unsigned long *membase;
+ const unsigned long test[NUMMEMTESTS][NUMMEMWORDS] = {
+ {0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF},
+ {0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000},
+ {0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
+ 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555},
+ {0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
+ 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA},
+ {0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
+ 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A},
+ {0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
+ 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5},
+ {0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
+ 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA},
+ {0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
+ 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55}};
+
+ for (bxcr_num = 0; bxcr_num < MAXBXCR; bxcr_num++) {
+ mtdcr(memcfga, mem_b0cr + (bxcr_num << 2));
+ if ((mfdcr(memcfgd) & SDRAM_BXCR_SDBE) == SDRAM_BXCR_SDBE) {
+ /* Bank is enabled */
+ membase = (unsigned long*)
+ (mfdcr(memcfgd) & SDRAM_BXCR_SDBA_MASK);
+
+ /*
+ * Run the short memory test
+ */
+ for (i = 0; i < NUMMEMTESTS; i++) {
+ for (j = 0; j < NUMMEMWORDS; j++) {
+ membase[j] = test[i][j];
+ ppcDcbf((unsigned long)&(membase[j]));
+ }
+
+ for (j = 0; j < NUMMEMWORDS; j++) {
+ if (membase[j] != test[i][j]) {
+ ppcDcbf((unsigned long)&(membase[j]));
+ return 0;
+ }
+ ppcDcbf((unsigned long)&(membase[j]));
+ }
+
+ if (j < NUMMEMWORDS)
+ return 0;
+ }
+
+ /*
+ * see if the rdclt value passed
+ */
+ if (i < NUMMEMTESTS)
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static void program_tr1(void)
{
unsigned long tr0;
unsigned long tr1;
@@ -1015,8 +1043,7 @@ void program_tr1 (void)
unsigned long ecc_temp;
unsigned long dlycal;
unsigned long dly_val;
- unsigned long i, j, k;
- unsigned long bxcr_num;
+ unsigned long k;
unsigned long max_pass_length;
unsigned long current_pass_length;
unsigned long current_fail_length;
@@ -1029,7 +1056,6 @@ void program_tr1 (void)
unsigned char window_found;
unsigned char fail_found;
unsigned char pass_found;
- unsigned long * membase;
PPC440_SYS_INFO sys_info;
/*
@@ -1079,55 +1105,16 @@ void program_tr1 (void)
window_found = FALSE;
fail_found = FALSE;
pass_found = FALSE;
-#ifdef DEBUG
- printf("Starting memory test ");
-#endif
+ debug("Starting memory test ");
+
for (k = 0; k < NUMHALFCYCLES; k++) {
- for (rdclt = 0; rdclt < dly_val; rdclt++) {
+ for (rdclt = 0; rdclt < dly_val; rdclt++) {
/*
* Set the timing reg for the test.
*/
mtsdram(mem_tr1, (tr1 | SDRAM_TR1_RDCT_ENCODE(rdclt)));
- for (bxcr_num = 0; bxcr_num < MAXBXCR; bxcr_num++) {
- mtdcr(memcfga, mem_b0cr + (bxcr_num<<2));
- if ((mfdcr(memcfgd) & SDRAM_BXCR_SDBE) == SDRAM_BXCR_SDBE) {
- /* Bank is enabled */
- membase = (unsigned long*)
- (mfdcr(memcfgd) & SDRAM_BXCR_SDBA_MASK);
-
- /*
- * Run the short memory test
- */
- for (i = 0; i < NUMMEMTESTS; i++) {
- for (j = 0; j < NUMMEMWORDS; j++) {
- membase[j] = test[i][j];
- ppcDcbf((unsigned long)&(membase[j]));
- }
-
- for (j = 0; j < NUMMEMWORDS; j++) {
- if (membase[j] != test[i][j]) {
- ppcDcbf((unsigned long)&(membase[j]));
- break;
- }
- ppcDcbf((unsigned long)&(membase[j]));
- }
-
- if (j < NUMMEMWORDS) {
- break;
- }
- }
-
- /*
- * see if the rdclt value passed
- */
- if (i < NUMMEMTESTS) {
- break;
- }
- }
- }
-
- if (bxcr_num == MAXBXCR) {
+ if (short_mem_test()) {
if (fail_found == TRUE) {
pass_found = TRUE;
if (current_pass_length == 0) {
@@ -1157,9 +1144,8 @@ void program_tr1 (void)
}
}
}
-#ifdef DEBUG
- printf(".");
-#endif
+ debug(".");
+
if (window_found == TRUE) {
break;
}
@@ -1167,9 +1153,7 @@ void program_tr1 (void)
tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK;
rdclt_offset += dly_val;
}
-#ifdef DEBUG
- printf("\n");
-#endif
+ debug("\n");
/*
* make sure we find the window
@@ -1218,18 +1202,17 @@ void program_tr1 (void)
}
tr1 |= SDRAM_TR1_RDCT_ENCODE(rdclt_average);
-#if 0
- printf("tr1: %x\n", tr1);
-#endif
+ debug("tr1: %x\n", tr1);
+
/*
* program SDRAM Timing Register 1 TR1
*/
mtsdram(mem_tr1, tr1);
}
-unsigned long program_bxcr(unsigned long* dimm_populated,
- unsigned char* iic0_dimm_addr,
- unsigned long num_dimm_banks)
+static unsigned long program_bxcr(unsigned long *dimm_populated,
+ unsigned char *iic0_dimm_addr,
+ unsigned long num_dimm_banks)
{
unsigned long dimm_num;
unsigned long bank_base_addr;
@@ -1262,8 +1245,8 @@ unsigned long program_bxcr(unsigned long* dimm_populated,
#ifdef CONFIG_BAMBOO
/*
* This next section is hardware dependent and must be programmed
- * to match the hardware. For bammboo, the following holds...
- * 1. SDRAM0_B0CR: Bank 0 of dimm 0 ctrl_bank_num : 0
+ * to match the hardware. For bamboo, the following holds...
+ * 1. SDRAM0_B0CR: Bank 0 of dimm 0 ctrl_bank_num : 0 (soldered onboard)
* 2. SDRAM0_B1CR: Bank 0 of dimm 1 ctrl_bank_num : 1
* 3. SDRAM0_B2CR: Bank 1 of dimm 1 ctrl_bank_num : 1
* 4. SDRAM0_B3CR: Bank 0 of dimm 2 ctrl_bank_num : 3
@@ -1273,10 +1256,12 @@ unsigned long program_bxcr(unsigned long* dimm_populated,
ctrl_bank_num[1] = 1;
ctrl_bank_num[2] = 3;
#else
+ /*
+ * Ocotea, Ebony and the other IBM/AMCC eval boards have
+ * 2 DIMM slots with each max 2 banks
+ */
ctrl_bank_num[0] = 0;
- ctrl_bank_num[1] = 1;
- ctrl_bank_num[2] = 2;
- ctrl_bank_num[3] = 3;
+ ctrl_bank_num[1] = 2;
#endif
/*
@@ -1290,6 +1275,8 @@ unsigned long program_bxcr(unsigned long* dimm_populated,
num_col_addr = spd_read(iic0_dimm_addr[dimm_num], 4);
num_banks = spd_read(iic0_dimm_addr[dimm_num], 5);
bank_size_id = spd_read(iic0_dimm_addr[dimm_num], 31);
+ debug("DIMM%d: row=%d col=%d banks=%d\n", dimm_num,
+ num_row_addr, num_col_addr, num_banks);
/*
* Set the SDRAM0_BxCR regs
@@ -1354,9 +1341,12 @@ unsigned long program_bxcr(unsigned long* dimm_populated,
cr |= SDRAM_BXCR_SDBE;
for (i = 0; i < num_banks; i++) {
- bank_parms[ctrl_bank_num[dimm_num]+i+dimm_num].bank_size_bytes =
- (4 * 1024 * 1024) * bank_size_id;
- bank_parms[ctrl_bank_num[dimm_num]+i+dimm_num].cr = cr;
+ bank_parms[ctrl_bank_num[dimm_num]+i].bank_size_bytes =
+ (4 << 20) * bank_size_id;
+ bank_parms[ctrl_bank_num[dimm_num]+i].cr = cr;
+ debug("DIMM%d-bank %d (SDRAM0_B%dCR): bank_size_bytes=%d\n",
+ dimm_num, i, ctrl_bank_num[dimm_num]+i,
+ bank_parms[ctrl_bank_num[dimm_num]+i].bank_size_bytes);
}
}
}
@@ -1400,13 +1390,15 @@ unsigned long program_bxcr(unsigned long* dimm_populated,
bank_parms[sorted_bank_num[bx_cr_num]].cr;
mtdcr(memcfgd, temp);
bank_base_addr += bank_parms[sorted_bank_num[bx_cr_num]].bank_size_bytes;
+ debug("SDRAM0_B%dCR=0x%08lx\n", sorted_bank_num[bx_cr_num], temp);
}
}
return(bank_base_addr);
}
-void program_ecc (unsigned long num_bytes)
+#ifdef CONFIG_DDR_ECC
+static void program_ecc(unsigned long num_bytes)
{
unsigned long bank_base_addr;
unsigned long current_address;
@@ -1425,14 +1417,12 @@ void program_ecc (unsigned long num_bytes)
bank_base_addr = CFG_SDRAM_BASE;
if ((cfg0 & SDRAM_CFG0_MCHK_MASK) != SDRAM_CFG0_MCHK_NON) {
- mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) |
- SDRAM_CFG0_MCHK_GEN);
+ mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | SDRAM_CFG0_MCHK_GEN);
- if ((cfg0 & SDRAM_CFG0_DMWD_MASK) == SDRAM_CFG0_DMWD_32) {
+ if ((cfg0 & SDRAM_CFG0_DMWD_MASK) == SDRAM_CFG0_DMWD_32)
address_increment = 4;
- } else {
+ else
address_increment = 8;
- }
current_address = (unsigned long)(bank_base_addr);
end_address = (unsigned long)(bank_base_addr) + num_bytes;
@@ -1446,4 +1436,5 @@ void program_ecc (unsigned long num_bytes)
SDRAM_CFG0_MCHK_CHK);
}
}
+#endif /* CONFIG_DDR_ECC */
#endif /* CONFIG_SPD_EEPROM */
diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c
index 2ecd3e4..48b9ee2 100644
--- a/cpu/ppc4xx/44x_spd_ddr2.c
+++ b/cpu/ppc4xx/44x_spd_ddr2.c
@@ -465,7 +465,11 @@ long int initdram(int board_type)
* Set the SDRAM Clock Timing Register
*-----------------------------------------------------------------*/
mfsdram(SDRAM_CLKTR, val);
+#ifdef CFG_44x_DDR2_CKTR_180
+ mtsdram(SDRAM_CLKTR, (val & ~SDRAM_CLKTR_CLKP_MASK) | SDRAM_CLKTR_CLKP_180_DEG_ADV);
+#else
mtsdram(SDRAM_CLKTR, (val & ~SDRAM_CLKTR_CLKP_MASK) | SDRAM_CLKTR_CLKP_0_DEG);
+#endif
/*------------------------------------------------------------------
* Program the BxCF registers.
@@ -1117,7 +1121,8 @@ static void program_codt(unsigned long *dimm_populated,
modt3 = 0x00000000;
}
if (total_rank == 4) {
- codt |= CALC_ODT_R(0) | CALC_ODT_R(1) | CALC_ODT_R(2) | CALC_ODT_R(3);
+ codt |= CALC_ODT_R(0) | CALC_ODT_R(1) |
+ CALC_ODT_R(2) | CALC_ODT_R(3);
modt0 = CALC_ODT_RW(2);
modt1 = 0x00000000;
modt2 = CALC_ODT_RW(0);
diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c
index 8e6bc84..c07bc0c 100644
--- a/cpu/ppc4xx/cpu.c
+++ b/cpu/ppc4xx/cpu.c
@@ -139,6 +139,7 @@ static char *bootstrap_str[] = {
"Reserved",
"I2C (Addr 0x50)",
};
+static char bootstrap_char[] = { 'A', 'B', 'C', 'B', 'D', 'E', 'x', 'F' };
#endif
#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
@@ -149,6 +150,7 @@ static char *bootstrap_str[] = {
"I2C (Addr 0x54)",
"I2C (Addr 0x50)",
};
+static char bootstrap_char[] = { 'A', 'B', 'C', 'D'};
#endif
#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
@@ -163,6 +165,7 @@ static char *bootstrap_str[] = {
"PCI",
"I2C (Addr 0x52)",
};
+static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'G', 'F', 'H' };
#endif
#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
@@ -177,6 +180,7 @@ static char *bootstrap_str[] = {
"PCI",
"I2C (Addr 0x52)",
};
+static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'G', 'F', 'H' };
#endif
#if defined(CONFIG_405EZ)
@@ -199,6 +203,8 @@ static char *bootstrap_str[] = {
"SPI (slow)",
"I2C (Addr 0x50)",
};
+static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', \
+ 'I', 'x', 'K', 'L', 'M', 'N', 'O', 'P' };
#endif
#if defined(SDR0_PINSTP_SHIFT)
@@ -427,7 +433,7 @@ int checkcpu (void)
printf (" I2C boot EEPROM %sabled\n", i2c_bootrom_enabled() ? "en" : "dis");
#endif /* I2C_BOOTROM */
#if defined(SDR0_PINSTP_SHIFT)
- printf (" Bootstrap Option %c - ", (char)bootstrap_option() + 'A');
+ printf (" Bootstrap Option %c - ", bootstrap_char[bootstrap_option()]);
printf ("Boot ROM Location %s\n", bootstrap_str[bootstrap_option()]);
#endif /* SDR0_PINSTP_SHIFT */
diff --git a/cpu/ppc4xx/ndfc.c b/cpu/ppc4xx/ndfc.c
index b198ff4..f63fc79 100644
--- a/cpu/ppc4xx/ndfc.c
+++ b/cpu/ppc4xx/ndfc.c
@@ -3,7 +3,7 @@
* Platform independend driver for NDFC (NanD Flash Controller)
* integrated into EP440 cores
*
- * (C) Copyright 2006
+ * (C) Copyright 2006-2007
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* Based on original work by
@@ -33,12 +33,15 @@
#if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY) && \
(defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
- defined(CONFIG_440EPX) || defined(CONFIG_440GRX))
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_405EZ))
#include <nand.h>
#include <linux/mtd/ndfc.h>
+#include <linux/mtd/nand_ecc.h>
#include <asm/processor.h>
-#include <ppc440.h>
+#include <asm/io.h>
+#include <ppc4xx.h>
static u8 hwctl = 0;
@@ -69,11 +72,11 @@ static void ndfc_write_byte(struct mtd_info *mtdinfo, u_char byte)
ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
if (hwctl & 0x1)
- out8(base + NDFC_CMD, byte);
+ out_8((u8 *)(base + NDFC_CMD), byte);
else if (hwctl & 0x2)
- out8(base + NDFC_ALE, byte);
+ out_8((u8 *)(base + NDFC_ALE), byte);
else
- out8(base + NDFC_DATA, byte);
+ out_8((u8 *)(base + NDFC_DATA), byte);
}
static u_char ndfc_read_byte(struct mtd_info *mtdinfo)
@@ -81,7 +84,7 @@ static u_char ndfc_read_byte(struct mtd_info *mtdinfo)
struct nand_chip *this = mtdinfo->priv;
ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
- return (in8(base + NDFC_DATA));
+ return (in_8((u8 *)(base + NDFC_DATA)));
}
static int ndfc_dev_ready(struct mtd_info *mtdinfo)
@@ -89,17 +92,41 @@ static int ndfc_dev_ready(struct mtd_info *mtdinfo)
struct nand_chip *this = mtdinfo->priv;
ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
- while (!(in32(base + NDFC_STAT) & NDFC_STAT_IS_READY))
+ while (!(in_be32((u32 *)(base + NDFC_STAT)) & NDFC_STAT_IS_READY))
;
return 1;
}
-#ifndef CONFIG_NAND_SPL
-/*
- * Don't use these speedup functions in NAND boot image, since the image
- * has to fit into 4kByte.
- */
+static void ndfc_enable_hwecc(struct mtd_info *mtdinfo, int mode)
+{
+ struct nand_chip *this = mtdinfo->priv;
+ ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
+ u32 ccr;
+
+ ccr = in_be32((u32 *)(base + NDFC_CCR));
+ ccr |= NDFC_CCR_RESET_ECC;
+ out_be32((u32 *)(base + NDFC_CCR), ccr);
+}
+
+static int ndfc_calculate_ecc(struct mtd_info *mtdinfo,
+ const u_char *dat, u_char *ecc_code)
+{
+ struct nand_chip *this = mtdinfo->priv;
+ ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
+ u32 ecc;
+ u8 *p = (u8 *)&ecc;
+
+ ecc = in_be32((u32 *)(base + NDFC_ECC));
+
+ /* The NDFC uses Smart Media (SMC) bytes order
+ */
+ ecc_code[0] = p[2];
+ ecc_code[1] = p[1];
+ ecc_code[2] = p[3];
+
+ return 0;
+}
/*
* Speedups for buffer read/write/verify
@@ -115,9 +142,14 @@ static void ndfc_read_buf(struct mtd_info *mtdinfo, uint8_t *buf, int len)
uint32_t *p = (uint32_t *) buf;
for (;len > 0; len -= 4)
- *p++ = in32(base + NDFC_DATA);
+ *p++ = in_be32((u32 *)(base + NDFC_DATA));
}
+#ifndef CONFIG_NAND_SPL
+/*
+ * Don't use these speedup functions in NAND boot image, since the image
+ * has to fit into 4kByte.
+ */
static void ndfc_write_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len)
{
struct nand_chip *this = mtdinfo->priv;
@@ -125,7 +157,7 @@ static void ndfc_write_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len
uint32_t *p = (uint32_t *) buf;
for (; len > 0; len -= 4)
- out32(base + NDFC_DATA, *p++);
+ out_be32((u32 *)(base + NDFC_DATA), *p++);
}
static int ndfc_verify_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len)
@@ -135,7 +167,7 @@ static int ndfc_verify_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len
uint32_t *p = (uint32_t *) buf;
for (; len > 0; len -= 4)
- if (*p++ != in32(base + NDFC_DATA))
+ if (*p++ != in_be32((u32 *)(base + NDFC_DATA)))
return -1;
return 0;
@@ -152,8 +184,8 @@ void board_nand_select_device(struct nand_chip *nand, int chip)
ulong base = (ulong)nand->IO_ADDR_W & 0xfffffffc;
/* Set NandFlash Core Configuration Register */
- /* 1col x 2 rows */
- out32(base + NDFC_CCR, 0x00000000 | (cs << 24));
+ /* 1 col x 2 rows */
+ out_be32((u32 *)(base + NDFC_CCR), 0x00000000 | (cs << 24));
}
int board_nand_init(struct nand_chip *nand)
@@ -161,23 +193,25 @@ int board_nand_init(struct nand_chip *nand)
int cs = (ulong)nand->IO_ADDR_W & 0x00000003;
ulong base = (ulong)nand->IO_ADDR_W & 0xfffffffc;
- nand->eccmode = NAND_ECC_SOFT;
-
nand->hwcontrol = ndfc_hwcontrol;
nand->read_byte = ndfc_read_byte;
+ nand->read_buf = ndfc_read_buf;
nand->write_byte = ndfc_write_byte;
nand->dev_ready = ndfc_dev_ready;
+ nand->eccmode = NAND_ECC_HW3_256;
+ nand->enable_hwecc = ndfc_enable_hwecc;
+ nand->calculate_ecc = ndfc_calculate_ecc;
+ nand->correct_data = nand_correct_data;
+
#ifndef CONFIG_NAND_SPL
nand->write_buf = ndfc_write_buf;
- nand->read_buf = ndfc_read_buf;
nand->verify_buf = ndfc_verify_buf;
#else
/*
* Setup EBC (CS0 only right now)
*/
- mtdcr(ebccfga, xbcfg);
- mtdcr(ebccfgd, 0xb8400000);
+ mtebc(EBC0_CFG, 0xb8400000);
mtebc(pb0cr, CFG_EBC_PB0CR);
mtebc(pb0ap, CFG_EBC_PB0AP);
@@ -187,7 +221,7 @@ int board_nand_init(struct nand_chip *nand)
* Select required NAND chip in NDFC
*/
board_nand_select_device(nand, cs);
- out32(base + NDFC_BCFG0 + (cs << 2), 0x80002222);
+ out_be32((u32 *)(base + NDFC_BCFG0 + (cs << 2)), 0x80002222);
return 0;
}
diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S
index a96083c..78d0042 100644
--- a/cpu/ppc4xx/start.S
+++ b/cpu/ppc4xx/start.S
@@ -110,6 +110,13 @@
# endif
#endif /* CFG_INIT_DCACHE_CS */
+#define function_prolog(func_name) .text; \
+ .align 2; \
+ .globl func_name; \
+ func_name:
+#define function_epilog(func_name) .type func_name,@function; \
+ .size func_name,.-func_name
+
/* We don't want the MMU yet.
*/
#undef MSR_KERNEL
@@ -148,7 +155,9 @@
* NAND U-Boot image is started from offset 0
*/
.text
+#if defined(CONFIG_440)
bl reconfig_tlb0
+#endif
GET_GOT
bl cpu_init_f /* run low-level CPU init code (from Flash) */
bl board_init_f
@@ -388,8 +397,9 @@ rsttlb: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/
2:
#if defined(CONFIG_NAND_SPL)
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
/*
- * Enable internal SRAM
+ * Enable internal SRAM (only on 440EPx/GRx, 440EP/GR have no OCM)
*/
lis r2,0x7fff
ori r2,r2,0xffff
@@ -399,6 +409,45 @@ rsttlb: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/
mfdcr r1,isram0_pmeg
and r1,r1,r2 /* Disable pwr mgmt */
mtdcr isram0_pmeg,r1
+#endif
+#if defined(CONFIG_440EP)
+ /*
+ * On 440EP with no internal SRAM, we setup SDRAM very early
+ * and copy the NAND_SPL to SDRAM and jump to it
+ */
+ /* Clear Dcache to use as RAM */
+ addis r3,r0,CFG_INIT_RAM_ADDR@h
+ ori r3,r3,CFG_INIT_RAM_ADDR@l
+ addis r4,r0,CFG_INIT_RAM_END@h
+ ori r4,r4,CFG_INIT_RAM_END@l
+ rlwinm. r5,r4,0,27,31
+ rlwinm r5,r4,27,5,31
+ beq ..d_ran3
+ addi r5,r5,0x0001
+..d_ran3:
+ mtctr r5
+..d_ag3:
+ dcbz r0,r3
+ addi r3,r3,32
+ bdnz ..d_ag3
+ /*----------------------------------------------------------------*/
+ /* Setup the stack in internal SRAM */
+ /*----------------------------------------------------------------*/
+ lis r1,CFG_INIT_RAM_ADDR@h
+ ori r1,r1,CFG_INIT_SP_OFFSET@l
+ li r0,0
+ stwu r0,-4(r1)
+ stwu r0,-4(r1) /* Terminate call chain */
+
+ stwu r1,-8(r1) /* Save back chain and move SP */
+ lis r0,RESET_VECTOR@h /* Address of reset vector */
+ ori r0,r0, RESET_VECTOR@l
+ stwu r1,-8(r1) /* Save back chain and move SP */
+ stw r0,+12(r1) /* Save return addr (underflow vect) */
+ sync
+ bl early_sdram_init
+ sync
+#endif /* CONFIG_440EP */
/*
* Copy SPL from cache into internal SRAM
@@ -429,7 +478,7 @@ spl_loop:
start_ram:
sync
isync
-#endif
+#endif /* CONFIG_NAND_SPL */
bl 3f
b _start
@@ -783,7 +832,7 @@ _start:
mtdcr ocmdscr2, r3 /* Set Data Side */
mtdcr ocmiscr2, r3 /* Set Instruction Side */
addis r3,0,0x0800 /* OCM Data Parity Disable - 1 Wait State */
- mtdcr ocmdsisdpc,r4
+ mtdcr ocmdsisdpc,r3
isync
#else /* CONFIG_405EZ */
@@ -810,6 +859,38 @@ _start:
#endif /* CONFIG_405EZ */
#endif
+#ifdef CONFIG_NAND_SPL
+ /*
+ * Copy SPL from cache into internal SRAM
+ */
+ li r4,(CFG_NAND_BOOT_SPL_SIZE >> 2) - 1
+ mtctr r4
+ lis r2,CFG_NAND_BOOT_SPL_SRC@h
+ ori r2,r2,CFG_NAND_BOOT_SPL_SRC@l
+ lis r3,CFG_NAND_BOOT_SPL_DST@h
+ ori r3,r3,CFG_NAND_BOOT_SPL_DST@l
+spl_loop:
+ lwzu r4,4(r2)
+ stwu r4,4(r3)
+ bdnz spl_loop
+
+ /*
+ * Jump to code in RAM
+ */
+ bl 00f
+00: mflr r10
+ lis r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@h
+ ori r3,r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@l
+ sub r10,r10,r3
+ addi r10,r10,28
+ mtlr r10
+ blr
+
+start_ram:
+ sync
+ isync
+#endif /* CONFIG_NAND_SPL */
+
/*----------------------------------------------------------------------- */
/* Setup temporary stack in DCACHE or OCM if needed for SDRAM SPD. */
/*----------------------------------------------------------------------- */
@@ -920,12 +1001,16 @@ _start:
stw r0, +12(r1) /* Save return addr (underflow vect) */
#endif /* !(CFG_INIT_DCACHE_CS || !CFG_TEM_STACK_OCM) */
+#ifdef CONFIG_NAND_SPL
+ bl nand_boot /* will not return */
+#else
GET_GOT /* initialize GOT access */
bl cpu_init_f /* run low-level CPU init code (from Flash) */
/* NEVER RETURNS! */
bl board_init_f /* run first part of init code (from Flash) */
+#endif /* CONFIG_NAND_SPL */
#endif /* CONFIG_405GP || CONFIG_405CR || CONFIG_405 || CONFIG_405EP */
/*----------------------------------------------------------------------- */
@@ -1137,27 +1222,9 @@ crit_return:
lwz r1,GPR1(r1)
SYNC
rfci
-#endif /* CONFIG_NAND_SPL */
/* Cache functions.
*/
-invalidate_icache:
- iccci r0,r0 /* for 405, iccci invalidates the */
- blr /* entire I cache */
-
-invalidate_dcache:
- addi r6,0,0x0000 /* clear GPR 6 */
- /* Do loop for # of dcache congruence classes. */
- lis r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha /* TBS for large sized cache */
- ori r7, r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
- /* NOTE: dccci invalidates both */
- mtctr r7 /* ways in the D cache */
-..dcloop:
- dccci 0,r6 /* invalidate line */
- addi r6,r6, CFG_CACHELINE_SIZE /* bump to next line */
- bdnz ..dcloop
- blr
-
flush_dcache:
addis r9,r0,0x0002 /* set mask for EE and CE msr bits */
ori r9,r9,0x8000
@@ -1255,24 +1322,6 @@ wr_tcr:
blr
/*------------------------------------------------------------------------------- */
-/* Function: in8 */
-/* Description: Input 8 bits */
-/*------------------------------------------------------------------------------- */
- .globl in8
-in8:
- lbz r3,0x0000(r3)
- blr
-
-/*------------------------------------------------------------------------------- */
-/* Function: out8 */
-/* Description: Output 8 bits */
-/*------------------------------------------------------------------------------- */
- .globl out8
-out8:
- stb r4,0x0000(r3)
- blr
-
-/*------------------------------------------------------------------------------- */
/* Function: out16 */
/* Description: Output 16 bits */
/*------------------------------------------------------------------------------- */
@@ -1291,15 +1340,6 @@ out16r:
blr
/*------------------------------------------------------------------------------- */
-/* Function: out32 */
-/* Description: Output 32 bits */
-/*------------------------------------------------------------------------------- */
- .globl out32
-out32:
- stw r4,0x0000(r3)
- blr
-
-/*------------------------------------------------------------------------------- */
/* Function: out32r */
/* Description: Byte reverse and output 32 bits */
/*------------------------------------------------------------------------------- */
@@ -1327,15 +1367,6 @@ in16r:
blr
/*------------------------------------------------------------------------------- */
-/* Function: in32 */
-/* Description: Input 32 bits */
-/*------------------------------------------------------------------------------- */
- .globl in32
-in32:
- lwz 3,0x0000(3)
- blr
-
-/*------------------------------------------------------------------------------- */
/* Function: in32r */
/* Description: Input 32 bits and byte reverse */
/*------------------------------------------------------------------------------- */
@@ -1377,9 +1408,6 @@ ppcSync:
sync
blr
-/*------------------------------------------------------------------------------*/
-
-#ifndef CONFIG_NAND_SPL
/*
* void relocate_code (addr_sp, gd, addr_moni)
*
@@ -1644,8 +1672,105 @@ trap_reloc:
stw r0, 4(r7)
blr
+
+#if defined(CONFIG_440)
+/*----------------------------------------------------------------------------+
+| dcbz_area.
++----------------------------------------------------------------------------*/
+ function_prolog(dcbz_area)
+ rlwinm. r5,r4,0,27,31
+ rlwinm r5,r4,27,5,31
+ beq ..d_ra2
+ addi r5,r5,0x0001
+..d_ra2:mtctr r5
+..d_ag2:dcbz r0,r3
+ addi r3,r3,32
+ bdnz ..d_ag2
+ sync
+ blr
+ function_epilog(dcbz_area)
+
+/*----------------------------------------------------------------------------+
+| dflush. Assume 32K at vector address is cachable.
++----------------------------------------------------------------------------*/
+ function_prolog(dflush)
+ mfmsr r9
+ rlwinm r8,r9,0,15,13
+ rlwinm r8,r8,0,17,15
+ mtmsr r8
+ addi r3,r0,0x0000
+ mtspr dvlim,r3
+ mfspr r3,ivpr
+ addi r4,r0,1024
+ mtctr r4
+..dflush_loop:
+ lwz r6,0x0(r3)
+ addi r3,r3,32
+ bdnz ..dflush_loop
+ addi r3,r3,-32
+ mtctr r4
+..ag: dcbf r0,r3
+ addi r3,r3,-32
+ bdnz ..ag
+ sync
+ mtmsr r9
+ blr
+ function_epilog(dflush)
+#endif /* CONFIG_440 */
#endif /* CONFIG_NAND_SPL */
+/*------------------------------------------------------------------------------- */
+/* Function: in8 */
+/* Description: Input 8 bits */
+/*------------------------------------------------------------------------------- */
+ .globl in8
+in8:
+ lbz r3,0x0000(r3)
+ blr
+
+/*------------------------------------------------------------------------------- */
+/* Function: out8 */
+/* Description: Output 8 bits */
+/*------------------------------------------------------------------------------- */
+ .globl out8
+out8:
+ stb r4,0x0000(r3)
+ blr
+
+/*------------------------------------------------------------------------------- */
+/* Function: out32 */
+/* Description: Output 32 bits */
+/*------------------------------------------------------------------------------- */
+ .globl out32
+out32:
+ stw r4,0x0000(r3)
+ blr
+
+/*------------------------------------------------------------------------------- */
+/* Function: in32 */
+/* Description: Input 32 bits */
+/*------------------------------------------------------------------------------- */
+ .globl in32
+in32:
+ lwz 3,0x0000(3)
+ blr
+
+invalidate_icache:
+ iccci r0,r0 /* for 405, iccci invalidates the */
+ blr /* entire I cache */
+
+invalidate_dcache:
+ addi r6,0,0x0000 /* clear GPR 6 */
+ /* Do loop for # of dcache congruence classes. */
+ lis r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha /* TBS for large sized cache */
+ ori r7, r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
+ /* NOTE: dccci invalidates both */
+ mtctr r7 /* ways in the D cache */
+..dcloop:
+ dccci 0,r6 /* invalidate line */
+ addi r6,r6, CFG_CACHELINE_SIZE /* bump to next line */
+ bdnz ..dcloop
+ blr
/**************************************************************************/
/* PPC405EP specific stuff */
@@ -1892,13 +2017,6 @@ pll_wait:
#endif /* CONFIG_405EP */
#if defined(CONFIG_440)
-#define function_prolog(func_name) .text; \
- .align 2; \
- .globl func_name; \
- func_name:
-#define function_epilog(func_name) .type func_name,@function; \
- .size func_name,.-func_name
-
/*----------------------------------------------------------------------------+
| mttlb3.
+----------------------------------------------------------------------------*/
@@ -1946,47 +2064,4 @@ pll_wait:
TLBRE(3,3,0)
blr
function_epilog(mftlb1)
-
-/*----------------------------------------------------------------------------+
-| dcbz_area.
-+----------------------------------------------------------------------------*/
- function_prolog(dcbz_area)
- rlwinm. r5,r4,0,27,31
- rlwinm r5,r4,27,5,31
- beq ..d_ra2
- addi r5,r5,0x0001
-..d_ra2:mtctr r5
-..d_ag2:dcbz r0,r3
- addi r3,r3,32
- bdnz ..d_ag2
- sync
- blr
- function_epilog(dcbz_area)
-
-/*----------------------------------------------------------------------------+
-| dflush. Assume 32K at vector address is cachable.
-+----------------------------------------------------------------------------*/
- function_prolog(dflush)
- mfmsr r9
- rlwinm r8,r9,0,15,13
- rlwinm r8,r8,0,17,15
- mtmsr r8
- addi r3,r0,0x0000
- mtspr dvlim,r3
- mfspr r3,ivpr
- addi r4,r0,1024
- mtctr r4
-..dflush_loop:
- lwz r6,0x0(r3)
- addi r3,r3,32
- bdnz ..dflush_loop
- addi r3,r3,-32
- mtctr r4
-..ag: dcbf r0,r3
- addi r3,r3,-32
- bdnz ..ag
- sync
- mtmsr r9
- blr
- function_epilog(dflush)
#endif /* CONFIG_440 */