From d1cbe85b084ce543ba0b09def03a1b20940e6c03 Mon Sep 17 00:00:00 2001 From: wdenk Date: Sat, 28 Jun 2003 17:24:46 +0000 Subject: Merge from "stable branch", tag LABEL_2003_06_28_1800-stable: - Allow to call sysmon function interactively - PIC on LWMON board needs delay after power-on - Add missing RSR definitions for MPC8xx - Improve log buffer handling: guarantee clean reset after power-on - Add support for EXBITGEN board - Add support for SL8245 board --- board/exbitgen/Makefile | 49 +++ board/exbitgen/config.mk | 33 ++ board/exbitgen/exbitgen.c | 117 ++++++ board/exbitgen/exbitgen.h | 52 +++ board/exbitgen/flash.c | 597 +++++++++++++++++++++++++++ board/exbitgen/init.S | 1009 +++++++++++++++++++++++++++++++++++++++++++++ board/exbitgen/u-boot.lds | 144 +++++++ board/lwmon/lwmon.c | 3 + board/sl8245/Makefile | 40 ++ board/sl8245/config.mk | 30 ++ board/sl8245/flash.c | 488 ++++++++++++++++++++++ board/sl8245/sl8245.c | 86 ++++ board/sl8245/u-boot.lds | 128 ++++++ 13 files changed, 2776 insertions(+) create mode 100644 board/exbitgen/Makefile create mode 100644 board/exbitgen/config.mk create mode 100644 board/exbitgen/exbitgen.c create mode 100644 board/exbitgen/exbitgen.h create mode 100644 board/exbitgen/flash.c create mode 100644 board/exbitgen/init.S create mode 100644 board/exbitgen/u-boot.lds create mode 100644 board/sl8245/Makefile create mode 100644 board/sl8245/config.mk create mode 100644 board/sl8245/flash.c create mode 100644 board/sl8245/sl8245.c create mode 100644 board/sl8245/u-boot.lds (limited to 'board') diff --git a/board/exbitgen/Makefile b/board/exbitgen/Makefile new file mode 100644 index 0000000000..34bd4b2090 --- /dev/null +++ b/board/exbitgen/Makefile @@ -0,0 +1,49 @@ +# +# (C) Copyright 2000 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = lib$(BOARD).a + +OBJS = $(BOARD).o flash.o + +SOBJS = init.o + + +$(LIB): $(OBJS) $(SOBJS) + $(AR) crv $@ $^ + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/board/exbitgen/config.mk b/board/exbitgen/config.mk new file mode 100644 index 0000000000..42ea0c6d78 --- /dev/null +++ b/board/exbitgen/config.mk @@ -0,0 +1,33 @@ +# +# (C) Copyright 2000 +# 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 +# + +# +# ExbitGen board +# + +LDFLAGS += $(LINKER_UNDEFS) + +TEXT_BASE := 0xFFF80000 +#TEXT_BASE := 0x00100000 + +PLATFORM_RELFLAGS := $(PLATFORM_RELFLAGS) diff --git a/board/exbitgen/exbitgen.c b/board/exbitgen/exbitgen.c new file mode 100644 index 0000000000..f2cd8caec0 --- /dev/null +++ b/board/exbitgen/exbitgen.c @@ -0,0 +1,117 @@ +#include +#include +#include +#include "exbitgen.h" + +/* ************************************************************************ */ +int board_pre_init (void) +/* ------------------------------------------------------------------------ -- + * Purpose : + * Remarks : + * Restrictions: + * See also : + * Example : + * ************************************************************************ */ +{ + unsigned long i; + + /*-------------------------------------------------------------------------+ + | Interrupt controller setup for the Walnut board. + | Note: IRQ 0-15 405GP internally generated; active high; level sensitive + | IRQ 16 405GP internally generated; active low; level sensitive + | IRQ 17-24 RESERVED + | IRQ 25 (EXT IRQ 0) FPGA; active high; level sensitive + | IRQ 26 (EXT IRQ 1) SMI; active high; level sensitive + | IRQ 27 (EXT IRQ 2) Not Used + | IRQ 28 (EXT IRQ 3) PCI SLOT 3; active low; level sensitive + | IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive + | IRQ 30 (EXT IRQ 5) PCI SLOT 1; active low; level sensitive + | IRQ 31 (EXT IRQ 6) PCI SLOT 0; active low; level sensitive + | Note for Walnut board: + | An interrupt taken for the FPGA (IRQ 25) indicates that either + | the Mouse, Keyboard, IRDA, or External Expansion caused the + | interrupt. The FPGA must be read to determine which device + | caused the interrupt. The default setting of the FPGA clears + | + +-------------------------------------------------------------------------*/ + + mtdcr (uicsr, 0xFFFFFFFF); /* clear all ints */ + mtdcr (uicer, 0x00000000); /* disable all ints */ + mtdcr (uiccr, 0x00000020); /* set all but FPGA SMI to be non-critical */ + mtdcr (uicpr, 0xFFFFFF90); /* set int polarities */ + mtdcr (uictr, 0x10000000); /* set int trigger levels */ + mtdcr (uicvcr, 0x00000001); /* set vect base=0,INT0 highest priority */ + mtdcr (uicsr, 0xFFFFFFFF); /* clear all ints */ + + /* Perform reset of PHY connected to PPC via register in CPLD */ + out8 (PHY_CTRL_ADDR, 0x2e); /* activate nRESET,FDX,F100,ANEN, enable output */ + for (i = 0; i < 10000000; i++) { + ; + } + out8 (PHY_CTRL_ADDR, 0x2f); /* deactivate nRESET */ + + return 0; +} + + +/* ************************************************************************ */ +int checkboard (void) +/* ------------------------------------------------------------------------ -- + * Purpose : + * Remarks : + * Restrictions: + * See also : + * Example : + * ************************************************************************ */ +{ + printf ("Exbit H/W id: %d\n", in8 (HW_ID_ADDR)); + return (0); +} + +/* ************************************************************************ */ +long int initdram (int board_type) +/* ------------------------------------------------------------------------ -- + * Purpose : Determines size of mounted DRAM. + * Remarks : Size is determined by reading SDRAM configuration registers as + * set up by sdram_init. + * Restrictions: + * See also : + * Example : + * ************************************************************************ */ +{ + ulong tot_size; + ulong bank_size; + ulong tmp; + + tot_size = 0; + + mtdcr (memcfga, mem_mb0cf); + tmp = mfdcr (memcfgd); + if (tmp & 0x00000001) { + bank_size = 0x00400000 << ((tmp >> 17) & 0x7); + tot_size += bank_size; + } + + mtdcr (memcfga, mem_mb1cf); + tmp = mfdcr (memcfgd); + if (tmp & 0x00000001) { + bank_size = 0x00400000 << ((tmp >> 17) & 0x7); + tot_size += bank_size; + } + + mtdcr (memcfga, mem_mb2cf); + tmp = mfdcr (memcfgd); + if (tmp & 0x00000001) { + bank_size = 0x00400000 << ((tmp >> 17) & 0x7); + tot_size += bank_size; + } + + mtdcr (memcfga, mem_mb3cf); + tmp = mfdcr (memcfgd); + if (tmp & 0x00000001) { + bank_size = 0x00400000 << ((tmp >> 17) & 0x7); + tot_size += bank_size; + } + + return tot_size; +} diff --git a/board/exbitgen/exbitgen.h b/board/exbitgen/exbitgen.h new file mode 100644 index 0000000000..058ad48ea2 --- /dev/null +++ b/board/exbitgen/exbitgen.h @@ -0,0 +1,52 @@ +/* + * (C) Copyright 2003 + * 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 + */ + +#define GPIO_CPU_LED GPIO_3 + + +#define CPLD_BASE 0x10000000 /* t.b.m. */ +#define DEBUG_LEDS_ADDR CPLD_BASE + 0x01 +#define HW_ID_ADDR CPLD_BASE + 0x02 +#define DIP_SWITCH_ADDR CPLD_BASE + 0x04 +#define PHY_CTRL_ADDR CPLD_BASE + 0x05 +#define SPI_OUT_ADDR CPLD_BASE + 0x07 +#define SPI_IN_ADDR CPLD_BASE + 0x08 +#define MDIO_OUT_ADDR CPLD_BASE + 0x09 +#define MDIO_IN_ADDR CPLD_BASE + 0x0A +#define MISC_OUT_ADDR CPLD_BASE + 0x0B + +/* Addresses used on I2C bus */ +#define LM75_CHIP_ADDR 0x9C +#define LM75_CPU_ADDR 0x9E +#define SDRAM_SPD_ADDR 0xA0 + +#define SDRAM_SPD_WRITE_ADDRESS (SDRAM_SPD_ADDR) +#define SDRAM_SPD_READ_ADDRESS (SDRAM_SPD_ADDR+1) + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif diff --git a/board/exbitgen/flash.c b/board/exbitgen/flash.c new file mode 100644 index 0000000000..f687ea3a26 --- /dev/null +++ b/board/exbitgen/flash.c @@ -0,0 +1,597 @@ +/* + * (C) Copyright 2003 + * 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 + */ + +/* + * Modified 4/5/2001 + * Wait for completion of each sector erase command issued + * 4/5/2001 + * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com + */ + +#include +#include +#include +#include + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +/*----------------------------------------------------------------------- + * Functions + */ +static ulong flash_get_size (vu_long *addr, flash_info_t *info); +static int write_word (flash_info_t *info, ulong dest, ulong data); + +#ifdef MEIGSBOARD_ONBOARD_FLASH /* onboard = 2MB */ +# ifdef CONFIG_EXBITGEN +# define FLASH_WORD_SIZE unsigned long +# endif +#else /* Meigsboard socket flash = 512KB */ +# ifdef CONFIG_EXBITGEN +# define FLASH_WORD_SIZE unsigned char +# endif +#endif + +#ifdef CONFIG_EXBITGEN +#define ADDR0 0x5555 +#define ADDR1 0x2aaa +#define FLASH_WORD_SIZE unsigned char +#endif + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ + unsigned long bank_size; + unsigned long tot_size; + unsigned long bank_addr; + int i; + + /* Init: no FLASHes known */ + for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) { + flash_info[i].flash_id = FLASH_UNKNOWN; + flash_info[i].size = 0; + } + + tot_size = 0; + + /* Detect Boot Flash */ + bank_addr = CFG_FLASH0_BASE; + bank_size = flash_get_size((vu_long *)bank_addr, &flash_info[0]); + if (bank_size > 0) { + (void)flash_protect(FLAG_PROTECT_CLEAR, + bank_addr, + bank_addr + bank_size - 1, + &flash_info[0]); + } + if (flash_info[0].flash_id == FLASH_UNKNOWN) { + printf ("## Unknown FLASH on Boot Flash Bank\n"); + } + flash_info[0].size = bank_size; + tot_size += bank_size; + + /* Detect Application Flash */ + bank_addr = CFG_FLASH1_BASE; + for (i = 1; i < CFG_MAX_FLASH_BANKS; ++i) { + bank_size = flash_get_size((vu_long *)bank_addr, &flash_info[i]); + if (flash_info[i].flash_id == FLASH_UNKNOWN) { + break; + } + if (bank_size > 0) { + (void)flash_protect(FLAG_PROTECT_CLEAR, + bank_addr, + bank_addr + bank_size - 1, + &flash_info[i]); + } + flash_info[i].size = bank_size; + tot_size += bank_size; + bank_addr += bank_size; + } + if (flash_info[1].flash_id == FLASH_UNKNOWN) { + printf ("## Unknown FLASH on Application Flash Bank\n"); + } + + /* Protect monitor and environment sectors */ +#if CFG_MONITOR_BASE >= CFG_FLASH0_BASE + flash_protect(FLAG_PROTECT_SET, + CFG_MONITOR_BASE, + CFG_MONITOR_BASE + monitor_flash_len - 1, + &flash_info[0]); +#if 0xfffffffc >= CFG_FLASH0_BASE +#if 0xfffffffc <= CFG_FLASH0_BASE + CFG_FLASH0_SIZE - 1 + flash_protect(FLAG_PROTECT_SET, + 0xfffffffc, 0xffffffff, + &flash_info[0]); +#endif +#endif +#endif + +#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR) + flash_protect(FLAG_PROTECT_SET, + CFG_ENV_ADDR, + CFG_ENV_ADDR + CFG_ENV_SIZE - 1, + &flash_info[0]); +#endif + + return tot_size; +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t *info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("missing or unknown FLASH type\n"); + return; + } + + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_AMD: printf ("AMD "); break; + case FLASH_MAN_FUJ: printf ("FUJITSU "); break; + case FLASH_MAN_SST: printf ("SST "); break; + default: printf ("Unknown Vendor "); break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_AM040: printf ("AM29F040 (512 Kbit, uniform sector size)\n"); + break; + case FLASH_AM400B: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n"); + break; + case FLASH_AM400T: printf ("AM29LV400T (4 Mbit, top boot sector)\n"); + break; + case FLASH_AM800B: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n"); + break; + case FLASH_AM800T: printf ("AM29LV800T (8 Mbit, top boot sector)\n"); + break; + case FLASH_AM160B: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n"); + break; + case FLASH_AM160T: printf ("AM29LV160T (16 Mbit, top boot sector)\n"); + break; + case FLASH_AM320B: printf ("AM29LV320B (32 Mbit, bottom boot sect)\n"); + break; + case FLASH_AM320T: printf ("AM29LV320T (32 Mbit, top boot sector)\n"); + break; + case FLASH_AMDLV033C: printf ("AM29LV033C (32 Mbit, uniform sector size)\n"); + break; + case FLASH_AMDLV065D: printf ("AM29LV065D (64 Mbit, uniform sector size)\n"); + break; + case FLASH_SST800A: printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n"); + break; + case FLASH_SST160A: printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n"); + break; + case FLASH_SST040: printf ("SST39LF/VF040 (4 Mbit, uniform sector size)\n"); + break; + default: printf ("Unknown Chip Type\n"); + break; + } + + printf (" Size: %ld KB in %d Sectors\n", + info->size >> 10, info->sector_count); + + printf (" Sector Start Addresses:"); + for (i=0; isector_count; ++i) { + if ((i % 5) == 0) + printf ("\n "); + printf (" %08lX%s", + info->start[i], + info->protect[i] ? " (RO)" : " " + ); + } + printf ("\n"); +} + +/*----------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------- + */ + +/* + * The following code cannot be run from FLASH! + */ +static ulong flash_get_size (vu_long *addr, flash_info_t *info) +{ + short i; + FLASH_WORD_SIZE value; + ulong base = (ulong)addr; + volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)addr; + + /* Write auto select command: read Manufacturer ID */ + addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA; + addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055; + addr2[ADDR0] = (FLASH_WORD_SIZE)0x00900090; + + value = addr2[0]; + + switch (value) { + case (FLASH_WORD_SIZE)AMD_MANUFACT: + info->flash_id = FLASH_MAN_AMD; + break; + case (FLASH_WORD_SIZE)FUJ_MANUFACT: + info->flash_id = FLASH_MAN_FUJ; + break; + case (FLASH_WORD_SIZE)SST_MANUFACT: + info->flash_id = FLASH_MAN_SST; + break; + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + return (0); /* no or unknown flash */ + } + + value = addr2[1]; /* device ID */ + + switch (value) { + case (FLASH_WORD_SIZE)AMD_ID_F040B: + info->flash_id += FLASH_AM040; + info->sector_count = 8; + info->size = 0x0080000; /* => 512 ko */ + break; + case (FLASH_WORD_SIZE)AMD_ID_LV400T: + info->flash_id += FLASH_AM400T; + info->sector_count = 11; + info->size = 0x00080000; + break; /* => 0.5 MB */ + + case (FLASH_WORD_SIZE)AMD_ID_LV400B: + info->flash_id += FLASH_AM400B; + info->sector_count = 11; + info->size = 0x00080000; + break; /* => 0.5 MB */ + + case (FLASH_WORD_SIZE)AMD_ID_LV800T: + info->flash_id += FLASH_AM800T; + info->sector_count = 19; + info->size = 0x00100000; + break; /* => 1 MB */ + + case (FLASH_WORD_SIZE)AMD_ID_LV800B: + info->flash_id += FLASH_AM800B; + info->sector_count = 19; + info->size = 0x00100000; + break; /* => 1 MB */ + + case (FLASH_WORD_SIZE)AMD_ID_LV160T: + info->flash_id += FLASH_AM160T; + info->sector_count = 35; + info->size = 0x00200000; + break; /* => 2 MB */ + + case (FLASH_WORD_SIZE)AMD_ID_LV160B: + info->flash_id += FLASH_AM160B; + info->sector_count = 35; + info->size = 0x00200000; + break; /* => 2 MB */ + + case (FLASH_WORD_SIZE)AMD_ID_LV033C: + info->flash_id += FLASH_AMDLV033C; + info->sector_count = 64; + info->size = 0x00400000; + break; /* => 4 MB */ + + case (FLASH_WORD_SIZE)AMD_ID_LV065D: + info->flash_id += FLASH_AMDLV065D; + info->sector_count = 128; + info->size = 0x00800000; + break; /* => 8 MB */ + + case (FLASH_WORD_SIZE)AMD_ID_LV320T: + info->flash_id += FLASH_AM320T; + info->sector_count = 67; + info->size = 0x00400000; + break; /* => 4 MB */ + + case (FLASH_WORD_SIZE)AMD_ID_LV320B: + info->flash_id += FLASH_AM320B; + info->sector_count = 67; + info->size = 0x00400000; + break; /* => 4 MB */ + + case (FLASH_WORD_SIZE)SST_ID_xF800A: + info->flash_id += FLASH_SST800A; + info->sector_count = 16; + info->size = 0x00100000; + break; /* => 1 MB */ + + case (FLASH_WORD_SIZE)SST_ID_xF160A: + info->flash_id += FLASH_SST160A; + info->sector_count = 32; + info->size = 0x00200000; + break; /* => 2 MB */ + case (FLASH_WORD_SIZE)SST_ID_xF040: + info->flash_id += FLASH_SST040; + info->sector_count = 128; + info->size = 0x00080000; + break; /* => 512KB */ + + default: + info->flash_id = FLASH_UNKNOWN; + return (0); /* => no or unknown flash */ + + } + + /* set up sector start address table */ + if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) || + (info->flash_id == FLASH_AM040) || + (info->flash_id == FLASH_AMDLV033C) || + (info->flash_id == FLASH_AMDLV065D)) { + ulong sectsize = info->size / info->sector_count; + for (i = 0; i < info->sector_count; i++) + info->start[i] = base + (i * sectsize); + } else { + if (info->flash_id & FLASH_BTYPE) { + /* set sector offsets for bottom boot block type */ + info->start[0] = base + 0x00000000; + info->start[1] = base + 0x00004000; + info->start[2] = base + 0x00006000; + info->start[3] = base + 0x00008000; + for (i = 4; i < info->sector_count; i++) { + info->start[i] = base + (i * 0x00010000) - 0x00030000; + } + } else { + /* set sector offsets for top boot block type */ + i = info->sector_count - 1; + info->start[i--] = base + info->size - 0x00004000; + info->start[i--] = base + info->size - 0x00006000; + info->start[i--] = base + info->size - 0x00008000; + for (; i >= 0; i--) { + info->start[i] = base + i * 0x00010000; + } + } + } + + /* check for protected sectors */ + for (i = 0; i < info->sector_count; i++) { + /* read sector protection at sector address, (A7 .. A0) = 0x02 */ + /* D0 = 1 if protected */ + + addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]); + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) + info->protect[i] = 0; + else + info->protect[i] = addr2[2] & 1; + } + + /* switch to the read mode */ + if (info->flash_id != FLASH_UNKNOWN) { + addr2 = (FLASH_WORD_SIZE *)info->start[0]; + *addr2 = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */ + } + + return (info->size); +} + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t *info, int s_first, int s_last) +{ + volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]); + volatile FLASH_WORD_SIZE *addr2; + int flag, prot, sect; + ulong start, now, last; + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return 1; + } + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("Can't erase unknown flash type - aborted\n"); + return 1; + } + + prot = 0; + for (sect=s_first; sect<=s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } + + start = get_timer (0); + last = start; + /* Start erase on unprotected sectors */ + for (sect = s_first; sect <= s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + addr2 = (FLASH_WORD_SIZE *)(info->start[sect]); + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA; + addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055; + addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080; + addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA; + addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055; + addr2[0] = (FLASH_WORD_SIZE)0x00300030; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* wait at least 80us - let's wait 1 ms */ + udelay (1000); + + while ((addr2[0] & 0x00800080) != + (FLASH_WORD_SIZE) 0x00800080) { + if ((now=get_timer(start)) > + CFG_FLASH_ERASE_TOUT) { + printf ("Timeout\n"); + addr[0] = (FLASH_WORD_SIZE)0x00F000F0; + return 1; + } + + /* show that we're waiting */ + if ((now - last) > 1000) { /* every second */ + putc ('.'); + last = now; + } + } + + addr[0] = (FLASH_WORD_SIZE)0x00F000F0; + } + } + + printf (" done\n"); + + return 0; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ + +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + ulong cp, wp, data; + int i, l, rc; + + wp = (addr & ~3); /* get lower word aligned address */ + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i=0, cp=wp; i0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt==0 && i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + } + + /* + * handle word aligned part + */ + while (cnt >= 4) { + data = 0; + for (i=0; i<4; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + cnt -= 4; + } + + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + return (write_word(info, wp, data)); +} + +/*----------------------------------------------------------------------- + * Write a word to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_word (flash_info_t *info, ulong dest, ulong data) +{ + volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)(info->start[0]); + volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *)dest; + volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *)&data; + ulong start; + int flag; + int i; + + /* Check if Flash is (sufficiently) erased */ + if ((*((volatile ulong *)dest) & data) != data) { + printf("dest = %08lx, *dest = %08lx, data = %08lx\n", + dest, *(volatile ulong *)dest, data); + return 2; + } + + for (i=0; i < 4/sizeof(FLASH_WORD_SIZE); i++) { + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA; + addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055; + addr2[ADDR0] = (FLASH_WORD_SIZE)0x00A000A0; + dest2[i] = data2[i]; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* data polling for D7 */ + start = get_timer (0); + while ((dest2[i] & 0x00800080) != (data2[i] & 0x00800080)) { + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + addr2[0] = (FLASH_WORD_SIZE)0x00F000F0; + return (1); + } + } + } + + addr2[0] = (FLASH_WORD_SIZE)0x00F000F0; + + return (0); +} + +/*----------------------------------------------------------------------- + */ diff --git a/board/exbitgen/init.S b/board/exbitgen/init.S new file mode 100644 index 0000000000..96b0abae1b --- /dev/null +++ b/board/exbitgen/init.S @@ -0,0 +1,1009 @@ +/*----------------------------------------------------------------------+ + * + * This source code has been made available to you by IBM on an AS-IS + * basis. Anyone receiving this source is licensed under IBM + * copyrights to use it in any way he or she deems fit, including + * copying it, modifying it, compiling it, and redistributing it either + * with or without modifications. No license under IBM patents or + * patent applications is to be implied by the copyright license. + * + * Any user of this software should understand that IBM cannot provide + * technical support for this software and will not be responsible for + * any consequences resulting from the use of this software. + * + * Any person who transfers this source code or any derivative work + * must include the IBM copyright notice, this paragraph, and the + * preceding two paragraphs in the transferred software. + * + * COPYRIGHT I B M CORPORATION 1995 + * LICENSED MATERIAL - PROGRAM PROPERTY OF I B M + *----------------------------------------------------------------------- + */ + +#include +#include +#include "config.h" + +#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ +#define FPGA_BRDC 0xF0300004 + +#include +#include + +#include +#include + +#include "exbitgen.h" + +/* IIC declarations (This is an extract from 405gp_i2c.h, which also contains some */ +/* c-code declarations and consequently can't be included here). */ +/* (Possibly to be solved somehow else). */ +/*--------------------------------------------------------------------- */ +#define I2C_REGISTERS_BASE_ADDRESS 0xEF600500 +#define IIC_MDBUF (I2C_REGISTERS_BASE_ADDRESS+IICMDBUF) +#define IIC_SDBUF (I2C_REGISTERS_BASE_ADDRESS+IICSDBUF) +#define IIC_LMADR (I2C_REGISTERS_BASE_ADDRESS+IICLMADR) +#define IIC_HMADR (I2C_REGISTERS_BASE_ADDRESS+IICHMADR) +#define IIC_CNTL (I2C_REGISTERS_BASE_ADDRESS+IICCNTL) +#define IIC_MDCNTL (I2C_REGISTERS_BASE_ADDRESS+IICMDCNTL) +#define IIC_STS (I2C_REGISTERS_BASE_ADDRESS+IICSTS) +#define IIC_EXTSTS (I2C_REGISTERS_BASE_ADDRESS+IICEXTSTS) +#define IIC_LSADR (I2C_REGISTERS_BASE_ADDRESS+IICLSADR) +#define IIC_HSADR (I2C_REGISTERS_BASE_ADDRESS+IICHSADR) +#define IIC_CLKDIV (I2C_REGISTERS_BASE_ADDRESS+IICCLKDIV) +#define IIC_INTRMSK (I2C_REGISTERS_BASE_ADDRESS+IICINTRMSK) +#define IIC_XFRCNT (I2C_REGISTERS_BASE_ADDRESS+IICXFRCNT) +#define IIC_XTCNTLSS (I2C_REGISTERS_BASE_ADDRESS+IICXTCNTLSS) +#define IIC_DIRECTCNTL (I2C_REGISTERS_BASE_ADDRESS+IICDIRECTCNTL) + +/* MDCNTL Register Bit definition */ +#define IIC_MDCNTL_HSCL 0x01 +#define IIC_MDCNTL_EUBS 0x02 +#define IIC_MDCNTL_FMDB 0x40 +#define IIC_MDCNTL_FSDB 0x80 + +/* CNTL Register Bit definition */ +#define IIC_CNTL_PT 0x01 +#define IIC_CNTL_READ 0x02 +#define IIC_CNTL_CHT 0x04 + +/* STS Register Bit definition */ +#define IIC_STS_PT 0X01 +#define IIC_STS_ERR 0X04 +#define IIC_STS_MDBS 0X20 + +/* EXTSTS Register Bit definition */ +#define IIC_EXTSTS_XFRA 0X01 +#define IIC_EXTSTS_ICT 0X02 +#define IIC_EXTSTS_LA 0X04 + +/* LED codes used for inditing progress and errors during read of DIMM SPD. */ +/*--------------------------------------------------------------------- */ +#define LED_SDRAM_CODE_1 0xef +#define LED_SDRAM_CODE_2 0xee +#define LED_SDRAM_CODE_3 0xed +#define LED_SDRAM_CODE_4 0xec +#define LED_SDRAM_CODE_5 0xeb +#define LED_SDRAM_CODE_6 0xea +#define LED_SDRAM_CODE_7 0xe9 +#define LED_SDRAM_CODE_8 0xe8 +#define LED_SDRAM_CODE_9 0xe7 +#define LED_SDRAM_CODE_10 0xe6 +#define LED_SDRAM_CODE_11 0xe5 +#define LED_SDRAM_CODE_12 0xe4 +#define LED_SDRAM_CODE_13 0xe3 +#define LED_SDRAM_CODE_14 0xe2 +#define LED_SDRAM_CODE_15 0xe1 +#define LED_SDRAM_CODE_16 0xe0 + + +#define TIMEBASE_10PS (1000000000 / CONFIG_SYS_CLK_FREQ) * 100 + +#define FLASH_8bit_AP 0x9B015480 +#define FLASH_8bit_CR 0xFFF18000 /* 1MB(min), 8bit, R/W */ + +#define FLASH_32bit_AP 0x9B015480 +#define FLASH_32bit_CR 0xFFE3C000 /* 2MB, 32bit, R/W */ + + +#define WDCR_EBC(reg,val) addi r4,0,reg;\ + mtdcr ebccfga,r4;\ + addis r4,0,val@h;\ + ori r4,r4,val@l;\ + mtdcr ebccfgd,r4 + +/*--------------------------------------------------------------------- + * Function: ext_bus_cntlr_init + * Description: Initializes the External Bus Controller for the external + * peripherals. IMPORTANT: For pass1 this code must run from + * cache since you can not reliably change a peripheral banks + * timing register (pbxap) while running code from that bank. + * For ex., since we are running from ROM on bank 0, we can NOT + * execute the code that modifies bank 0 timings from ROM, so + * we run it from cache. + * Bank 0 - Boot flash + * Bank 1-4 - application flash + * Bank 5 - CPLD + * Bank 6 - not used + * Bank 7 - Heathrow chip + *--------------------------------------------------------------------- + */ + .globl ext_bus_cntlr_init +ext_bus_cntlr_init: + mflr r4 /* save link register */ + bl ..getAddr +..getAddr: + mflr r3 /* get address of ..getAddr */ + mtlr r4 /* restore link register */ + addi r4,0,14 /* set ctr to 10; used to prefetch */ + mtctr r4 /* 10 cache lines to fit this function */ + /* in cache (gives us 8x10=80 instrctns) */ +..ebcloop: + icbt r0,r3 /* prefetch cache line for addr in r3 */ + addi r3,r3,32 /* move to next cache line */ + bdnz ..ebcloop /* continue for 10 cache lines */ + + mflr r31 /* save link register */ + + /*----------------------------------------------------------- + * Delay to ensure all accesses to ROM are complete before changing + * bank 0 timings. 200usec should be enough. + * 200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles + *----------------------------------------------------------- + */ + + addis r3,0,0x0 + ori r3,r3,0xA000 /* ensure 200usec have passed since reset */ + mtctr r3 +..spinlp: + bdnz ..spinlp /* spin loop */ + + /*--------------------------------------------------------------- + * Memory Bank 0 (Boot Flash) initialization + *--------------------------------------------------------------- + */ + WDCR_EBC(pb0ap, FLASH_32bit_AP) + WDCR_EBC(pb0cr, 0xffe38000) +/*pnc WDCR_EBC(pb0cr, FLASH_32bit_CR) */ + + /*--------------------------------------------------------------- + * Memory Bank 5 (CPLD) initialization + *--------------------------------------------------------------- + */ + WDCR_EBC(pb5ap, 0x01010040) +/*jsa recommendation: WDCR_EBC(pb5ap, 0x00010040) */ + WDCR_EBC(pb5cr, 0x10038000) + + /*--------------------------------------------------------------- */ + /* Memory Bank 6 (not used) initialization */ + /*--------------------------------------------------------------- */ + WDCR_EBC(pb6cr, 0x00000000) + + /* Read HW ID to determine whether old H2 board or new generic CPU board */ + addis r3, 0, HW_ID_ADDR@h + ori r3, r3, HW_ID_ADDR@l + lbz r3,0x0000(r3) + cmpi 0, r3, 1 /* if (HW_ID==1) */ + beq setup_h2evalboard /* then jump */ + cmpi 0, r3, 2 /* if (HW_ID==2) */ + beq setup_genieboard /* then jump */ + cmpi 0, r3, 3 /* if (HW_ID==3) */ + beq setup_genieboard /* then jump */ + +setup_genieboard: + /*--------------------------------------------------------------- */ + /* Memory Bank 1 (Application Flash) initialization for generic CPU board */ + /*--------------------------------------------------------------- */ +/* WDCR_EBC(pb1ap, 0x7b015480) /###* T.B.M. */ +/* WDCR_EBC(pb1ap, 0x7F8FFE80) /###* T.B.M. */ + WDCR_EBC(pb1ap, 0x9b015480) /* hlb-20020207: burst 8 bit 6 cycles */ + +/* WDCR_EBC(pb1cr, 0x20098000) /###* 16 MB */ + WDCR_EBC(pb1cr, 0x200B8000) /* 32 MB */ + + /*--------------------------------------------------------------- */ + /* Memory Bank 4 (Onboard FPGA) initialization for generic CPU board */ + /*--------------------------------------------------------------- */ + WDCR_EBC(pb4ap, 0x01010000) /* */ + WDCR_EBC(pb4cr, 0x1021c000) /* */ + + /*--------------------------------------------------------------- */ + /* Memory Bank 7 (Heathrow chip on Reference board) initialization */ + /*--------------------------------------------------------------- */ + WDCR_EBC(pb7ap, 0x200ffe80) /* No Ready, many wait states (let reflections die out) */ + WDCR_EBC(pb7cr, 0X4001A000) + + bl setup_continue + + +setup_h2evalboard: + /*--------------------------------------------------------------- */ + /* Memory Bank 1 (Application Flash) initialization */ + /*--------------------------------------------------------------- */ + WDCR_EBC(pb1ap, 0x7b015480) /* T.B.M. */ +/*3010 WDCR_EBC(pb1ap, 0x7F8FFE80) /###* T.B.M. */ + WDCR_EBC(pb1cr, 0x20058000) + + /*--------------------------------------------------------------- */ + /* Memory Bank 2 (Application Flash) initialization */ + /*--------------------------------------------------------------- */ + WDCR_EBC(pb2ap, 0x7b015480) /* T.B.M. */ +/*3010 WDCR_EBC(pb2ap, 0x7F8FFE80) /###* T.B.M. */ + WDCR_EBC(pb2cr, 0x20458000) + + /*--------------------------------------------------------------- */ + /* Memory Bank 3 (Application Flash) initialization */ + /*--------------------------------------------------------------- */ + WDCR_EBC(pb3ap, 0x7b015480) /* T.B.M. */ +/*3010 WDCR_EBC(pb3ap, 0x7F8FFE80) /###* T.B.M. */ + WDCR_EBC(pb3cr, 0x20858000) + + /*--------------------------------------------------------------- */ + /* Memory Bank 4 (Application Flash) initialization */ + /*--------------------------------------------------------------- */ + WDCR_EBC(pb4ap, 0x7b015480) /* T.B.M. */ +/*3010 WDCR_EBC(pb4ap, 0x7F8FFE80) /###* T.B.M. */ + WDCR_EBC(pb4cr, 0x20C58000) + + /*--------------------------------------------------------------- */ + /* Memory Bank 7 (Heathrow chip) initialization */ + /*--------------------------------------------------------------- */ + WDCR_EBC(pb7ap, 0x02000280) /* No Ready, 4 wait states */ + WDCR_EBC(pb7cr, 0X4001A000) + +setup_continue: + + + mtlr r31 /* restore lr */ + nop /* pass2 DCR errata #8 */ + blr + +/*--------------------------------------------------------------------- */ +/* Function: sdram_init */ +/* Description: Configures SDRAM memory banks. */ +/*--------------------------------------------------------------------- */ + .globl sdram_init + +sdram_init: +#if CFG_MONITOR_BASE < CFG_FLASH_BASE + blr +#else + mflr r31 + + /* output SDRAM code on LEDs */ + addi r4, 0, LED_SDRAM_CODE_1 + addis r5, 0, 0x1000 + ori r5, r5, 0x0001 + stb r4,0(r5) + eieio + + /* Read contents of spd */ + /*--------------------- */ + bl read_spd + + /*----------------------------------------------------------- */ + /* */ + /* */ + /* Update SDRAM timing register */ + /* */ + /* */ + /*----------------------------------------------------------- */ + + /* Read PLL feedback divider and calculate clock period of local bus in */ + /* granularity of 10 ps. Save clock period in r30 */ + /*-------------------------------------------------------------- */ + mfdcr r4, pllmd + addi r9, 0, 25 + srw r4, r4, r9 + andi. r4, r4, 0x07 + addis r5, 0, TIMEBASE_10PS@h + ori r5, r5, TIMEBASE_10PS@l + divwu r30, r5, r4 + + /* Determine CASL */ + /*--------------- */ + bl find_casl /* Returns CASL in r3 */ + + /* Calc trp_clocks = (trp * 100 + (clk - 1)) / clk */ + /* (trp read from byte 27 in granularity of 1 ns) */ + /*------------------------------------------------ */ + mulli r16, r16, 100 + add r16, r16, r30 + addi r6, 0, 1 + subf r16, r6, r16 + divwu r16, r16, r30 + + /* Calc trcd_clocks = (trcd * 100 + (clk - 1) ) / clk */ + /* (trcd read from byte 29 in granularity of 1 ns) */ + /*--------------------------------------------------- */ + mulli r17, r17, 100 + add r17, r17, r30 + addi r6, 0, 1 + subf r17, r6, r17 + divwu r17, r17, r30 + + /* Calc tras_clocks = (tras * 100 + (clk - 1) ) / clk */ + /* (tras read from byte 30 in granularity of 1 ns) */ + /*--------------------------------------------------- */ + mulli r18, r18, 100 + add r18, r18, r30 + addi r6, 0, 1 + subf r18, r6, r18 + divwu r18, r18, r30 + + /* Calc trc_clocks = trp_clocks + tras_clocks */ + /*------------------------------------------- */ + add r18, r18, r16 + + /* CASL value */ + /*----------- */ + addi r9, 0, 23 + slw r4, r3, r9 + + /* PTA = trp_clocks - 1 */ + /*--------------------- */ + addi r6, 0, 1 + subf r5, r6, r16 + addi r9, 0, 18 + slw r5, r5, r9 + or r4, r4, r5 + + /* CTP = trc_clocks - trp_clocks - trcd_clocks - 1 */ + /*------------------------------------------------ */ + addi r5, r18, 0 + subf r5, r16, r5 + subf r5, r17, r5 + addi r6, 0, 1 + subf r5, r6, r5 + addi r9, 0, 16 + slw r5, r5, r9 + or r4, r4, r5 + + /* LDF = 1 */ + /*-------- */ + ori r4, r4, 0x4000 + + /* RFTA = trc_clocks - 4 */ + /*---------------------- */ + addi r6, 0, 4 + subf r5, r6, r18 + addi r9, 0, 2 + slw r5, r5, r9 + or r4, r4, r5 + + /* RCD = trcd_clocks - 1 */ + /*---------------------- */ + addi r6, 0, 1 + subf r5, r6, r17 + or r4, r4, r5 + + /*----------------------------------------------------------- */ + /* Set SDTR1 */ + /*----------------------------------------------------------- */ + addi r5,0,mem_sdtr1 + mtdcr memcfga,r5 + mtdcr memcfgd,r4 + + /*----------------------------------------------------------- */ + /* */ + /* */ + /* Update memory bank 0-3 configuration registers */ + /* */ + /* */ + /*----------------------------------------------------------- */ + + /* Build contents of configuration register for bank 0 into r6 */ + /*------------------------------------------------------------ */ + bl find_mode /* returns addressing mode in r3 */ + addi r29, r3, 0 /* save mode temporarily in r29 */ + bl find_size_code /* returns size code in r3 */ + addi r9, 0, 17 /* bit offset of size code in configuration register */ + slw r3, r3, r9 /* */ + addi r9, 0, 13 /* bit offset of addressing mode in configuration register */ + slw r29, r29, r9 /* */ + or r3, r29, r3 /* merge size code and addressing mode */ + ori r6, r3, CFG_SDRAM_BASE + 1 /* insert base address and enable bank */ + + /* Calculate banksize r15 = (density << 22) / 2 */ + /*--------------------------------------------- */ + addi r9, 0, 21 + slw r15, r15, r9 + + /* Set SDRAM bank 0 register and adjust r6 for next bank */ + /*------------------------------------------------------ */ + addi r7,0,mem_mb0cf + mtdcr memcfga,r7 + mtdcr memcfgd,r6 + + add r6, r6, r15 /* add bank size to base address for next bank */ + + /* If two rows/banks then set SDRAM bank 1 register and adjust r6 for next bank */ + /*---------------------------------------------------------------------------- */ + cmpi 0, r12, 2 + bne b1skip + + addi r7,0,mem_mb1cf + mtdcr memcfga,r7 + mtdcr memcfgd,r6 + + add r6, r6, r15 /* add bank size to base address for next bank */ + + /* Set SDRAM bank 2 register and adjust r6 for next bank */ + /*------------------------------------------------------ */ +b1skip: addi r7,0,mem_mb2cf + mtdcr memcfga,r7 + mtdcr memcfgd,r6 + + add r6, r6, r15 /* add bank size to base address for next bank */ + + /* If two rows/banks then set SDRAM bank 3 register */ + /*------------------------------------------------ */ + cmpi 0, r12, 2 + bne b3skip + + addi r7,0,mem_mb3cf + mtdcr memcfga,r7 + mtdcr memcfgd,r6 +b3skip: + + /*----------------------------------------------------------- */ + /* Set RTR */ + /*----------------------------------------------------------- */ + cmpi 0, r30, 1600 + bge rtr_1 + addis r7, 0, 0x05F0 /* RTR value for 100Mhz */ + bl rtr_2 +rtr_1: addis r7, 0, 0x03F8 +rtr_2: addi r4,0,mem_rtr + mtdcr memcfga,r4 + mtdcr memcfgd,r7 + + /*----------------------------------------------------------- */ + /* Delay to ensure 200usec have elapsed since reset. Assume worst */ + /* case that the core is running 200Mhz: */ + /* 200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles */ + /*----------------------------------------------------------- */ + addis r3,0,0x0000 + ori r3,r3,0xA000 /* ensure 200usec have passed since reset */ + mtctr r3 +..spinlp2: + bdnz ..spinlp2 /* spin loop */ + + /*----------------------------------------------------------- */ + /* Set memory controller options reg, MCOPT1. */ + /* Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst */ + /* read/prefetch. */ + /*----------------------------------------------------------- */ + addi r4,0,mem_mcopt1 + mtdcr memcfga,r4 + addis r4,0,0x80C0 /* set DC_EN=1 */ + ori r4,r4,0x0000 + mtdcr memcfgd,r4 + + + /*----------------------------------------------------------- */ + /* Delay to ensure 10msec have elapsed since reset. This is */ + /* required for the MPC952 to stabalize. Assume worst */ + /* case that the core is running 200Mhz: */ + /* 200,000,000 (cycles/sec) X .010 (sec) = 0x1E8480 cycles */ + /* This delay should occur before accessing SDRAM. */ + /*----------------------------------------------------------- */ + addis r3,0,0x001E + ori r3,r3,0x8480 /* ensure 10msec have passed since reset */ + mtctr r3 +..spinlp3: + bdnz ..spinlp3 /* spin loop */ + + /* output SDRAM code on LEDs */ + addi r4, 0, LED_SDRAM_CODE_16 + addis r5, 0, 0x1000 + ori r5, r5, 0x0001 + stb r4,0(r5) + eieio + + mtlr r31 /* restore lr */ + blr + +/*--------------------------------------------------------------------- */ +/* Function: read_spd */ +/* Description: Reads contents of SPD and saves parameters to be used for */ +/* configuration in dedicated registers (see code below). */ +/*--------------------------------------------------------------------- */ + +#define WRITE_I2C(reg,val) \ + addi r3,0,val;\ + addis r4, 0, 0xef60;\ + ori r4, r4, 0x0500 + reg;\ + stb r3, 0(r4);\ + eieio + +#define READ_I2C(reg) \ + addis r3, 0, 0xef60;\ + ori r3, r3, 0x0500 + reg;\ + lbz r3, 0x0000(r3);\ + eieio + +read_spd: + + mflr r5 + + /* Initialize i2c */ + /*--------------- */ + WRITE_I2C(IICLMADR, 0x00) /* clear lo master address */ + WRITE_I2C(IICHMADR, 0x00) /* clear hi master address */ + WRITE_I2C(IICLSADR, 0x00) /* clear lo slave address */ + WRITE_I2C(IICHSADR, 0x00) /* clear hi slave address */ + WRITE_I2C(IICSTS, 0x08) /* update status register */ + WRITE_I2C(IICEXTSTS, 0x8f) + WRITE_I2C(IICCLKDIV, 0x05) + WRITE_I2C(IICINTRMSK, 0x00) /* no interrupts */ + WRITE_I2C(IICXFRCNT, 0x00) /* clear transfer count */ + WRITE_I2C(IICXTCNTLSS, 0xf0) /* clear extended control & stat */ + WRITE_I2C(IICMDCNTL, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB) /* mode control */ + READ_I2C(IICMDCNTL) + ori r3, r3, IIC_MDCNTL_EUBS | IIC_MDCNTL_HSCL + WRITE_I2C(IICMDCNTL, r3) /* mode control */ + WRITE_I2C(IICCNTL, 0x00) /* clear control reg */ + + /* Wait until initialization completed */ + /*------------------------------------ */ + bl wait_i2c_transfer_done + + WRITE_I2C(IICHMADR, 0x00) /* 7-bit addressing */ + WRITE_I2C(IICLMADR, SDRAM_SPD_WRITE_ADDRESS) + + /* Write 0 into buffer(start address) */ + /*----------------------------------- */ + WRITE_I2C(IICMDBUF, 0x00); + + /* Wait a little */ + /*-------------- */ + addis r3,0,0x0000 + ori r3,r3,0xA000 + mtctr r3 +in02: bdnz in02 + + /* Issue write command */ + /*-------------------- */ + WRITE_I2C(IICCNTL, IIC_CNTL_PT) + bl wait_i2c_transfer_done + + /* Read 128 bytes */ + /*--------------- */ + addi r7, 0, 0 /* byte counter in r7 */ + addi r8, 0, 0 /* checksum in r8 */ +rdlp: + /* issue read command */ + /*------------------- */ + cmpi 0, r7, 127 + blt rd01 + WRITE_I2C(IICCNTL, IIC_CNTL_READ | IIC_CNTL_PT) + bl rd02 +rd01: WRITE_I2C(IICCNTL, IIC_CNTL_READ | IIC_CNTL_CHT | IIC_CNTL_PT) +rd02: bl wait_i2c_transfer_done + + /* Fetch byte from buffer */ + /*----------------------- */ + READ_I2C(IICMDBUF) + + /* Retrieve parameters that are going to be used during configuration. */ + /* Save them in dedicated registers. */ + /*------------------------------------------------------------ */ + cmpi 0, r7, 3 /* Save byte 3 in r10 */ + bne rd10 + addi r10, r3, 0 +rd10: cmpi 0, r7, 4 /* Save byte 4 in r11 */ + bne rd11 + addi r11, r3, 0 +rd11: cmpi 0, r7, 5 /* Save byte 5 in r12 */ + bne rd12 + addi r12, r3, 0 +rd12: cmpi 0, r7, 17 /* Save byte 17 in r13 */ + bne rd13 + addi r13, r3, 0 +rd13: cmpi 0, r7, 18 /* Save byte 18 in r14 */ + bne rd14 + addi r14, r3, 0 +rd14: cmpi 0, r7, 31 /* Save byte 31 in r15 */ + bne rd15 + addi r15, r3, 0 +rd15: cmpi 0, r7, 27 /* Save byte 27 in r16 */ + bne rd16 + addi r16, r3, 0 +rd16: cmpi 0, r7, 29 /* Save byte 29 in r17 */ + bne rd17 + addi r17, r3, 0 +rd17: cmpi 0, r7, 30 /* Save byte 30 in r18 */ + bne rd18 + addi r18, r3, 0 +rd18: cmpi 0, r7, 9 /* Save byte 9 in r19 */ + bne rd19 + addi r19, r3, 0 +rd19: cmpi 0, r7, 23 /* Save byte 23 in r20 */ + bne rd20 + addi r20, r3, 0 +rd20: cmpi 0, r7, 25 /* Save byte 25 in r21 */ + bne rd21 + addi r21, r3, 0 +rd21: + + /* Calculate checksum of the first 63 bytes */ + /*----------------------------------------- */ + cmpi 0, r7, 63 + bgt rd31 + beq rd30 + add r8, r8, r3 + bl rd31 + + /* Verify checksum at byte 63 */ + /*--------------------------- */ +rd30: andi. r8, r8, 0xff /* use only 8 bits */ + cmp 0, r8, r3 + beq rd31 + addi r4, 0, LED_SDRAM_CODE_8 + addis r5, 0, 0x1000 + ori r5, r5, 0x0001 + stb r4,0(r5) + eieio +rderr: bl rderr + +rd31: + + /* Increment byte counter and check whether all bytes have been read. */ + /*------------------------------------------------------------------- */ + addi r7, r7, 1 + cmpi 0, r7, 127 + bgt rd05 + bl rdlp +rd05: + mtlr r5 /* restore lr */ + blr + +wait_i2c_transfer_done: + mflr r6 +wt01: READ_I2C(IICSTS) + andi. r4, r3, IIC_STS_PT + cmpi 0, r4, IIC_STS_PT + beq wt01 + mtlr r6 /* restore lr */ + blr + +/*--------------------------------------------------------------------- */ +/* Function: find_mode */ +/* Description: Determines addressing mode to be used dependent on */ +/* number of rows (r10 = byte 3 from SPD), number of columns (r11 = */ +/* byte 4 from SPD) and number of banks (r13 = byte 17 from SPD). */ +/* mode is returned in r3. */ +/* (It would be nicer having a table, pnc). */ +/*--------------------------------------------------------------------- */ +find_mode: + + mflr r5 + + cmpi 0, r10, 11 + bne fm01 + cmpi 0, r11, 9 + bne fm01 + cmpi 0, r13, 2 + bne fm01 + addi r3, 0, 1 + bl fmfound + +fm01: cmpi 0, r10, 11 + bne fm02 + cmpi 0, r11, 10 + bne fm02 + cmpi 0, r13, 2 + bne fm02 + addi r3, 0, 1 + bl fmfound + +fm02: cmpi 0, r10, 12 + bne fm03 + cmpi 0, r11, 9 + bne fm03 + cmpi 0, r13, 4 + bne fm03 + addi r3, 0, 2 + bl fmfound + +fm03: cmpi 0, r10, 12 + bne fm04 + cmpi 0, r11, 10 + bne fm04 + cmpi 0, r13, 4 + bne fm04 + addi r3, 0, 2 + bl fmfound + +fm04: cmpi 0, r10, 13 + bne fm05 + cmpi 0, r11, 9 + bne fm05 + cmpi 0, r13, 4 + bne fm05 + addi r3, 0, 3 + bl fmfound + +fm05: cmpi 0, r10, 13 + bne fm06 + cmpi 0, r11, 10 + bne fm06 + cmpi 0, r13, 4 + bne fm06 + addi r3, 0, 3 + bl fmfound + +fm06: cmpi 0, r10, 13 + bne fm07 + cmpi 0, r11, 11 + bne fm07 + cmpi 0, r13, 4 + bne fm07 + addi r3, 0, 3 + bl fmfound + +fm07: cmpi 0, r10, 12 + bne fm08 + cmpi 0, r11, 8 + bne fm08 + cmpi 0, r13, 2 + bne fm08 + addi r3, 0, 4 + bl fmfound + +fm08: cmpi 0, r10, 12 + bne fm09 + cmpi 0, r11, 8 + bne fm09 + cmpi 0, r13, 4 + bne fm09 + addi r3, 0, 4 + bl fmfound + +fm09: cmpi 0, r10, 11 + bne fm10 + cmpi 0, r11, 8 + bne fm10 + cmpi 0, r13, 2 + bne fm10 + addi r3, 0, 5 + bl fmfound + +fm10: cmpi 0, r10, 11 + bne fm11 + cmpi 0, r11, 8 + bne fm11 + cmpi 0, r13, 4 + bne fm11 + addi r3, 0, 5 + bl fmfound + +fm11: cmpi 0, r10, 13 + bne fm12 + cmpi 0, r11, 8 + bne fm12 + cmpi 0, r13, 2 + bne fm12 + addi r3, 0, 6 + bl fmfound + +fm12: cmpi 0, r10, 13 + bne fm13 + cmpi 0, r11, 8 + bne fm13 + cmpi 0, r13, 4 + bne fm13 + addi r3, 0, 6 + bl fmfound + +fm13: cmpi 0, r10, 13 + bne fm14 + cmpi 0, r11, 9 + bne fm14 + cmpi 0, r13, 2 + bne fm14 + addi r3, 0, 7 + bl fmfound + +fm14: cmpi 0, r10, 13 + bne fm15 + cmpi 0, r11, 10 + bne fm15 + cmpi 0, r13, 2 + bne fm15 + addi r3, 0, 7 + bl fmfound + +fm15: + /* not found, error code to be issued on LEDs */ + addi r7, 0, LED_SDRAM_CODE_2 + addis r6, 0, 0x1000 + ori r6, r6, 0x0001 + stb r7,0(r6) + eieio +fmerr: bl fmerr + +fmfound:addi r6, 0, 1 + subf r3, r6, r3 + + mtlr r5 /* restore lr */ + blr + +/*--------------------------------------------------------------------- */ +/* Function: find_size_code */ +/* Description: Determines size code to be used in configuring SDRAM controller */ +/* dependent on density (r15 = byte 31 from SPD) */ +/*--------------------------------------------------------------------- */ +find_size_code: + + mflr r5 + + addi r3, r15, 0 /* density */ + addi r7, 0, 0 +fs01: andi. r6, r3, 0x01 + cmpi 0, r6, 1 + beq fs04 + + addi r7, r7, 1 + cmpi 0, r7, 7 + bge fs02 + addi r9, 0, 1 + srw r3, r3, r9 + bl fs01 + + /* not found, error code to be issued on LEDs */ +fs02: addi r4, 0, LED_SDRAM_CODE_3 + addis r8, 0, 0x1000 + ori r8, r8, 0x0001 + stb r4,0(r8) + eieio +fs03: bl fs03 + +fs04: addi r3, r7, 0 + cmpi 0, r3, 0 + beq fs05 + addi r6, 0, 1 + subf r3, r6, r3 +fs05: + mtlr r5 /* restore lr */ + blr + +/*--------------------------------------------------------------------- */ +/* Function: find_casl */ +/* Description: Determines CAS latency */ +/*--------------------------------------------------------------------- */ +find_casl: + + mflr r5 + + andi. r14, r14, 0x7f /* r14 holds supported CAS latencies */ + addi r3, 0, 0xff /* preset determined CASL */ + addi r4, 0, 6 /* Start at bit 6 of supported CAS latencies */ + addi r2, 0, 0 /* Start finding highest CAS latency */ + +fc01: srw r6, r14, r4 /* */ + andi. r6, r6, 0x01 /* */ + cmpi 0, r6, 1 /* Check bit for current latency */ + bne fc06 /* If not supported, go to next */ + + cmpi 0, r2, 2 /* Check if third-highest latency */ + bge fc04 /* If so, go calculate with another format */ + + cmpi 0, r2, 0 /* Check if highest latency */ + bgt fc02 /* */ + addi r7, r19, 0 /* SDRAM cycle time for highest CAS latenty */ + + bl fc03 +fc02: + addi r7, r20, 0 /* SDRAM cycle time for next-highest CAS latenty */ +fc03: + addi r8, r7, 0 + addi r9, 0, 4 + srw r7, r7, r9 + andi. r7, r7, 0x0f + mulli r7, r7, 100 + andi. r8, r8, 0x0f + mulli r8, r8, 10 + add r7, r7, r8 + cmp 0, r7, r30 + bgt fc05 + addi r3, r2, 0 + bl fc05 +fc04: + addi r7, r21, 0 /* SDRAM cycle time for third-highest CAS latenty */ + addi r8, r7, 0 + addi r9, 0, 2 + srw r7, r7, r9 + andi. r7, r7, 0x3f + mulli r7, r7, 100 + andi. r8, r8, 0x03 + mulli r8, r8, 25 + add r7, r7, r8 + + cmp 0, r7, r30 + bgt fc05 + addi r3, r2, 0 + +fc05: addi r2, r2, 1 /* next latency */ + cmpi 0, r2, 3 + bge fc07 +fc06: addi r6, 0, 1 + subf r4, r6, r4 + cmpi 0, r4, 0 + bne fc01 + +fc07: + + mtlr r5 /* restore lr */ + blr +#endif + + +/* Peripheral Bank 1 Access Parameters */ +/* 0 BME = 1 ; burstmode enabled */ +/* " 1:8" TWT=00110110 ;Transfer wait (details below) */ +/* 1:5 FWT=00110 ; first wait = 6 cycles */ +/* 6:8 BWT=110 ; burst wait = 6 cycles */ +/* 9:11 000 ; reserved */ +/* 12:13 CSN=00 ; chip select on timing = 0 */ +/* 14:15 OEN=01 ; output enable */ +/* 16:17 WBN=01 ; write byte enable on timing 1 cycle */ +/* 18:19 WBF=01 ; write byte enable off timing 1 cycle */ +/* 20:22 TH=010 ; transfer hold = 2 cycles */ +/* 23 RE=0 ; ready enable = disabled */ +/* 24 SOR=1 ; sample on ready = same PerClk */ +/* 25 BEM=0 ; byte enable mode = only for write cycles */ +/* 26 PEN=0 ; parity enable = disable */ +/* 27:31 00000 ;reserved */ +/* */ +/* 1 + 00110 + 110 + 000 + 00 + 01 + 01 + 01 + 010 + 0 + 1 + 0 + 0 + 00000 = 0x9b015480 */ +/* */ +/* */ +/* Code for BDI probe: */ +/* */ +/* WDCR 18 0x00000011 ;Select PB1AP */ +/* WDCR 19 0x1b015480 ;PB1AP: Flash */ +/* */ +/* Peripheral Bank 0 Access Parameters */ +/* 0:11 BAS=0x200 ; base address select = 0x200 * 0x100000 (1MB) = */ +/* 12:14 BS=100 ; bank size = 16MB (100) / 32MB (101) */ +/* 15:16 BU=11 ; bank usage = read/write */ +/* 17:18 BW=00 ; bus width = 8-bit */ +/* 19:31 ; reserved */ +/* */ +/* 0x200 + 100 + 11 + 00 + 0 0000 0000 0000 = 0x20098000 */ +/* WDCR 18 0x00000001 ;Select PB1CR */ +/* WDCR 19 0x20098000 ;PB1CR: 1MB at 0x00100000, r/w, 8bit */ + +/* For CPLD */ +/* 0 + 00000 + 010 + 000 + 00 + 01 + 00 + 00 + 000 + 0 + 0 + 1 + 0 + 00000 */ +/* WDCR_EBC(pb5ap, 0x01010040) */ +/*jsa recommendation: WDCR_EBC(pb5ap, 0x00010040) */ +/* WDCR_EBC(pb5cr, 0X10018000) */ +/* Access parms */ +/* 100 3 8 0 0 0 */ +/* 0x100 + 001 + 11 + 00 + 0 0000 0000 0000 = 0x10038000 */ +/* Address : 0x10000000 */ +/* Size: 2 MB */ +/* Usage: read/write */ +/* Width: 32 bit */ + +/* For Genie onboard fpga 32 bit interface */ +/* 0 1 0 1 0 0 0 0 */ +/* 0 + 00000 + 010 + 000 + 00 + 01 + 00 + 00 + 000 + 0 + 0 + 0 + 0 + 00000 */ +/* 0x01010000 */ +/* Access parms */ +/* 102 1 c 0 0 0 */ +/* 0x102 + 000 + 11 + 10 + 0 0000 0000 0000 = 0x1021c000 */ +/* Address : 0x10200000 */ +/* Size: 2 MB */ +/* Usage: read/write */ +/* Width: 32 bit */ + +/* Walnut fpga pb7ap */ +/* 0 1 8 1 5 2 8 0 */ +/* 0 + 00000 + 011 + 000 + 00 + 01 + 01 + 01 + 001 + 0 + 1 + 0 + 0 + 00000 */ +/* Walnut fpga pb7cr */ +/* 0xF0318000 */ +/* */ diff --git a/board/exbitgen/u-boot.lds b/board/exbitgen/u-boot.lds new file mode 100644 index 0000000000..863a7e423d --- /dev/null +++ b/board/exbitgen/u-boot.lds @@ -0,0 +1,144 @@ +/* + * (C) Copyright 2000 + * 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 + */ + +OUTPUT_ARCH(powerpc) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + .resetvec 0xFFFFFFFC : + { + *(.resetvec) + } = 0xffff + + /* 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 : + { + /* WARNING - the following is hand-optimized to fit within */ + /* the sector layout of our flash chips! XXX FIXME XXX */ + + cpu/ppc4xx/start.o (.text) + board/exbitgen/init.o (.text) + cpu/ppc4xx/kgdb.o (.text) + cpu/ppc4xx/traps.o (.text) + cpu/ppc4xx/interrupts.o (.text) + cpu/ppc4xx/serial.o (.text) + cpu/ppc4xx/cpu_init.o (.text) + cpu/ppc4xx/speed.o (.text) + common/dlmalloc.o (.text) + lib_generic/crc32.o (.text) + lib_ppc/extable.o (.text) + lib_generic/zlib.o (.text) + +/* . = env_offset;*/ + common/environment.o(.text) + + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; + __fixup_entries = (. - _FIXUP_TABLE_)>>2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(256); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(256); + __init_end = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + . = ALIGN(4); + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); +} diff --git a/board/lwmon/lwmon.c b/board/lwmon/lwmon.c index b359ec758d..91aa58cf29 100644 --- a/board/lwmon/lwmon.c +++ b/board/lwmon/lwmon.c @@ -513,6 +513,9 @@ static void kbd_init (void) gd->kbd_status = 0; + /* Forced by PIC. Delays <= 175us loose */ + udelay(1000); + /* Read initial keyboard error code */ val = KEYBD_CMD_READ_STATUS; i2c_write (kbd_addr, 0, 0, &val, 1); diff --git a/board/sl8245/Makefile b/board/sl8245/Makefile new file mode 100644 index 0000000000..da60318d7f --- /dev/null +++ b/board/sl8245/Makefile @@ -0,0 +1,40 @@ +# +# (C) Copyright 2001 - 2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = lib$(BOARD).a + +OBJS = $(BOARD).o flash.o + +$(LIB): .depend $(OBJS) + $(AR) crv $@ $^ + +######################################################################### + +.depend: Makefile $(OBJS:.o=.c) + $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/board/sl8245/config.mk b/board/sl8245/config.mk new file mode 100644 index 0000000000..299fc6ce20 --- /dev/null +++ b/board/sl8245/config.mk @@ -0,0 +1,30 @@ +# +# (C) Copyright 2001 - 2003 +# 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 +# + +# +# SL8245 board +# + +TEXT_BASE = 0xFFF00000 + +PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) diff --git a/board/sl8245/flash.c b/board/sl8245/flash.c new file mode 100644 index 0000000000..553dc98226 --- /dev/null +++ b/board/sl8245/flash.c @@ -0,0 +1,488 @@ +/* + * (C) Copyright 2001 - 2003 + * 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 +#include +#include + +#if defined(CFG_ENV_IS_IN_FLASH) +# ifndef CFG_ENV_ADDR +# define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET) +# endif +# ifndef CFG_ENV_SIZE +# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE +# endif +# ifndef CFG_ENV_SECT_SIZE +# define CFG_ENV_SECT_SIZE CFG_ENV_SIZE +# endif +#endif + +#define FLASH_BANK_SIZE 0x800000 +#define MAIN_SECT_SIZE 0x40000 +#define PARAM_SECT1_SIZE 0x20000 +#define PARAM_SECT23_SIZE 0x8000 +#define PARAM_SECT4_SIZE 0x10000 + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; + +static int write_data (flash_info_t *info, ulong dest, ulong *data); +static void write_via_fpu(vu_long *addr, ulong *data); +static __inline__ unsigned long get_msr(void); +static __inline__ void set_msr(unsigned long msr); + +/*---------------------------------------------------------------------*/ +#undef DEBUG_FLASH + +/*---------------------------------------------------------------------*/ +#ifdef DEBUG_FLASH +#define DEBUGF(fmt,args...) printf(fmt ,##args) +#else +#define DEBUGF(fmt,args...) +#endif +/*---------------------------------------------------------------------*/ + +#define __align__ __attribute__ ((aligned (8))) +static __align__ ulong precmd0[2] = { 0x00aa00aa, 0x00aa00aa }; +static __align__ ulong precmd1[2] = { 0x00550055, 0x00550055 }; +static __align__ ulong cmdid[2] = { 0x00900090, 0x00900090 }; +static __align__ ulong cmderase[2] = { 0x00800080, 0x00800080 }; +static __align__ ulong cmdersusp[2] = { 0x00b000b0, 0x00b000b0 }; +static __align__ ulong cmdsecter[2] = { 0x00300030, 0x00300030 }; +static __align__ ulong cmdprog[2] = { 0x00a000a0, 0x00a000a0 }; +static __align__ ulong cmdres[2] = { 0x00f000f0, 0x00f000f0 }; + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ + int i, j; + ulong size = 0; + + for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { + vu_long *addr = (vu_long *) (CFG_FLASH_BASE + i * FLASH_BANK_SIZE); + + write_via_fpu (&addr[0xaaa], precmd0); + write_via_fpu (&addr[0x554], precmd1); + write_via_fpu (&addr[0xaaa], cmdid); + + DEBUGF ("Flash bank # %d:\n" + "\tManuf. ID @ 0x%08lX: 0x%08lX\n" + "\tDevice ID @ 0x%08lX: 0x%08lX\n", + i, + (ulong) (&addr[0]), addr[0], + (ulong) (&addr[2]), addr[2]); + + if ((addr[0] == addr[1]) && (addr[0] == AMD_MANUFACT) && + (addr[2] == addr[3]) && (addr[2] == AMD_ID_LV160T)) { + flash_info[i].flash_id = (FLASH_MAN_AMD & FLASH_VENDMASK) | + (FLASH_AM160T & FLASH_TYPEMASK); + } else { + flash_info[i].flash_id = FLASH_UNKNOWN; + write_via_fpu (addr, cmdres); + goto Done; + } + + DEBUGF ("flash_id = 0x%08lX\n", flash_info[i].flash_id); + + write_via_fpu (addr, cmdres); + + flash_info[i].size = FLASH_BANK_SIZE; + flash_info[i].sector_count = CFG_MAX_FLASH_SECT; + memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT); + for (j = 0; j < 32; j++) { + flash_info[i].start[j] = CFG_FLASH_BASE + + i * FLASH_BANK_SIZE + j * MAIN_SECT_SIZE; + } + flash_info[i].start[32] = + flash_info[i].start[31] + PARAM_SECT1_SIZE; + flash_info[i].start[33] = + flash_info[i].start[32] + PARAM_SECT23_SIZE; + flash_info[i].start[34] = + flash_info[i].start[33] + PARAM_SECT23_SIZE; + size += flash_info[i].size; + } + + /* Protect monitor and environment sectors + */ +#if CFG_MONITOR_BASE >= CFG_FLASH_BASE +#if CFG_MONITOR_BASE >= CFG_FLASH_BASE + FLASH_BANK_SIZE + flash_protect ( FLAG_PROTECT_SET, + CFG_MONITOR_BASE, + CFG_MONITOR_BASE + monitor_flash_len - 1, + &flash_info[1]); +#else + flash_protect ( FLAG_PROTECT_SET, + CFG_MONITOR_BASE, + CFG_MONITOR_BASE + monitor_flash_len - 1, + &flash_info[0]); +#endif +#endif + +#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR) +#if CFG_ENV_ADDR >= CFG_FLASH_BASE + FLASH_BANK_SIZE + flash_protect ( FLAG_PROTECT_SET, + CFG_ENV_ADDR, + CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[1]); +#else + flash_protect ( FLAG_PROTECT_SET, + CFG_ENV_ADDR, + CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]); +#endif +#endif + +Done: + return size; +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t * info) +{ + int i; + + switch ((i = info->flash_id & FLASH_VENDMASK)) { + case (FLASH_MAN_AMD & FLASH_VENDMASK): + printf ("Intel: "); + break; + default: + printf ("Unknown Vendor 0x%04x ", i); + break; + } + + switch ((i = info->flash_id & FLASH_TYPEMASK)) { + case (FLASH_AM160T & FLASH_TYPEMASK): + printf ("AM29LV160BT (16Mbit)\n"); + break; + default: + printf ("Unknown Chip Type 0x%04x\n", i); + goto Done; + break; + } + + printf (" Size: %ld MB in %d Sectors\n", + info->size >> 20, info->sector_count); + + printf (" Sector Start Addresses:"); + for (i = 0; i < info->sector_count; i++) { + if ((i % 5) == 0) { + printf ("\n "); + } + printf (" %08lX%s", info->start[i], + info->protect[i] ? " (RO)" : " "); + } + printf ("\n"); + + Done: + return; +} + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t * info, int s_first, int s_last) +{ + int flag, prot, sect; + ulong start, now, last; + + DEBUGF ("Erase flash bank %d sect %d ... %d\n", + info - &flash_info[0], s_first, s_last); + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return 1; + } + + if ((info->flash_id & FLASH_VENDMASK) != + (FLASH_MAN_AMD & FLASH_VENDMASK)) { + printf ("Can erase only AMD flash types - aborted\n"); + return 1; + } + + prot = 0; + for (sect = s_first; sect <= s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } + + start = get_timer (0); + last = start; + /* Start erase on unprotected sectors */ + for (sect = s_first; sect <= s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + vu_long *addr = (vu_long *) (info->start[sect]); + + DEBUGF ("Erase sect %d @ 0x%08lX\n", sect, (ulong) addr); + + /* Disable interrupts which might cause a timeout + * here. + */ + flag = disable_interrupts (); + + write_via_fpu (&addr[0xaaa], precmd0); + write_via_fpu (&addr[0x554], precmd1); + write_via_fpu (&addr[0xaaa], cmderase); + write_via_fpu (&addr[0xaaa], precmd0); + write_via_fpu (&addr[0x554], precmd1); + write_via_fpu (&addr[0xaaa], cmdsecter); + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts (); + + /* wait at least 80us - let's wait 1 ms */ + udelay (1000); + + while (((addr[0] & 0x00800080) != 0x00800080) || + ((addr[1] & 0x00800080) != 0x00800080)) { + if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT) { + printf ("Timeout\n"); + write_via_fpu (addr, cmdersusp); + write_via_fpu (addr, cmdres); + return 1; + } + + /* show that we're waiting */ + if ((now - last) > 1000) { /* every second */ + putc ('.'); + last = now; + } + } + + write_via_fpu (addr, cmdres); + } + } + printf (" done\n"); + return 0; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + * 4 - Flash not identified + */ + +#define FLASH_WIDTH 8 /* flash bus width in bytes */ + +int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) +{ + ulong wp, cp, msr; + int l, rc, i; + ulong data[2]; + ulong *datah = &data[0]; + ulong *datal = &data[1]; + + DEBUGF ("Flash write_buff: @ 0x%08lx, src 0x%08lx len %ld\n", + addr, (ulong) src, cnt); + + if (info->flash_id == FLASH_UNKNOWN) { + return 4; + } + + msr = get_msr (); + set_msr (msr | MSR_FP); + + wp = (addr & ~(FLASH_WIDTH - 1)); /* get lower aligned address */ + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + *datah = *datal = 0; + + for (i = 0, cp = wp; i < l; i++, cp++) { + if (i >= 4) { + *datah = (*datah << 8) | ((*datal & 0xFF000000) >> 24); + } + + *datal = (*datal << 8) | (*(uchar *) cp); + } + for (; i < FLASH_WIDTH && cnt > 0; ++i) { + char tmp; + + tmp = *src; + + src++; + + if (i >= 4) { + *datah = (*datah << 8) | ((*datal & 0xFF000000) >> 24); + } + + *datal = (*datal << 8) | tmp; + + --cnt; + ++cp; + } + + for (; cnt == 0 && i < FLASH_WIDTH; ++i, ++cp) { + if (i >= 4) { + *datah = (*datah << 8) | ((*datal & 0xFF000000) >> 24); + } + + *datal = (*datah << 8) | (*(uchar *) cp); + } + + if ((rc = write_data (info, wp, data)) != 0) { + set_msr (msr); + return (rc); + } + + wp += FLASH_WIDTH; + } + + /* + * handle FLASH_WIDTH aligned part + */ + while (cnt >= FLASH_WIDTH) { + *datah = *(ulong *) src; + *datal = *(ulong *) (src + 4); + if ((rc = write_data (info, wp, data)) != 0) { + set_msr (msr); + return (rc); + } + wp += FLASH_WIDTH; + cnt -= FLASH_WIDTH; + src += FLASH_WIDTH; + } + + if (cnt == 0) { + set_msr (msr); + return (0); + } + + /* + * handle unaligned tail bytes + */ + *datah = *datal = 0; + for (i = 0, cp = wp; i < FLASH_WIDTH && cnt > 0; ++i, ++cp) { + char tmp; + + tmp = *src; + + src++; + + if (i >= 4) { + *datah = (*datah << 8) | ((*datal & 0xFF000000) >> 24); + } + + *datal = (*datal << 8) | tmp; + + --cnt; + } + + for (; i < FLASH_WIDTH; ++i, ++cp) { + if (i >= 4) { + *datah = (*datah << 8) | ((*datal & 0xFF000000) >> 24); + } + + *datal = (*datal << 8) | (*(uchar *) cp); + } + + rc = write_data (info, wp, data); + set_msr (msr); + + return (rc); +} + +/*----------------------------------------------------------------------- + * Write a word to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_data (flash_info_t * info, ulong dest, ulong * data) +{ + vu_long *chip = (vu_long *) (info->start[0]); + vu_long *addr = (vu_long *) dest; + ulong start; + int flag; + + /* Check if Flash is (sufficiently) erased */ + if (((addr[0] & data[0]) != data[0]) || + ((addr[1] & data[1]) != data[1])) { + return (2); + } + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts (); + + write_via_fpu (&chip[0xaaa], precmd0); + write_via_fpu (&chip[0x554], precmd1); + write_via_fpu (&chip[0xaaa], cmdprog); + write_via_fpu (addr, data); + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts (); + + start = get_timer (0); + + while (((addr[0] & 0x00800080) != (data[0] & 0x00800080)) || + ((addr[1] & 0x00800080) != (data[1] & 0x00800080))) { + if (get_timer (start) > CFG_FLASH_WRITE_TOUT) { + write_via_fpu (chip, cmdres); + return (1); + } + } + + write_via_fpu (chip, cmdres); + + return (0); +} + +/*----------------------------------------------------------------------- + */ +static void write_via_fpu (vu_long * addr, ulong * data) +{ + __asm__ __volatile__ ("lfd 1, 0(%0)"::"r" (data)); + __asm__ __volatile__ ("stfd 1, 0(%0)"::"r" (addr)); +} + +/*----------------------------------------------------------------------- + */ +static __inline__ unsigned long get_msr (void) +{ + unsigned long msr; + + __asm__ __volatile__ ("mfmsr %0":"=r" (msr):); + + return msr; +} + +static __inline__ void set_msr (unsigned long msr) +{ + __asm__ __volatile__ ("mtmsr %0"::"r" (msr)); +} diff --git a/board/sl8245/sl8245.c b/board/sl8245/sl8245.c new file mode 100644 index 0000000000..1a30b4ca6b --- /dev/null +++ b/board/sl8245/sl8245.c @@ -0,0 +1,86 @@ +/* + * (C) Copyright 2003 + * 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 +#include + +int checkboard (void) +{ + ulong busfreq = get_bus_freq(0); + char buf[32]; + + printf("Board: SL8245, local bus @ %s MHz\n", strmhz(buf, busfreq)); + return 0; +} + +long int initdram (int board_type) +{ +#ifndef CFG_RAMBOOT + int i, cnt; + volatile uchar * base= CFG_SDRAM_BASE; + volatile ulong * addr; + ulong save[32]; + ulong val, ret = 0; + + for (i=0, cnt=(CFG_MAX_RAM_SIZE / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) { + addr = (volatile ulong *)base + cnt; + save[i++] = *addr; + *addr = ~cnt; + } + + addr = (volatile ulong *)base; + save[i] = *addr; + *addr = 0; + + if (*addr != 0) { + *addr = save[i]; + goto Done; + } + + for (cnt = 1; cnt < CFG_MAX_RAM_SIZE / sizeof(long); cnt <<= 1) { + addr = (volatile ulong *)base + cnt; + val = *addr; + *addr = save[--i]; + if (val != ~cnt) { + ulong new_bank0_end = cnt * sizeof(long) - 1; + ulong mear1 = mpc824x_mpc107_getreg(MEAR1); + ulong emear1 = mpc824x_mpc107_getreg(EMEAR1); + mear1 = (mear1 & 0xFFFFFF00) | + ((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT); + emear1 = (emear1 & 0xFFFFFF00) | + ((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT); + mpc824x_mpc107_setreg(MEAR1, mear1); + mpc824x_mpc107_setreg(EMEAR1, emear1); + + ret = cnt * sizeof(long); + goto Done; + } + } + + ret = CFG_MAX_RAM_SIZE; +Done: + return ret; +#else + return CFG_MAX_RAM_SIZE; +#endif +} diff --git a/board/sl8245/u-boot.lds b/board/sl8245/u-boot.lds new file mode 100644 index 0000000000..627a53b3b6 --- /dev/null +++ b/board/sl8245/u-boot.lds @@ -0,0 +1,128 @@ +/* + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(powerpc) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* 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/mpc824x/start.o (.text) + lib_ppc/board.o (.text) + lib_ppc/ppcstring.o (.text) + lib_generic/vsprintf.o (.text) + lib_generic/crc32.o (.text) + lib_generic/zlib.o (.text) + + . = DEFINED(env_offset) ? env_offset : .; + common/environment.o (.text) + + *(.text) + + *(.fixup) + *(.got1) + . = ALIGN(16); + *(.rodata) + *(.rodata1) + } + .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 = .); + + __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 = .); +} + -- cgit v1.2.1