From: wdenk Date: Sun, 28 Dec 2003 11:44:59 +0000 (+0000) Subject: Patch by Reinhard Meyer, 28 Dec 2003: X-Git-Tag: LABEL_2006_03_12_0025~682 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=c18960049f8ea9b0a8ad0a05c93e23fbab025da0;p=oweals%2Fu-boot.git Patch by Reinhard Meyer, 28 Dec 2003: Add initial support for TOP5200 board --- diff --git a/CHANGELOG b/CHANGELOG index 84e3092e6f..4c0bd2b429 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ Changes since U-Boot 1.0.0: ====================================================================== +* Patch by Reinhard Meyer, 28 Dec 2003: + Add initial support for TOP5200 board + * Make CPU clock on ICA-IP board controllable by a "cpuclk" environment variable which can set to "100", "133", or "150". The CPU clock will be configured accordingly upon next reboot. Other diff --git a/board/emk/top5200/Makefile b/board/emk/top5200/Makefile new file mode 100644 index 0000000000..eb5ed591a9 --- /dev/null +++ b/board/emk/top5200/Makefile @@ -0,0 +1,47 @@ + +# +# (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 $(TOPDIR)/config.mk + +LIB = lib$(BOARD).a + +OBJS := $(BOARD).o flash.o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) crv $@ $(OBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +-include .depend + +######################################################################### diff --git a/board/emk/top5200/config.mk b/board/emk/top5200/config.mk new file mode 100644 index 0000000000..14af97a028 --- /dev/null +++ b/board/emk/top5200/config.mk @@ -0,0 +1,31 @@ +# +# (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 +# + +# +# TOP5200 board, on optional MINI5200 and EVAL5200 boards +# + +TEXT_BASE = 0xfff00000 +#TEXT_BASE = 0x00100000 + +PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)/board diff --git a/board/emk/top5200/flash.c b/board/emk/top5200/flash.c new file mode 100644 index 0000000000..b951b5f084 --- /dev/null +++ b/board/emk/top5200/flash.c @@ -0,0 +1,489 @@ +/* + * (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 + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +typedef unsigned char FLASH_PORT_WIDTH; +typedef volatile unsigned char FLASH_PORT_WIDTHV; +#define FLASH_ID_MASK 0xFF + +#define FPW FLASH_PORT_WIDTH +#define FPWV FLASH_PORT_WIDTHV + +#define FLASH_CYCLE1 0x0aaa +#define FLASH_CYCLE2 0x0555 + +/*----------------------------------------------------------------------- + * Functions + */ +static ulong flash_get_size(FPWV *addr, flash_info_t *info); +static void flash_reset(flash_info_t *info); +static int write_word_amd(flash_info_t *info, FPWV *dest, FPW data); +static flash_info_t *flash_get_info(ulong base); + +/*----------------------------------------------------------------------- + * flash_init() + * + * sets up flash_info and returns size of FLASH (bytes) + */ +unsigned long flash_init (void) +{ + unsigned long size = 0; + int i; + extern void flash_preinit(void); + extern void flash_afterinit(uint, ulong, ulong); + ulong flashbase = CFG_FLASH_BASE; + + flash_preinit(); + + /* There is only ONE FLASH device */ + memset(&flash_info[0], 0, sizeof(flash_info_t)); + flash_info[0].size = + flash_get_size((FPW *)flashbase, &flash_info[0]); + size += flash_info[0].size; + +#if CFG_MONITOR_BASE >= CFG_FLASH_BASE + /* monitor protection ON by default */ + flash_protect(FLAG_PROTECT_SET, + CFG_MONITOR_BASE, + CFG_MONITOR_BASE+monitor_flash_len-1, + flash_get_info(CFG_MONITOR_BASE)); +#endif + +#ifdef CFG_ENV_IS_IN_FLASH + /* ENV protection ON by default */ + flash_protect(FLAG_PROTECT_SET, + CFG_ENV_ADDR, + CFG_ENV_ADDR+CFG_ENV_SIZE-1, + flash_get_info(CFG_ENV_ADDR)); +#endif + + + flash_afterinit(0, flash_info[0].start[0], flash_info[0].size); + return size ? size : 1; +} + +/*----------------------------------------------------------------------- + */ +static void flash_reset(flash_info_t *info) +{ + FPWV *base = (FPWV *)(info->start[0]); + + /* Put FLASH back in read mode */ + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) + *base = (FPW)0x00FF00FF; /* Intel Read Mode */ + else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) + *base = (FPW)0x00F000F0; /* AMD Read Mode */ +} + +/*----------------------------------------------------------------------- + */ + +static flash_info_t *flash_get_info(ulong base) +{ + int i; + flash_info_t * info; + + for (i = 0; i < CFG_MAX_FLASH_BANKS; i ++) { + info = & flash_info[i]; + if (info->size && + info->start[0] <= base && base <= info->start[0] + info->size - 1) + break; + } + + return i == CFG_MAX_FLASH_BANKS ? 0 : info; +} + +/*----------------------------------------------------------------------- + */ + +void flash_print_info (flash_info_t *info) +{ + int i; + uchar *boottype; + uchar *bootletter; + uchar *fmt; + uchar botbootletter[] = "B"; + uchar topbootletter[] = "T"; + uchar botboottype[] = "bottom boot sector"; + uchar topboottype[] = "top boot sector"; + + 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; +#if 0 + case FLASH_MAN_BM: printf ("BRIGHT MICRO "); break; + case FLASH_MAN_FUJ: printf ("FUJITSU "); break; + case FLASH_MAN_SST: printf ("SST "); break; + case FLASH_MAN_STM: printf ("STM "); break; + case FLASH_MAN_INTEL: printf ("INTEL "); break; +#endif + default: printf ("Unknown Vendor "); break; + } + + /* check for top or bottom boot, if it applies */ + if (info->flash_id & FLASH_BTYPE) { + boottype = botboottype; + bootletter = botbootletter; + } else { + boottype = topboottype; + bootletter = topbootletter; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_AM160T: + case FLASH_AM160B: + fmt = "29LV160%s (16 Mbit, %s)\n"; + break; + case FLASH_AMDLV065D: + fmt = "29LV065 (64 Mbit, uniform sectors)\n"; + break; + default: + fmt = "Unknown Chip Type\n"; + break; + } + + printf (fmt, bootletter, boottype); + + printf (" Size: %ld MB in %d Sectors\n", + info->size >> 20, + 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! + */ + +ulong flash_get_size (FPWV *addr, flash_info_t *info) +{ + int i; + ulong offset; + + /* Write auto select command: read Manufacturer ID */ + /* Write auto select command sequence and test FLASH answer */ + addr[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* for AMD, Intel ignores this */ + addr[FLASH_CYCLE2] = (FPW)0x00550055; /* for AMD, Intel ignores this */ + addr[FLASH_CYCLE1] = (FPW)0x00900090; /* selects Intel or AMD */ + + /* The manufacturer codes are only 1 byte, so just use 1 byte. + * This works for any bus width and any FLASH device width. + */ + udelay(100); + switch (addr[0] & 0xff) { + + case (uchar)AMD_MANUFACT: + info->flash_id = FLASH_MAN_AMD; + break; + +#if 0 + case (uchar)INTEL_MANUFACT: + info->flash_id = FLASH_MAN_INTEL; + break; +#endif + + default: + printf ("unknown vendor=%x ", addr[0] & 0xff); + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + break; + } + + /* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */ + if (info->flash_id != FLASH_UNKNOWN) switch ((FPW)addr[2]) { + + case (FPW)AMD_ID_LV160B: + info->flash_id += FLASH_AM160B; + info->sector_count = 35; + info->size = 0x00200000; + offset = 0x00e00000; + info->start[0] = (ulong)addr + offset; + info->start[1] = (ulong)addr + offset + 0x4000; + info->start[2] = (ulong)addr + offset + 0x6000; + info->start[3] = (ulong)addr + offset + 0x8000; + for (i = 4; i < info->sector_count; i++) { + info->start[i] = (ulong)addr + offset + 0x10000 * (i-3); + } + break; + + case (FPW)AMD_ID_LV065D: + info->flash_id += FLASH_AMDLV065D; + info->sector_count = 128; + info->size = 0x00800000; + offset = 0x00800000; + for (i = 0; i < info->sector_count; i++) + info->start[i] = (ulong)addr + offset + (i * 0x10000); + break; /* => 8 or 16 MB */ + + default: + printf ("unknown AMD device=%x ", (FPW)addr[2]); + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + return (0); /* => no or unknown flash */ + } + + /* Put FLASH back in read mode */ + flash_reset(info); + + return (info->size); +} + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t *info, int s_first, int s_last) +{ + FPWV *addr; + int flag, prot, sect; + int intel = (info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL; + ulong start, now, last; + int rcode = 0; + + 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; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_AMDLV065D: + break; + case FLASH_UNKNOWN: + default: + printf ("Can't erase unknown flash type %08lx - aborted\n", + info->flash_id); + 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"); + } + + last = get_timer(0); + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect<=s_last && rcode == 0; sect++) { + + if (info->protect[sect] != 0) /* protected, skip it */ + continue; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + addr = (FPWV *)(info->start[sect]); + if (intel) { + *addr = (FPW)0x00500050; /* clear status register */ + *addr = (FPW)0x00200020; /* erase setup */ + *addr = (FPW)0x00D000D0; /* erase confirm */ + } + else { + /* must be AMD style if not Intel */ + FPWV *base; /* first address in bank */ + + base = (FPWV *)(info->start[0]); + base[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* unlock */ + base[FLASH_CYCLE2] = (FPW)0x00550055; /* unlock */ + base[FLASH_CYCLE1] = (FPW)0x00800080; /* erase mode */ + base[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* unlock */ + base[FLASH_CYCLE2] = (FPW)0x00550055; /* unlock */ + *addr = (FPW)0x00300030; /* erase sector */ + } + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + start = get_timer(0); + + /* wait at least 50us for AMD, 80us for Intel. + * Let's wait 1 ms. + */ + udelay (1000); + + while ((*addr & (FPW)0x00800080) != (FPW)0x00800080) { + if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { + printf ("Timeout\n"); + + if (intel) { + /* suspend erase */ + *addr = (FPW)0x00B000B0; + } + + flash_reset(info); /* reset to read mode */ + rcode = 1; /* failed */ + break; + } + + /* show that we're waiting */ + if ((get_timer(last)) > CFG_HZ) {/* every second */ + putc ('.'); + last = get_timer(0); + } + } + + /* show that we're waiting */ + if ((get_timer(last)) > CFG_HZ) { /* every second */ + putc ('.'); + last = get_timer(0); + } + + flash_reset(info); /* reset to read mode */ + } + + printf (" done\n"); + return rcode; +} + +/*----------------------------------------------------------------------- + * 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) +{ + FPW data = 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */ + int bytes; /* number of bytes to program in current word */ + int left; /* number of bytes left to program */ + int i, res; + + for (left = cnt, res = 0; + left > 0 && res == 0; + addr += sizeof(data), left -= sizeof(data) - bytes) { + + bytes = addr & (sizeof(data) - 1); + addr &= ~(sizeof(data) - 1); + + /* combine source and destination data so can program + * an entire word of 16 or 32 bits + */ + for (i = 0; i < sizeof(data); i++) { + data <<= 8; + if (i < bytes || i - bytes >= left ) + data += *((uchar *)addr + i); + else + data += *src++; + } + + /* write one word to the flash */ + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_AMD: + res = write_word_amd(info, (FPWV *)addr, data); + break; + default: + /* unknown flash type, error! */ + printf ("missing or unknown FLASH type\n"); + res = 1; /* not really a timeout, but gives error */ + break; + } + } + + return (res); +} + +/*----------------------------------------------------------------------- + * Write a word to Flash for AMD FLASH + * A word is 16 or 32 bits, whichever the bus width of the flash bank + * (not an individual chip) is. + * + * returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_word_amd (flash_info_t *info, FPWV *dest, FPW data) +{ + ulong start; + int flag; + int res = 0; /* result, assume success */ + FPWV *base; /* first address in flash bank */ + + /* Check if Flash is (sufficiently) erased */ + if ((*dest & data) != data) { + return (2); + } + + + base = (FPWV *)(info->start[0]); + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + base[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* unlock */ + base[FLASH_CYCLE2] = (FPW)0x00550055; /* unlock */ + base[FLASH_CYCLE1] = (FPW)0x00A000A0; /* selects program mode */ + + *dest = data; /* start programming the data */ + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + start = get_timer (0); + + /* data polling for D7 */ + while (res == 0 && (*dest & (FPW)0x00800080) != (data & (FPW)0x00800080)) { + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + *dest = (FPW)0x00F000F0; /* reset bank */ + res = 1; + } + } + + return (res); +} diff --git a/board/emk/top5200/top5200.c b/board/emk/top5200/top5200.c new file mode 100644 index 0000000000..536a5152a6 --- /dev/null +++ b/board/emk/top5200/top5200.c @@ -0,0 +1,216 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2003 + * Reinhard Meyer, EMK Elektronik GmbH, r.meyer@emk-elektronik.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 + +/***************************************************************************** + * initialize SDRAM/DDRAM controller. + * TBD: get data from I2C EEPROM + *****************************************************************************/ +long int initdram (int board_type) +{ + ulong dramsize = 0; +#ifndef CFG_RAMBOOT + ulong t; + ulong tap_del; + + #define MODE_EN 0x80000000 + #define SOFT_PRE 2 + #define SOFT_REF 4 + + /* configure SDRAM start/end */ + *(vu_long *)MPC5XXX_SDRAM_CS0CFG = (CFG_SDRAM_BASE & 0xFFF00000) | CFG_DRAM_RAM_SIZE; + *(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x80000000; /* disabled */ + + /* setup config registers */ + *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = CFG_DRAM_CONFIG1; + *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = CFG_DRAM_CONFIG2; + + /* unlock mode register */ + *(vu_long *)MPC5XXX_SDRAM_CTRL = CFG_DRAM_CONTROL | MODE_EN; + /* precharge all banks */ + *(vu_long *)MPC5XXX_SDRAM_CTRL = CFG_DRAM_CONTROL | MODE_EN | SOFT_PRE; +#if CFG_DRAM_DDR + /* set extended mode register */ + *(vu_short *)MPC5XXX_SDRAM_MODE = CFG_DRAM_EMODE; +#endif + /* set mode register */ + *(vu_short *)MPC5XXX_SDRAM_MODE = CFG_DRAM_MODE | 0x0400; + /* precharge all banks */ + *(vu_long *)MPC5XXX_SDRAM_CTRL = CFG_DRAM_CONTROL | MODE_EN | SOFT_PRE; + /* auto refresh */ + *(vu_long *)MPC5XXX_SDRAM_CTRL = CFG_DRAM_CONTROL | MODE_EN | SOFT_REF; + /* set mode register */ + *(vu_short *)MPC5XXX_SDRAM_MODE = CFG_DRAM_MODE; + /* normal operation */ + *(vu_long *)MPC5XXX_SDRAM_CTRL = CFG_DRAM_CONTROL; + /* write default TAP delay */ + *(vu_long *)MPC5XXX_CDM_PORCFG = CFG_DRAM_TAP_DEL << 24; + +#if 0 + for (tap_del = 0; tap_del < 32; tap_del++) { + *(vu_long *)MPC5XXX_CDM_PORCFG = tap_del << 24; + + printf ("\nTAP Delay:%x Filling DRAM...", *(vu_long *)MPC5XXX_CDM_PORCFG); + for (t = 0; t < 0x04000000; t+=4) + *(vu_long *) t = t; + printf ("Checking DRAM...\n"); + for (t = 0; t < 0x04000000; t+=4) { + ulong rval = *(vu_long *) t; + if (rval != t) { + printf ("mismatch at %x: ", t); + printf (" 1.read %x", rval); + printf (" 2.read %x", *(vu_long *) t); + printf (" 3.read %x", *(vu_long *) t); + break; + } + } + } +#endif +#endif /* CFG_RAMBOOT */ + + dramsize = ((1 << (*(vu_long *)MPC5XXX_SDRAM_CS0CFG - 0x13)) << 20); + + /* return total ram size */ + return dramsize; +} + +/***************************************************************************** + * print board identification + *****************************************************************************/ +int checkboard (void) +{ +#if defined (CONFIG_EVAL5200) + puts ("Board: EMK TOP5200 on EVAL5200\n"); +#else +#if defined (CONFIG_MINI5200) + puts ("Board: EMK TOP5200 on MINI5200\n"); +#else + puts ("Board: EMK TOP5200\n"); +#endif +#endif + return 0; +} + +/***************************************************************************** + * prepare for FLASH detection + *****************************************************************************/ +void flash_preinit(void) +{ + /* + * Now, when we are in RAM, enable flash write + * access for detection process. + * Note that CS_BOOT cannot be cleared when + * executing in flash. + */ + *(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */ +} + +/***************************************************************************** + * finalize FLASH setup + *****************************************************************************/ +void flash_afterinit(uint bank, ulong start, ulong size) +{ + if (bank == 0) { /* adjust mapping */ + *(vu_long *)MPC5XXX_BOOTCS_START = + *(vu_long *)MPC5XXX_CS0_START = START_REG(start); + *(vu_long *)MPC5XXX_BOOTCS_STOP = + *(vu_long *)MPC5XXX_CS0_STOP = STOP_REG(start, size); + } +} + +/***************************************************************************** + * otherinits after RAM is there and we are relocated to RAM + * note: though this is an int function, nobody cares for the result! + *****************************************************************************/ +int misc_init_r (void) +{ + /* read 'factory' part of EEPROM */ + uchar buf[81]; + uchar *p; + uint length; + uint addr; + uint len; + + /* get length first */ + addr = CFG_FACT_OFFSET; + if (eeprom_read (CFG_I2C_FACT_ADDR, addr, buf, 2)) { +bailout: + printf ("cannot read factory configuration\n"); + printf ("be sure to set ethaddr yourself!\n"); + return 0; + } + length = buf[0] + (buf[1] << 8); + addr += 2; + + /* sanity check */ + if (length < 20 || length > CFG_FACT_SIZE - 2) + goto bailout; + + /* read lines */ + while (length > 0) { + /* read one line */ + len = length > 80 ? 80 : length; + if (eeprom_read (CFG_I2C_FACT_ADDR, addr, buf, len)) + goto bailout; + /* mark end of buffer */ + buf[len] = 0; + /* search end of line */ + for (p = buf; *p && *p != 0x0a; p++); + if (!*p) + goto bailout; + *p++ = 0; + /* advance to next line start */ + length -= p - buf; + addr += p - buf; + /*printf ("%s\n", buf); */ + /* search for our specific entry */ + if (!strncmp ((char *) buf, "[RLA/lan/Ethernet] ", 19)) { + setenv ("ethaddr", buf + 19); + } else if (!strncmp ((char *) buf, "[BOARD/SERIAL] ", 15)) { + setenv ("serial#", buf + 15); + } else if (!strncmp ((char *) buf, "[BOARD/TYPE] ", 13)) { + setenv ("board_id", buf + 13); + } + } + return (0); +} + +/***************************************************************************** + * initialize the PCI system + *****************************************************************************/ +#ifdef CONFIG_PCI +static struct pci_controller hose; + +extern void pci_mpc5xxx_init(struct pci_controller *); + +void pci_init_board(void) +{ + pci_mpc5xxx_init(&hose); +} +#endif diff --git a/board/emk/top5200/u-boot.lds b/board/emk/top5200/u-boot.lds new file mode 100644 index 0000000000..d999dd16ad --- /dev/null +++ b/board/emk/top5200/u-boot.lds @@ -0,0 +1,122 @@ +/* + * (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 + */ + +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/mpc5xxx/start.o (.text) + *(.text) + *(.fixup) + *(.got1) + . = ALIGN(16); + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x0FFF) & 0xFFFFF000; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2; + __fixup_entries = (. - _FIXUP_TABLE_) >> 2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(4096); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(4096); + __init_end = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); +} diff --git a/include/configs/TOP5200.h b/include/configs/TOP5200.h new file mode 100644 index 0000000000..21daa2d971 --- /dev/null +++ b/include/configs/TOP5200.h @@ -0,0 +1,291 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * modified for TOP5200 by Reinhard Meyer, www.emk-elektronik.de + * TOP5200 differences from IceCube: + * 1 FLASH Bank for one Chip only, up to 64 MB in 16 MB Banks + * bank switch controlled by TIMER_6(LSB) and TIMER_7(MSB) Pins + * 1 SDRAM/DDRAM Bank up to 256 MB + * local VPD I2C Bus is software driven and uses + * GPIO_WKUP_6 for SDA, GPIO_WKUP_7 for SCL + * FLASH is located at 0x80000000 + * Internal regs are at 0xfff00000 + * Reset jumps to 0x00000100 + * + * 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 + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * High Level Configuration Options + * (easy to change) + */ + +#define CONFIG_MPC5XXX 1 /* This is an MPC5xxx CPU */ +#define CONFIG_MPC5200 1 /* More exactly a MPC5200 */ +#define CONFIG_TOP5200 1 /* ... on TOP5200 board - we need this for FEC.C */ + +#define CFG_MPC5XXX_CLKIN 33333333 /* ... running at 33MHz */ + +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +#define CFG_CACHELINE_SIZE 32 /* For MPC5xxx CPUs */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +# define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */ +#endif + +/* + * Serial console configuration + */ +#define CONFIG_PSC_CONSOLE 1 /* console is on PSC1 */ +#define CONFIG_BAUDRATE 9600 /* ... at 9600 bps */ +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, 230400 } + + +#ifdef CONFIG_EVAL5200 /* PCI is supported with Evaluation board only */ +/* + * PCI Mapping: + * 0x40000000 - 0x4fffffff - PCI Memory + * 0x50000000 - 0x50ffffff - PCI IO Space + */ +# define CONFIG_PCI 1 +# define CONFIG_PCI_PNP 1 +# define CONFIG_PCI_SCAN_SHOW 1 + +# define CONFIG_PCI_MEM_BUS 0x40000000 +# define CONFIG_PCI_MEM_PHYS CONFIG_PCI_MEM_BUS +# define CONFIG_PCI_MEM_SIZE 0x10000000 + +# define CONFIG_PCI_IO_BUS 0x50000000 +# define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS +# define CONFIG_PCI_IO_SIZE 0x01000000 + +# define ADD_PCI_CMD CFG_CMD_PCI + +#else /* no Evaluation board */ + +# define ADD_PCI_CMD 0 /* no CFG_CMD_PCI */ + +#endif + +/* + * Supported commands + */ +#define CONFIG_COMMANDS (CONFIG_CMD_DFL | ADD_PCI_CMD | \ + CFG_CMD_I2C | CFG_CMD_EEPROM) + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include + +/* + * Autobooting + */ +#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */ +#define CONFIG_BOOTCOMMAND "bootm 100000" /* autoboot command */ +#define CONFIG_BOOTARGS "root=/dev/ram rw" + +/* + * IPB Bus clocking configuration. + */ +#undef CFG_IPBSPEED_133 /* define for 133MHz speed */ + +/* + * I2C configuration + */ +/* + * EEPROM configuration + */ +#define CFG_EEPROM_PAGE_WRITE_BITS 3 +#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 70 + +#define CFG_I2C_EEPROM_ADDR_LEN 2 +#define CFG_EEPROM_SIZE 0x2000 + +#define CONFIG_ENV_OVERWRITE +#define CONFIG_MISC_INIT_R + +#undef CONFIG_HARD_I2C /* I2C with hardware support */ +#define CONFIG_SOFT_I2C 1 + +#if defined (CONFIG_SOFT_I2C) +# define SDA0 0x40 +# define SCL0 0x80 +# define GPIOE0 *((volatile uchar*)(CFG_MBAR+0x0c00)) +# define DDR0 *((volatile uchar*)(CFG_MBAR+0x0c08)) +# define DVO0 *((volatile uchar*)(CFG_MBAR+0x0c0c)) +# define DVI0 *((volatile uchar*)(CFG_MBAR+0x0c20)) +# define ODE0 *((volatile uchar*)(CFG_MBAR+0x0c04)) +# define I2C_INIT {GPIOE0|=(SDA0|SCL0);ODE0|=(SDA0|SCL0);DVO0|=(SDA0|SCL0);DDR0|=(SDA0|SCL0);} +# define I2C_READ ((DVI0&SDA0)?1:0) +# define I2C_SDA(x) {if(x)DVO0|=SDA0;else DVO0&=~SDA0;} +# define I2C_SCL(x) {if(x)DVO0|=SCL0;else DVO0&=~SCL0;} +# define I2C_DELAY {udelay(5);} +# define I2C_ACTIVE {DDR0|=SDA0;} +# define I2C_TRISTATE {DDR0&=~SDA0;} +# define CFG_I2C_SPEED 100000 +# define CFG_I2C_SLAVE 0x7F +#endif + +#if defined (CONFIG_HARD_I2C) +# define CFG_I2C_MODULE 2 /* Select I2C module #1 or #2 */ +# define CFG_I2C_SPEED 100000 /* 100 kHz */ +# define CFG_I2C_SLAVE 0x7F +#endif + +/* + * Flash configuration, expect one 16 Megabyte Bank at most + */ +#define CFG_FLASH_BASE 0xff000000 +#define CFG_FLASH_SIZE 0x01000000 +#define CFG_MAX_FLASH_BANKS 1 /* max num of memory banks */ +#define CFG_ENV_ADDR (CFG_FLASH_BASE + 0) + +#define CFG_MAX_FLASH_SECT 256 /* max num of sects on one chip */ + +#define CFG_FLASH_ERASE_TOUT 240000 /* Flash Erase Timeout (in ms) */ +#define CFG_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (in ms) */ + +#undef CONFIG_FLASH_16BIT /* Flash is 8-bit */ + +/* + * DRAM configuration - will be read from VPD later... TODO! + */ +#if 0 +/* 2x MT48LC16M16A2 - 7.0 ns SDRAMS = 64 MegaBytes Total */ +#define CFG_DRAM_DDR 0 +#define CFG_DRAM_EMODE 0 +#define CFG_DRAM_MODE 0x008D +#define CFG_DRAM_CONTROL 0x514F0000 +#define CFG_DRAM_CONFIG1 0xC2233A00 +#define CFG_DRAM_CONFIG2 0x88B70004 +#define CFG_DRAM_TAP_DEL 0x08 +#define CFG_DRAM_RAM_SIZE 0x19 +#endif +#if 1 +/* 2x MT48LC16M16A2 - 7.5 ns SDRAMS = 64 MegaBytes Total */ +#define CFG_DRAM_DDR 0 +#define CFG_DRAM_EMODE 0 +#define CFG_DRAM_MODE 0x00CD +#define CFG_DRAM_CONTROL 0x514F0000 +#define CFG_DRAM_CONFIG1 0xD2333A00 +#define CFG_DRAM_CONFIG2 0x8AD70004 +#define CFG_DRAM_TAP_DEL 0x08 +#define CFG_DRAM_RAM_SIZE 0x19 +#endif + +/* + * Environment settings + */ +#define CFG_ENV_IS_IN_EEPROM 1 /* turn on EEPROM env feature */ +#define CFG_ENV_OFFSET 0x1000 +#define CFG_ENV_SIZE 0x0700 +#define CFG_I2C_EEPROM_ADDR 0x57 + +/* + * VPD settings + */ +#define CFG_FACT_OFFSET 0x1800 +#define CFG_FACT_SIZE 0x0800 +#define CFG_I2C_FACT_ADDR 0x57 + +/* + * Memory map + * + * Warning!!! with the current BestComm Task, MBAR MUST BE set to 0xf0000000 + */ +#define CFG_MBAR 0xf0000000 /* DO NOT CHANGE this */ +#define CFG_SDRAM_BASE 0x00000000 +#define CFG_DEFAULT_MBAR 0x80000000 + +/* Use SRAM until RAM will be available */ +#define CFG_INIT_RAM_ADDR MPC5XXX_SRAM +#define CFG_INIT_RAM_END MPC5XXX_SRAM_SIZE /* End of used area in DPRAM */ + + +#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ +#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET + +#define CFG_MONITOR_BASE TEXT_BASE +#if (CFG_MONITOR_BASE < CFG_FLASH_BASE) +# define CFG_RAMBOOT 1 +#endif + +#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ +#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ + +/* + * Ethernet configuration + */ +#define CONFIG_MPC5XXX_FEC 1 +#define CONFIG_FEC_10MBIT 1 /* Workaround for FEC 100Mbit problem */ +#define CONFIG_PHY_ADDR 0x1f +#define CONFIG_PHY_TYPE 0x79c874 +/* + * GPIO configuration: + * PSC1,2,3 predefined as UART + * PCI disabled + * Ethernet 100 with MD + */ +#define CFG_GPS_PORT_CONFIG 0x00058444 + +/* + * Miscellaneous configurable options + */ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +# define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else +# define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +#define CFG_MEMTEST_START 0x00100000 /* memtest works on */ +#define CFG_MEMTEST_END 0x01f00000 /* 1 ... 31 MB in DRAM */ + +#define CFG_LOAD_ADDR 0x100000 /* default load address */ + +#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ + +/* + * Various low-level settings + */ +#define CFG_HID0_INIT HID0_ICE | HID0_ICFI +#define CFG_HID0_FINAL HID0_ICE + +#define CFG_BOOTCS_START CFG_FLASH_BASE +#define CFG_BOOTCS_SIZE CFG_FLASH_SIZE +#define CFG_BOOTCS_CFG 0x00047801 +#define CFG_CS0_START CFG_FLASH_BASE +#define CFG_CS0_SIZE CFG_FLASH_SIZE + +#define CFG_CS_BURST 0x00000000 +#define CFG_CS_DEADCYCLE 0x33333333 + +#define CFG_RESET_ADDRESS 0x7f000000 + +#endif /* __CONFIG_H */