From 39539887ea7dc298c98ac1fddd38551dfa335120 Mon Sep 17 00:00:00 2001 From: wdenk Date: Thu, 1 Jul 2004 16:30:44 +0000 Subject: * Code cleanup (ARM mostly) * Patch by Curt Brune, 17 May 2004: - Add support for Samsung S3C4510B CPU (ARM7tdmi based SoC) - Add support for ESPD-Inc. EVB4510 Board --- board/evb4510/Makefile | 47 +++++ board/evb4510/config.mk | 27 +++ board/evb4510/evb4510.c | 86 ++++++++ board/evb4510/flash.c | 540 +++++++++++++++++++++++++++++++++++++++++++++++ board/evb4510/memsetup.S | 157 ++++++++++++++ board/evb4510/u-boot.lds | 68 ++++++ 6 files changed, 925 insertions(+) create mode 100644 board/evb4510/Makefile create mode 100644 board/evb4510/config.mk create mode 100644 board/evb4510/evb4510.c create mode 100644 board/evb4510/flash.c create mode 100644 board/evb4510/memsetup.S create mode 100644 board/evb4510/u-boot.lds (limited to 'board/evb4510') diff --git a/board/evb4510/Makefile b/board/evb4510/Makefile new file mode 100644 index 0000000..1ab4dfb --- /dev/null +++ b/board/evb4510/Makefile @@ -0,0 +1,47 @@ +# +# (C) Copyright 2000-2004 +# 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 := evb4510.o flash.o +SOBJS := memsetup.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 $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +-include .depend + +######################################################################### diff --git a/board/evb4510/config.mk b/board/evb4510/config.mk new file mode 100644 index 0000000..4d1a019 --- /dev/null +++ b/board/evb4510/config.mk @@ -0,0 +1,27 @@ +# +# Copyright (c) 2004 Cucy Systems (http://www.cucy.com) +# Curt Brune +# +# (C) Copyright 2000-2004 +# 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 +# + +TEXT_BASE = 0x007d0000 diff --git a/board/evb4510/evb4510.c b/board/evb4510/evb4510.c new file mode 100644 index 0000000..72d1f4e --- /dev/null +++ b/board/evb4510/evb4510.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2004 Cucy Systems (http://www.cucy.com) + * Curt Brune + * + * 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 + +/* ------------------------------------------------------------------------- */ + + +#define PUT_LED(val) (PUT_REG(REG_IOPDATA, (~val)&0xFF)) +#define GET_LED() ((~GET_REG( REG_IOPDATA)) & 0xFF) +#define SET_LED(val) { u32 led = GET_LED(); led |= 1 << (val); PUT_LED( led); } +#define CLR_LED(val) { u32 led = GET_LED(); led &= ~(1 << (val)); PUT_LED( led); } + +/* + * Miscelaneous platform dependent initialisations + */ + +int board_init (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + icache_enable(); + + /* address for the kernel command line */ + gd->bd->bi_boot_params = 0x800; + + /* enable board LEDs for output */ + PUT_REG( REG_IOPDATA, 0x0); + PUT_REG( REG_IOPMODE, 0xFFFF); + PUT_REG( REG_IOPDATA, 0xFF); + + /* enable LED 7 to show we're alive */ + SET_LED( 7); + + /* configure free running timer 1 */ + /* Stop timer 1 */ + CLR_REG( REG_TMOD, TM1_RUN); + + /* Configure for toggle mode */ + SET_REG( REG_TMOD, TM1_TOGGLE); + + /* Load Timer data register with count down value */ + PUT_REG( REG_TDATA1, 0xFFFFFFFF); + + /* Clear timer counter register */ + PUT_REG( REG_TCNT1, 0x0); + + /* Start timer -- count down timer */ + SET_REG( REG_TMOD, TM1_RUN); + + return 0; +} + +int dram_init (void) +{ + DECLARE_GLOBAL_DATA_PTR; + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; +#if CONFIG_NR_DRAM_BANKS == 2 + gd->bd->bi_dram[1].start = PHYS_SDRAM_2; + gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; +#endif + return 0; +} diff --git a/board/evb4510/flash.c b/board/evb4510/flash.c new file mode 100644 index 0000000..5491827 --- /dev/null +++ b/board/evb4510/flash.c @@ -0,0 +1,540 @@ +/* + * + * Copyright (c) 2004 Cucy Systems (http://www.cucy.com) + * Curt Brune + * + * 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 + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; + +typedef enum { + FLASH_DEV_U9_512KB = 0, + FLASH_DEV_U7_2MB = 1 +} FLASH_DEV; + +#define FLASH_DQ7 (0x80) +#define FLASH_DQ5 (0x20) + +#define PROG_ADDR (0xAAA) +#define SETUP_ADDR (0xAAA) +#define ID_ADDR (0xAAA) +#define UNLOCK_ADDR1 (0xAAA) +#define UNLOCK_ADDR2 (0x555) + +#define UNLOCK_CMD1 (0xAA) +#define UNLOCK_CMD2 (0x55) +#define ERASE_SUSPEND_CMD (0xB0) +#define ERASE_RESUME_CMD (0x30) +#define RESET_CMD (0xF0) +#define ID_CMD (0x90) +#define SELECT_CMD (0x90) +#define CHIPERASE_CMD (0x10) +#define BYPASS_CMD (0x20) +#define SECERASE_CMD (0x30) +#define PROG_CMD (0xa0) +#define SETUP_CMD (0x80) + +#if 0 +#define WRITE_UNLOCK(addr) { \ + PUT__U8( addr + UNLOCK_ADDR1, UNLOCK_CMD1); \ + PUT__U8( addr + UNLOCK_ADDR2, UNLOCK_CMD2); \ +} + +/* auto select command */ +#define CMD_ID(addr) WRITE_UNLOCK(addr); { \ + PUT__U8( addr + ID_ADDR, ID_CMD); \ +} + +#define CMD_RESET(addr) WRITE_UNLOCK(addr); { \ + PUT__U8( addr + ID_ADDR, RESET_CMD); \ +} + +#define CMD_ERASE_SEC(base, addr) WRITE_UNLOCK(base); \ + PUT__U8( base + SETUP_ADDR, SETUP_CMD); \ + WRITE_UNLOCK(base); \ + PUT__U8( addr, SECERASE_CMD); + +#define CMD_ERASE_CHIP(base) WRITE_UNLOCK(base); \ + PUT__U8( base + SETUP_ADDR, SETUP_CMD); \ + WRITE_UNLOCK(base); \ + PUT__U8( base + SETUP_ADDR, CHIPERASE_CMD); + +/* prepare for bypass programming */ +#define CMD_UNLOCK_BYPASS(addr) WRITE_UNLOCK(addr); { \ + PUT__U8( addr + ID_ADDR, 0x20); \ +} + +/* terminate bypass programming */ +#define CMD_BYPASS_RESET(addr) { \ + PUT__U8(addr, 0x90); \ + PUT__U8(addr, 0x00); \ +} +#endif + +inline static void FLASH_CMD_UNLOCK (FLASH_DEV dev, u32 base) +{ + switch (dev) { + case FLASH_DEV_U7_2MB: + PUT__U8 (base + 0xAAA, 0xAA); + PUT__U8 (base + 0x555, 0x55); + break; + case FLASH_DEV_U9_512KB: + PUT__U8 (base + 0x555, 0xAA); + PUT__U8 (base + 0x2AA, 0x55); + break; + } +} + +inline static void FLASH_CMD_SELECT (FLASH_DEV dev, u32 base) +{ + switch (dev) { + case FLASH_DEV_U7_2MB: + FLASH_CMD_UNLOCK (dev, base); + PUT__U8 (base + 0xAAA, SELECT_CMD); + break; + case FLASH_DEV_U9_512KB: + FLASH_CMD_UNLOCK (dev, base); + PUT__U8 (base + 0x555, SELECT_CMD); + break; + } +} + +inline static void FLASH_CMD_RESET (FLASH_DEV dev, u32 base) +{ + switch (dev) { + case FLASH_DEV_U7_2MB: + FLASH_CMD_UNLOCK (dev, base); + PUT__U8 (base + 0xAAA, RESET_CMD); + break; + case FLASH_DEV_U9_512KB: + FLASH_CMD_UNLOCK (dev, base); + PUT__U8 (base + 0x555, RESET_CMD); + break; + } +} + +inline static void FLASH_CMD_ERASE_SEC (FLASH_DEV dev, u32 base, u32 addr) +{ + switch (dev) { + case FLASH_DEV_U7_2MB: + FLASH_CMD_UNLOCK (dev, base); + PUT__U8 (base + 0xAAA, SETUP_CMD); + FLASH_CMD_UNLOCK (dev, base); + PUT__U8 (addr, SECERASE_CMD); + break; + case FLASH_DEV_U9_512KB: + FLASH_CMD_UNLOCK (dev, base); + PUT__U8 (base + 0x555, SETUP_CMD); + FLASH_CMD_UNLOCK (dev, base); + PUT__U8 (addr, SECERASE_CMD); + break; + } +} + +inline static void FLASH_CMD_ERASE_CHIP (FLASH_DEV dev, u32 base) +{ + switch (dev) { + case FLASH_DEV_U7_2MB: + FLASH_CMD_UNLOCK (dev, base); + PUT__U8 (base + 0xAAA, SETUP_CMD); + FLASH_CMD_UNLOCK (dev, base); + PUT__U8 (base, CHIPERASE_CMD); + break; + case FLASH_DEV_U9_512KB: + FLASH_CMD_UNLOCK (dev, base); + PUT__U8 (base + 0x555, SETUP_CMD); + FLASH_CMD_UNLOCK (dev, base); + PUT__U8 (base, CHIPERASE_CMD); + break; + } +} + +inline static void FLASH_CMD_UNLOCK_BYPASS (FLASH_DEV dev, u32 base) +{ + switch (dev) { + case FLASH_DEV_U7_2MB: + FLASH_CMD_UNLOCK (dev, base); + PUT__U8 (base + 0xAAA, BYPASS_CMD); + break; + case FLASH_DEV_U9_512KB: + FLASH_CMD_UNLOCK (dev, base); + PUT__U8 (base + 0x555, BYPASS_CMD); + break; + } +} + +inline static void FLASH_CMD_BYPASS_RESET (FLASH_DEV dev, u32 base) +{ + PUT__U8 (base, SELECT_CMD); + PUT__U8 (base, 0x0); +} + +/* poll for flash command completion */ +static u16 _flash_poll (FLASH_DEV dev, u32 addr, u16 data, ulong timeOut) +{ + u32 done = 0; + ulong t0; + + u16 error = 0; + volatile u16 flashData; + + data = data & 0xFF; + t0 = get_timer (0); + while (get_timer (t0) < timeOut) { + /* for( i = 0; i < POLL_LOOPS; i++) { */ + /* Read the Data */ + flashData = GET__U8 (addr); + + /* FLASH_DQ7 = Data? */ + if ((flashData & FLASH_DQ7) == (data & FLASH_DQ7)) { + done = 1; + break; + } + + /* Check Timeout (FLASH_DQ5==1) */ + if (flashData & FLASH_DQ5) { + /* Read the Data */ + flashData = GET__U8 (addr); + + /* FLASH_DQ7 = Data? */ + if (!((flashData & FLASH_DQ7) == (data & FLASH_DQ7))) { + printf ("_flash_poll(): FLASH_DQ7 & flashData not equal to write value\n"); + error = ERR_PROG_ERROR; + } + FLASH_CMD_RESET (dev, addr); + done = 1; + break; + } + /* spin delay */ + udelay (10); + } + + + /* error update */ + if (!done) { + printf ("_flash_poll(): Timeout\n"); + error = ERR_TIMOUT; + } + + /* Check the data */ + if (!error) { + /* Read the Data */ + flashData = GET__U8 (addr); + if (flashData != data) { + error = ERR_PROG_ERROR; + printf ("_flash_poll(): flashData(0x%04x) not equal to data(0x%04x)\n", + flashData, data); + } + } + + return error; +} + +/*----------------------------------------------------------------------- + */ +static int _flash_check_protection (flash_info_t * info, int s_first, int s_last) +{ + int sect, prot = 0; + + for (sect = s_first; sect <= s_last; sect++) + if (info->protect[sect]) { + printf (" Flash sector %d protected.\n", sect); + prot++; + } + return prot; +} + +static int _detectFlash (FLASH_DEV dev, u32 base, u8 venId, u8 devId) +{ + + u32 baseAddr = base | CACHE_DISABLE_MASK; + u8 vendorId, deviceId; + + /* printf(__FUNCTION__"(): detecting flash @ 0x%08x\n", base); */ + + /* Send auto select command and read manufacturer info */ + FLASH_CMD_SELECT (dev, baseAddr); + vendorId = GET__U8 (baseAddr); + FLASH_CMD_RESET (dev, baseAddr); + + /* Send auto select command and read device info */ + FLASH_CMD_SELECT (dev, baseAddr); + + if (dev == FLASH_DEV_U7_2MB) { + deviceId = GET__U8 (baseAddr + 2); + } else if (dev == FLASH_DEV_U9_512KB) { + deviceId = GET__U8 (baseAddr + 1); + } else { + return 0; + } + + FLASH_CMD_RESET (dev, baseAddr); + + /* printf (__FUNCTION__"(): found vendorId 0x%04x, deviceId 0x%04x\n", + vendorId, deviceId); + */ + + return (vendorId == venId) && (deviceId == devId); + +} + +/****************************************************************************** + * + * Public u-boot interface functions below + * + *****************************************************************************/ + +/*************************************************************************** + * + * Flash initialization + * + * This board has two banks of flash, but the base addresses depend on + * how the board is jumpered. + * + * The two flash types are: + * + * AMD Am29LV160DB (2MB) sectors layout 16KB, 2x8KB, 32KB, 31x64KB + * + * AMD Am29LV040B (512KB) sectors: 8x64KB + *****************************************************************************/ + +unsigned long flash_init (void) +{ + flash_info_t *info; + u16 i; + u32 flashtest; + s16 amd160 = -1; + u32 amd160base = 0; + +#if CFG_MAX_FLASH_BANKS == 2 + s16 amd040 = -1; + u32 amd040base = 0; +#endif + + /* configure PHYS_FLASH_1 */ + if (_detectFlash (FLASH_DEV_U7_2MB, PHYS_FLASH_1, 0x1, 0x49)) { + amd160 = 0; + amd160base = PHYS_FLASH_1; +#if CFG_MAX_FLASH_BANKS == 1 + } +#else + if (_detectFlash + (FLASH_DEV_U9_512KB, PHYS_FLASH_2, 0x1, 0x4F)) { + amd040 = 1; + amd040base = PHYS_FLASH_2; + } else { + printf (__FUNCTION__ + "(): Unable to detect PHYS_FLASH_2: 0x%08x\n", + PHYS_FLASH_2); + } + } else if (_detectFlash (FLASH_DEV_U9_512KB, PHYS_FLASH_1, 0x1, 0x4F)) { + amd040 = 0; + amd040base = PHYS_FLASH_1; + if (_detectFlash (FLASH_DEV_U7_2MB, PHYS_FLASH_2, 0x1, 0x49)) { + amd160 = 1; + amd160base = PHYS_FLASH_2; + } else { + printf (__FUNCTION__ + "(): Unable to detect PHYS_FLASH_2: 0x%08x\n", + PHYS_FLASH_2); + } + } +#endif + else { + printf (__FUNCTION__ + "(): Unable to detect PHYS_FLASH_1: 0x%08x\n", + PHYS_FLASH_1); + } + + /* Configure AMD Am29LV160DB (2MB) */ + info = &flash_info[amd160]; + info->flash_id = FLASH_DEV_U7_2MB; + info->sector_count = 35; + info->size = 2 * 1024 * 1024; /* 2MB */ + /* 1*16K Boot Block + 2*8K Parameter Block + 1*32K Small Main Block */ + info->start[0] = amd160base; + info->start[1] = amd160base + 0x4000; + info->start[2] = amd160base + 0x6000; + info->start[3] = amd160base + 0x8000; + for (i = 1; i < info->sector_count; i++) + info->start[3 + i] = amd160base + i * (64 * 1024); + + for (i = 0; i < info->sector_count; i++) { + /* Write auto select command sequence and query sector protection */ + FLASH_CMD_SELECT (info->flash_id, + info->start[i] | CACHE_DISABLE_MASK); + flashtest = + GET__U8 (((info->start[i] + 4) | CACHE_DISABLE_MASK)); + FLASH_CMD_RESET (info->flash_id, + amd160base | CACHE_DISABLE_MASK); + info->protect[i] = (flashtest & 0x0001); + } + + /* + * protect monitor and environment sectors in 2MB flash + */ + flash_protect (FLAG_PROTECT_SET, + amd160base, amd160base + monitor_flash_len - 1, info); + + flash_protect (FLAG_PROTECT_SET, + CFG_ENV_ADDR, CFG_ENV_ADDR + CFG_ENV_SIZE - 1, info); + +#if CFG_MAX_FLASH_BANKS == 2 + /* Configure AMD Am29LV040B (512KB) */ + info = &flash_info[amd040]; + info->flash_id = FLASH_DEV_U9_512KB; + info->sector_count = 8; + info->size = 512 * 1024; /* 512KB, 8 x 64KB */ + for (i = 0; i < info->sector_count; i++) { + info->start[i] = amd040base + i * (64 * 1024); + /* Write auto select command sequence and query sector protection */ + FLASH_CMD_SELECT (info->flash_id, + info->start[i] | CACHE_DISABLE_MASK); + flashtest = + GET__U8 (((info->start[i] + 2) | CACHE_DISABLE_MASK)); + FLASH_CMD_RESET (info->flash_id, + amd040base | CACHE_DISABLE_MASK); + info->protect[i] = (flashtest & 0x0001); + } +#endif + + return flash_info[0].size +#if CFG_MAX_FLASH_BANKS == 2 + + flash_info[1].size +#endif + ; +} + +void flash_print_info (flash_info_t * info) +{ + int i; + + if (info->flash_id == FLASH_DEV_U7_2MB) { + printf ("AMD Am29LV160DB (2MB) 16KB,2x8KB,32KB,31x64KB\n"); + } else if (info->flash_id == FLASH_DEV_U9_512KB) { + printf ("AMD Am29LV040B (512KB) 8x64KB\n"); + } else { + printf ("Unknown flash_id ...\n"); + return; + } + + printf (" Size: %ld KB in %d Sectors\n", + info->size >> 10, info->sector_count); + printf (" Sector Start Addresses:"); + for (i = 0; i < info->sector_count; i++) { + if ((i % 4) == 0) + printf ("\n "); + printf (" S%02d @ 0x%08lX%s", i, + info->start[i], info->protect[i] ? " !" : " "); + } + printf ("\n"); +} + +int flash_erase (flash_info_t * info, int s_first, int s_last) +{ + u16 i, error = 0; + + printf ("\n"); + + /* check flash protection bits */ + if (_flash_check_protection (info, s_first, s_last)) { + printf (" Flash erase aborted due to protected sectors\n"); + return ERR_PROTECTED; + } + + if ((s_first < info->sector_count) && (s_first <= s_last)) { + for (i = s_first; i <= s_last && !error; i++) { + printf (" Erasing Sector %d @ 0x%08lx ... ", i, + info->start[i]); + /* bypass the cache to access the flash memory */ + FLASH_CMD_ERASE_SEC (info->flash_id, + (info-> + start[0] | CACHE_DISABLE_MASK), + (info-> + start[i] | CACHE_DISABLE_MASK)); + /* look for sector to become 0xFF after erase */ + error = _flash_poll (info->flash_id, + info-> + start[i] | CACHE_DISABLE_MASK, + 0xFF, CFG_FLASH_ERASE_TOUT); + FLASH_CMD_RESET (info->flash_id, + (info-> + start[0] | CACHE_DISABLE_MASK)); + printf ("done\n"); + if (error) { + break; + } + } + } else + error = ERR_INVAL; + + return error; +} + +int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) +{ + u16 error = 0, i; + u32 n; + u8 *bp, *bps; + + /* Write Setup */ + /* bypass the cache to access the flash memory */ + FLASH_CMD_UNLOCK_BYPASS (info->flash_id, + (info->start[0] | CACHE_DISABLE_MASK)); + + /* Write the Data to Flash */ + + bp = (u8 *) (addr | CACHE_DISABLE_MASK); + bps = (u8 *) src; + + for (n = 0; n < cnt && !error; n++, bp++, bps++) { + + if (!(n % (cnt / 15))) { + printf ("."); + } + + /* write the flash command for flash memory */ + *bp = 0xA0; + + /* Write the data */ + *bp = *bps; + + /* Check if the write is done */ + for (i = 0; i < 0xff; i++); + error = _flash_poll (info->flash_id, (u32) bp, *bps, + CFG_FLASH_WRITE_TOUT); + if (error) { + return error; + } + } + + /* Reset the Flash Mode to read */ + FLASH_CMD_BYPASS_RESET (info->flash_id, info->start[0]); + + printf (" "); + + return error; +} diff --git a/board/evb4510/memsetup.S b/board/evb4510/memsetup.S new file mode 100644 index 0000000..915af1e --- /dev/null +++ b/board/evb4510/memsetup.S @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2004 Cucy Systems (http://www.cucy.com) + * Curt Brune + * + * 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 + +/*********************************************************************** + * Configure Memory Map + * + * This memory map allows us to relocate from FLASH to SRAM. After + * power-on reset the CPU only knows about the FLASH memory at address + * 0x00000000. After memsetup completes the memory map will be: + * + * Memory Addr + * 0x00000000 + * to 8MB SRAM (U5) -- 8MB Map + * 0x00800000 + * + * 0x01000000 + * to 2MB Flash @ 0x00000000 (U7) -- 2MB Map + * 0x01200000 + * + * 0x02000000 + * to 512KB Flash @ 0x02000000 (U9) -- 2MB Map + * 0x02080000 + * + * Load all 12 memory registers with the STMIA instruction since + * memory access is disabled once these registers are written. The + * last register written re-enables memory access. For more info see + * the user's manual for the S3C4510B, available from Samsung's web + * site. Search for part number "S3C4510B". + * + ***********************************************************************/ + +.globl memsetup +memsetup: + + /* preserve the temp register (r12 AKA ip) and remap it. */ + ldr r1, =SRAM_BASE+0xC + add r0, r12, #0x01000000 + str r0, [r1] + + /* remap the link register for when we return */ + add lr, lr, #0x01000000 + + /* store a short program in the on chip SRAM, which is + * unaffected when remapping memory. Note the cache must be + * disabled for the on chip SRAM to be available. + */ + ldr r1, =SRAM_BASE + ldr r0, =0xe8801ffe /* stmia r0, {r1-r12} */ + str r0, [r1] + add r1, r1, #4 + ldr r0, =0xe59fc000 /* ldr r12, [pc, #0] */ + str r0, [r1] + add r1, r1, #4 + ldr r0, =0xe1a0f00e /* mov pc, lr */ + str r0, [r1] + + adr r0, memory_map_data + ldmia r0, {r1-r12} + ldr r0, =REG_EXTDBWTH + + ldr pc, =SRAM_BASE + +.globl reset_cpu +reset_cpu: + /* + * reset the cpu by re-mapping FLASH 0 to 0x0 and jumping to + * address 0x0. We accomplish this by storing a few + * instructions into the on chip SRAM (8KB) and run from + * there. Note the cache must be disabled for the on chip + * SRAM to be available. + * + * load r2 with REG_ROMCON0 + * load r3 with 0x12040060 configure FLASH bank 0 @ 0x00000000 + * load r4 with REG_DRAMCON0 + * load r5 with 0x08000380 configure RAM bank 0 @ 0x01000000 + * load r6 with REG_REFEXTCON + * load r7 with 0x9c218360 + * load r8 with 0x0 + * store str r3,[r2] @ SRAM_BASE + * store str r5,[r4] @ SRAM_BASE + 0x4 + * store str r7,[r6] @ SRAM_BASE + 0x8 + * store mov pc,r8 @ SRAM_BASE + 0xC + * mov pc, SRAM_BASE + * + */ + + /* disable cache */ + ldr r0, =REG_SYSCFG + ldr r1, =0x83ffffa0 /* cache-disabled */ + str r1, [r0] + + ldr r2, =REG_ROMCON0 + ldr r3, =0x02000060 /* Bank0 2MB FLASH @ 0x00000000 */ + ldr r4, =REG_DRAMCON0 + ldr r5, =0x18040380 /* DRAM0 8MB SRAM @ 0x01000000 */ + ldr r6, =REG_REFEXTCON + ldr r7, =0xce278360 + ldr r8, =0x00000000 + ldr r1, =SRAM_BASE + ldr r0, =0xe5823000 /* str r3, [r2] */ + str r0, [r1] + ldr r1, =SRAM_BASE+4 + ldr r0, =0xe5845000 /* str r5, [r4] */ + str r0, [r1] + ldr r1, =SRAM_BASE+8 + ldr r0, =0xe5867000 /* str r7, [r6] */ + str r0, [r1] + ldr r1, =SRAM_BASE+0xC + ldr r0, =0xe1a0f008 /* mov pc, r8 */ + str r0, [r1] + ldr r1, =SRAM_BASE + mov pc, r1 + + /* never return */ + +/************************************************************************ + * Below are twelve 32-bit values for the twelve memory registers of + * the system manager, starting with register REG_EXTDBWTH. + ***********************************************************************/ +memory_map_data: + .long 0x00f03005 /* memory widths */ + .long 0x12040060 /* Bank0 2MB FLASH @ 0x01000000 */ + .long 0x22080060 /* Bank1 512KB FLASH @ 0x02000000 */ + .long 0x00000000 + .long 0x00000000 + .long 0x00000000 + .long 0x00000000 + .long 0x08000380 /* DRAM0 8MB SRAM @ 0x00000000 */ + .long 0x00000000 + .long 0x00000000 + .long 0x00000000 + .long 0x9c218360 /* enable memory */ diff --git a/board/evb4510/u-boot.lds b/board/evb4510/u-boot.lds new file mode 100644 index 0000000..9899790 --- /dev/null +++ b/board/evb4510/u-boot.lds @@ -0,0 +1,68 @@ +/* + * (C) Copyright 2000-2004 + * 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_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + cpu/arm720t/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} -- cgit v1.1