diff options
author | wdenk <wdenk> | 2003-03-06 21:55:29 +0000 |
---|---|---|
committer | wdenk <wdenk> | 2003-03-06 21:55:29 +0000 |
commit | 1cb8e980c41e86760fa93de63f4e4cf643bef9d9 (patch) | |
tree | e1993fba07dea51d92f1cec4c814a67173c1f8fb /board/mpl | |
parent | 500545cc6b83958209128bffa825b3c842a21a4e (diff) | |
download | u-boot-1cb8e980c41e86760fa93de63f4e4cf643bef9d9.zip u-boot-1cb8e980c41e86760fa93de63f4e4cf643bef9d9.tar.gz u-boot-1cb8e980c41e86760fa93de63f4e4cf643bef9d9.tar.bz2 |
* Patches by David Müller, 31 Jan 2003:LABEL_2003_03_06_2255
- minimal setup for CardBus bridges
- add EEPROM read/write support in the CS8900 driver
- add support for the builtin I2C controller in the Samsung s3c24x0 chips
- add support for MPL's VCMA9 (Samsung s3c2410 based) board
* Patch by Steven Scholz, 04 Feb 2003:
add support for RTC DS1307
* Patch by Reinhard Meyer, 5 Feb 2003:
fix PLPRCR/SCCR init sequence on 8xx to allow for
changes of EBDF by software
* Patch by Vladimir Gurevich, 07 Feb 2003:
"API-compatibility patch" for 4xx I2C driver
Diffstat (limited to 'board/mpl')
-rw-r--r-- | board/mpl/common/common_util.c | 55 | ||||
-rw-r--r-- | board/mpl/vcma9/Makefile | 49 | ||||
-rw-r--r-- | board/mpl/vcma9/cmd_vcma9.c | 144 | ||||
-rw-r--r-- | board/mpl/vcma9/config.mk | 24 | ||||
-rw-r--r-- | board/mpl/vcma9/flash.c | 445 | ||||
-rw-r--r-- | board/mpl/vcma9/memsetup.S | 160 | ||||
-rw-r--r-- | board/mpl/vcma9/u-boot.lds | 54 | ||||
-rw-r--r-- | board/mpl/vcma9/vcma9.c | 248 | ||||
-rw-r--r-- | board/mpl/vcma9/vcma9.h | 43 |
9 files changed, 1207 insertions, 15 deletions
diff --git a/board/mpl/common/common_util.c b/board/mpl/common/common_util.c index a4a73a6..0a67090 100644 --- a/board/mpl/common/common_util.c +++ b/board/mpl/common/common_util.c @@ -27,6 +27,7 @@ #include <video_fb.h> #include "common_util.h" #include <asm/processor.h> +#include <asm/byteorder.h> #include <i2c.h> #include <devices.h> #include <pci.h> @@ -39,7 +40,7 @@ extern int mem_test(unsigned long start, unsigned long ramsize, int quiet); extern flash_info_t flash_info[]; /* info for FLASH chips */ -image_header_t header; +static image_header_t header; @@ -51,6 +52,13 @@ int mpl_prg(unsigned long src,unsigned long size) unsigned long *magic = (unsigned long *)src; info = &flash_info[0]; + +#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) + if(ntohl(magic[0]) != IH_MAGIC) { + printf("Bad Magic number\n"); + return -1; + } + start = 0 - size; for(i=info->sector_count-1;i>0;i--) { @@ -60,13 +68,25 @@ int mpl_prg(unsigned long src,unsigned long size) } /* set-up flash location */ /* now erase flash */ - if(magic[0]!=IH_MAGIC) { - printf("Bad Magic number\n"); - return -1; - } printf("Erasing at %lx (sector %d) (start %lx)\n", start,i,info->start[i]); flash_erase (info, i, info->sector_count-1); + +#elif defined(CONFIG_VCMA9) + start = 0; + for (i = 0; i <info->sector_count; i++) + { + info->protect[i] = 0; /* unprotect this sector */ + if (size < info->start[i]) + break; + } + /* set-up flash location */ + /* now erase flash */ + printf("Erasing at %lx (sector %d) (start %lx)\n", + start,0,info->start[0]); + flash_erase (info, 0, i); + +#endif printf("flash erased, programming from 0x%lx 0x%lx Bytes\n",src,size); if ((rc = flash_write ((uchar *)src, start, size)) != 0) { puts ("ERROR "); @@ -84,7 +104,7 @@ int mpl_prg_image(unsigned long ld_addr) image_header_t *hdr=&header; /* Copy header so we can blank CRC field for re-calculation */ memcpy (&header, (char *)ld_addr, sizeof(image_header_t)); - if (hdr->ih_magic != IH_MAGIC) { + if (ntohl(hdr->ih_magic) != IH_MAGIC) { printf ("Bad Magic Number\n"); return 1; } @@ -99,16 +119,16 @@ int mpl_prg_image(unsigned long ld_addr) } data = (ulong)&header; len = sizeof(image_header_t); - checksum = hdr->ih_hcrc; + checksum = ntohl(hdr->ih_hcrc); hdr->ih_hcrc = 0; if (crc32 (0, (char *)data, len) != checksum) { printf ("Bad Header Checksum\n"); return 1; } data = ld_addr + sizeof(image_header_t); - len = hdr->ih_size; + len = ntohl(hdr->ih_size); printf ("Verifying Checksum ... "); - if (crc32 (0, (char *)data, len) != hdr->ih_dcrc) { + if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) { printf ("Bad Data CRC\n"); return 1; } @@ -152,14 +172,14 @@ void set_backup_values(int overwrite) } } memcpy(back.signature,"MPL\0",4); - i=getenv_r("serial#",back.serial_name,16); - if(i==0) { + i = getenv_r("serial#",back.serial_name,16); + if(i < 0) { printf("Not possible to write Backup\n"); return; } back.serial_name[16]=0; - i=getenv_r("ethaddr",back.eth_addr,20); - if(i==0) { + i = getenv_r("ethaddr",back.eth_addr,20); + if(i < 0) { printf("Not possible to write Backup\n"); return; } @@ -338,7 +358,7 @@ void show_stdio_dev(void) #define SW_CS_PRINTF(fmt,args...) #endif - +#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) int switch_cs(unsigned char boot) { unsigned long pbcr; @@ -391,7 +411,12 @@ int switch_cs(unsigned char boot) return 0; } } - +#elif defined(CONFIG_VCMA9) +int switch_cs(unsigned char boot) +{ + return 0; +} +#endif /* CONFIG_VCMA9 */ int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { diff --git a/board/mpl/vcma9/Makefile b/board/mpl/vcma9/Makefile new file mode 100644 index 0000000..428eea2 --- /dev/null +++ b/board/mpl/vcma9/Makefile @@ -0,0 +1,49 @@ +# +# (C) Copyright 2000, 2001, 2002 +# 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 := vcma9.o flash.o cmd_vcma9.o +OBJS += ../common/common_util.o ../common/memtst.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/mpl/vcma9/cmd_vcma9.c b/board/mpl/vcma9/cmd_vcma9.c new file mode 100644 index 0000000..cdafc50 --- /dev/null +++ b/board/mpl/vcma9/cmd_vcma9.c @@ -0,0 +1,144 @@ +/* + * (C) Copyright 2002 + * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch + * + * adapted for VCMA9 + * David Mueller, ELSOFT AG, d.mueller@elsoft.ch + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include <common.h> +#include <command.h> +#include "vcma9.h" +#include "../common/common_util.h" + +#if defined(CONFIG_DRIVER_CS8900) +#include <../drivers/cs8900.h> + +static uchar cs8900_chksum(ushort data) +{ + return((data >> 8) & 0x00FF) + (data & 0x00FF); +} + +#endif + +extern void print_vcma9_info(void); +extern int vcma9_cantest(void); +extern int vcma9_nandtest(void); +extern int vcma9_dactest(void); +extern int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + +/* ------------------------------------------------------------------------- */ + +int do_vcma9(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + DECLARE_GLOBAL_DATA_PTR; + + if (strcmp(argv[1], "info") == 0) + { + print_vcma9_info(); + return 0; + } +#if defined(CONFIG_DRIVER_CS8900) + if (strcmp(argv[1], "cs8900_eeprom") == 0) { + if (strcmp(argv[2], "read") == 0) { + uchar addr; ushort data; + + addr = simple_strtoul(argv[3], NULL, 16); + cs8900_e2prom_read(addr, &data); + printf("0x%2.2X: 0x%4.4X\n", addr, data); + } else if (strcmp(argv[2], "write") == 0) { + uchar addr; ushort data; + + addr = simple_strtoul(argv[3], NULL, 16); + data = simple_strtoul(argv[4], NULL, 16); + cs8900_e2prom_write(addr, data); + } else if (strcmp(argv[2], "setaddr") == 0) { + uchar addr, i, csum; ushort data; + + /* check for valid ethaddr */ + for (i = 0; i < 6; i++) + if (gd->bd->bi_enetaddr[i] != 0) + break; + + if (i < 6) { + addr = 1; + data = 0x2158; + cs8900_e2prom_write(addr, data); + csum = cs8900_chksum(data); + addr++; + for (i = 0; i < 6; i+=2) { + data = gd->bd->bi_enetaddr[i+1] << 8 | + gd->bd->bi_enetaddr[i]; + cs8900_e2prom_write(addr, data); + csum += cs8900_chksum(data); + addr++; + } + /* calculate header link byte */ + data = 0xA100 | (addr * 2); + cs8900_e2prom_write(0, data); + csum += cs8900_chksum(data); + /* write checksum word */ + cs8900_e2prom_write(addr, (0 - csum) << 8); + } else { + printf("\nplease defined 'ethaddr'\n"); + } + } else if (strcmp(argv[2], "dump") == 0) { + uchar addr, endaddr, csum; ushort data; + + printf("Dump of CS8900 config device: "); + cs8900_e2prom_read(addr, &data); + if ((data & 0xE000) == 0xA000) { + endaddr = (data & 0x00FF) / 2; + csum = cs8900_chksum(data); + for (addr = 1; addr <= endaddr; addr++) { + cs8900_e2prom_read(addr, &data); + printf("\n0x%2.2X: 0x%4.4X", addr, data); + csum += cs8900_chksum(data); + } + printf("\nChecksum: %s", (csum == 0) ? "ok" : "wrong"); + } else { + printf("no valid config found"); + } + printf("\n"); + } + + return 0; + } +#endif +#if 0 + if (strcmp(argv[1], "cantest") == 0) { + vcma9_cantest(); + return 0; + } + if (strcmp(argv[1], "nandtest") == 0) { + vcma9_nandtest(); + return 0; + } + if (strcmp(argv[1], "dactest") == 0) { + vcma9_dactest(); + return 0; + } +#endif + + return (do_mplcommon(cmdtp, flag, argc, argv)); +} + diff --git a/board/mpl/vcma9/config.mk b/board/mpl/vcma9/config.mk new file mode 100644 index 0000000..19ef187 --- /dev/null +++ b/board/mpl/vcma9/config.mk @@ -0,0 +1,24 @@ +# +# (C) Copyright 2002 +# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch> +# +# MPL VCMA9 board with S3C2410X (ARM920T) cpu +# +# see http://www.mpl.ch/ for more information about the MPL VCMA9 +# + +# +# MPL VCMA9 has 1 bank of 64 MB DRAM +# +# 3000'0000 to 3400'0000 +# +# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000 +# optionally with a ramdisk at 3080'0000 +# +# we load ourself to 33F0'0000 +# +# download area is 3300'0000 +# + + +TEXT_BASE = 0x33F00000 diff --git a/board/mpl/vcma9/flash.c b/board/mpl/vcma9/flash.c new file mode 100644 index 0000000..c2075da --- /dev/null +++ b/board/mpl/vcma9/flash.c @@ -0,0 +1,445 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.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> + +ulong myflush(void); + + +#define FLASH_BANK_SIZE PHYS_FLASH_SIZE +#define MAIN_SECT_SIZE 0x10000 /* 64 KB */ + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; + + +#define CMD_READ_ARRAY 0x000000F0 +#define CMD_UNLOCK1 0x000000AA +#define CMD_UNLOCK2 0x00000055 +#define CMD_ERASE_SETUP 0x00000080 +#define CMD_ERASE_CONFIRM 0x00000030 +#define CMD_PROGRAM 0x000000A0 +#define CMD_UNLOCK_BYPASS 0x00000020 + +#define MEM_FLASH_ADDR1 (*(volatile u16 *)(CFG_FLASH_BASE + (0x00000555 << 1))) +#define MEM_FLASH_ADDR2 (*(volatile u16 *)(CFG_FLASH_BASE + (0x000002AA << 1))) + +#define BIT_ERASE_DONE 0x00000080 +#define BIT_RDY_MASK 0x00000080 +#define BIT_PROGRAM_ERROR 0x00000020 +#define BIT_TIMEOUT 0x80000000 /* our flag */ + +#define READY 1 +#define ERR 2 +#define TMO 4 + +/*----------------------------------------------------------------------- + */ + +ulong flash_init(void) +{ + int i, j; + ulong size = 0; + + for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) + { + ulong flashbase = 0; + flash_info[i].flash_id = +#if defined(CONFIG_AMD_LV400) + (AMD_MANUFACT & FLASH_VENDMASK) | + (AMD_ID_LV400B & FLASH_TYPEMASK); +#elif defined(CONFIG_AMD_LV800) + (AMD_MANUFACT & FLASH_VENDMASK) | + (AMD_ID_LV800B & FLASH_TYPEMASK); +#else +#error "Unknown flash configured" +#endif + flash_info[i].size = FLASH_BANK_SIZE; + flash_info[i].sector_count = CFG_MAX_FLASH_SECT; + memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT); + if (i == 0) + flashbase = PHYS_FLASH_1; + else + panic("configured to many flash banks!\n"); + for (j = 0; j < flash_info[i].sector_count; j++) + { + if (j <= 3) + { + /* 1st one is 16 KB */ + if (j == 0) + { + flash_info[i].start[j] = flashbase + 0; + } + + /* 2nd and 3rd are both 8 KB */ + if ((j == 1) || (j == 2)) + { + flash_info[i].start[j] = flashbase + 0x4000 + (j-1)*0x2000; + } + + /* 4th 32 KB */ + if (j == 3) + { + flash_info[i].start[j] = flashbase + 0x8000; + } + } + else + { + flash_info[i].start[j] = flashbase + (j - 3)*MAIN_SECT_SIZE; + } + } + size += flash_info[i].size; + } + + flash_protect(FLAG_PROTECT_SET, + CFG_FLASH_BASE, + CFG_FLASH_BASE + _armboot_end - _armboot_start, + &flash_info[0]); + + flash_protect(FLAG_PROTECT_SET, + CFG_ENV_ADDR, + CFG_ENV_ADDR + CFG_ENV_SIZE - 1, + &flash_info[0]); + + return size; +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t *info) +{ + int i; + + switch (info->flash_id & FLASH_VENDMASK) + { + case (AMD_MANUFACT & FLASH_VENDMASK): + printf("AMD: "); + break; + default: + printf("Unknown Vendor "); + break; + } + + switch (info->flash_id & FLASH_TYPEMASK) + { + case (AMD_ID_LV400B & FLASH_TYPEMASK): + printf("1x Amd29LV400BB (4Mbit)\n"); + break; + case (AMD_ID_LV800B & FLASH_TYPEMASK): + printf("1x Amd29LV800BB (8Mbit)\n"); + break; + default: + printf("Unknown Chip Type\n"); + goto Done; + break; + } + + printf(" Size: %ld MB in %d Sectors\n", + info->size >> 20, info->sector_count); + + printf(" Sector Start Addresses:"); + for (i = 0; i < info->sector_count; i++) + { + if ((i % 5) == 0) + { + printf ("\n "); + } + printf (" %08lX%s", info->start[i], + info->protect[i] ? " (RO)" : " "); + } + printf ("\n"); + +Done: +} + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t *info, int s_first, int s_last) +{ + ushort result; + int iflag, cflag, prot, sect; + int rc = ERR_OK; + int chip; + + /* first look for protection bits */ + + if (info->flash_id == FLASH_UNKNOWN) + return ERR_UNKNOWN_FLASH_TYPE; + + if ((s_first < 0) || (s_first > s_last)) { + return ERR_INVAL; + } + + if ((info->flash_id & FLASH_VENDMASK) != + (AMD_MANUFACT & FLASH_VENDMASK)) { + return ERR_UNKNOWN_FLASH_VENDOR; + } + + prot = 0; + for (sect=s_first; sect<=s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + if (prot) + return ERR_PROTECTED; + + /* + * Disable interrupts which might cause a timeout + * here. Remember that our exception vectors are + * at address 0 in the flash, and we don't want a + * (ticker) exception to happen while the flash + * chip is in programming mode. + */ + cflag = icache_status(); + icache_disable(); + iflag = disable_interrupts(); + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect<=s_last && !ctrlc(); sect++) + { + printf("Erasing sector %2d ... ", sect); + + /* arm simple, non interrupt dependent timer */ + reset_timer_masked(); + + if (info->protect[sect] == 0) + { /* not protected */ + vu_short *addr = (vu_short *)(info->start[sect]); + + MEM_FLASH_ADDR1 = CMD_UNLOCK1; + MEM_FLASH_ADDR2 = CMD_UNLOCK2; + MEM_FLASH_ADDR1 = CMD_ERASE_SETUP; + + MEM_FLASH_ADDR1 = CMD_UNLOCK1; + MEM_FLASH_ADDR2 = CMD_UNLOCK2; + *addr = CMD_ERASE_CONFIRM; + + /* wait until flash is ready */ + chip = 0; + + do + { + result = *addr; + + /* check timeout */ + if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) + { + MEM_FLASH_ADDR1 = CMD_READ_ARRAY; + chip = TMO; + break; + } + + if (!chip && (result & 0xFFFF) & BIT_ERASE_DONE) + chip = READY; + + if (!chip && (result & 0xFFFF) & BIT_PROGRAM_ERROR) + chip = ERR; + + } while (!chip); + + MEM_FLASH_ADDR1 = CMD_READ_ARRAY; + + if (chip == ERR) + { + rc = ERR_PROG_ERROR; + goto outahere; + } + if (chip == TMO) + { + rc = ERR_TIMOUT; + goto outahere; + } + + printf("ok.\n"); + } + else /* it was protected */ + { + printf("protected!\n"); + } + } + + if (ctrlc()) + printf("User Interrupt!\n"); + +outahere: + /* allow flash to settle - wait 10 ms */ + udelay_masked(10000); + + if (iflag) + enable_interrupts(); + + if (cflag) + icache_enable(); + + return rc; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash + */ + +volatile static int write_hword (flash_info_t *info, ulong dest, ushort data) +{ + vu_short *addr = (vu_short *)dest; + ushort result; + int rc = ERR_OK; + int cflag, iflag; + int chip; + + /* + * Check if Flash is (sufficiently) erased + */ + result = *addr; + if ((result & data) != data) + return ERR_NOT_ERASED; + + + /* + * Disable interrupts which might cause a timeout + * here. Remember that our exception vectors are + * at address 0 in the flash, and we don't want a + * (ticker) exception to happen while the flash + * chip is in programming mode. + */ + cflag = icache_status(); + icache_disable(); + iflag = disable_interrupts(); + + MEM_FLASH_ADDR1 = CMD_UNLOCK1; + MEM_FLASH_ADDR2 = CMD_UNLOCK2; + MEM_FLASH_ADDR1 = CMD_PROGRAM; + *addr = data; + + /* arm simple, non interrupt dependent timer */ + reset_timer_masked(); + + /* wait until flash is ready */ + chip = 0; + do + { + result = *addr; + + /* check timeout */ + if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) + { + chip = ERR | TMO; + break; + } + if (!chip && ((result & 0x80) == (data & 0x80))) + chip = READY; + + if (!chip && ((result & 0xFFFF) & BIT_PROGRAM_ERROR)) + { + result = *addr; + + if ((result & 0x80) == (data & 0x80)) + chip = READY; + else + chip = ERR; + } + + } while (!chip); + + *addr = CMD_READ_ARRAY; + + if (chip == ERR || *addr != data) + rc = ERR_PROG_ERROR; + + if (iflag) + enable_interrupts(); + + if (cflag) + icache_enable(); + + return rc; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash. + */ + +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + ulong cp, wp; + int l; + int i, rc; + ushort data; + + wp = (addr & ~1); /* get lower word aligned address */ + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i=0, cp=wp; i<l; ++i, ++cp) { + data = (data >> 8) | (*(uchar *)cp << 8); + } + for (; i<2 && cnt>0; ++i) { + data = (data >> 8) | (*src++ << 8); + --cnt; + ++cp; + } + for (; cnt==0 && i<2; ++i, ++cp) { + data = (data >> 8) | (*(uchar *)cp << 8); + } + + if ((rc = write_hword(info, wp, data)) != 0) { + return (rc); + } + wp += 2; + } + + /* + * handle word aligned part + */ + while (cnt >= 2) { + data = *((vu_short*)src); + if ((rc = write_hword(info, wp, data)) != 0) { + return (rc); + } + src += 2; + wp += 2; + cnt -= 2; + } + + if (cnt == 0) { + return ERR_OK; + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i=0, cp=wp; i<2 && cnt>0; ++i, ++cp) { + data = (data >> 8) | (*src++ << 8); + --cnt; + } + for (; i<2; ++i, ++cp) { + data = (data >> 8) | (*(uchar *)cp << 8); + } + + return write_hword(info, wp, data); +} diff --git a/board/mpl/vcma9/memsetup.S b/board/mpl/vcma9/memsetup.S new file mode 100644 index 0000000..80721cd --- /dev/null +++ b/board/mpl/vcma9/memsetup.S @@ -0,0 +1,160 @@ +/* + * Memory Setup stuff - taken from blob memsetup.S + * + * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and + * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) + * + * Modified for the Samsung SMDK2410 by + * (C) Copyright 2002 + * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch> + * + * 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 <config.h> +#include <version.h> + + +/* some parameters for the board */ + +#define BWSCON 0x48000000 + +/* BWSCON */ +#define DW8 (0x0) +#define DW16 (0x1) +#define DW32 (0x2) +#define WAIT (0x1<<2) +#define UBLB (0x1<<3) + +#define B1_BWSCON (DW16) +#define B2_BWSCON (DW32) +#define B3_BWSCON (DW32) +#define B4_BWSCON (DW16 + WAIT + UBLB) +#define B5_BWSCON (DW8 + UBLB) +#define B6_BWSCON (DW32) +#define B7_BWSCON (DW32) + +/* BANK0CON */ +#define B0_Tacs 0x0 /* 0clk */ +#define B0_Tcos 0x0 /* 0clk */ +#define B0_Tacc 0x5 /* 8clk */ +#define B0_Tcoh 0x0 /* 0clk */ +#define B0_Tah 0x0 /* 0clk */ +#define B0_Tacp 0x0 /* page mode is not used */ +#define B0_PMC 0x0 /* page mode disabled */ + +/* BANK1CON */ +#define B1_Tacs 0x0 /* 0clk */ +#define B1_Tcos 0x0 /* 0clk */ +#define B1_Tacc 0x5 /* 8clk */ +#define B1_Tcoh 0x0 /* 0clk */ +#define B1_Tah 0x0 /* 0clk */ +#define B1_Tacp 0x0 /* page mode is not used */ +#define B1_PMC 0x0 /* page mode disabled */ + +#define B2_Tacs 0x3 /* 4clk */ +#define B2_Tcos 0x3 /* 4clk */ +#define B2_Tacc 0x7 /* 14clk */ +#define B2_Tcoh 0x3 /* 4clk */ +#define B2_Tah 0x3 /* 4clk */ +#define B2_Tacp 0x0 /* page mode is not used */ +#define B2_PMC 0x0 /* page mode disabled */ + +#define B3_Tacs 0x3 /* 4clk */ +#define B3_Tcos 0x3 /* 4clk */ +#define B3_Tacc 0x7 /* 14clk */ +#define B3_Tcoh 0x3 /* 4clk */ +#define B3_Tah 0x3 /* 4clk */ +#define B3_Tacp 0x0 /* page mode is not used */ +#define B3_PMC 0x0 /* page mode disabled */ + +#define B4_Tacs 0x3 /* 4clk */ +#define B4_Tcos 0x1 /* 1clk */ +#define B4_Tacc 0x7 /* 14clk */ +#define B4_Tcoh 0x1 /* 1clk */ +#define B4_Tah 0x0 /* 0clk */ +#define B4_Tacp 0x0 /* page mode is not used */ +#define B4_PMC 0x0 /* page mode disabled */ + +#define B5_Tacs 0x0 /* 0clk */ +#define B5_Tcos 0x3 /* 4clk */ +#define B5_Tacc 0x5 /* 8clk */ +#define B5_Tcoh 0x2 /* 2clk */ +#define B5_Tah 0x1 /* 1clk */ +#define B5_Tacp 0x0 /* page mode is not used */ +#define B5_PMC 0x0 /* page mode disabled */ + +#define B6_MT 0x3 /* SDRAM */ +#define B6_Trcd 0x1 /* 3clk */ +#define B6_SCAN 0x2 /* 10bit */ + +#define B7_MT 0x3 /* SDRAM */ +#define B7_Trcd 0x1 /* 3clk */ +#define B7_SCAN 0x2 /* 10bit */ + +/* REFRESH parameter */ +#define REFEN 0x1 /* Refresh enable */ +#define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh */ +#define Trp 0x0 /* 2clk */ +#define Trc 0x3 /* 7clk */ +#define Tchr 0x2 /* 3clk */ +#define REFCNT 1113 /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */ +/**************************************/ + +_TEXT_BASE: + .word TEXT_BASE + +.globl memsetup +memsetup: + /* memory control configuration */ + /* make r0 relative the current location so that it */ + /* reads SMRDATA out of FLASH rather than memory ! */ + ldr r0, =SMRDATA + ldr r1, _TEXT_BASE + sub r0, r0, r1 + ldr r1, =BWSCON /* Bus Width Status Controller */ + add r2, r0, #13*4 +0: + ldr r3, [r0], #4 + str r3, [r1], #4 + cmp r2, r0 + bne 0b + + /* everything is fine now */ + mov pc, lr + + .ltorg +/* the literal pools origin */ + +SMRDATA: + .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28)) + .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) + .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) + .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) + .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) + .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) + .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) + .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) + .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) + .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT) + .word 0x32 + .word 0x30 + .word 0x30 diff --git a/board/mpl/vcma9/u-boot.lds b/board/mpl/vcma9/u-boot.lds new file mode 100644 index 0000000..8c9c218 --- /dev/null +++ b/board/mpl/vcma9/u-boot.lds @@ -0,0 +1,54 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <gj@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_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/ +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + cpu/arm920t/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + armboot_end_data = .; + + . = ALIGN(4); + .bss : { *(.bss) } + + armboot_end = .; +} diff --git a/board/mpl/vcma9/vcma9.c b/board/mpl/vcma9/vcma9.c new file mode 100644 index 0000000..8e3552e --- /dev/null +++ b/board/mpl/vcma9/vcma9.c @@ -0,0 +1,248 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <s3c2410.h> +#include <i2c.h> + +#include "vcma9.h" +#include "../common/common_util.h" + +/* ------------------------------------------------------------------------- */ + +#define FCLK_SPEED 1 + +#if FCLK_SPEED==0 /* Fout = 203MHz, Fin = 12MHz for Audio */ +#define M_MDIV 0xC3 +#define M_PDIV 0x4 +#define M_SDIV 0x1 +#elif FCLK_SPEED==1 /* Fout = 202.8MHz */ +#define M_MDIV 0xA1 +#define M_PDIV 0x3 +#define M_SDIV 0x1 +#endif + +#define USB_CLOCK 1 + +#if USB_CLOCK==0 +#define U_M_MDIV 0xA1 +#define U_M_PDIV 0x3 +#define U_M_SDIV 0x1 +#elif USB_CLOCK==1 +#define U_M_MDIV 0x48 +#define U_M_PDIV 0x3 +#define U_M_SDIV 0x2 +#endif + +static inline void delay(unsigned long loops) +{ + __asm__ volatile ("1:\n" + "subs %0, %1, #1\n" + "bne 1b":"=r" (loops):"0" (loops)); +} + +/* + * Miscellaneous platform dependent initialisations + */ + +int board_init(void) +{ + DECLARE_GLOBAL_DATA_PTR; + + /* to reduce PLL lock time, adjust the LOCKTIME register */ + rLOCKTIME = 0xFFFFFF; + + /* configure MPLL */ + rMPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV); + + /* some delay between MPLL and UPLL */ + delay (4000); + + /* configure UPLL */ + rUPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV); + + /* some delay between MPLL and UPLL */ + delay (8000); + + /* set up the I/O ports */ + rGPACON = 0x007FFFFF; + rGPBCON = 0x002AAAAA; + rGPBUP = 0x000002BF; + rGPCCON = 0xAAAAAAAA; + rGPCUP = 0x0000FFFF; + rGPDCON = 0xAAAAAAAA; + rGPDUP = 0x0000FFFF; + rGPECON = 0xAAAAAAAA; + rGPEUP = 0x000037F7; + rGPFCON = 0x00000000; + rGPFUP = 0x00000000; + rGPGCON = 0xFFEAFF5A; + rGPGUP = 0x0000F0DC; + rGPHCON = 0x0028AAAA; + rGPHUP = 0x00000656; + + /* setup correct IRQ modes for NIC */ + rEXTINT2 = (rEXTINT2 & ~(7<<8)) | (4<<8); /* rising edge mode */ + + /* init serial */ + gd->baudrate = CONFIG_BAUDRATE; + gd->have_console = 1; + serial_init(); + + /* arch number of VCMA9-Board */ + gd->bd->bi_arch_number = 227; + + /* adress of boot parameters */ + gd->bd->bi_boot_params = 0x30000100; + + icache_enable(); + dcache_enable(); + + 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; + + return 0; +} + +/* + * Get some Board/PLD Info + */ + +static uchar Get_PLD_ID(void) +{ + return(*(volatile uchar *)PLD_ID_REG); +} + +static uchar Get_PLD_BOARD(void) +{ + return(*(volatile uchar *)PLD_BOARD_REG); +} + +static uchar Get_PLD_Version(void) +{ + return((Get_PLD_ID() >> 4) & 0x0F); +} + +static uchar Get_PLD_Revision(void) +{ + return(Get_PLD_ID() & 0x0F); +} + +static int Get_Board_Config(void) +{ + uchar config = Get_PLD_BOARD() & 0x03; + + if (config == 3) + return 1; + else + return 0; +} + +static uchar Get_Board_PCB(void) +{ + return(((Get_PLD_BOARD() >> 4) & 0x03) + 'A'); +} + +/* ------------------------------------------------------------------------- */ + +/* + * Check Board Identity: + */ + +int checkboard(void) +{ + unsigned char s[50]; + unsigned char bc, var, rc; + int i; + backup_t *b = (backup_t *) s; + + puts("Board: "); + + i = getenv_r("serial#", s, 32); + if ((i < 0) || strncmp (s, "VCMA9", 5)) { + get_backup_values (b); + if (strncmp (b->signature, "MPL\0", 4) != 0) { + puts ("### No HW ID - assuming VCMA9"); + } else { + b->serial_name[5] = 0; + printf ("%s-%d Rev %c SN: %s", b->serial_name, Get_Board_Config(), + Get_Board_PCB(), &b->serial_name[6]); + } + } else { + s[5] = 0; + printf ("%s-%d Rev %c SN: %s", s, Get_Board_Config(), Get_Board_PCB(), + &s[6]); + } + printf("\n"); + return(0); +} + + + +void print_vcma9_rev(void) +{ + printf("Board: VCMA9-%d Rev: %c (PLD Ver: %d, Rev: %d)\n", + Get_Board_Config(), Get_Board_PCB(), + Get_PLD_Version(), Get_PLD_Revision()); +} + + +int last_stage_init(void) +{ + print_vcma9_rev(); + show_stdio_dev(); + check_env(); + return 0; +} + +/*************************************************************************** + * some helping routines + */ + +int overwrite_console(void) +{ + /* return TRUE if console should be overwritten */ + return 0; +} + + +/************************************************************************ +* Print VCMA9 Info +************************************************************************/ +void print_vcma9_info(void) +{ + print_vcma9_rev(); +} + + diff --git a/board/mpl/vcma9/vcma9.h b/board/mpl/vcma9/vcma9.h new file mode 100644 index 0000000..bc0e3a4 --- /dev/null +++ b/board/mpl/vcma9/vcma9.h @@ -0,0 +1,43 @@ +/* + * (C) Copyright 2002 + * David Mueller, ELSOFT AG, d.mueller@elsoft.ch + * + * 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 + * + */ + /**************************************************************************** + * Global routines used for VCMA9 + *****************************************************************************/ + + +extern int mem_test(unsigned long start, unsigned long ramsize,int mode); + +void print_vcma9_info(void); + + +#define PLD_BASE_ADDRESS 0x2C000100 +#define PLD_ID_REG (PLD_BASE_ADDRESS + 0) +#define PLD_NIC_REG (PLD_BASE_ADDRESS + 1) +#define PLD_CAN_REG (PLD_BASE_ADDRESS + 2) +#define PLD_MISC_REG (PLD_BASE_ADDRESS + 3) +#define PLD_GPCD_REG (PLD_BASE_ADDRESS + 4) +#define PLD_BOARD_REG (PLD_BASE_ADDRESS + 5) + + + |