diff options
author | Stefan Roese <sr@denx.de> | 2005-08-22 17:51:53 +0200 |
---|---|---|
committer | Stefan Roese <sr@denx.de> | 2005-08-22 17:51:53 +0200 |
commit | 5e4b3361bc0ccb2138569f872be60165ebeefb57 (patch) | |
tree | 1c68b9470b453554bb51ab23c431d8a183b1871a /board/esd/pf5200 | |
parent | c0233d979bda450ba23896357aa4711aecf55f7c (diff) | |
download | u-boot-imx-5e4b3361bc0ccb2138569f872be60165ebeefb57.zip u-boot-imx-5e4b3361bc0ccb2138569f872be60165ebeefb57.tar.gz u-boot-imx-5e4b3361bc0ccb2138569f872be60165ebeefb57.tar.bz2 |
Add esd cpci5200 and pf5200 boards
Patch by Reinhard Arlt, 22 Aug 2005
Diffstat (limited to 'board/esd/pf5200')
-rw-r--r-- | board/esd/pf5200/Makefile | 53 | ||||
-rw-r--r-- | board/esd/pf5200/config.mk | 44 | ||||
-rw-r--r-- | board/esd/pf5200/flash.c | 461 | ||||
-rw-r--r-- | board/esd/pf5200/mt46v16m16-75.h | 37 | ||||
-rw-r--r-- | board/esd/pf5200/pf5200.c | 370 | ||||
-rw-r--r-- | board/esd/pf5200/u-boot.lds | 122 |
6 files changed, 1087 insertions, 0 deletions
diff --git a/board/esd/pf5200/Makefile b/board/esd/pf5200/Makefile new file mode 100644 index 0000000..603bbe2 --- /dev/null +++ b/board/esd/pf5200/Makefile @@ -0,0 +1,53 @@ + +# +# (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 + +# Objects for Xilinx JTAG programming (CPLD) +# CPLD = ../common/xilinx_jtag/lenval.o \ +# ../common/xilinx_jtag/micro.o \ +# ../common/xilinx_jtag/ports.o + +# OBJS = $(BOARD).o flash.o $(CPLD) +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/esd/pf5200/config.mk b/board/esd/pf5200/config.mk new file mode 100644 index 0000000..07b5de1 --- /dev/null +++ b/board/esd/pf5200/config.mk @@ -0,0 +1,44 @@ +# +# (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 +# + +# +# IceCube board: +# +# Valid values for TEXT_BASE are: +# +# 0xFFF00000 boot high (standard configuration) +# 0xFF000000 boot low for 16 MiB boards +# 0xFF800000 boot low for 8 MiB boards +# 0x00100000 boot from RAM (for testing only) +# + +sinclude $(TOPDIR)/board/$(BOARDDIR)/config.tmp + +ifndef TEXT_BASE +## Standard: boot high +TEXT_BASE = 0xFFF00000 +## For testing: boot from RAM +# TEXT_BASE = 0x00100000 +endif + +PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)/board diff --git a/board/esd/pf5200/flash.c b/board/esd/pf5200/flash.c new file mode 100644 index 0000000..bfbd090 --- /dev/null +++ b/board/esd/pf5200/flash.c @@ -0,0 +1,461 @@ +/* + * (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 <common.h> + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +typedef unsigned short FLASH_PORT_WIDTH; +typedef volatile unsigned short FLASH_PORT_WIDTHV; + +#define FLASH_ID_MASK 0x00FF + +#define FPW FLASH_PORT_WIDTH +#define FPWV FLASH_PORT_WIDTHV + +#define FLASH_CYCLE1 0x0555 +#define FLASH_CYCLE2 0x0aaa +#define FLASH_ID1 0x00 +#define FLASH_ID2 0x01 +#define FLASH_ID3 0x0E +#define FLASH_ID4 0x0F + +/*----------------------------------------------------------------------- + * 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 = 0; + 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[i], 0, sizeof(flash_info_t)); + flash_info[i].size = flash_get_size((FPW *) flashbase, &flash_info[i]); + size += flash_info[i].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(i, flash_info[i].start[0], flash_info[i].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 *fmt; + + 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; + default: + printf("Unknown Vendor "); + break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_AMLV256U: + fmt = "29LV256M (256 Mbit)\n"; + break; + default: + fmt = "Unknown Chip Type\n"; + break; + } + + printf(fmt); + 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) { + ulong size; + int erased; + ulong *flash = (unsigned long *)info->start[i]; + + if ((i % 5) == 0) { + printf("\n "); + } + + /* + * Check if whole sector is erased + */ + size = + (i != + (info->sector_count - 1)) ? (info->start[i + 1] - + info->start[i]) >> 2 : (info-> + start + [0] + + info-> + size - + info-> + start + [i]) + >> 2; + + for (flash = (unsigned long *)info->start[i], erased = 1; + (flash != (unsigned long *)info->start[i] + size) + && erased; flash++) { + erased = *flash == ~0x0UL; + } + printf(" %08lX %s %s", info->start[i], erased ? "E" : " ", + 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; + + /* 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[FLASH_ID1] & 0x00ff) { + case (uchar) AMD_MANUFACT: + info->flash_id = FLASH_MAN_AMD; + break; + default: + printf("unknown vendor=%x ", addr[FLASH_ID1] & 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[FLASH_ID2]) { + case (FPW) AMD_ID_MIRROR: + /* MIRROR BIT FLASH, read more ID bytes */ + if ((FPW) addr[FLASH_ID3] == (FPW) AMD_ID_LV256U_2 + && (FPW) addr[FLASH_ID4] == (FPW) AMD_ID_LV256U_3) { + /* attention: only the first 16 MB will be used in u-boot */ + info->flash_id += FLASH_AMLV256U; + info->sector_count = 512; + info->size = 0x02000000; + for (i = 0; i < info->sector_count; i++) { + info->start[i] = + (ulong) addr + 0x10000 * i; + } + break; + } + /* fall thru to here ! */ + default: + printf("unknown AMD device=%x %x %x", + (FPW) addr[FLASH_ID2], (FPW) addr[FLASH_ID3], + (FPW) addr[FLASH_ID4]); + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0x800000; + break; + } + + /* 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_AMLV256U: + 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/esd/pf5200/mt46v16m16-75.h b/board/esd/pf5200/mt46v16m16-75.h new file mode 100644 index 0000000..22d0a55 --- /dev/null +++ b/board/esd/pf5200/mt46v16m16-75.h @@ -0,0 +1,37 @@ +/* + * (C) Copyright 2004 + * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#define SDRAM_DDR 1 /* is DDR */ + +#if defined(CONFIG_MPC5200) +/* Settings for XLB = 132 MHz */ +#define SDRAM_MODE 0x018D0000 +#define SDRAM_EMODE 0x40090000 +#define SDRAM_CONTROL 0x705f0f00 +#define SDRAM_CONFIG1 0x73722930 +#define SDRAM_CONFIG2 0x47770000 +#define SDRAM_TAPDELAY 0x10000000 + +#else +#error CONFIG_MPC5200 not defined +#endif diff --git a/board/esd/pf5200/pf5200.c b/board/esd/pf5200/pf5200.c new file mode 100644 index 0000000..fa71c79 --- /dev/null +++ b/board/esd/pf5200/pf5200.c @@ -0,0 +1,370 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2004 + * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * pf5200.c - main board support/init for the esd pf5200. + */ + +#include <common.h> +#include <mpc5xxx.h> +#include <pci.h> +#include <command.h> + +#include "mt46v16m16-75.h" + +void init_power_switch(void); + +static void sdram_start(int hi_addr) +{ + long hi_addr_bit = hi_addr ? 0x01000000 : 0; + + /* unlock mode register */ + *(vu_long *) MPC5XXX_SDRAM_CTRL = + SDRAM_CONTROL | 0x80000000 | hi_addr_bit; + __asm__ volatile ("sync"); + + /* precharge all banks */ + *(vu_long *) MPC5XXX_SDRAM_CTRL = + SDRAM_CONTROL | 0x80000002 | hi_addr_bit; + __asm__ volatile ("sync"); + + /* set mode register: extended mode */ + *(vu_long *) MPC5XXX_SDRAM_MODE = SDRAM_EMODE; + __asm__ volatile ("sync"); + + /* set mode register: reset DLL */ + *(vu_long *) MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000; + __asm__ volatile ("sync"); + + /* precharge all banks */ + *(vu_long *) MPC5XXX_SDRAM_CTRL = + SDRAM_CONTROL | 0x80000002 | hi_addr_bit; + __asm__ volatile ("sync"); + + /* auto refresh */ + *(vu_long *) MPC5XXX_SDRAM_CTRL = + SDRAM_CONTROL | 0x80000004 | hi_addr_bit; + __asm__ volatile ("sync"); + + /* set mode register */ + *(vu_long *) MPC5XXX_SDRAM_MODE = SDRAM_MODE; + __asm__ volatile ("sync"); + + /* normal operation */ + *(vu_long *) MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit; + __asm__ volatile ("sync"); +} + +/* + * ATTENTION: Although partially referenced initdram does NOT make real use + * use of CFG_SDRAM_BASE. The code does not work if CFG_SDRAM_BASE + * is something else than 0x00000000. + */ + +long int initdram(int board_type) +{ + ulong dramsize = 0; + ulong test1, test2; + + /* setup SDRAM chip selects */ + *(vu_long *) MPC5XXX_SDRAM_CS0CFG = 0x0000001e; /* 2G at 0x0 */ + *(vu_long *) MPC5XXX_SDRAM_CS1CFG = 0x80000000; /* disabled */ + __asm__ volatile ("sync"); + + /* setup config registers */ + *(vu_long *) MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1; + *(vu_long *) MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2; + __asm__ volatile ("sync"); + + /* set tap delay */ + *(vu_long *) MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY; + __asm__ volatile ("sync"); + + /* find RAM size using SDRAM CS0 only */ + sdram_start(0); + test1 = get_ram_size((ulong *) CFG_SDRAM_BASE, 0x80000000); + sdram_start(1); + test2 = get_ram_size((ulong *) CFG_SDRAM_BASE, 0x80000000); + + if (test1 > test2) { + sdram_start(0); + dramsize = test1; + } else { + dramsize = test2; + } + + /* memory smaller than 1MB is impossible */ + if (dramsize < (1 << 20)) { + dramsize = 0; + } + + /* set SDRAM CS0 size according to the amount of RAM found */ + if (dramsize > 0) { + *(vu_long *) MPC5XXX_SDRAM_CS0CFG = + 0x13 + __builtin_ffs(dramsize >> 20) - 1; + /* let SDRAM CS1 start right after CS0 */ + *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e; /* 2G */ + } else { +#if 0 + *(vu_long *) MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */ + /* let SDRAM CS1 start right after CS0 */ + *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e; /* 2G */ +#else + *(vu_long *) MPC5XXX_SDRAM_CS0CFG = + 0x13 + __builtin_ffs(0x08000000 >> 20) - 1; + /* let SDRAM CS1 start right after CS0 */ + *(vu_long *) MPC5XXX_SDRAM_CS1CFG = 0x08000000 + 0x0000001e; /* 2G */ +#endif + } + +#if 0 + /* find RAM size using SDRAM CS1 only */ + sdram_start(0); + get_ram_size((ulong *) (CFG_SDRAM_BASE + dramsize), 0x80000000); + sdram_start(1); + get_ram_size((ulong *) (CFG_SDRAM_BASE + dramsize), 0x80000000); + sdram_start(0); +#endif + /* set SDRAM CS1 size according to the amount of RAM found */ + + *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */ + + init_power_switch(); + return (dramsize); +} + +int checkboard(void) +{ + puts("Board: esd ParaFinder (pf5200)\n"); + return 0; +} + +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 */ +} + +void flash_afterinit(ulong size) +{ + if (size == 0x02000000) { + /* adjust mapping */ + *(vu_long *) MPC5XXX_BOOTCS_START = + *(vu_long *) MPC5XXX_CS0_START = + START_REG(CFG_BOOTCS_START | size); + *(vu_long *) MPC5XXX_BOOTCS_STOP = + *(vu_long *) MPC5XXX_CS0_STOP = + STOP_REG(CFG_BOOTCS_START | size, size); + } +} + +#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 + +#if defined (CFG_CMD_IDE) && defined (CONFIG_IDE_RESET) + +#define GPIO_PSC1_4 0x01000000UL + +void init_ide_reset(void) +{ + debug("init_ide_reset\n"); + + /* Configure PSC1_4 as GPIO output for ATA reset */ + *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC1_4; + *(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_PSC1_4; +} + +void ide_set_reset(int idereset) +{ + debug("ide_reset(%d)\n", idereset); + + if (idereset) { + *(vu_long *) MPC5XXX_WU_GPIO_DATA &= ~GPIO_PSC1_4; + } else { + *(vu_long *) MPC5XXX_WU_GPIO_DATA |= GPIO_PSC1_4; + } +} +#endif /* defined (CFG_CMD_IDE) && defined (CONFIG_IDE_RESET) */ + +#define MPC5XXX_SIMPLEIO_GPIO_ENABLE (MPC5XXX_GPIO + 0x0004) +#define MPC5XXX_SIMPLEIO_GPIO_DIR (MPC5XXX_GPIO + 0x000C) +#define MPC5XXX_SIMPLEIO_GPIO_DATA_OUTPUT (MPC5XXX_GPIO + 0x0010) +#define MPC5XXX_SIMPLEIO_GPIO_DATA_INPUT (MPC5XXX_GPIO + 0x0014) + +#define MPC5XXX_INTERRUPT_GPIO_ENABLE (MPC5XXX_GPIO + 0x0020) +#define MPC5XXX_INTERRUPT_GPIO_DIR (MPC5XXX_GPIO + 0x0028) +#define MPC5XXX_INTERRUPT_GPIO_DATA_OUTPUT (MPC5XXX_GPIO + 0x002C) +#define MPC5XXX_INTERRUPT_GPIO_STATUS (MPC5XXX_GPIO + 0x003C) + +#define GPIO_WU6 0x40000000UL +#define GPIO_USB0 0x00010000UL +#define GPIO_USB9 0x08000000UL +#define GPIO_USB9S 0x00080000UL + +void init_power_switch(void) +{ + debug("init_power_switch\n"); + + /* Configure GPIO_WU6 as GPIO output for ATA reset */ + *(vu_long *) MPC5XXX_WU_GPIO_DATA |= GPIO_WU6; + *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_WU6; + *(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_WU6; + __asm__ volatile ("sync"); + + *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_DATA_OUTPUT &= ~GPIO_USB0; + *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_ENABLE |= GPIO_USB0; + *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_DIR |= GPIO_USB0; + __asm__ volatile ("sync"); + + *(vu_long *) MPC5XXX_INTERRUPT_GPIO_DATA_OUTPUT &= ~GPIO_USB9; + *(vu_long *) MPC5XXX_INTERRUPT_GPIO_ENABLE &= ~GPIO_USB9; + __asm__ volatile ("sync"); + + if ((*(vu_long *) MPC5XXX_INTERRUPT_GPIO_STATUS & GPIO_USB9S) == 0) { + *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_DATA_OUTPUT |= GPIO_USB0; + __asm__ volatile ("sync"); + } + *(vu_char *) CFG_CS1_START = 0x02; /* Red Power LED on */ + __asm__ volatile ("sync"); + + *(vu_char *) (CFG_CS1_START + 1) = 0x02; /* Disable driver for KB11 */ + __asm__ volatile ("sync"); +} + +void power_set_reset(int power) +{ + debug("ide_set_reset(%d)\n", power); + + if (power) { + *(vu_long *) MPC5XXX_WU_GPIO_DATA &= ~GPIO_WU6; + *(vu_long *) MPC5XXX_INTERRUPT_GPIO_DATA_OUTPUT &= ~GPIO_USB9; + } else { + *(vu_long *) MPC5XXX_WU_GPIO_DATA |= GPIO_WU6; + if ((*(vu_long *) MPC5XXX_INTERRUPT_GPIO_STATUS & GPIO_USB9S) == + 0) { + *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_DATA_OUTPUT |= + GPIO_USB0; + } + + } +} + +int do_poweroff(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + power_set_reset(1); + return (0); +} + +U_BOOT_CMD(poweroff, 1, 1, do_poweroff, "poweroff- Switch off power\n", NULL); + +int phypower(int flag) +{ + u32 addr; + vu_long *reg; + int status; + pci_dev_t dev; + + dev = PCI_BDF(0, 0x18, 0); + status = pci_read_config_dword(dev, PCI_BASE_ADDRESS_1, &addr); + if (status == 0) { + reg = (vu_long *) (addr + 0x00000040); + *reg |= 0x40000000; + __asm__ volatile ("sync"); + + reg = (vu_long *) (addr + 0x001000c); + *reg |= 0x20000000; + __asm__ volatile ("sync"); + + reg = (vu_long *) (addr + 0x0010004); + if (flag != 0) { + *reg &= ~0x20000000; + } else { + *reg |= 0x20000000; + } + __asm__ volatile ("sync"); + } + return (status); +} + +int do_phypower(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + int status; + + if (argv[1][0] == '0') { + status = phypower(0); + } else { + status = phypower(1); + } + return (0); +} + +U_BOOT_CMD(phypower, 2, 2, do_phypower, + "phypower- Switch power of ethernet phy\n", NULL); + +int do_writepci(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + unsigned int addr; + unsigned int size; + int i; + volatile unsigned long *ptr; + + addr = simple_strtol(argv[1], NULL, 16); + size = simple_strtol(argv[2], NULL, 16); + + printf("\nWriting at addr %08x, size %08x.\n", addr, size); + + while (1) { + ptr = (volatile unsigned long *)addr; + for (i = 0; i < (size >> 2); i++) { + *ptr++ = i; + } + + /* Abort if ctrl-c was pressed */ + if (ctrlc()) { + puts("\nAbort\n"); + return 0; + } + putc('.'); + } + return 0; +} + +U_BOOT_CMD(writepci, 3, 1, do_writepci, + "writepci- Write some data to pcibus\n", + "<addr> <size>\n" " - Write some data to pcibus.\n"); diff --git a/board/esd/pf5200/u-boot.lds b/board/esd/pf5200/u-boot.lds new file mode 100644 index 0000000..d999dd1 --- /dev/null +++ b/board/esd/pf5200/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 = .); +} |