diff options
author | wdenk <wdenk> | 2004-06-09 13:37:52 +0000 |
---|---|---|
committer | wdenk <wdenk> | 2004-06-09 13:37:52 +0000 |
commit | f39748ae8edb03017647b0d731cdd06e7bdcde13 (patch) | |
tree | 1401c99d4d11bef3828da3bda191e8923f3f1147 | |
parent | aa24509041ff8a4892071c2abec023dddd53874f (diff) | |
download | u-boot-imx-f39748ae8edb03017647b0d731cdd06e7bdcde13.zip u-boot-imx-f39748ae8edb03017647b0d731cdd06e7bdcde13.tar.gz u-boot-imx-f39748ae8edb03017647b0d731cdd06e7bdcde13.tar.bz2 |
* Patch by Paul Ruhland, 17 May 2004:
- Add support for the Logic Zoom LH7A40x based SDK board(s),
specifically the LPD7A400.
* Patches by Robert Schwebel, 15 May 2004:
- call MAC address reading code also for SMSC91C111;
- make SMSC91C111 timeout configurable, remove duplicate code
- fix get_timer() for PXA
- update doc/README.JFFS2
- use "bootfile" env variable also for jffs2
-rw-r--r-- | CHANGELOG | 11 | ||||
-rw-r--r-- | CREDITS | 4 | ||||
-rw-r--r-- | MAKEALL | 7 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | README | 20 | ||||
-rw-r--r-- | board/lpd7a40x/Makefile | 47 | ||||
-rw-r--r-- | board/lpd7a40x/config.mk | 38 | ||||
-rw-r--r-- | board/lpd7a40x/flash.c | 494 | ||||
-rw-r--r-- | board/lpd7a40x/lpd7a40x.c | 82 | ||||
-rw-r--r-- | board/lpd7a40x/memsetup.S | 212 | ||||
-rw-r--r-- | board/lpd7a40x/u-boot.lds | 56 | ||||
-rw-r--r-- | common/cmd_jffs2.c | 8 | ||||
-rw-r--r-- | cpu/lh7a40x/Makefile | 43 | ||||
-rw-r--r-- | cpu/lh7a40x/config.mk | 27 | ||||
-rw-r--r-- | cpu/lh7a40x/cpu.c | 183 | ||||
-rw-r--r-- | cpu/lh7a40x/interrupts.c | 326 | ||||
-rw-r--r-- | cpu/lh7a40x/serial.c | 183 | ||||
-rw-r--r-- | cpu/lh7a40x/speed.c | 83 | ||||
-rw-r--r-- | cpu/lh7a40x/start.S | 426 | ||||
-rw-r--r-- | cpu/pxa/interrupts.c | 2 | ||||
-rw-r--r-- | doc/README.JFFS2 | 4 | ||||
-rw-r--r-- | drivers/smc91111.c | 47 | ||||
-rw-r--r-- | include/bmp_logo.h | 2 | ||||
-rw-r--r-- | include/common.h | 5 | ||||
-rw-r--r-- | include/configs/innokom.h | 1 | ||||
-rw-r--r-- | include/configs/lpd7a400-10.h | 80 | ||||
-rw-r--r-- | include/configs/lpd7a400.h | 114 | ||||
-rw-r--r-- | include/lh7a400.h | 93 | ||||
-rw-r--r-- | include/lh7a40x.h | 258 | ||||
-rw-r--r-- | include/lpd7a400_cpld.h | 195 | ||||
-rw-r--r-- | lib_arm/board.c | 15 |
31 files changed, 3031 insertions, 37 deletions
@@ -2,6 +2,17 @@ Changes since U-Boot 1.1.1: ====================================================================== +* Patch by Paul Ruhland, 17 May 2004: + - Add support for the Logic Zoom LH7A40x based SDK board(s), + specifically the LPD7A400. + +* Patches by Robert Schwebel, 15 May 2004: + - call MAC address reading code also for SMSC91C111; + - make SMSC91C111 timeout configurable, remove duplicate code + - fix get_timer() for PXA + - update doc/README.JFFS2 + - use "bootfile" env variable also for jffs2 + * Patch by Tolunay Orkun, 14 May 2004: Add support for Cogent CSB472 board (8MB Flash Rev) @@ -358,3 +358,7 @@ W: www.elinos.com N: Xianghua Xiao E: x.xiao@motorola.com D: Support for Motorola 85xx(PowerQUICC III) chip, MPC8540ADS and MPC8560ADS boards. + +N: Paul Ruhland +E: pruhland@rochester.rr.com +D: Port to Logic Zoom LH7A40x SDK board(s) @@ -139,9 +139,10 @@ LIST_ARM7="B2 ep7312 impa7" LIST_ARM9=" \ at91rm9200dk integratorcp integratorap \ - omap1510inn omap1610h2 omap1610inn \ - omap730p2 smdk2400 smdk2410 \ - trab VCMA9 versatile \ + lpd7a400 omap1510inn omap1610h2 \ + omap1610inn omap730p2 smdk2400 \ + smdk2410 trab VCMA9 \ + versatile \ " ######################################################################### @@ -1096,6 +1096,8 @@ trab_old_config: unconfig VCMA9_config : unconfig @./mkconfig $(@:_config=) arm arm920t vcma9 mpl +lpd7a400_config: unconfig + @./mkconfig $(@:_config=) arm lh7a40x lpd7a40x ######################################################################### ## S3C44B0 Systems @@ -294,9 +294,9 @@ The following options need to be configured: CONFIG_AT91RM9200DK, CONFIG_DNP1110, CONFIG_EP7312, CONFIG_H2_OMAP1610, CONFIG_HHP_CRADLE, CONFIG_IMPA7, CONFIG_INNOVATOROMAP1510, CONFIG_INNOVATOROMAP1610, CONFIG_LART, - CONFIG_LUBBOCK, CONFIG_OSK_OMAP5912, CONFIG_SHANNON, - CONFIG_P2_OMAP730, CONFIG_SMDK2400, CONFIG_SMDK2410, - CONFIG_TRAB, CONFIG_VCMA9 + CONFIG_LPD7A400 CONFIG_LUBBOCK, CONFIG_OSK_OMAP5912, + CONFIG_SHANNON, CONFIG_P2_OMAP730, CONFIG_SMDK2400, + CONFIG_SMDK2410, CONFIG_TRAB, CONFIG_VCMA9 MicroBlaze based boards: ------------------------ @@ -741,6 +741,20 @@ The following options need to be configured: CONFIG_LAN91C96_USE_32_BIT Define this to enable 32 bit addressing + CONFIG_DRIVER_SMC91111 + Support for SMSC's LAN91C111 chip + + CONFIG_SMC91111_BASE + Define this to hold the physical address + of the device (I/O space) + + CONFIG_SMC_USE_32_BIT + Define this if data bus is 32 bits + + CONFIG_SMC_USE_IOFUNCS + Define this to use i/o functions instead of macros + (some hardware wont work with macros) + - USB Support: At the moment only the UHCI host controller is supported (PIP405, MIP405, MPC5200); define diff --git a/board/lpd7a40x/Makefile b/board/lpd7a40x/Makefile new file mode 100644 index 0000000..f0999d1 --- /dev/null +++ b/board/lpd7a40x/Makefile @@ -0,0 +1,47 @@ +# +# (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 := lpd7a40x.o flash.o +SOBJS := memsetup.o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) crv $@ $(OBJS) $(SOBJS) + +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/lpd7a40x/config.mk b/board/lpd7a40x/config.mk new file mode 100644 index 0000000..bc03874 --- /dev/null +++ b/board/lpd7a40x/config.mk @@ -0,0 +1,38 @@ +# +# 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 +# + +# Logic ZOOM LH7A400 SDK board w/Logic LH7A400-10 card engine +# w/Sharp LH7A400 SoC (ARM920T) cpu +# + +# +# 32 or 64 MB SDRAM on SDCSC0 @ 0xc0000000 +# +# Linux-Kernel is @ 0xC0008000, entry 0xc0008000 +# params @ 0xc0000100 +# optionally with a ramdisk at 0xc0300000 +# +# we load ourself to 0xc1fc0000 (32M - 256K) +# +# download area is 0xc0f00000 +# + +TEXT_BASE = 0xc1fc0000 +#TEXT_BASE = 0x00000000 diff --git a/board/lpd7a40x/flash.c b/board/lpd7a40x/flash.c new file mode 100644 index 0000000..26a9ce4 --- /dev/null +++ b/board/lpd7a40x/flash.c @@ -0,0 +1,494 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (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 + */ + +/* #define DEBUG */ + +#include <common.h> +#include <environment.h> + +#define FLASH_BANK_SIZE 0x1000000 /* 16MB (2 x 8 MB) */ +#define MAIN_SECT_SIZE 0x40000 /* 256KB (2 x 128kB) */ + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; + + +#define CMD_READ_ARRAY 0x00FF00FF +#define CMD_IDENTIFY 0x00900090 +#define CMD_ERASE_SETUP 0x00200020 +#define CMD_ERASE_CONFIRM 0x00D000D0 +#define CMD_PROGRAM 0x00400040 +#define CMD_RESUME 0x00D000D0 +#define CMD_SUSPEND 0x00B000B0 +#define CMD_STATUS_READ 0x00700070 +#define CMD_STATUS_RESET 0x00500050 + +#define BIT_BUSY 0x00800080 +#define BIT_ERASE_SUSPEND 0x00400040 +#define BIT_ERASE_ERROR 0x00200020 +#define BIT_PROGRAM_ERROR 0x00100010 +#define BIT_VPP_RANGE_ERROR 0x00080008 +#define BIT_PROGRAM_SUSPEND 0x00040004 +#define BIT_PROTECT_ERROR 0x00020002 +#define BIT_UNDEFINED 0x00010001 + +#define BIT_SEQUENCE_ERROR 0x00300030 +#define BIT_TIMEOUT 0x80000000 + +/*----------------------------------------------------------------------- + */ + +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 = + (INTEL_MANUFACT & FLASH_VENDMASK) | + (INTEL_ID_28F640J3A & FLASH_TYPEMASK); + 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 = CFG_FLASH_BASE; + else + panic ("configured too many flash banks!\n"); + for (j = 0; j < flash_info[i].sector_count; j++) { + flash_info[i].start[j] = flashbase; + + /* uniform sector size */ + flashbase += MAIN_SECT_SIZE; + } + size += flash_info[i].size; + } + + /* + * Protect monitor and environment sectors + */ + flash_protect ( FLAG_PROTECT_SET, + CFG_FLASH_BASE, + CFG_FLASH_BASE + monitor_flash_len - 1, + &flash_info[0]); + + flash_protect ( FLAG_PROTECT_SET, + CFG_ENV_ADDR, + CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]); + +#ifdef CFG_ENV_ADDR_REDUND + flash_protect ( FLAG_PROTECT_SET, + CFG_ENV_ADDR_REDUND, + CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1, + &flash_info[0]); +#endif + + return size; +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t * info) +{ + int i; + + switch (info->flash_id & FLASH_VENDMASK) { + case (INTEL_MANUFACT & FLASH_VENDMASK): + printf ("Intel: "); + break; + default: + printf ("Unknown Vendor "); + break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case (INTEL_ID_28F640J3A & FLASH_TYPEMASK): + printf ("2x 28F640J3A (64Mbit)\n"); + break; + default: + printf ("Unknown Chip Type\n"); + return; + 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"); +} + +/*----------------------------------------------------------------------- + */ + +int flash_error (ulong code) +{ + /* Check bit patterns */ + /* SR.7=0 is busy, SR.7=1 is ready */ + /* all other flags indicate error on 1 */ + /* SR.0 is undefined */ + /* Timeout is our faked flag */ + + /* sequence is described in Intel 290644-005 document */ + + /* check Timeout */ + if (code & BIT_TIMEOUT) { + puts ("Timeout\n"); + return ERR_TIMOUT; + } + + /* check Busy, SR.7 */ + if (~code & BIT_BUSY) { + puts ("Busy\n"); + return ERR_PROG_ERROR; + } + + /* check Vpp low, SR.3 */ + if (code & BIT_VPP_RANGE_ERROR) { + puts ("Vpp range error\n"); + return ERR_PROG_ERROR; + } + + /* check Device Protect Error, SR.1 */ + if (code & BIT_PROTECT_ERROR) { + puts ("Device protect error\n"); + return ERR_PROG_ERROR; + } + + /* check Command Seq Error, SR.4 & SR.5 */ + if (code & BIT_SEQUENCE_ERROR) { + puts ("Command seqence error\n"); + return ERR_PROG_ERROR; + } + + /* check Block Erase Error, SR.5 */ + if (code & BIT_ERASE_ERROR) { + puts ("Block erase error\n"); + return ERR_PROG_ERROR; + } + + /* check Program Error, SR.4 */ + if (code & BIT_PROGRAM_ERROR) { + puts ("Program error\n"); + return ERR_PROG_ERROR; + } + + /* check Block Erase Suspended, SR.6 */ + if (code & BIT_ERASE_SUSPEND) { + puts ("Block erase suspended\n"); + return ERR_PROG_ERROR; + } + + /* check Program Suspended, SR.2 */ + if (code & BIT_PROGRAM_SUSPEND) { + puts ("Program suspended\n"); + return ERR_PROG_ERROR; + } + + /* OK, no error */ + return ERR_OK; +} + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t * info, int s_first, int s_last) +{ + ulong result, result1; + int iflag, prot, sect; + int rc = ERR_OK; + +#ifdef USE_920T_MMU + int cflag; +#endif + + debug ("flash_erase: s_first %d s_last %d\n", s_first, s_last); + + /* 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) != + (INTEL_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) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } + + /* + * 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. + */ +#ifdef USE_920T_MMU + cflag = dcache_status (); + dcache_disable (); +#endif + iflag = disable_interrupts (); + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect <= s_last && !ctrlc (); sect++) { + + debug ("Erasing sector %2d @ %08lX... ", + sect, info->start[sect]); + + /* arm simple, non interrupt dependent timer */ + reset_timer(); + + if (info->protect[sect] == 0) { /* not protected */ + vu_long *addr = (vu_long *) (info->start[sect]); + ulong bsR7, bsR7_2, bsR5, bsR5_2; + ulong tstart; + + /* *addr = CMD_STATUS_RESET; */ + *addr = CMD_ERASE_SETUP; + *addr = CMD_ERASE_CONFIRM; + + /* wait until flash is ready */ + tstart = get_timer(0); + do { + ulong now; + /* check timeout */ + //if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) { + if ((now = get_timer(tstart)) > CFG_FLASH_ERASE_TOUT) { + printf("tstart = 0x%08lx, now = 0x%08lx\n", tstart, now); + *addr = CMD_STATUS_RESET; + result = BIT_TIMEOUT; + break; + } + + *addr = CMD_STATUS_READ; + result = *addr; + bsR7 = result & (1 << 7); + bsR7_2 = result & (1 << 23); + } while (!bsR7 | !bsR7_2); + + *addr = CMD_STATUS_READ; + result1 = *addr; + bsR5 = result1 & (1 << 5); + bsR5_2 = result1 & (1 << 21); +#ifdef SAMSUNG_FLASH_DEBUG + printf ("bsR5 %lx bsR5_2 %lx\n", bsR5, bsR5_2); + if (bsR5 != 0 && bsR5_2 != 0) + printf ("bsR5 %lx bsR5_2 %lx\n", bsR5, bsR5_2); +#endif + + *addr = CMD_READ_ARRAY; + *addr = CMD_RESUME; + + if ((rc = flash_error (result)) != ERR_OK) + goto outahere; +#if 0 + printf ("ok.\n"); + } else { /* it was protected */ + + printf ("protected!\n"); +#endif + } + } + +outahere: + /* allow flash to settle - wait 10 ms */ + udelay_masked (10000); + + if (iflag) + enable_interrupts (); + +#ifdef USE_920T_MMU + if (cflag) + dcache_enable (); +#endif + return rc; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash + */ + +volatile static int write_word (flash_info_t * info, ulong dest, + ulong data) +{ + vu_long *addr = (vu_long *) dest; + ulong result; + int rc = ERR_OK; + int iflag; + +#ifdef USE_920T_MMU + int cflag; +#endif + + /* + * 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. + */ +#ifdef USE_920T_MMU + cflag = dcache_status (); + dcache_disable (); +#endif + iflag = disable_interrupts (); + + /* *addr = CMD_STATUS_RESET; */ + *addr = CMD_PROGRAM; + *addr = data; + + /* arm simple, non interrupt dependent timer */ + reset_timer_masked (); + + /* wait until flash is ready */ + do { + /* check timeout */ + if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) { + *addr = CMD_SUSPEND; + result = BIT_TIMEOUT; + break; + } + + *addr = CMD_STATUS_READ; + result = *addr; + } while (~result & BIT_BUSY); + + /* *addr = CMD_READ_ARRAY; */ + *addr = CMD_STATUS_READ; + result = *addr; + + rc = flash_error (result); + + if (iflag) + enable_interrupts (); + +#ifdef USE_920T_MMU + if (cflag) + dcache_enable (); +#endif + *addr = CMD_READ_ARRAY; + *addr = CMD_RESUME; + return rc; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash. + */ + +int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) +{ + ulong cp, wp, data; + int l; + int i, rc; + + wp = (addr & ~3); /* get lower word aligned address */ + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i = 0, cp = wp; i < l; ++i, ++cp) { + data = (data >> 8) | (*(uchar *) cp << 24); + } + for (; i < 4 && cnt > 0; ++i) { + data = (data >> 8) | (*src++ << 24); + --cnt; + ++cp; + } + for (; cnt == 0 && i < 4; ++i, ++cp) { + data = (data >> 8) | (*(uchar *) cp << 24); + } + + if ((rc = write_word (info, wp, data)) != 0) { + return (rc); + } + wp += 4; + } + + /* + * handle word aligned part + */ + while (cnt >= 4) { + data = *((vu_long *) src); + if ((rc = write_word (info, wp, data)) != 0) { + return (rc); + } + src += 4; + wp += 4; + cnt -= 4; + } + + if (cnt == 0) { + return ERR_OK; + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) { + data = (data >> 8) | (*src++ << 24); + --cnt; + } + for (; i < 4; ++i, ++cp) { + data = (data >> 8) | (*(uchar *) cp << 24); + } + + return write_word (info, wp, data); +} diff --git a/board/lpd7a40x/lpd7a40x.c b/board/lpd7a40x/lpd7a40x.c new file mode 100644 index 0000000..8492df3 --- /dev/null +++ b/board/lpd7a40x/lpd7a40x.c @@ -0,0 +1,82 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (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 + */ + +#include <common.h> +#if defined(CONFIG_LH7A400) +#include <lh7a400.h> +#include <lpd7a400_cpld.h> +#elif defined(CONFIG_LH7A404) +#include <lh7a404.h> +#include <lpd7a404_cpld.h> +#else +#error "No CPU defined!" +#endif + +/* + * Miscellaneous platform dependent initialisations + */ + +int board_init (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + /* set up the I/O ports */ + +#if defined(CONFIG_LH7A400) + + /* enable flash programming */ + *(LPD7A400_CPLD_REGPTR(LPD7A400_CPLD_FLASH_REG)) |= FLASH_FPEN; + + /* Auto wakeup, LCD disable, WLAN enable */ + *(LPD7A400_CPLD_REGPTR(LPD7A400_CPLD_CECTL_REG)) &= + ~(CECTL_AWKP|CECTL_LCDV|CECTL_WLPE); + + /* Status LED 2 on (leds are active low) */ + *(LPD7A400_CPLD_REGPTR(LPD7A400_CPLD_EXTGPIO_REG)) = + (EXTGPIO_STATUS1|EXTGPIO_GPIO1) & ~(EXTGPIO_STATUS2); + + /* arch number of Logic-Board - MACH_TYPE_LPD7A400 */ + gd->bd->bi_arch_number = MACH_TYPE_LPD7A400; + +#elif defined(CONFIG_LH7A404) +#endif + + /* adress of boot parameters */ + gd->bd->bi_boot_params = 0xc0000100; + + 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; +} diff --git a/board/lpd7a40x/memsetup.S b/board/lpd7a40x/memsetup.S new file mode 100644 index 0000000..09ab5e7 --- /dev/null +++ b/board/lpd7a40x/memsetup.S @@ -0,0 +1,212 @@ +/* + * Memory Setup - initialize memory controller(s) for devices required + * to boot and relocate + * + * 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> + + +/* memory controller */ +#define BCRX_DEFAULT (0x0000fbe0) +#define BCRX_MW_8 (0x00000000) +#define BCRX_MW_16 (0x10000000) +#define BCRX_MW_32 (0x20000000) +#define BCRX_PME (0x08000000) +#define BCRX_WP (0x04000000) +#define BCRX_WST2_SHIFT (11) +#define BCRX_WST1_SHIFT (5) +#define BCRX_IDCY_SHIFT (0) + +/* Bank0 Async Flash */ +#define BCR0 (0x80002000) +#define BCR0_FLASH (BCRX_MW_32 | (0x08<<BCRX_WST2_SHIFT) | (0x0E<<BCRX_WST1_SHIFT)) + +/* Bank1 Open */ +#define BCR1 (0x80002004) + +/* Bank2 Not used (EEPROM?) */ +#define BCR2 (0x80002008) + +/* Bank3 Not used */ +#define BCR3 (0x8000200C) + +/* Bank4 PC Card1 */ + +/* Bank5 PC Card2 */ + +/* Bank6 CPLD IO Controller Peripherals (slow) */ +#define BCR6 (0x80002018) +#define BCR6_CPLD_SLOW (BCRX_DEFAULT | BCRX_MW_16) + +/* Bank7 CPLD IO Controller Peripherals (fast) */ +#define BCR7 (0x8000201C) +#define BCR7_CPLD_FAST (BCRX_MW_16 | (0x16<<BCRX_WST2_SHIFT) | (0x16<<BCRX_WST1_SHIFT) | (0x2<<BCRX_IDCY_SHIFT)) + +/* SDRAM */ +#define GBLCNFG (0x80002404) +#define GC_CKE (0x80000000) +#define GC_CKSD (0x40000000) +#define GC_LCR (0x00000040) +#define GC_SMEMBURST (0x00000020) +#define GC_MRS (0x00000002) +#define GC_INIT (0x00000001) + +#define GC_CMD_NORMAL (GC_CKE) +#define GC_CMD_MODE (GC_CKE | GC_MRS) +#define GC_CMD_SYNCFLASH_LOAD (GC_CKE | GC_MRS | GC_LCR) +#define GC_CMD_PRECHARGEALL (GC_CKE | GC_INIT) +#define GC_CMD_NOP (GC_CKE | GC_INIT | GC_MRS) + +#define RFSHTMR (0x80002408) +#define RFSHTMR_INIT (10) /* period=100 ns, HCLK=100Mhz, (2048+1-15.6*66) */ +#define RFSHTMR_NORMAL (1500) /* period=15.6 us, HCLK=100Mhz, (2048+1-15.6*66) */ + +#define SDCSCX_BASE (0x80002410) +#define SDCSCX_DEFAULT (0x01220008) +#define SDCSCX_AUTOPC (0x01000000) +#define SDCSCX_RAS2CAS_2 (0x00200000) +#define SDCSCX_RAS2CAS_3 (0x00300000) +#define SDCSCX_WBL (0x00080000) +#define SDCSCX_CASLAT_8 (0x00070000) +#define SDCSCX_CASLAT_7 (0x00060000) +#define SDCSCX_CASLAT_6 (0x00050000) +#define SDCSCX_CASLAT_5 (0x00040000) +#define SDCSCX_CASLAT_4 (0x00030000) +#define SDCSCX_CASLAT_3 (0x00020000) +#define SDCSCX_CASLAT_2 (0x00010000) +#define SDCSCX_2KPAGE (0x00000040) +#define SDCSCX_SROMLL (0x00000020) +#define SDCSCX_SROM512 (0x00000010) +#define SDCSCX_4BNK (0x00000008) +#define SDCSCX_2BNK (0x00000000) +#define SDCSCX_EBW_16 (0x00000004) +#define SDCSCX_EBW_32 (0x00000000) + +#define SDRAM_BASE (0xC0000000) +#define SDCSC_BANK_OFFSET (0x10000000) + +/* + * The SDRAM DEVICE MODE PROGRAMMING VALUE + */ +#define BURST_LENGTH_4 (0x010 << 10) +#define BURST_LENGTH_8 (0x011 << 10) +#define WBURST_LENGTH_BL (0x01 << 19) +#define WBURST_LENGTH_SINGLE (0x01 << 19) +#define CAS_2 (0x010 << 14) +#define CAS_3 (0x011 << 14) +#define BAT_SEQUENTIAL (0 << 13) +#define BAT_INTERLEAVED (1 << 13) +#define OPM_NORMAL (0x00 << 17) +#define SDRAM_DEVICE_MODE (WBURST_LENGTH_BL|OPM_NORMAL|CAS_3|BAT_SEQUENTIAL|BURST_LENGTH_4) + + +#define TIMER1_BASE (0x80000C00) + +/* + * special lookup flags + */ +#define DO_MEM_DELAY 1 +#define DO_MEM_READ 2 + +_TEXT_BASE: + .word TEXT_BASE + +.globl memsetup +memsetup: + mov r9, lr @ save return address + + /* memory control configuration */ + /* make r0 relative the current location so that it */ + /* reads INITMEM_DATA out of FLASH rather than memory ! */ + /* r0 = current word pointer */ + /* r1 = end word location, one word past last actual word */ + /* r3 = address for writes, special lookup flags */ + /* r4 = value for writes, delay constants, or read addresses */ + /* r2 = location for mem reads */ + + ldr r0, =INITMEM_DATA + ldr r1, _TEXT_BASE + sub r0, r0, r1 + add r1, r0, #112 + +mem_loop: + cmp r1, r0 + moveq pc, r9 @ Done + + ldr r3, [r0], #4 @ Fetch Destination Register Address, or 1 for delay + ldr r4, [r0], #4 @ value + + cmp r3, #DO_MEM_DELAY + bleq mem_delay + beq mem_loop + cmp r3, #DO_MEM_READ + ldreq r2, [r4] + beq mem_loop + str r4, [r3] @ normal register/ram store + b mem_loop + +mem_delay: + ldr r5, =TIMER1_BASE + mov r6, r4, LSR #1 @ timer resolution is ~2us + str r6, [r5] + mov r6, #0x88 @ using 508.469KHz clock, enable + str r6, [r5, #8] +0: ldr r6, [r5, #4] @ timer value + cmp r6, #0 + bne 0b + mov r6, #0 @ disable timer + str r6, [r5, #8] + mov pc, lr + + .ltorg +/* the literal pools origin */ + +INITMEM_DATA: + .word BCR0 + .word BCR0_FLASH + .word BCR6 + .word BCR6_CPLD_SLOW + .word BCR7 + .word BCR7_CPLD_FAST + .word SDCSCX_BASE + .word (SDCSCX_RAS2CAS_3 | SDCSCX_CASLAT_3 | SDCSCX_SROMLL | SDCSCX_4BNK | SDCSCX_EBW_32) + .word GBLCNFG + .word GC_CMD_NOP + .word DO_MEM_DELAY + .word 200 + .word GBLCNFG + .word GC_CMD_PRECHARGEALL + .word RFSHTMR + .word RFSHTMR_INIT + .word DO_MEM_DELAY + .word 8 + .word RFSHTMR + .word RFSHTMR_NORMAL + .word GBLCNFG + .word GC_CMD_MODE + .word DO_MEM_READ + .word (SDRAM_BASE | SDRAM_DEVICE_MODE) + .word GBLCNFG + .word GC_CMD_NORMAL + .word SDCSCX_BASE + .word (SDCSCX_AUTOPC | SDCSCX_RAS2CAS_3 | SDCSCX_CASLAT_3 | SDCSCX_SROMLL | SDCSCX_4BNK | SDCSCX_EBW_32) diff --git a/board/lpd7a40x/u-boot.lds b/board/lpd7a40x/u-boot.lds new file mode 100644 index 0000000..719d8b1 --- /dev/null +++ b/board/lpd7a40x/u-boot.lds @@ -0,0 +1,56 @@ +/* + * (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/lh7a40x/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 = .; +} diff --git a/common/cmd_jffs2.c b/common/cmd_jffs2.c index 085781f..207c211 100644 --- a/common/cmd_jffs2.c +++ b/common/cmd_jffs2.c @@ -126,7 +126,13 @@ do_jffs2_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) int jffs2_1pass_load(char *, struct part_info *,const char *); char *fsname; - char *filename = "uImage"; + char *filename; + + /* pre-set Boot file name */ + if ((filename = getenv("bootfile")) == NULL) { + filename = "uImage"; + } + ulong offset = load_addr; int size; struct part_info *part; diff --git a/cpu/lh7a40x/Makefile b/cpu/lh7a40x/Makefile new file mode 100644 index 0000000..b45bd6a --- /dev/null +++ b/cpu/lh7a40x/Makefile @@ -0,0 +1,43 @@ +# +# (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$(CPU).a + +START = start.o +OBJS = cpu.o speed.o interrupts.o serial.o + +all: .depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) crv $@ $(OBJS) + +######################################################################### + +.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/cpu/lh7a40x/config.mk b/cpu/lh7a40x/config.mk new file mode 100644 index 0000000..cef7d26 --- /dev/null +++ b/cpu/lh7a40x/config.mk @@ -0,0 +1,27 @@ +# +# (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 +# + +PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \ + -mshort-load-bytes -msoft-float + +PLATFORM_CPPFLAGS += -mapcs-32 -march=armv4 diff --git a/cpu/lh7a40x/cpu.c b/cpu/lh7a40x/cpu.c new file mode 100644 index 0000000..2a2b578 --- /dev/null +++ b/cpu/lh7a40x/cpu.c @@ -0,0 +1,183 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (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 + */ + +/* + * CPU specific code + */ + +#include <common.h> +#include <command.h> +#include <arm920t.h> + +/* read co-processor 15, register #1 (control register) */ +static unsigned long read_p15_c1 (void) +{ + unsigned long value; + + __asm__ __volatile__( + "mrc p15, 0, %0, c1, c0, 0 @ read control reg\n" + : "=r" (value) + : + : "memory"); + +#ifdef MMU_DEBUG + printf ("p15/c1 is = %08lx\n", value); +#endif + return value; +} + +/* write to co-processor 15, register #1 (control register) */ +static void write_p15_c1 (unsigned long value) +{ +#ifdef MMU_DEBUG + printf ("write %08lx to p15/c1\n", value); +#endif + __asm__ __volatile__( + "mcr p15, 0, %0, c1, c0, 0 @ write it back\n" + : + : "r" (value) + : "memory"); + + read_p15_c1 (); +} + +static void cp_delay (void) +{ + volatile int i; + + /* copro seems to need some delay between reading and writing */ + for (i = 0; i < 100; i++); +} + +/* See also ARM Ref. Man. */ +#define C1_MMU (1<<0) /* mmu off/on */ +#define C1_ALIGN (1<<1) /* alignment faults off/on */ +#define C1_DC (1<<2) /* dcache off/on */ +#define C1_BIG_ENDIAN (1<<7) /* big endian off/on */ +#define C1_SYS_PROT (1<<8) /* system protection */ +#define C1_ROM_PROT (1<<9) /* ROM protection */ +#define C1_IC (1<<12) /* icache off/on */ +#define C1_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */ +#define RESERVED_1 (0xf << 3) /* must be 111b for R/W */ + +int cpu_init (void) +{ + /* + * setup up stacks if necessary + */ +#ifdef CONFIG_USE_IRQ + DECLARE_GLOBAL_DATA_PTR; + + IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4; + FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ; +#endif + return 0; +} + +int cleanup_before_linux (void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + */ + + unsigned long i; + + disable_interrupts (); + + /* turn off I/D-cache */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + i &= ~(C1_DC | C1_IC); + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + + /* flush I/D-cache */ + i = 0; + asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); + return (0); +} + +int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + extern void reset_cpu (ulong addr); + + disable_interrupts (); + reset_cpu (0); + /*NOTREACHED*/ + return (0); +} + +void icache_enable (void) +{ + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + write_p15_c1 (reg | C1_IC); +} + +void icache_disable (void) +{ + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + write_p15_c1 (reg & ~C1_IC); +} + +int icache_status (void) +{ + return (read_p15_c1 () & C1_IC) != 0; +} + +#ifdef USE_920T_MMU +/* It makes no sense to use the dcache if the MMU is not enabled */ +void dcache_enable (void) +{ + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + write_p15_c1 (reg | C1_DC); +} + +void dcache_disable (void) +{ + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + reg &= ~C1_DC; + write_p15_c1 (reg); +} + +int dcache_status (void) +{ + return (read_p15_c1 () & C1_DC) != 0; +} +#endif diff --git a/cpu/lh7a40x/interrupts.c b/cpu/lh7a40x/interrupts.c new file mode 100644 index 0000000..2ebbe56 --- /dev/null +++ b/cpu/lh7a40x/interrupts.c @@ -0,0 +1,326 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.de> + * + * (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 + */ + +#include <common.h> +#include <arm920t.h> +#include <lh7a40x.h> + +#include <asm/proc-armv/ptrace.h> + +extern void reset_cpu(ulong addr); +static ulong timer_load_val = 0; + +/* macro to read the 16 bit timer */ +static inline ulong READ_TIMER(void) +{ + LH7A40X_TIMERS_PTR(timers); + lh7a40x_timer_t* timer = &timers->timer1; + + return (timer->value & 0x0000ffff); +} + +#ifdef CONFIG_USE_IRQ +/* enable IRQ interrupts */ +void enable_interrupts (void) +{ + unsigned long temp; + __asm__ __volatile__("mrs %0, cpsr\n" + "bic %0, %0, #0x80\n" + "msr cpsr_c, %0" + : "=r" (temp) + : + : "memory"); +} + + +/* + * disable IRQ/FIQ interrupts + * returns true if interrupts had been enabled before we disabled them + */ +int disable_interrupts (void) +{ + unsigned long old,temp; + __asm__ __volatile__("mrs %0, cpsr\n" + "orr %1, %0, #0xc0\n" + "msr cpsr_c, %1" + : "=r" (old), "=r" (temp) + : + : "memory"); + return (old & 0x80) == 0; +} +#else +void enable_interrupts (void) +{ + return; +} +int disable_interrupts (void) +{ + return 0; +} +#endif + + +void bad_mode (void) +{ + panic ("Resetting CPU ...\n"); + reset_cpu (0); +} + +void show_regs (struct pt_regs *regs) +{ + unsigned long flags; + const char *processor_modes[] = { + "USER_26", "FIQ_26", "IRQ_26", "SVC_26", + "UK4_26", "UK5_26", "UK6_26", "UK7_26", + "UK8_26", "UK9_26", "UK10_26", "UK11_26", + "UK12_26", "UK13_26", "UK14_26", "UK15_26", + "USER_32", "FIQ_32", "IRQ_32", "SVC_32", + "UK4_32", "UK5_32", "UK6_32", "ABT_32", + "UK8_32", "UK9_32", "UK10_32", "UND_32", + "UK12_32", "UK13_32", "UK14_32", "SYS_32", + }; + + flags = condition_codes (regs); + + printf ("pc : [<%08lx>] lr : [<%08lx>]\n" + "sp : %08lx ip : %08lx fp : %08lx\n", + instruction_pointer (regs), + regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp); + printf ("r10: %08lx r9 : %08lx r8 : %08lx\n", + regs->ARM_r10, regs->ARM_r9, regs->ARM_r8); + printf ("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n", + regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4); + printf ("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n", + regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0); + printf ("Flags: %c%c%c%c", + flags & CC_N_BIT ? 'N' : 'n', + flags & CC_Z_BIT ? 'Z' : 'z', + flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v'); + printf (" IRQs %s FIQs %s Mode %s%s\n", + interrupts_enabled (regs) ? "on" : "off", + fast_interrupts_enabled (regs) ? "on" : "off", + processor_modes[processor_mode (regs)], + thumb_mode (regs) ? " (T)" : ""); +} + +void do_undefined_instruction (struct pt_regs *pt_regs) +{ + printf ("undefined instruction\n"); + show_regs (pt_regs); + bad_mode (); +} + +void do_software_interrupt (struct pt_regs *pt_regs) +{ + printf ("software interrupt\n"); + show_regs (pt_regs); + bad_mode (); +} + +void do_prefetch_abort (struct pt_regs *pt_regs) +{ + printf ("prefetch abort\n"); + show_regs (pt_regs); + bad_mode (); +} + +void do_data_abort (struct pt_regs *pt_regs) +{ + printf ("data abort\n"); + show_regs (pt_regs); + bad_mode (); +} + +void do_not_used (struct pt_regs *pt_regs) +{ + printf ("not used\n"); + show_regs (pt_regs); + bad_mode (); +} + +void do_fiq (struct pt_regs *pt_regs) +{ + printf ("fast interrupt request\n"); + show_regs (pt_regs); + bad_mode (); +} + +void do_irq (struct pt_regs *pt_regs) +{ + printf ("interrupt request\n"); + show_regs (pt_regs); + bad_mode (); +} + +static ulong timestamp; +static ulong lastdec; + +int interrupt_init (void) +{ + LH7A40X_TIMERS_PTR(timers); + lh7a40x_timer_t* timer = &timers->timer1; + + /* a periodic timer using the 508kHz source */ + timer->control = (TIMER_PER | TIMER_CLK508K); + + if (timer_load_val == 0) { + /* + * 10ms period with 508.469kHz clock = 5084 + */ + timer_load_val = CFG_HZ/100; + } + + /* load value for 10 ms timeout */ + lastdec = timer->load = timer_load_val; + + /* auto load, start timer */ + timer->control = timer->control | TIMER_EN; + timestamp = 0; + + return (0); +} + +/* + * timer without interrupts + */ + +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return (get_timer_masked() - base); +} + +void set_timer (ulong t) +{ + timestamp = t; +} + +void udelay (unsigned long usec) +{ + ulong tmo,tmp; + + /* normalize */ + if (usec >= 1000) { + tmo = usec / 1000; + tmo *= CFG_HZ; + tmo /= 1000; + } + else { + if (usec > 1) { + tmo = usec * CFG_HZ; + tmo /= (1000*1000); + } + else + tmo = 1; + } + + /* check for rollover during this delay */ + tmp = get_timer (0); + if ((tmp + tmo) < tmp ) + reset_timer_masked(); /* timer would roll over */ + else + tmo += tmp; + + while (get_timer_masked () < tmo); +} + +void reset_timer_masked (void) +{ + /* reset time */ + lastdec = READ_TIMER(); + timestamp = 0; +} + +ulong get_timer_masked (void) +{ + ulong now = READ_TIMER(); + + if (lastdec >= now) { + /* normal mode */ + timestamp += (lastdec - now); + } else { + /* we have an overflow ... */ + timestamp += ((lastdec + timer_load_val) - now); + } + lastdec = now; + + return timestamp; +} + +void udelay_masked (unsigned long usec) +{ + ulong tmo; + + /* normalize */ + if (usec >= 1000) { + tmo = usec / 1000; + tmo *= CFG_HZ; + tmo /= 1000; + } + else { + if (usec > 1) { + tmo = usec * CFG_HZ; + tmo /= (1000*1000); + } + else + tmo = 1; + } + + reset_timer_masked (); + + while (get_timer_masked () < tmo); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + ulong tbclk; + + tbclk = timer_load_val * 100; + + return tbclk; +} diff --git a/cpu/lh7a40x/serial.c b/cpu/lh7a40x/serial.c new file mode 100644 index 0000000..241d568 --- /dev/null +++ b/cpu/lh7a40x/serial.c @@ -0,0 +1,183 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> + * + * 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 <lh7a40x.h> + +#if defined(CONFIG_CONSOLE_UART1) +# define UART_CONSOLE 1 +#elif defined(CONFIG_CONSOLE_UART2) +# define UART_CONSOLE 2 +#elif defined(CONFIG_CONSOLE_UART3) +# define UART_CONSOLE 3 +#else +# error "No console configured ... " +#endif + +void serial_setbrg (void) +{ + DECLARE_GLOBAL_DATA_PTR; + LH7A40X_UART_PTR(uart,UART_CONSOLE); + int i; + unsigned int reg = 0; + + /* + * userguide 15.1.2.4 + * + * BAUDDIV is (UART_REF_FREQ/(16 X BAUD))-1 + * + * UART_REF_FREQ = external system clock input / 2 (Hz) + * BAUD is desired baudrate (bits/s) + * + * NOTE: we add (divisor/2) to numerator to round for + * more precision + */ + reg = (((get_PLLCLK()/2) + ((16*gd->baudrate)/2)) / (16 * gd->baudrate)) - 1; + uart->brcon = reg; + + for (i = 0; i < 100; i++); +} + +/* + * Initialise the serial port with the given baudrate. The settings + * are always 8 data bits, no parity, 1 stop bit, no start bits. + * + */ +int serial_init (void) +{ + LH7A40X_UART_PTR(uart,UART_CONSOLE); + + /* UART must be enabled before writing to any config registers */ + uart->con |= (UART_EN); + +#ifdef CONFIG_CONSOLE_UART1 + /* infrared disabled */ + uart->con |= UART_SIRD; +#endif + /* loopback disabled */ + uart->con &= ~(UART_LBE); + + /* modem lines and tx/rx polarities */ + uart->con &= ~(UART_MXP | UART_TXP | UART_RXP); + + /* FIFO enable, N81 */ + uart->fcon = (UART_WLEN_8 | UART_FEN | UART_STP2_1); + + /* set baudrate */ + serial_setbrg (); + + /* enable rx interrupt */ + uart->inten |= UART_RI; + + return (0); +} + +/* + * Read a single byte from the serial port. Returns 1 on success, 0 + * otherwise. When the function is succesfull, the character read is + * written into its argument c. + */ +int serial_getc (void) +{ + LH7A40X_UART_PTR(uart,UART_CONSOLE); + + /* wait for character to arrive */ + while (uart->status & UART_RXFE); + + return(uart->data & 0xff); +} + +#ifdef CONFIG_HWFLOW +static int hwflow = 0; /* turned off by default */ +int hwflow_onoff(int on) +{ + switch(on) { + case 0: + default: + break; /* return current */ + case 1: + hwflow = 1; /* turn on */ + break; + case -1: + hwflow = 0; /* turn off */ + break; + } + return hwflow; +} +#endif + +#ifdef CONFIG_MODEM_SUPPORT +static int be_quiet = 0; +void disable_putc(void) +{ + be_quiet = 1; +} + +void enable_putc(void) +{ + be_quiet = 0; +} +#endif + + +/* + * Output a single byte to the serial port. + */ +void serial_putc (const char c) +{ + LH7A40X_UART_PTR(uart,UART_CONSOLE); + +#ifdef CONFIG_MODEM_SUPPORT + if (be_quiet) + return; +#endif + + /* wait for room in the tx FIFO */ + while (!(uart->status & UART_TXFE)); + +#ifdef CONFIG_HWFLOW + /* Wait for CTS up */ + while(hwflow && !(uart->status & UART_CTS)); +#endif + + uart->data = c; + + /* If \n, also do \r */ + if (c == '\n') + serial_putc ('\r'); +} + +/* + * Test whether a character is in the RX buffer + */ +int serial_tstc (void) +{ + LH7A40X_UART_PTR(uart,UART_CONSOLE); + + return(!(uart->status & UART_RXFE)); +} + +void +serial_puts (const char *s) +{ + while (*s) { + serial_putc (*s++); + } +} diff --git a/cpu/lh7a40x/speed.c b/cpu/lh7a40x/speed.c new file mode 100644 index 0000000..e80b046 --- /dev/null +++ b/cpu/lh7a40x/speed.c @@ -0,0 +1,83 @@ +/* + * (C) Copyright 2001-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.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 <lh7a40x.h> + + +/* ------------------------------------------------------------------------- */ +/* NOTE: This describes the proper use of this file. + * + * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL. + * + * get_FCLK(), get_HCLK(), get_PCLK() return the clock of + * the specified bus in HZ. + */ +/* ------------------------------------------------------------------------- */ + +ulong get_PLLCLK (void) +{ + return CONFIG_SYS_CLK_FREQ; +} + +/* return FCLK frequency */ +ulong get_FCLK (void) +{ + LH7A40X_CSC_PTR (csc); + ulong maindiv1, maindiv2, prediv, ps; + + /* + * from userguide 6.1.1.2 + * + * FCLK = ((MAINDIV1 +2) * (MAINDIV2 +2) * 14.7456MHz) / + * ((PREDIV+2) * (2^PS)) + */ + maindiv2 = (csc->clkset & CLKSET_MAINDIV2) >> 11; + maindiv1 = (csc->clkset & CLKSET_MAINDIV1) >> 7; + prediv = (csc->clkset & CLKSET_PREDIV) >> 2; + ps = (csc->clkset & CLKSET_PS) >> 16; + + return (((maindiv2 + 2) * (maindiv1 + 2) * CONFIG_SYS_CLK_FREQ) / + ((prediv + 2) * (1 << ps))); +} + + +/* return HCLK frequency */ +ulong get_HCLK (void) +{ + LH7A40X_CSC_PTR (csc); + + return (get_FCLK () / ((csc->clkset & CLKSET_HCLKDIV) + 1)); +} + +/* return PCLK frequency */ +ulong get_PCLK (void) +{ + LH7A40X_CSC_PTR (csc); + + return (get_HCLK () / + (1 << (((csc->clkset & CLKSET_PCLKDIV) >> 16) + 1))); +} diff --git a/cpu/lh7a40x/start.S b/cpu/lh7a40x/start.S new file mode 100644 index 0000000..160f889 --- /dev/null +++ b/cpu/lh7a40x/start.S @@ -0,0 +1,426 @@ +/* + * armboot - Startup Code for ARM920 CPU-core + * + * Copyright (c) 2001 Marius Gröger <mag@sysgo.de> + * Copyright (c) 2002 Alex Züpke <azu@sysgo.de> + * Copyright (c) 2002 Gary Jennejohn <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 + */ + + +#include <config.h> +#include <version.h> + + +/* + ************************************************************************* + * + * Jump vector table as in table 3.1 in [1] + * + ************************************************************************* + */ + + +.globl _start +_start: b reset + ldr pc, _undefined_instruction + ldr pc, _software_interrupt + ldr pc, _prefetch_abort + ldr pc, _data_abort + ldr pc, _not_used + ldr pc, _irq + ldr pc, _fiq + +_undefined_instruction: .word undefined_instruction +_software_interrupt: .word software_interrupt +_prefetch_abort: .word prefetch_abort +_data_abort: .word data_abort +_not_used: .word not_used +_irq: .word irq +_fiq: .word fiq + + .balignl 16,0xdeadbeef + + +/* + ************************************************************************* + * + * Startup Code (reset vector) + * + * do important init only if we don't start from memory! + * relocate armboot to ram + * setup stack + * jump to second stage + * + ************************************************************************* + */ + +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +#ifdef CONFIG_USE_IRQ +/* IRQ stack memory (calculated at run-time) */ +.globl IRQ_STACK_START +IRQ_STACK_START: + .word 0x0badc0de + +/* IRQ stack memory (calculated at run-time) */ +.globl FIQ_STACK_START +FIQ_STACK_START: + .word 0x0badc0de +#endif + + +/* + * the actual reset code + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + +#define pWDTCTL 0x80001400 /* Watchdog Timer control register */ +#define pINTENC 0x8000050C /* Interupt-Controller enable clear register */ +#define pCLKSET 0x80000420 /* clock divisor register */ + + /* disable watchdog, set watchdog control register to + * all zeros (default reset) + */ + ldr r0, =pWDTCTL + mov r1, #0x0 + str r1, [r0] + + /* + * mask all IRQs by setting all bits in the INTENC register (default) + */ + mov r1, #0xffffffff + ldr r0, =pINTENC + str r1, [r0] + + /* FCLK:HCLK:PCLK = 1:2:2 */ + /* default FCLK is 200 MHz, using 14.7456 MHz fin */ + ldr r0, =pCLKSET + ldr r1, =0x0004ee39 +@ ldr r1, =0x0005ee39 @ 1: 2: 4 + str r1, [r0] + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifdef CONFIG_INIT_CRITICAL + bl cpu_init_crit +#endif + +relocate: /* relocate U-Boot to RAM */ + adr r0, _start /* r0 <- current position of code */ + ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ + cmp r0, r1 /* don't reloc during debug */ + beq stack_setup + + ldr r2, _armboot_start + ldr r3, _bss_start + sub r2, r3, r2 /* r2 <- size of armboot */ + add r2, r0, r2 /* r2 <- source end address */ + +copy_loop: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end addreee [r2] */ + blt copy_loop /* a 'ble' here actually copies */ + /* four bytes of bss */ + + /* Set up the stack */ +stack_setup: + ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ + sub r0, r0, #CFG_MALLOC_LEN /* malloc area */ + sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ +#ifdef CONFIG_USE_IRQ + sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) +#endif + sub sp, r0, #12 /* leave 3 words for abort-stack */ + +clear_bss: + ldr r0, _bss_start /* find start of bss segment */ + @add r0, r0, #4 /* start at first byte of bss */ + /* why inc. 4 bytes past then? */ + ldr r1, _bss_end /* stop here */ + mov r2, #0x00000000 /* clear */ + +clbss_l:str r2, [r0] /* clear loop... */ + add r0, r0, #4 + cmp r0, r1 + bne clbss_l + + ldr pc, _start_armboot + +_start_armboot: .word start_armboot + + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + + +cpu_init_crit: + /* + * flush v4 I/D caches + */ + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ + mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ + + /* + * disable MMU stuff and caches + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) + bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) + orr r0, r0, #0x00000002 @ set bit 2 (A) Align + orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache + orr r0, r0, #0x40000000 @ set bit 30 (nF) notFastBus + mcr p15, 0, r0, c1, c0, 0 + + + /* + * before relocating, we have to setup RAM timing + * because memory timing is board-dependend, you will + * find a memsetup.S in your board directory. + */ + mov ip, lr + bl memsetup + mov lr, ip + + mov pc, lr + + +/* + ************************************************************************* + * + * Interrupt handling + * + ************************************************************************* + */ + +@ +@ IRQ stack frame. +@ +#define S_FRAME_SIZE 72 + +#define S_OLD_R0 68 +#define S_PSR 64 +#define S_PC 60 +#define S_LR 56 +#define S_SP 52 + +#define S_IP 48 +#define S_FP 44 +#define S_R10 40 +#define S_R9 36 +#define S_R8 32 +#define S_R7 28 +#define S_R6 24 +#define S_R5 20 +#define S_R4 16 +#define S_R3 12 +#define S_R2 8 +#define S_R1 4 +#define S_R0 0 + +#define MODE_SVC 0x13 +#define I_BIT 0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling + */ + + .macro bad_save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + ldr r2, _armboot_start + sub r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN) + sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack + ldmia r2, {r2 - r3} @ get pc, cpsr + add r0, sp, #S_FRAME_SIZE @ restore sp_SVC + + add r5, sp, #S_SP + mov r1, lr + stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr + mov r0, sp + .endm + + .macro irq_save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + add r8, sp, #S_PC + stmdb r8, {sp, lr}^ @ Calling SP, LR + str lr, [r8, #0] @ Save calling PC + mrs r6, spsr + str r6, [r8, #4] @ Save CPSR + str r0, [r8, #8] @ Save OLD_R0 + mov r0, sp + .endm + + .macro irq_restore_user_regs + ldmia sp, {r0 - lr}^ @ Calling r0 - lr + mov r0, r0 + ldr lr, [sp, #S_PC] @ Get PC + add sp, sp, #S_FRAME_SIZE + subs pc, lr, #4 @ return & move spsr_svc into cpsr + .endm + + .macro get_bad_stack + ldr r13, _armboot_start @ setup our mode stack + sub r13, r13, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN) + sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack + + str lr, [r13] @ save caller lr / spsr + mrs lr, spsr + str lr, [r13, #4] + + mov r13, #MODE_SVC @ prepare SVC-Mode + @ msr spsr_c, r13 + msr spsr, r13 + mov lr, pc + movs pc, lr + .endm + + .macro get_irq_stack @ setup IRQ stack + ldr sp, IRQ_STACK_START + .endm + + .macro get_fiq_stack @ setup FIQ stack + ldr sp, FIQ_STACK_START + .endm + +/* + * exception handlers + */ + .align 5 +undefined_instruction: + get_bad_stack + bad_save_user_regs + bl do_undefined_instruction + + .align 5 +software_interrupt: + get_bad_stack + bad_save_user_regs + bl do_software_interrupt + + .align 5 +prefetch_abort: + get_bad_stack + bad_save_user_regs + bl do_prefetch_abort + + .align 5 +data_abort: + get_bad_stack + bad_save_user_regs + bl do_data_abort + + .align 5 +not_used: + get_bad_stack + bad_save_user_regs + bl do_not_used + +#ifdef CONFIG_USE_IRQ + + .align 5 +irq: + get_irq_stack + irq_save_user_regs + bl do_irq + irq_restore_user_regs + + .align 5 +fiq: + get_fiq_stack + /* someone ought to write a more effiction fiq_save_user_regs */ + irq_save_user_regs + bl do_fiq + irq_restore_user_regs + +#else + + .align 5 +irq: + get_bad_stack + bad_save_user_regs + bl do_irq + + .align 5 +fiq: + get_bad_stack + bad_save_user_regs + bl do_fiq + +#endif + + .align 5 +.globl reset_cpu +reset_cpu: + bl disable_interrupts + + /* Disable watchdog */ + ldr r1, =pWDTCTL + mov r3, #0 + str r3, [r1] + + /* reset counter */ + ldr r3, =0x00001984 + str r3, [r1, #4] + + /* Enable the watchdog */ + mov r3, #1 + str r3, [r1] + +_loop_forever: + b _loop_forever diff --git a/cpu/pxa/interrupts.c b/cpu/pxa/interrupts.c index b161b74..8aec0b9 100644 --- a/cpu/pxa/interrupts.c +++ b/cpu/pxa/interrupts.c @@ -165,7 +165,7 @@ void reset_timer (void) ulong get_timer (ulong base) { - return get_timer_masked (); + return get_timer_masked () - base; } void set_timer (ulong t) diff --git a/doc/README.JFFS2 b/doc/README.JFFS2 index f854984..270da90 100644 --- a/doc/README.JFFS2 +++ b/doc/README.JFFS2 @@ -8,6 +8,7 @@ The module adds three new commands. fsload - load binary file from a file system image fsinfo - print information about file systems ls - list files in a directory +chpart - change active partition If you boot from a partition which is mounted writable, and you update your boot environment by replacing single files on that @@ -68,9 +69,6 @@ jffs2_part_info(int part_num) TODO. - Add a new command so it's actually possible to change - partition. - Remove the assumption that JFFS can dereference a pointer into the disk. The current code do not work with memory holes or hardware with a sliding window (PCMCIA). diff --git a/drivers/smc91111.c b/drivers/smc91111.c index 9f9f364..8b1103b 100644 --- a/drivers/smc91111.c +++ b/drivers/smc91111.c @@ -61,6 +61,7 @@ #include <common.h> #include <command.h> +#include <config.h> #include "smc91111.h" #include <net.h> @@ -78,6 +79,11 @@ static const char version[] = "smc91111.c:v1.0 04/25/01 by Daris A Nevil (dnevil@snmc.com)\n"; #endif +/* Autonegotiation timeout in seconds */ +#ifndef CONFIG_SMC_AUTONEG_TIMEOUT +#define CONFIG_SMC_AUTONEG_TIMEOUT 10 +#endif + /*------------------------------------------------------------------------ . . Configuration options, for the experienced user to change. @@ -353,7 +359,7 @@ static inline void smc_wait_mmu_release_complete (void) */ static void smc_reset (void) { - PRINTK2 ("%s:smc_reset\n", SMC_DEV_NAME); + PRINTK2 ("%s: smc_reset\n", SMC_DEV_NAME); /* This resets the registers mostly to defaults, but doesn't affect EEPROM. That seems unnecessary */ @@ -414,7 +420,7 @@ static void smc_reset (void) */ static void smc_enable() { - PRINTK2("%s:smc_enable\n", SMC_DEV_NAME); + PRINTK2("%s: smc_enable\n", SMC_DEV_NAME); SMC_SELECT_BANK( 0 ); /* see the header file for options in TCR/RCR DEFAULT*/ SMC_outw( TCR_DEFAULT, TCR_REG ); @@ -440,7 +446,7 @@ static void smc_enable() */ static void smc_shutdown() { - PRINTK2(CARDNAME ":smc_shutdown\n"); + PRINTK2(CARDNAME ": smc_shutdown\n"); /* no more interrupts for me */ SMC_SELECT_BANK( 2 ); @@ -489,7 +495,7 @@ static int smc_send_packet (volatile void *packet, int packet_length) saved_pnr = SMC_inb( PN_REG ); saved_ptr = SMC_inw( PTR_REG ); - PRINTK3 ("%s:smc_hardware_send_packet\n", SMC_DEV_NAME); + PRINTK3 ("%s: smc_hardware_send_packet\n", SMC_DEV_NAME); length = ETH_ZLEN < packet_length ? packet_length : ETH_ZLEN; @@ -677,7 +683,7 @@ again: */ void smc_destructor() { - PRINTK2(CARDNAME ":smc_destructor\n"); + PRINTK2(CARDNAME ": smc_destructor\n"); } @@ -691,7 +697,7 @@ static int smc_open (bd_t * bd) { int i, err; - PRINTK2 ("%s:smc_open\n", SMC_DEV_NAME); + PRINTK2 ("%s: smc_open\n", SMC_DEV_NAME); /* reset the hardware */ smc_reset (); @@ -764,7 +770,7 @@ static int smc_rcv() return 0; } - PRINTK3("%s:smc_rcv\n", SMC_DEV_NAME); + PRINTK3("%s: smc_rcv\n", SMC_DEV_NAME); /* start reading from the start of the packet */ SMC_outw( PTR_READ | PTR_RCV | PTR_AUTOINC, PTR_REG ); @@ -860,7 +866,7 @@ static int smc_rcv() -----------------------------------------------------*/ static int smc_close() { - PRINTK2("%s:smc_close\n", SMC_DEV_NAME); + PRINTK2("%s: smc_close\n", SMC_DEV_NAME); /* clear everything */ smc_shutdown(); @@ -1222,7 +1228,7 @@ static void smc_phy_configure () word status = 0; /*;my status = 0 */ int failed = 0; - PRINTK3 ("%s:smc_program_phy()\n", SMC_DEV_NAME); + PRINTK3 ("%s: smc_program_phy()\n", SMC_DEV_NAME); /* Get the detected phy address */ @@ -1286,8 +1292,8 @@ static void smc_phy_configure () /* the link does not come up. */ smc_read_phy_register(PHY_AD_REG); - PRINTK2 ("%s:phy caps=%x\n", SMC_DEV_NAME, my_phy_caps); - PRINTK2 ("%s:phy advertised caps=%x\n", SMC_DEV_NAME, my_ad_caps); + PRINTK2 ("%s: phy caps=%x\n", SMC_DEV_NAME, my_phy_caps); + PRINTK2 ("%s: phy advertised caps=%x\n", SMC_DEV_NAME, my_ad_caps); /* Restart auto-negotiation process in order to advertise my caps */ smc_write_phy_register (PHY_CNTL_REG, @@ -1296,8 +1302,9 @@ static void smc_phy_configure () /* Wait for the auto-negotiation to complete. This may take from */ /* 2 to 3 seconds. */ /* Wait for the reset to complete, or time out */ - timeout = 20; /* Wait up to 10 seconds */ + timeout = CONFIG_SMC_AUTONEG_TIMEOUT * 2; while (timeout--) { + status = smc_read_phy_register (PHY_STAT_REG); if (status & PHY_STAT_ANEG_ACK) { /* auto-negotiate complete */ @@ -1308,11 +1315,11 @@ static void smc_phy_configure () /* Restart auto-negotiation if remote fault */ if (status & PHY_STAT_REM_FLT) { - printf ("%s:PHY remote fault detected\n", + printf ("%s: PHY remote fault detected\n", SMC_DEV_NAME); /* Restart auto-negotiation */ - printf ("%s:PHY restarting auto-negotiation\n", + printf ("%s: PHY restarting auto-negotiation\n", SMC_DEV_NAME); smc_write_phy_register (PHY_CNTL_REG, PHY_CNTL_ANEG_EN | @@ -1323,15 +1330,13 @@ static void smc_phy_configure () } if (timeout < 1) { - printf ("%s:PHY auto-negotiate timed out\n", SMC_DEV_NAME); - printf ("%s:PHY auto-negotiate timed out\n", SMC_DEV_NAME); + printf ("%s: PHY auto-negotiate timed out\n", SMC_DEV_NAME); failed = 1; } /* Fail if we detected an auto-negotiate remote fault */ if (status & PHY_STAT_REM_FLT) { - printf ("%s:PHY remote fault detected\n", SMC_DEV_NAME); - printf ("%s:PHY remote fault detected\n", SMC_DEV_NAME); + printf ("%s: PHY remote fault detected\n", SMC_DEV_NAME); failed = 1; } @@ -1469,12 +1474,16 @@ int get_rom_mac (char *v_rom_mac) return (1); #else int i; + int valid_mac = 0; + SMC_SELECT_BANK (1); for (i=0; i<6; i++) { v_rom_mac[i] = SMC_inb (ADDR0_REG + i); + valid_mac |= v_rom_mac[i]; } - return (1); + + return (valid_mac ? 1 : 0); #endif } #endif /* CONFIG_DRIVER_SMC91111 */ diff --git a/include/bmp_logo.h b/include/bmp_logo.h index 265f744..9c924b8 100644 --- a/include/bmp_logo.h +++ b/include/bmp_logo.h @@ -18,7 +18,7 @@ unsigned short bmp_logo_palette[] = { 0x0343, 0x0454, 0x0565, 0x0565, 0x0676, 0x0787, 0x0898, 0x0999, 0x0AAA, 0x0ABA, 0x0BCB, 0x0CCC, 0x0DDD, 0x0EEE, 0x0FFF, 0x0FB3, 0x0FB4, 0x0FC4, 0x0FC5, 0x0FC6, 0x0FD7, 0x0FD8, 0x0FD9, 0x0FDA, - 0x0FEA, 0x0FEB, 0x0FEC, 0x0FFD, 0x0FFE, 0x0FFF, 0x0FFF, + 0x0FEA, 0x0FEB, 0x0FEC, 0x0FFD, 0x0FFE, 0x0FFF, 0x0FFF, }; unsigned char bmp_logo_bitmap[] = { diff --git a/include/common.h b/include/common.h index 8a81e43..db1a114 100644 --- a/include/common.h +++ b/include/common.h @@ -384,12 +384,15 @@ int prt_mpc5xxx_clks (void); ulong get_OPB_freq (void); ulong get_PCI_freq (void); #endif -#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) +#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_LH7A40X) ulong get_FCLK (void); ulong get_HCLK (void); ulong get_PCLK (void); ulong get_UCLK (void); #endif +#if defined(CONFIG_LH7A40X) +ulong get_PLLCLK (void); +#endif #if defined CONFIG_INCA_IP uint incaip_get_cpuclk (void); #endif diff --git a/include/configs/innokom.h b/include/configs/innokom.h index 77439e6..f884519 100644 --- a/include/configs/innokom.h +++ b/include/configs/innokom.h @@ -140,6 +140,7 @@ #define CONFIG_SMC91111_BASE 0x14000000 /* chip select 5 */ #undef CONFIG_SMC_USE_32_BIT /* 16 bit bus access */ #undef CONFIG_SMC_91111_EXT_PHY /* we use internal phy */ +#define CONFIG_SMC_AUTONEG_TIMEOUT 10 /* timeout 10 seconds */ #undef CONFIG_SHOW_ACTIVITY #define CONFIG_NET_RETRY_COUNT 10 /* # of retries */ diff --git a/include/configs/lpd7a400-10.h b/include/configs/lpd7a400-10.h new file mode 100644 index 0000000..ecf2b5f --- /dev/null +++ b/include/configs/lpd7a400-10.h @@ -0,0 +1,80 @@ +/* + * 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 + */ + +/* + * Logic LH7A400-10 card engine + */ + +#ifndef __LPD7A400_10_H +#define __LPD7A400_10_H + + +#define CONFIG_ARM920T 1 /* arm920t core */ +#define CONFIG_LH7A40X 1 /* Sharp LH7A400 SoC */ +#define CONFIG_LH7A400 1 + +/* The system clock PLL input frequency */ +#define CONFIG_SYS_CLK_FREQ 14745600 /* System Clock PLL Input (Hz) */ + +/* ticks per second */ +#define CFG_HZ (508469) + +/*----------------------------------------------------------------------- + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (128*1024) /* regular stack */ +#ifdef CONFIG_USE_IRQ +#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */ +#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */ +#endif + +/*----------------------------------------------------------------------- + * Physical Memory Map + */ +#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */ +#define PHYS_SDRAM_1 0xc0000000 /* SDRAM Bank #1 */ +#define PHYS_SDRAM_1_SIZE 0x02000000 /* 32 MB */ + +#define CFG_FLASH_BASE 0x00000000 /* Flash Bank #1 */ + +/*----------------------------------------------------------------------- + * FLASH and environment organization + */ +#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ +#define CFG_MAX_FLASH_SECT (64) /* max number of sectors on one chip */ + +/* timeout values are in ticks */ +#define CFG_FLASH_ERASE_TOUT (5*CFG_HZ) /* Timeout for Flash Erase */ +#define CFG_FLASH_WRITE_TOUT (5*CFG_HZ) /* Timeout for Flash Write */ + +/*---------------------------------------------------------------------- + * Using SMC91C111 LAN chip + * + * Default IO base of chip is 0x300, Card Engine has this address lines + * (LAN chip) tied to Vcc, so we just care about the chip select + */ +#define CONFIG_DRIVER_SMC91111 +#define CONFIG_SMC91111_BASE (0x70000000) +#undef CONFIG_SMC_USE_32_BIT +#define CONFIG_SMC_USE_IOFUNCS + +#endif /* __LPD7A400_10_H */ diff --git a/include/configs/lpd7a400.h b/include/configs/lpd7a400.h new file mode 100644 index 0000000..3e91536 --- /dev/null +++ b/include/configs/lpd7a400.h @@ -0,0 +1,114 @@ +/* + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __LPD7A400_H_ +#define __LPD7A400_H_ + +/* + * If we are developing, we might want to start armboot from ram + * so we MUST NOT initialize critical regs like mem-timing ... + */ +#define CONFIG_INIT_CRITICAL /* undef for developing */ + +#undef CONFIG_USE_IRQ + +#define MACH_TYPE_LPD7A400 389 + +/* + * This board uses the logic LH7A400-10 card engine + */ +#include <configs/lpd7a400-10.h> + +#define CONFIG_LPD7A400 /* Logic LH7A400 SDK */ + +#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ +#define CONFIG_SETUP_MEMORY_TAGS 1 +#define CONFIG_INITRD_TAG 1 + +/* + * Size of malloc() pool + */ +#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024) +#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ + +/* + * select serial console configuration + */ +#define CONFIG_CONSOLE_UART2 /* UART2 LH7A40x for console */ + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +#define CONFIG_BAUDRATE 115200 +#define CONFIG_IPADDR 192.168.1.100 +#define CONFIG_NETMASK 255.255.1.0 +#define CONFIG_SERVERIP 192.168.1.1 + +#define CONFIG_TIMESTAMP 1 /* Print timestamp info for images */ + +#ifndef USE_920T_MMU +#define CONFIG_COMMANDS ((CONFIG_CMD_DFL | CFG_CMD_PING) & ~(CFG_CMD_CACHE)) +#else +#define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_DATE) +#endif + + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include <cmd_confdefs.h> + +#define CONFIG_BOOTDELAY 3 + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port */ +/* what's this ? it's not used anywhere */ +#define CONFIG_KGDB_SER_INDEX 1 /* which serial port to use */ +#endif + +/* + * Miscellaneous configurable options + */ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_PROMPT "LPD7A400> " /* Monitor Command Prompt */ +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +#define CFG_MEMTEST_START 0xc0300000 /* memtest works on */ +#define CFG_MEMTEST_END 0xc0500000 /* 2 MB in DRAM */ + +#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ + +#define CFG_LOAD_ADDR 0xc0f00000 /* default load address */ + +/* valid baudrates */ +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } + +/* size and location of u-boot in flash */ +#define CFG_MONITOR_BASE CFG_FLASH_BASE +#define CFG_MONITOR_LEN (256<<10) + +#define CFG_ENV_IS_IN_FLASH 1 + +/* Address and size of Primary Environment Sector */ +#define CFG_ENV_ADDR (CFG_FLASH_BASE + 0xFC0000) +#define CFG_ENV_SIZE 0x40000 + +#endif /* __LPD7A400_H_ */ diff --git a/include/lh7a400.h b/include/lh7a400.h new file mode 100644 index 0000000..e43667d --- /dev/null +++ b/include/lh7a400.h @@ -0,0 +1,93 @@ +/* + * 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 + */ + +/* + * lh7a400 SoC interface + */ + +#ifndef __LH7A400_H__ +#define __LH7A400_H__ + +#include "lh7a40x.h" + +/* Interrupt Controller (userguide 8.2.1) */ +typedef struct { + volatile u32 intsr; + volatile u32 intrsr; + volatile u32 intens; + volatile u32 intenc; + volatile u32 rsvd1; + volatile u32 rsvd2; + volatile u32 rsvd3; +} /*__attribute__((__packed__))*/ lh7a400_interrupt_t; +#define LH7A400_INTERRUPT_BASE (0x80000500) +#define LH7A400_INTERRUPT_PTR(name) lh7a400_interrupt_t* name = (lh7a400_interrupt_t*) LH7A400_INTERRUPT_BASE + +/* (DMA) Direct Memory Access Controller (userguide 9.2.1) */ +typedef struct { + volatile u32 maxcnt; + volatile u32 base; + volatile u32 current; + volatile u32 rsvd1; +} lh7a400_dmabuf_t; + +typedef struct { + volatile u32 control; + volatile u32 interrupt; + volatile u32 rsvd1; + volatile u32 status; + volatile u32 rsvd2; + volatile u32 remain; + volatile u32 rsvd3; + volatile u32 rsvd4; + lh7a400_dmabuf_t buf[2]; +} /*__attribute__((__packed__))*/ lh7a400_dmachan_t; + +typedef struct { + lh7a400_dmachan_t chan[15]; + volatile u32 glblint; + volatile u32 rsvd1; + volatile u32 rsvd2; + volatile u32 rsvd3; +} /*__attribute__((__packed__))*/ lh7a400_dma_t; +#define LH7A400_DMA_BASE (0x80002800) +#define DMA_USBTX_OFFSET (0x000) +#define DMA_USBRX_OFFSET (0x040) +#define DMA_MMCTX_OFFSET (0x080) +#define DMA_MMCRX_OFFSET (0x0C0) +#define DMA_AC97_BASE (0x80002A00) + +#define LH7A400_DMA_PTR(name) lh7a400_dma_t* name = (lh7a400_dma_t*) LH7A400_DMA_BASE +#define LH7A400_DMA_USBTX(name) \ + lh7a400_dmachan_t* name = (lh7a400_dmachan_t*) (LH7A400_DMA_BASE + DMA_USBTX_OFFSET) +#define LH7A400_DMA_USBRX(name) \ + lh7a400_dmachan_t* name = (lh7a400_dmachan_t*) (LH7A400_DMA_BASE + DMA_USBRX_OFFSET) +#define LH7A400_DMA_MMCTX(name) \ + lh7a400_dmachan_t* name = (lh7a400_dmachan_t*) (LH7A400_DMA_BASE + DMA_MMCTX_OFFSET) +#define LH7A400_DMA_MMCRX(name) \ + lh7a400_dmachan_t* name = (lh7a400_dmachan_t*) (LH7A400_DMA_BASE + DMA_MMCRX_OFFSET) +#define LH7A400_AC97RX(name,n) \ + lh7a400_dmachan_t* name = (lh7a400_dmachan_t*) (LH7A400_AC97_BASE + \ + ((2*n) * sizeof(lh7a400_dmachan_t))) +#define LH7A400_AC97TX(name,n) \ + lh7a400_dmachan_t* name = (lh7a400_dmachan_t*) (LH7A400_AC97_BASE + \ + (((2*n)+1) * sizeof(lh7a400_dmachan_t))) + +#endif /* __LH7A400_H__ */ diff --git a/include/lh7a40x.h b/include/lh7a40x.h new file mode 100644 index 0000000..081009c --- /dev/null +++ b/include/lh7a40x.h @@ -0,0 +1,258 @@ +/* + * 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 + */ + +/* + * lh7a40x SoC series common interface + */ + +#ifndef __LH7A40X_H__ +#define __LH7A40X_H__ + +/* (SMC) Static Memory Controller (usersguide 4.2.1) */ +typedef struct { + volatile u32 attib; + volatile u32 com; + volatile u32 io; + volatile u32 rsvd1; +} /*__attribute__((__packed__))*/ lh7a40x_pccard_t; + +typedef struct { + volatile u32 bcr[8]; + lh7a40x_pccard_t pccard[2]; + volatile u32 pcmciacon; +} /*__attribute__((__packed__))*/ lh7a40x_smc_t; +#define LH7A40X_SMC_BASE (0x80002000) +#define LH7A40X_SMC_PTR(name) lh7a40x_smc_t* name = (lh7a40x_smc_t*) LH7A40X_SMC_BASE + +/* (SDMC) Synchronous Dynamic Ram Controller (usersguide 5.3.1) */ +typedef struct { + volatile u32 rsvd1; + volatile u32 gblcnfg; + volatile u32 rfshtmr; + volatile u32 bootstat; + volatile u32 sdcsc[4]; +} /*__attribute__((__packed__))*/ lh7a40x_sdmc_t; +#define LH7A40X_SDMC_BASE (0x80002400) +#define LH7A40X_SDMC_PTR(name) lh7a40x_sdmc_t* name = (lh7a40x_sdmc_t*) LH7A40X_SDMC_BASE + +/* (CSC) Clock and State Controller (userguide 6.2.1) */ +typedef struct { + volatile u32 pwrsr; + volatile u32 pwrcnt; + volatile u32 halt; + volatile u32 stby; + volatile u32 bleoi; + volatile u32 mceoi; + volatile u32 teoi; + volatile u32 stfclr; + volatile u32 clkset; + volatile u32 scrreg[2]; + volatile u32 rsvd1; + volatile u32 usbreset; +} /*__attribute__((__packed__))*/ lh7a40x_csc_t; +#define LH7A40X_STPWR_BASE (0x80000400) +#define LH7A40X_CSC_PTR(name) lh7a40x_csc_t* name = (lh7a40x_csc_t*) LH7A40X_STPWR_BASE + +#define CLKSET_SMCROM (0x01000000) +#define CLKSET_PS (0x000C0000) +#define CLKSET_PS_0 (0x00000000) +#define CLKSET_PS_1 (0x00040000) +#define CLKSET_PS_2 (0x00080000) +#define CLKSET_PS_3 (0x000C0000) +#define CLKSET_PCLKDIV (0x00030000) +#define CLKSET_PCLKDIV_2 (0x00000000) +#define CLKSET_PCLKDIV_4 (0x00010000) +#define CLKSET_PCLKDIV_8 (0x00020000) +#define CLKSET_MAINDIV2 (0x0000f800) +#define CLKSET_MAINDIV1 (0x00000780) +#define CLKSET_PREDIV (0x0000007C) +#define CLKSET_HCLKDIV (0x00000003) + +/* (WDT) Watchdog Timer (userguide 11.2.1) */ +typedef struct { + volatile u32 ctl; + volatile u32 rst; + volatile u32 status; + volatile u32 count[4]; +} /*__attribute__((__packed__))*/ lh7a40x_wdt_t; +#define LH7A40X_WDT_BASE (0x80001400) +#define LH7A40X_WDT_PTR(name) lh7a40x_wdt_t* name = (lh7a40x_wdt_t*) LH7A40X_WDT_BASE + +/* (RTC) Real Time Clock (lh7a400 userguide 12.2.1, lh7a404 userguide 13.2.1) */ +typedef struct { + volatile u32 rtcdr; + volatile u32 rtclr; + volatile u32 rtcmr; + volatile u32 unk1; + volatile u32 rtcstat_eoi; + volatile u32 rtccr; + volatile u32 rsvd1[58]; +} /*__attribute__((__packed__))*/ lh7a40x_rtc_t; +#define LH7A40X_RTC_BASE (0x80000D00) +#define LH7A40X_RTC_PTR(name) lh7a40x_rtc_t* name = (lh7a40x_rtc_t*) LH7A40X_RTC_BASE + +/* Timers (lh7a400 userguide 13.2.1, lh7a404 userguide 11.2.1) */ +typedef struct { + volatile u32 load; + volatile u32 value; + volatile u32 control; + volatile u32 tceoi; +} /*__attribute__((__packed__))*/ lh7a40x_timer_t; + +typedef struct { + lh7a40x_timer_t timer1; + volatile u32 rsvd1[4]; + lh7a40x_timer_t timer2; + volatile u32 unk1[4]; + volatile u32 bzcon; + volatile u32 unk2[15]; + lh7a40x_timer_t timer3; + /*volatile u32 rsvd2;*/ +} /*__attribute__((__packed__))*/ lh7a40x_timers_t; +#define LH7A40X_TIMERS_BASE (0x80000C00) +#define LH7A40X_TIMERS_PTR(name) lh7a40x_timers_t* name = (lh7a40x_timers_t*) LH7A40X_TIMERS_BASE + +#define TIMER_EN (0x00000080) +#define TIMER_PER (0x00000040) +#define TIMER_FREE (0x00000000) +#define TIMER_CLK508K (0x00000008) +#define TIMER_CLK2K (0x00000000) + +/* (SSP) Sychronous Serial Ports (lh7a400 userguide 14.2.1, lh7a404 userguide 14.2.1) */ +typedef struct { + volatile u32 cr0; + volatile u32 cr1; + volatile u32 irr_roeoi; + volatile u32 dr; + volatile u32 cpr; + volatile u32 sr; + /*volatile u32 rsvd1[58];*/ +} /*__attribute__((__packed__))*/ lh7a40x_ssp_t; +#define LH7A40X_SSP_BASE (0x80000B00) +#define LH7A40X_SSP_PTR(name) lh7a40x_ssp_t* name = (lh7a40x_ssp_t*) LH7A40X_SSP_BASE + +/* (UART) Universal Asychronous Receiver/Transmitter (lh7a400 userguide 15.2.1, lh7a404 userguide 15.2.1) */ +typedef struct { + volatile u32 data; + volatile u32 fcon; + volatile u32 brcon; + volatile u32 con; + volatile u32 status; + volatile u32 rawisr; + volatile u32 inten; + volatile u32 isr; + volatile u32 rsvd1[56]; +} /*__attribute__((__packed__))*/ lh7a40x_uart_t; +#define LH7A40X_UART_BASE (0x80000600) +#define LH7A40X_UART_PTR(name,n) \ + lh7a40x_uart_t* name = (lh7a40x_uart_t*) (LH7A40X_UART_BASE + ((n-1) * sizeof(lh7a40x_uart_t))) + +#define UART_BE (0x00000800) /* the rx error bits */ +#define UART_OE (0x00000400) +#define UART_PE (0x00000200) +#define UART_FE (0x00000100) + +#define UART_WLEN (0x00000060) /* fcon bits */ +#define UART_WLEN_8 (0x00000060) +#define UART_WLEN_7 (0x00000040) +#define UART_WLEN_6 (0x00000020) +#define UART_WLEN_5 (0x00000000) +#define UART_FEN (0x00000010) +#define UART_STP2 (0x00000008) +#define UART_STP2_2 (0x00000008) +#define UART_STP2_1 (0x00000000) +#define UART_EPS (0x00000004) +#define UART_EPS_EVEN (0x00000004) +#define UART_EPS_ODD (0x00000000) +#define UART_PEN (0x00000002) +#define UART_BRK (0x00000001) + +#define UART_BAUDDIV (0x0000ffff) /* brcon bits */ + +#define UART_SIRBD (0x00000080) /* con bits */ +#define UART_LBE (0x00000040) +#define UART_MXP (0x00000020) +#define UART_TXP (0x00000010) +#define UART_RXP (0x00000008) +#define UART_SIRLP (0x00000004) +#define UART_SIRD (0x00000002) +#define UART_EN (0x00000001) + +#define UART_TXFE (0x00000080) /* status bits */ +#define UART_RXFF (0x00000040) +#define UART_TXFF (0x00000020) +#define UART_RXFE (0x00000010) +#define UART_BUSY (0x00000008) +#define UART_DCD (0x00000004) +#define UART_DSR (0x00000002) +#define UART_CTS (0x00000001) + +#define UART_MSEOI (0xfffffff0) /* rawisr interrupt bits */ + +#define UART_RTI (0x00000008) /* generic interrupt bits */ +#define UART_MI (0x00000004) +#define UART_TI (0x00000002) +#define UART_RI (0x00000001) + +/* (GPIO) General Purpose IO and External Interrupts (userguide 16.2.1) */ +typedef struct { + volatile u32 pad; + volatile u32 pbd; + volatile u32 pcd; + volatile u32 pdd; + volatile u32 padd; + volatile u32 pbdd; + volatile u32 pcdd; + volatile u32 pddd; + volatile u32 ped; + volatile u32 pedd; + volatile u32 kbdctl; + volatile u32 pinmux; + volatile u32 pfd; + volatile u32 pfdd; + volatile u32 pgd; + volatile u32 pgdd; + volatile u32 phd; + volatile u32 phdd; + volatile u32 rsvd1; + volatile u32 inttype1; + volatile u32 inttype2; + volatile u32 gpiofeoi; + volatile u32 gpiointen; + volatile u32 intstatus; + volatile u32 rawintstatus; + volatile u32 gpiodb; + volatile u32 papd; + volatile u32 pbpd; + volatile u32 pcpd; + volatile u32 pdpd; + volatile u32 pepd; + volatile u32 pfpd; + volatile u32 pgpd; + volatile u32 phpd; +} /*__attribute__((__packed__))*/ lh7a40x_gpioint_t; +#define LH7A40X_GPIOINT_BASE (0x80000E00) +#define LH7A40X_GPIOINT_PTR(name) lh7a40x_gpioint_t* name = (lh7a40x_gpioint_t*) LH7A40X_GPIOINT_BASE + +/* Embedded SRAM */ +#define CFG_SRAM_BASE (0xB0000000) +#define CFG_SRAM_SIZE (80*1024) /* 80kB */ + +#endif /* __LH7A40X_H__ */ diff --git a/include/lpd7a400_cpld.h b/include/lpd7a400_cpld.h new file mode 100644 index 0000000..c70af09 --- /dev/null +++ b/include/lpd7a400_cpld.h @@ -0,0 +1,195 @@ +/* + * 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 + */ + +/* + * Logic lh7a400-10 Card Engine CPLD interface + */ + +#ifndef __LPD7A400_CPLD_H_ +#define __LPD7A400_CPLD_H_ + + +/* + * IO Controller Address and Register Definitions + * - using LH7A400-10 Card Engine IO Controller Specification + * (logic PN: 70000079) + */ + +/*------------------------------------------------------------------ + * Slow Peripherals (nCS6) + */ +#define LPD7A400_CPLD_CF (0x60200000) +#define LPD7A400_CPLD_ISA (0x60400000) + +/*------------------------------------------------------------------ + * Fast Peripherals (nCS7) + * + * The CPLD directs access to 0x70000000-0x701fffff to the onboard + * ethernet controller + */ +#define LPD7A400_CPLD_WLAN_BASE (0x70000000) + +/* All registers are 8 bit */ +#define LPD7A400_CPLD_CECTL_REG (0x70200000) +#define LPD7A400_CPLD_SPIDATA_REG (0x70600000) +#define LPD7A400_CPLD_SPICTL_REG (0x70800000) +#define LPD7A400_CPLD_EEPSPI_REG (0x70a00000) +#define LPD7A400_CPLD_INTMASK_REG (0x70c00000) +#define LPD7A400_CPLD_MODE_REG (0x70e00000) +#define LPD7A400_CPLD_FLASH_REG (0x71000000) +#define LPD7A400_CPLD_PWRMG_REG (0x71200000) +#define LPD7A400_CPLD_REV_REG (0x71400000) +#define LPD7A400_CPLD_EXTGPIO_REG (0x71600000) +#define LPD7A400_CPLD_GPIODATA_REG (0x71800000) +#define LPD7A400_CPLD_GPIODIR_REG (0x71a00000) + +#define LPD7A400_CPLD_REGPTR (volatile u8*) + +/* Card Engine Control Register (section 3.1.2) */ +#define CECTL_SWINT (0x80) /* Software settable interrupt source + (routed to uP PF3) + 0 = generate interrupt, 1 = do not */ +#define CECTL_OCMSK (0x40) /* USB1 connection interrupt mask + 0 = not masked, 1 = masked */ +#define CECTL_PDRV (0x20) /* PCC_nDRV output + 0 = active, 1 = inactive */ +#define CECTL_USB1C (0x10) /* USB1 connection interrupt + 0 = active, 1 = inactive */ +#define CECTL_USB1P (0x08) /* USB1 Power enable + 0 = enabled, 1 = disabled */ +#define CECTL_AWKP (0x04) /* Auto-Wakeup enable + 0 = enabled, 1 = disabled */ +#define CECTL_LCDV (0x02) /* LCD VEE enable + 0 = disabled, 1 = enabled */ +#define CECTL_WLPE (0x01) /* Wired LAN power enable + 0 = enabled, 1 = disabled */ + +/* SPI Control Register (section 3.1.5) */ +#define SPICTL_SPLD (0x20) /* SPI load (R) + 0 = data reg. has not been loaded, shift + count has not been reset + 1 = data reg. loaded, shift count reset */ +#define SPICTL_SPST (0x10) /* SPI start (RW) + 0 = don't load data reg. and reset shift count + 1 = ready to load data reg and reset shift count */ +#define SPICTL_SPDN (0x08) /* SPI done (R) + 0 = not done + 1 = access done */ +#define SPICTL_SPRW (0x04) /* SPI read/write (RW) + 0 = SPI write access + 1 = SPI read access */ +#define SPICTL_STCS (0x02) /* SPI touch chip select (RW) + 0 = not selected + 1 = selected */ +#define SPICTL_SCCS (0x01) /* SPI CODEC chip select (RW) {not used} + 0 = not selected + 1 = selected */ + +/* EEPROM SPI Interface Register (section 3.1.6) */ +#define EEPSPI_EECS (0x08) /* EEPROM chip select (RW) + 0 = not selected + 1 = selected */ +#define EEPSPI_EECK (0x04) /* EEPROM SPI clock (RW) */ +#define EEPSPI_EETX (0x02) /* EEPROM SPI tx data (RW) */ +#define EEPSPI_EERX (0x01) /* EEPROM SPI rx data (R) */ + +/* Interrupt/Mask Register (section 3.1.7) */ +#define INTMASK_CMSK (0x80) /* CPLD_nIRQD interrupt mask (RW) + 0 = not masked + 1 = masked */ +#define INTMASK_CIRQ (0x40) /* interrupt signal to CPLD (R) + 0 = interrupt active + 1 = no interrupt */ +#define INTMASK_PIRQ (0x10) /* legacy, no effect */ +#define INTMASK_TMSK (0x08) /* Touch chip interrupt mask (RW) + 0 = not masked + 1 = masked */ +#define INTMASK_WMSK (0x04) /* Wired LAN interrupt mask (RW) + 0 = not masked + 1 = masked */ +#define INTMASK_TIRQ (0x02) /* Touch chip interrupt request (R) + 0 = interrupt active + 1 = no interrupt */ +#define INTMASK_WIRQ (0x01) /* Wired LAN interrupt request (R) + 0 = interrupt active + 1 = no interrupt */ + +/* Mode Register (section 3.1.8) */ +#define MODE_VS1 (0x80) /* PCMCIA Voltage Sense 1 input (PCC_VS1) (R) + 0 = active slot VS1 pin is low + 1 = active slot VS1 pin is high */ +#define MODE_CD2 (0x40) /* PCMCIA Card Detect 2 input (PCC_nCD2) (R) + 0 = active slot CD2 is low + 1 = active slot CD2 is high */ +#define MODE_IOIS16 (0x20) /* PCMCIA IOIS16 input (PCC_nIOIS16) (R) + 0 = 16 bit access area + 1 = 8 bit access area */ +#define MODE_CD1 (0x10) /* PCMCIA Card Detect 1 input (PCC_nCD1) (R) + 0 = active slot CD1 is low + 1 = active slot CD1 is high */ +#define MODE_upMODE3 (0x08) /* Mode Pin 3 (R) + 0 = off-board boot device + 1 = on-board boot device (flash) */ +#define MODE_upMODE2 (0x04) /* Mode Pin 2 (R) (LH7A400 Little Endian only) + 0 = big endian + 1 = little endian */ +#define MODE_upMODE1 (0x02) /* Mode Pin 1 and Mode Pin 2 (R) */ +#define MODE_upMODE0 (0x01) /* - bus width at boot */ + + +/* Flash Register (section 3.1.9) */ +#define FLASH_FPOP (0x08) /* Flash populated (RW) + 0 = populated, 1 = not */ +#define FLASH_FST2 (0x04) /* Flash status (R) (RY/BY# pin for upper 16 bit chip + 0 = busy, 1 = ready */ +#define FLASH_FST1 (0x02) /* Flash status (R) (RY/BY# pin for lower 16 bit chip + 0 = busy, 1 = ready */ +#define FLASH_FPEN (0x01) /* Flash program enable (RW) + 0 = flash write protected + 1 = programming enabled */ + +/* Power Management Register (section 3.1.10) + * - when either of these is low an unmaskable interrupt to cpu + * is generated + */ +#define PWRMG_STBY (0x10) /* state of nSTANDBY signal to CPLD (R) + 0 = low, 1 = high */ +#define PWRMG_SPND (0x04) /* state of nSUSPEND signal to CPLD (R) + 0 = low, 1 = high */ + + +/* Extended GPIO Register (section 3.1.12) */ +#define EXTGPIO_STATUS1 (0x04) /* Status 1 output (RW) (uP_STATUS_1) + 0 = set pin low, 1 = set pin high */ +#define EXTGPIO_STATUS2 (0x02) /* Status 2 output (RW) (uP_STATUS_2) + 0 = set pin low, 1 = set pin high */ +#define EXTGPIO_GPIO1 (0x01) /* General purpose output (RW) (CPLD_GPIO_1) + 0 = set pin low, 1 = set pin high */ + +/* GPIO Data Register (section 3.1.13) */ +#define GPIODATA_GPIO2 (0x01) /* General purpose input/output (RW) (CPLD_GPIO_2) + 0 = set low (output) / read low (input) + 1 = set high (output) / read high (input) */ + +/* GPIO Direction Register (section 3.1.14) */ +#define GPIODIR_GPDR0 (0x01) /* GPIO2 direction (RW) + 0 = output, 1 = input */ + +#endif /* __LH7A400_H__ */ diff --git a/lib_arm/board.c b/lib_arm/board.c index 193980e..bba944a 100644 --- a/lib_arm/board.c +++ b/lib_arm/board.c @@ -32,6 +32,13 @@ #include <version.h> #include <net.h> +#ifdef CONFIG_DRIVER_SMC91111 +#include "../drivers/smc91111.h" +#endif +#ifdef CONFIG_DRIVER_LAN91C96 +#include "../drivers/lan91c96.h" +#endif + #if (CONFIG_COMMANDS & CFG_CMD_NAND) void nand_init (void); #endif @@ -58,9 +65,6 @@ extern void cs8900_get_enetaddr (uchar * addr); extern void rtl8019_get_enetaddr (uchar * addr); #endif -#ifdef CONFIG_DRIVER_LAN91C96 -#include "../drivers/lan91c96.h" -#endif /* * Begin and End of memory area for malloc(), and current "brk" */ @@ -302,11 +306,12 @@ void start_armboot (void) cs8900_get_enetaddr (gd->bd->bi_enetaddr); #endif -#ifdef CONFIG_DRIVER_LAN91C96 +#if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96) if (getenv ("ethaddr")) { smc_set_mac_addr(gd->bd->bi_enetaddr); } -#endif /* CONFIG_DRIVER_LAN91C96 */ + eth_init(gd->bd); +#endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */ /* Initialize from environment */ if ((s = getenv ("loadaddr")) != NULL) { |