Compare commits

...

5 Commits

Author SHA1 Message Date
wdenk
cdd8a0f151 Fix MIPS build problem 2003-03-27 18:00:16 +00:00
wdenk
c021880ac5 * Add support for MIPS32 4Kc CPUs
* Add support for INCA-IP Board
2003-03-27 12:09:35 +00:00
wdenk
ac6dbb85b7 Make compile clean, fix the usual small problems. 2003-03-26 11:42:53 +00:00
stroese
2a46cabd77 esd PCI405 updated. 2003-03-26 10:36:12 +00:00
wdenk
dc7c9a1a52 * Patch by Rick Bronson, 16 Mar 2003:
Add support for Atmel AT91RM9200DK w/NAND

* Patches by Robert Schwebel, 19 Mar 2003:
  - use arm-linux-gcc as default compiler for ARM
  - fix i2c fixup code
  - fix missing baudrate setting
  - added $loadaddr / CFG_LOAD_ADDR support to loadb
  - moved "ignoring trailing characters" _before_ u-boot wants to
    print out diagnostics messages; removes bogus characters at the
    end of transmission

* Patch by John Zhan, 18 Mar 2003:
  Add support for SinoVee Microsystems SC8xx boards

* Patch by Rolf Offermanns, 21 Mar 2003:
  ported the dnp1110 related changes from the current armboot cvs to
  current u-boot cvs. smc91111 does not work. problem marked in
  smc91111.c, grep for "FIXME".

* Patch by Brian Auld, 25 Mar 2003:
  Add support for STM flash chips on ebony board

 * Add PCI support for MPC8250 Boards (PM825 module)

 * Patch by Stefan Roese, 25 Mar 2003:
2003-03-26 06:55:25 +00:00
93 changed files with 13180 additions and 450 deletions

View File

@@ -2,6 +2,31 @@
Changes since U-Boot 0.2.2:
======================================================================
* Patch by Rick Bronson, 16 Mar 2003:
- Add NAND flash support for reading, writing, and erasing NAND
flash (certain forms of which are called SmartMedia).
- Add support for Atmel AT91RM9200DK ARM920T based development kit.
* Patches by Robert Schwebel, 19 Mar 2003:
- use arm-linux-gcc as default compiler for ARM
- fix i2c fixup code
- fix missing baudrate setting
- added $loadaddr / CFG_LOAD_ADDR support to loadb
- moved "ignoring trailing characters" _before_ u-boot wants to
print out diagnostics messages; removes bogus characters at the
end of transmission
* Patch by John Zhan, 18 Mar 2003:
Add support for SinoVee Microsystems SC8xx boards
* Patch by Rolf Offermanns, 21 Mar 2003:
ported the dnp1110 related changes from the current armboot cvs to
current u-boot cvs. smc91111 does not work. problem marked in
smc91111.c, grep for "FIXME".
* Patch by Brian Auld, 25 Mar 2003:
Add support for STM flash chips on ebony board
* Add PCI support for MPC8250 Boards (PM825 module)
* Patch by Stefan Roese, 25 Mar 2003:
@@ -13,6 +38,12 @@ Changes since U-Boot 0.2.2:
to existing PPC405GP designs.
- Clip udiv to 5 bits on PPC405 (serial.c).
* Extend INCAIP board support:
- add automatic RAM size detection
- add "bdinfo" command
- pass flash address and size to Linux kernel
- switch to 150 MHz clock
* Avoid flicker on the TRAB's VFD by synchronizing the enable with
the HSYNC/VSYNC. Requires new CPLD code (Version 101 for Rev. 100
boards, version 153 for Rev. 200 boards).
@@ -156,6 +187,10 @@ Changes since U-Boot 0.2.2:
* Patch by Stefan Roese, 10 Feb 2003:
Add support for 4MB and 128MB onboard SDRAM (cpu/ppc4xx/sdram.c)
* Add support for MIPS32 4Kc CPUs
* Add support for INCA-IP Board
======================================================================
Changes for U-Boot 0.2.2:
======================================================================

View File

@@ -46,6 +46,10 @@ N: Raphael Bossek
E: raphael.bossek@solutions4linux.de
D: 8xxrom-0.3.0
N: Rick Bronson
E: rick@efn.org
D: Atmel AT91RM9200DK and NAND support
N: David Brown
E: DBrown03@harris.com
D: Extensions to 8xxrom-0.3.0
@@ -262,6 +266,10 @@ N: Christian Vejlbo
E: christian.vejlbo@tellabs.com
D: FADS860T ethernet support
N: John Zhan
E: zhanz@sinovee.com
D: Support for SinoVee Microsystems SC8xx SBC
N: Alex Zuepke
E: azu@sysgo.de
D: Overall improvements on StrongARM, ARM720TDMI; Support for Tuxscreen; initial PCMCIA support for ARM

View File

@@ -32,6 +32,10 @@ Jerry Van Baren <vanbaren_gerald@si.com>
sacsng MPC8260
Rick Bronson <rick@efn.org>
AT91RM9200DK at91rm9200
Oliver Brown <obrown@adventnetworks.com>
gw8260 MPC8260
@@ -197,6 +201,10 @@ Rune Torgersen <runet@innovsys.com>
MPC8266ADS MPC8266
John Zhan <zhanz@sinovee.com>
svm_sc8xx MPC8xx
-------------------------------------------------------------------------
Unknown / orphaned boards:

23
MAKEALL
View File

@@ -25,9 +25,10 @@ LIST_8xx=" \
lwmon MBX MBX860T MHPC \
MVS1 NETVIA NX823 pcu_e \
R360MPI RPXClassic RPXlite RRvision \
SM850 SPD823TS SXNI855T TOP860 \
TQM823L TQM823L_LCD TQM850L TQM855L \
TQM860L TQM860L_FEC TTTech v37 \
SM850 SPD823TS svm_sc8xx SXNI855T \
TOP860 TQM823L TQM823L_LCD TQM850L \
TQM855L TQM860L TQM860L_FEC TTTech \
v37 \
"
#########################################################################
@@ -83,13 +84,13 @@ LIST_ppc="${LIST_8xx} ${LIST_824x} ${LIST_8260} \
## StrongARM Systems
#########################################################################
LIST_SA="lart shannon dnp1110"
LIST_SA="at91rm9200dk dnp1110 lart shannon"
#########################################################################
## ARM7 Systems
#########################################################################
LIST_ARM7="impa7 ep7312"
LIST_ARM7="ep7312 impa7"
#########################################################################
## ARM9 Systems
@@ -101,11 +102,19 @@ LIST_ARM9="smdk2400 smdk2410 trab VCMA9"
## Xscale Systems
#########################################################################
LIST_xscale="lubbock cradle csb226 innokom"
LIST_xscale="cradle csb226 innokom lubbock"
LIST_arm="${LIST_SA} ${LIST_ARM7} ${LIST_ARM9} ${LIST_xscale}"
#########################################################################
## MIPS 4Kc Systems
#########################################################################
LIST_mips4kc="incaip"
LIST_mips="${LIST_mips4kc}"
#----- for now, just run PPC by default -----
[ $# = 0 ] && set $LIST_ppc
@@ -127,7 +136,7 @@ build_target() {
for arg in $@
do
case "$arg" in
8xx|824x|8260|4xx|7xx|74xx|SA|ARM7|ARM9|ppc|arm|xscale)
8xx|824x|8260|4xx|7xx|74xx|SA|ARM7|ARM9|ppc|arm|xscale|mips)
for target in `eval echo '$LIST_'${arg}`
do
build_target ${target}

View File

@@ -57,7 +57,7 @@ ifeq ($(ARCH),ppc)
CROSS_COMPILE = ppc_8xx-
endif
ifeq ($(ARCH),arm)
CROSS_COMPILE = arm_920TDI-
CROSS_COMPILE = arm-linux-
endif
ifeq ($(ARCH),i386)
#CROSS_COMPILE = i386-elf-
@@ -314,6 +314,10 @@ SM850_config : unconfig
SPD823TS_config: unconfig
@./mkconfig $(@:_config=) ppc mpc8xx spd8xx
svm_sc8xx_config: unconfig
@ >include/config.h
@./mkconfig $(@:_config=) ppc mpc8xx svm_sc8xx
SXNI855T_config: unconfig
@./mkconfig $(@:_config=) ppc mpc8xx sixnet
@@ -624,6 +628,9 @@ ELPPC_config: unconfig
## StrongARM Systems
#########################################################################
at91rm9200dk_config : unconfig
@./mkconfig $(@:_config=) arm at91rm9200 at91rm9200dk
lart_config : unconfig
@./mkconfig $(@:_config=) arm sa1100 lart

3
README
View File

@@ -1549,6 +1549,7 @@ configuration.
Low Level (hardware related) configuration options:
---------------------------------------------------
- CFG_CACHELINE_SIZE:
Cache Line Size of the CPU.
@@ -1928,7 +1929,7 @@ Some configuration options can be set using Environment Variables:
ipaddr - IP address; needed for tftpboot command
loadaddr - Default load address for commands like "bootp",
"rarpboot", "tftpboot" or "diskboot"
"rarpboot", "tftpboot", "loadb" or "diskboot"
loads_echo - see CONFIG_LOADS_ECHO

View File

@@ -0,0 +1,47 @@
#
# (C) Copyright 2003
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
LIB = lib$(BOARD).a
OBJS := at91rm9200dk.o flash.o
SOBJS :=
$(LIB): $(OBJS) $(SOBJS)
$(AR) crv $@ $^
clean:
rm -f $(SOBJS) $(OBJS)
distclean: clean
rm -f $(LIB) core *.bak .depend
#########################################################################
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
$(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
-include .depend
#########################################################################

View File

@@ -0,0 +1,105 @@
/*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <AT91RM9200.h>
/* ------------------------------------------------------------------------- */
/*
* Miscelaneous platform dependent initialisations
*/
int board_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
/* memory and cpu-speed are setup before relocation */
/* so we do _nothing_ here */
/* arch number of AT91RM9200DK-Board */
gd->bd->bi_arch_number = 251;
/* adress of boot parameters */
gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
return 0;
}
int dram_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
gd->bd->bi_dram[0].start = PHYS_SDRAM;
gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE;
return 0;
}
/*
* Disk On Chip (NAND) Millenium initialization.
* The NAND lives in the CS2* space
*/
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
extern void
nand_probe(ulong physadr);
#define AT91_SMARTMEDIA_BASE 0x40000000 /* physical address to access memory on NCS3 */
void
nand_init(void)
{
/* Setup Smart Media, fitst enable the address range of CS3 */
*AT91C_EBI_CSA |= AT91C_EBI_CS3A_SMC_SmartMedia;
/* set the bus interface characteristics based on
tDS Data Set up Time 30 - ns
tDH Data Hold Time 20 - ns
tALS ALE Set up Time 20 - ns
16ns at 60 MHz ~= 3 */
/*memory mapping structures */
#define SM_ID_RWH (5 << 28)
#define SM_RWH (1 << 28)
#define SM_RWS (0 << 24)
#define SM_TDF (1 << 8)
#define SM_NWS (3)
AT91C_BASE_SMC2->SMC2_CSR[3] = ( SM_RWH|SM_RWS | AT91C_SMC2_ACSS_STANDARD |
AT91C_SMC2_DBW_8 | SM_TDF |
AT91C_SMC2_WSEN | SM_NWS);
/* enable the SMOE line PC0=SMCE, A21=CLE, A22=ALE */
*AT91C_PIOC_ASR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE | AT91C_PC3_BFBAA_SMWE;
*AT91C_PIOC_PDR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE | AT91C_PC3_BFBAA_SMWE;
/* Configure PC2 as input (signal READY of the SmartMedia) */
*AT91C_PIOC_PER = AT91C_PC2_BFAVD; /* enable direct output enable */
*AT91C_PIOC_ODR = AT91C_PC2_BFAVD; /* disable output */
/* Configure PB1 as input (signal Card Detect of the SmartMedia) */
*AT91C_PIOB_PER = AT91C_PIO_PB1; /* enable direct output enable */
*AT91C_PIOB_ODR = AT91C_PIO_PB1; /* disable output */
if (*AT91C_PIOB_PDSR & AT91C_PIO_PB1)
printf ("No ");
printf ("SmartMedia card inserted\n");
printf("Probing at 0x%.8x\n", AT91_SMARTMEDIA_BASE);
nand_probe(AT91_SMARTMEDIA_BASE);
}
#endif

View File

@@ -0,0 +1,2 @@
TEXT_BASE = 0x21fa0000

397
board/at91rm9200dk/flash.c Normal file
View File

@@ -0,0 +1,397 @@
/*
* (C) Copyright 2002
* Lineo, Inc. <www.lineo.com>
* Bernhard Kuhn <bkuhn@lineo.com>
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Alex Zuepke <azu@sysgo.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
ulong myflush(void);
#define FLASH_BANK_SIZE 0x200000 /* 2 MB */
#define MAIN_SECT_SIZE 0x10000 /* 64 KB */
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
#define CMD_READ_ARRAY 0x00F0
#define CMD_UNLOCK1 0x00AA
#define CMD_UNLOCK2 0x0055
#define CMD_ERASE_SETUP 0x0080
#define CMD_ERASE_CONFIRM 0x0030
#define CMD_PROGRAM 0x00A0
#define CMD_UNLOCK_BYPASS 0x0020
#define MEM_FLASH_ADDR1 (*(volatile u16 *)(CFG_FLASH_BASE + (0x00005555<<1)))
#define MEM_FLASH_ADDR2 (*(volatile u16 *)(CFG_FLASH_BASE + (0x00002AAA<<1)))
#define BIT_ERASE_DONE 0x0080
#define BIT_RDY_MASK 0x0080
#define BIT_PROGRAM_ERROR 0x0020
#define BIT_TIMEOUT 0x80000000 /* our flag */
#define READY 1
#define ERR 2
#define TMO 4
/*-----------------------------------------------------------------------
*/
ulong flash_init(void)
{
int i, j;
ulong size = 0;
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
{
ulong flashbase = 0;
flash_info[i].flash_id =
(ATM_MANUFACT & FLASH_VENDMASK) |
(ATM_ID_BV1614 & 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 = PHYS_FLASH_1;
else
panic("configured to many flash banks!\n");
for (j = 0; j < flash_info[i].sector_count; j++)
{
if (j <= 9)
{
/* 1st to 8th are 8 KB */
if (j <= 7)
{
flash_info[i].start[j] = flashbase + j*0x2000;
}
/* 9th and 10th are both 32 KB */
if ((j == 8) || (j == 9))
{
flash_info[i].start[j] = flashbase + 0x10000 + (j-8)*0x8000;
}
}
else
{
flash_info[i].start[j] = flashbase + (j-8)*MAIN_SECT_SIZE;
}
}
size += flash_info[i].size;
}
flash_protect(FLAG_PROTECT_SET,
CFG_FLASH_BASE,
CFG_ENV_ADDR - 1,
&flash_info[0]);
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
&flash_info[0]);
return size;
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t *info)
{
int i;
switch (info->flash_id & FLASH_VENDMASK)
{
case (ATM_MANUFACT & FLASH_VENDMASK):
printf("Atmel: ");
break;
default:
printf("Unknown Vendor ");
break;
}
switch (info->flash_id & FLASH_TYPEMASK)
{
case (ATM_ID_BV1614 & FLASH_TYPEMASK):
printf("AT49BV1614 (16Mbit)\n");
break;
default:
printf("Unknown Chip Type\n");
goto Done;
break;
}
printf(" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf(" Sector Start Addresses:");
for (i = 0; i < info->sector_count; i++)
{
if ((i % 5) == 0)
{
printf ("\n ");
}
printf (" %08lX%s", info->start[i],
info->protect[i] ? " (RO)" : " ");
}
printf ("\n");
Done:
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
ulong result;
int iflag, cflag, prot, sect;
int rc = ERR_OK;
int chip1;
/* 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) !=
(ATM_MANUFACT & FLASH_VENDMASK)) {
return ERR_UNKNOWN_FLASH_VENDOR;
}
prot = 0;
for (sect=s_first; sect<=s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (prot)
return ERR_PROTECTED;
/*
* Disable interrupts which might cause a timeout
* here. Remember that our exception vectors are
* at address 0 in the flash, and we don't want a
* (ticker) exception to happen while the flash
* chip is in programming mode.
*/
cflag = icache_status();
icache_disable();
iflag = disable_interrupts();
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last && !ctrlc(); sect++)
{
printf("Erasing sector %2d ... ", sect);
/* arm simple, non interrupt dependent timer */
reset_timer_masked();
if (info->protect[sect] == 0)
{ /* not protected */
volatile u16 *addr = (volatile u16 *)(info->start[sect]);
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
*addr = CMD_ERASE_CONFIRM;
/* wait until flash is ready */
chip1 = 0;
do
{
result = *addr;
/* check timeout */
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
{
MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
chip1 = TMO;
break;
}
if (!chip1 && (result & 0xFFFF) & BIT_ERASE_DONE)
chip1 = READY;
} while (!chip1);
MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
if (chip1 == ERR)
{
rc = ERR_PROG_ERROR;
goto outahere;
}
if (chip1 == TMO)
{
rc = ERR_TIMOUT;
goto outahere;
}
printf("ok.\n");
}
else /* it was protected */
{
printf("protected!\n");
}
}
if (ctrlc())
printf("User Interrupt!\n");
outahere:
/* allow flash to settle - wait 10 ms */
udelay_masked(10000);
if (iflag)
enable_interrupts();
if (cflag)
icache_enable();
return rc;
}
/*-----------------------------------------------------------------------
* Copy memory to flash
*/
volatile static int write_word (flash_info_t *info, ulong dest, ulong data)
{
volatile u16 *addr = (volatile u16 *)dest;
ulong result;
int rc = ERR_OK;
int cflag, iflag;
int chip1;
/*
* Check if Flash is (sufficiently) erased
*/
result = *addr;
if ((result & data) != data)
return ERR_NOT_ERASED;
/*
* Disable interrupts which might cause a timeout
* here. Remember that our exception vectors are
* at address 0 in the flash, and we don't want a
* (ticker) exception to happen while the flash
* chip is in programming mode.
*/
cflag = icache_status();
icache_disable();
iflag = disable_interrupts();
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
MEM_FLASH_ADDR1 = CMD_PROGRAM;
*addr = data;
/* arm simple, non interrupt dependent timer */
reset_timer_masked();
/* wait until flash is ready */
chip1 = 0;
do
{
result = *addr;
/* check timeout */
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
{
chip1 = ERR | TMO;
break;
}
if (!chip1 && ((result & 0x80) == (data & 0x80)))
chip1 = READY;
} while (!chip1);
*addr = CMD_READ_ARRAY;
if (chip1 == ERR || *addr != data)
rc = ERR_PROG_ERROR;
if (iflag)
enable_interrupts();
if (cflag)
icache_enable();
return rc;
}
/*-----------------------------------------------------------------------
* Copy memory to flash.
*/
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
ulong wp, data;
int rc;
if(addr & 1) {
printf("unaligned destination not supported\n");
return ERR_ALIGN;
};
if((int)src & 1) {
printf("unaligned source not supported\n");
return ERR_ALIGN;
};
wp = addr;
while (cnt >= 2) {
data = *((volatile u16*)src);
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
}
src += 2;
wp += 2;
cnt -= 2;
}
if(cnt == 1) {
data = (*((volatile u8*)src)) | (*((volatile u8*)(wp+1)) << 8);
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
}
src += 1;
wp += 1;
cnt -= 1;
};
return ERR_OK;
}

View File

@@ -0,0 +1,54 @@
/*
* (C) Copyright 2002
* Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
cpu/at91rm9200/start.o (.text)
*(.text)
}
. = ALIGN(4);
.rodata : { *(.rodata) }
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
.got : { *(.got) }
armboot_end_data = .;
. = ALIGN(4);
.bss : { *(.bss) }
armboot_end = .;
}

View File

@@ -23,7 +23,7 @@
*/
#include <common.h>
#include <SA-1100.h>
/* ------------------------------------------------------------------------- */
@@ -41,8 +41,9 @@ int board_init (void)
/* arch number of DNP1110-Board */
gd->bd->bi_arch_number = 255;
/* adress of boot parameters */
gd->bd->bi_boot_params = 0xc0000100;
/* flash vpp on */
PPDR |= 0x80; /* assumes LCD controller is off */
PPSR |= 0x80;
return 0;
}

View File

@@ -1,7 +1,9 @@
/*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Rolf Offermanns <rof@sysgo.de>
* (C) Copyright 2001
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
*
* (C) Copyright 2001
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -23,81 +25,58 @@
*/
#include <common.h>
ulong myflush(void);
#include <linux/byteorder/swab.h>
#define FLASH_BANK_SIZE 0x800000
#define MAIN_SECT_SIZE 0x20000
#define PARAM_SECT_SIZE 0x4000
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/* puzzle magic for lart
* data_*_flash are def'd in flashasm.S
/* Board support for 1 or 2 flash devices */
#undef FLASH_PORT_WIDTH32
#define FLASH_PORT_WIDTH16
#ifdef FLASH_PORT_WIDTH16
#define FLASH_PORT_WIDTH ushort
#define FLASH_PORT_WIDTHV vu_short
#define SWAP(x) __swab16(x)
#else
#define FLASH_PORT_WIDTH ulong
#define FLASH_PORT_WIDTHV vu_long
#define SWAP(x) __swab32(x)
#endif
#define FPW FLASH_PORT_WIDTH
#define FPWV FLASH_PORT_WIDTHV
#define mb() __asm__ __volatile__ ("" : : : "memory")
/*-----------------------------------------------------------------------
* Functions
*/
extern u32 data_from_flash(u32);
extern u32 data_to_flash(u32);
#define PUZZLE_FROM_FLASH(x) (x)
#define PUZZLE_TO_FLASH(x) (x)
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
static ulong flash_get_size (FPW *addr, flash_info_t *info);
static int write_data (flash_info_t *info, ulong dest, FPW data);
static void flash_get_offsets (ulong base, flash_info_t *info);
void inline spin_wheel(void);
/*-----------------------------------------------------------------------
*/
ulong flash_init(void)
unsigned long flash_init (void)
{
int i, j;
int i;
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_28F160F3B & 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 = PHYS_FLASH_1;
else
panic("configured to many flash banks!\n");
for (j = 0; j < flash_info[i].sector_count; j++)
{
if (j <= 7)
{
flash_info[i].start[j] = flashbase + j * PARAM_SECT_SIZE;
}
else
{
flash_info[i].start[j] = flashbase + (j - 7)*MAIN_SECT_SIZE;
}
}
switch (i)
{
case 0:
flash_get_size((FPW *)PHYS_FLASH_1, &flash_info[i]);
flash_get_offsets(PHYS_FLASH_1, &flash_info[i]);
break;
default:
panic("configured to many flash banks!\n");
break;
}
size += flash_info[i].size;
}
@@ -118,150 +97,138 @@ ulong flash_init(void)
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t *info)
static void flash_get_offsets (ulong base, flash_info_t *info)
{
int i;
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_28F160F3B & FLASH_TYPEMASK):
printf("2x 28F160F3B (16Mbit)\n");
break;
default:
printf("Unknown Chip Type\n");
goto Done;
break;
}
printf(" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf(" Sector Start Addresses:");
for (i = 0; i < info->sector_count; i++)
{
if ((i % 5) == 0)
{
printf ("\n ");
if (info->flash_id == FLASH_UNKNOWN) {
return;
}
printf (" %08lX%s", info->start[i],
info->protect[i] ? " (RO)" : " ");
}
printf ("\n");
Done:
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
for (i = 0; i < info->sector_count; i++) {
info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE);
info->protect[i] = 0;
}
}
}
/*-----------------------------------------------------------------------
*/
int flash_error (ulong code)
void flash_print_info (flash_info_t *info)
{
/* 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 */
int i;
/* sequence is described in Intel 290644-005 document */
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
return;
}
/* check Timeout */
if (code & BIT_TIMEOUT)
{
printf ("Timeout\n");
return ERR_TIMOUT;
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_INTEL: printf ("INTEL "); break;
default: printf ("Unknown Vendor "); break;
}
/* check Busy, SR.7 */
if (~code & BIT_BUSY)
{
printf ("Busy\n");
return ERR_PROG_ERROR;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_28F128J3A:
printf ("28F128J3A\n"); break;
default: printf ("Unknown Chip Type\n"); break;
}
/* check Vpp low, SR.3 */
if (code & BIT_VPP_RANGE_ERROR)
{
printf ("Vpp range error\n");
return ERR_PROG_ERROR;
}
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
/* check Device Protect Error, SR.1 */
if (code & BIT_PROTECT_ERROR)
{
printf ("Device protect error\n");
return ERR_PROG_ERROR;
}
/* check Command Seq Error, SR.4 & SR.5 */
if (code & BIT_SEQUENCE_ERROR)
{
printf ("Command seqence error\n");
return ERR_PROG_ERROR;
}
/* check Block Erase Error, SR.5 */
if (code & BIT_ERASE_ERROR)
{
printf ("Block erase error\n");
return ERR_PROG_ERROR;
}
/* check Program Error, SR.4 */
if (code & BIT_PROGRAM_ERROR)
{
printf ("Program error\n");
return ERR_PROG_ERROR;
}
/* check Block Erase Suspended, SR.6 */
if (code & BIT_ERASE_SUSPEND)
{
printf ("Block erase suspended\n");
return ERR_PROG_ERROR;
}
/* check Program Suspended, SR.2 */
if (code & BIT_PROGRAM_SUSPEND)
{
printf ("Program suspended\n");
return ERR_PROG_ERROR;
}
/* OK, no error */
return ERR_OK;
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");
return;
}
/*
* The following code cannot be run from FLASH!
*/
static ulong flash_get_size (FPW *addr, flash_info_t *info)
{
volatile FPW value;
/* Write auto select command: read Manufacturer ID */
addr[0x5555] = (FPW)0x00AA00AA;
addr[0x2AAA] = (FPW)0x00550055;
addr[0x5555] = (FPW)0x00900090;
mb();
value = addr[0];
switch (value) {
case (FPW)INTEL_MANUFACT:
info->flash_id = FLASH_MAN_INTEL;
break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
addr[0] = (FPW)0x00FF00FF; /* restore read mode */
return (0); /* no or unknown flash */
}
mb();
value = addr[1]; /* device ID */
switch (value) {
case (FPW)INTEL_ID_28F128J3A:
info->flash_id += FLASH_28F128J3A;
info->sector_count = 128;
info->size = 0x02000000;
break; /* => 16 MB */
default:
info->flash_id = FLASH_UNKNOWN;
break;
}
if (info->sector_count > CFG_MAX_FLASH_SECT) {
printf ("** ERROR: sector count %d > max (%d) **\n",
info->sector_count, CFG_MAX_FLASH_SECT);
info->sector_count = CFG_MAX_FLASH_SECT;
}
addr[0] = (FPW)0x00FF00FF; /* restore read mode */
return (info->size);
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
ulong result;
int iflag, cflag, prot, sect;
int rc = ERR_OK;
/* first look for protection bits */
if (info->flash_id == FLASH_UNKNOWN)
return ERR_UNKNOWN_FLASH_TYPE;
int flag, prot, sect;
ulong type, start, last;
int rcode = 0;
if ((s_first < 0) || (s_first > s_last)) {
return ERR_INVAL;
if (info->flash_id == FLASH_UNKNOWN) {
printf ("- missing\n");
} else {
printf ("- no sectors to erase\n");
}
return 1;
}
if ((info->flash_id & FLASH_VENDMASK) !=
(INTEL_MANUFACT & FLASH_VENDMASK)) {
return ERR_UNKNOWN_FLASH_VENDOR;
type = (info->flash_id & FLASH_VENDMASK);
if ((type != FLASH_MAN_INTEL)) {
printf ("Can't erase unknown flash type %08lx - aborted\n",
info->flash_id);
return 1;
}
prot = 0;
@@ -270,152 +237,79 @@ int flash_erase (flash_info_t *info, int s_first, int s_last)
prot++;
}
}
if (prot)
return ERR_PROTECTED;
/*
* Disable interrupts which might cause a timeout
* here. Remember that our exception vectors are
* at address 0 in the flash, and we don't want a
* (ticker) exception to happen while the flash
* chip is in programming mode.
*/
cflag = icache_status();
icache_disable();
iflag = disable_interrupts();
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
} else {
printf ("\n");
}
start = get_timer (0);
last = start;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last && !ctrlc(); sect++)
{
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
FPWV *addr = (FPWV *)(info->start[sect]);
FPW status;
printf("Erasing sector %2d ... ", sect);
/* arm simple, non interrupt dependent timer */
reset_timer_masked();
if (info->protect[sect] == 0)
{ /* not protected */
vu_long *addr = (vu_long *)(info->start[sect]);
*addr = (FPW)0x00500050; /* clear status register */
*addr = (FPW)0x00200020; /* erase setup */
*addr = (FPW)0x00D000D0; /* erase confirm */
*addr = PUZZLE_TO_FLASH(CMD_STATUS_RESET);
*addr = PUZZLE_TO_FLASH(CMD_ERASE_SETUP);
*addr = PUZZLE_TO_FLASH(CMD_ERASE_CONFIRM);
/* wait until flash is ready */
do
{
/* check timeout */
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
{
*addr = PUZZLE_TO_FLASH(CMD_SUSPEND);
result = BIT_TIMEOUT;
break;
}
result = PUZZLE_FROM_FLASH(*addr);
} while (~result & BIT_BUSY);
*addr = PUZZLE_TO_FLASH(CMD_READ_ARRAY);
if ((rc = flash_error(result)) != ERR_OK)
goto outahere;
printf("ok.\n");
}
else /* it was protected */
{
printf("protected!\n");
while (((status = *addr) & (FPW)0x00800080) != (FPW)0x00800080) {
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
*addr = (FPW)0x00B000B0; /* suspend erase */
*addr = (FPW)0x00FF00FF; /* reset to read mode */
rcode = 1;
break;
}
}
if (ctrlc())
printf("User Interrupt!\n");
*addr = (FPW)0x00500050; /* clear status register cmd. */
*addr = (FPW)0x00FF00FF; /* resest to read mode */
outahere:
/* allow flash to settle - wait 10 ms */
udelay_masked(10000);
if (iflag)
enable_interrupts();
if (cflag)
icache_enable();
return rc;
printf (" done\n");
}
}
return rcode;
}
/*-----------------------------------------------------------------------
* 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 cflag, iflag;
/* Check if Flash is (sufficiently) erased
*/
result = PUZZLE_FROM_FLASH(*addr);
if ((result & data) != data)
return ERR_NOT_ERASED;
/*
* Disable interrupts which might cause a timeout
* here. Remember that our exception vectors are
* at address 0 in the flash, and we don't want a
* (ticker) exception to happen while the flash
* chip is in programming mode.
*/
cflag = icache_status();
icache_disable();
iflag = disable_interrupts();
*addr = PUZZLE_TO_FLASH(CMD_STATUS_RESET);
*addr = PUZZLE_TO_FLASH(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 = PUZZLE_TO_FLASH(CMD_SUSPEND);
result = BIT_TIMEOUT;
break;
}
result = PUZZLE_FROM_FLASH(*addr);
} while (~result & BIT_BUSY);
*addr = PUZZLE_TO_FLASH(CMD_READ_ARRAY);
rc = flash_error(result);
if (iflag)
enable_interrupts();
if (cflag)
icache_enable();
return rc;
}
/*-----------------------------------------------------------------------
* Copy memory to flash.
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
* 4 - Flash not identified
*/
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
ulong cp, wp, data;
int l;
int i, rc;
ulong cp, wp;
FPW data;
int count, i, l, rc, port_width;
wp = (addr & ~3); /* get lower word aligned address */
if (info->flash_id == FLASH_UNKNOWN) {
return 4;
}
/* get lower word aligned address */
#ifdef FLASH_PORT_WIDTH16
wp = (addr & ~1);
port_width = 2;
#else
wp = (addr & ~3);
port_width = 4;
#endif
/*
* handle unaligned start bytes
@@ -423,51 +317,109 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
if ((l = addr - wp) != 0) {
data = 0;
for (i=0, cp=wp; i<l; ++i, ++cp) {
data = (data >> 8) | (*(uchar *)cp << 24);
data = (data << 8) | (*(uchar *)cp);
}
for (; i<4 && cnt>0; ++i) {
data = (data >> 8) | (*src++ << 24);
for (; i<port_width && cnt>0; ++i) {
data = (data << 8) | *src++;
--cnt;
++cp;
}
for (; cnt==0 && i<4; ++i, ++cp) {
data = (data >> 8) | (*(uchar *)cp << 24);
for (; cnt==0 && i<port_width; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
if ((rc = write_word(info, wp, data)) != 0) {
if ((rc = write_data(info, wp, SWAP(data))) != 0) {
return (rc);
}
wp += 4;
wp += port_width;
}
/*
* handle word aligned part
*/
while (cnt >= 4) {
data = *((vu_long*)src);
if ((rc = write_word(info, wp, data)) != 0) {
count = 0;
while (cnt >= port_width) {
data = 0;
for (i=0; i<port_width; ++i) {
data = (data << 8) | *src++;
}
if ((rc = write_data(info, wp, SWAP(data))) != 0) {
return (rc);
}
src += 4;
wp += 4;
cnt -= 4;
wp += port_width;
cnt -= port_width;
if (count++ > 0x800)
{
spin_wheel();
count = 0;
}
}
if (cnt == 0) {
return ERR_OK;
return (0);
}
/*
* handle unaligned tail bytes
*/
data = 0;
for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
data = (data >> 8) | (*src++ << 24);
for (i=0, cp=wp; i<port_width && cnt>0; ++i, ++cp) {
data = (data << 8) | *src++;
--cnt;
}
for (; i<4; ++i, ++cp) {
data = (data >> 8) | (*(uchar *)cp << 24);
for (; i<port_width; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
return (write_data(info, wp, SWAP(data)));
}
/*-----------------------------------------------------------------------
* Write a word or halfword to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_data (flash_info_t *info, ulong dest, FPW data)
{
FPWV *addr = (FPWV *)dest;
ulong status;
int flag;
/* Check if Flash is (sufficiently) erased */
if ((*addr & data) != data) {
printf("not erased at %08lx (%x)\n",(ulong)addr,*addr);
return (2);
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
*addr = (FPW)0x00400040; /* write setup */
*addr = data;
/* arm simple, non interrupt dependent timer */
reset_timer_masked();
/* wait while polling the status register */
while (((status = *addr) & (FPW)0x00800080) != (FPW)0x00800080) {
if (get_timer_masked() > CFG_FLASH_WRITE_TOUT) {
*addr = (FPW)0x00FF00FF; /* restore read mode */
return (1);
}
}
return write_word(info, wp, data);
*addr = (FPW)0x00FF00FF; /* restore read mode */
return (0);
}
void inline
spin_wheel(void)
{
static int p=0;
static char w[] = "\\/-";
printf("\010%c", w[p]);
(++p == 3) ? (p = 0) : 0;
}

View File

@@ -25,8 +25,8 @@
#include <config.h>
#include <version.h>
#include "config.h"
#include "version.h"
/* some parameters for the board */
@@ -34,63 +34,103 @@
MEM_BASE: .long 0xa0000000
MEM_START: .long 0xc0000000
#define MDCNFG 0x00
#define MDCAS0 0x04
#define MDCAS1 0x08
#define MDCAS2 0x0c
#define MSC0 0x10
#define MSC1 0x14
#define MECR 0x18
#define MDCNFG 0x00
#define MDCAS00 0x04 /* CAS waveform rotate reg 0 */
#define MDCAS01 0x08 /* CAS waveform rotate reg 1 bank */
#define MDCAS02 0x0C /* CAS waveform rotate reg 2 bank */
#define MDREFR 0x1C /* DRAM refresh control reg */
#define MDCAS20 0x20 /* CAS waveform rotate reg 0 bank */
#define MDCAS21 0x24 /* CAS waveform rotate reg 1 bank */
#define MDCAS22 0x28 /* CAS waveform rotate reg 2 bank */
#define MECR 0x18 /* Expansion memory (PCMCIA) bus configuration register */
#define MSC0 0x10 /* static memory control reg 0 */
#define MSC1 0x14 /* static memory control reg 1 */
#define MSC2 0x2C /* static memory control reg 2 */
#define SMCNFG 0x30 /* SMROM configuration reg */
mdcas0: .long 0xc71c703f
mdcas1: .long 0xffc71c71
mdcas2: .long 0xffffffff
/* mdcnfg: .long 0x0bb2bcbf */
mdcnfg: .long 0x0334b22f @ alt
/* mcs0: .long 0xfff8fff8 */
msc0: .long 0xad8c4888 @ alt
mecr: .long 0x00060006
/* mecr: .long 0x994a994a @ alt */
mdcas00: .long 0x5555557F
mdcas01: .long 0x55555555
mdcas02: .long 0x55555555
mdcas20: .long 0x5555557F
mdcas21: .long 0x55555555
mdcas22: .long 0x55555555
mdcnfg: .long 0x0000B25C
mdrefr: .long 0x007000C1
mecr: .long 0x10841084
msc0: .long 0x00004774
msc1: .long 0x00000000
msc2: .long 0x00000000
smcnfg: .long 0x00000000
/* setting up the memory */
.globl memsetup
memsetup:
ldr r0, MEM_BASE
/* Setup the flash memory */
ldr r1, msc0
str r1, [r0, #MSC0]
ldr r0, MEM_BASE
/* Set up the DRAM */
/* MDCAS0 */
ldr r1, mdcas0
str r1, [r0, #MDCAS0]
/* MDCAS00 */
ldr r1, mdcas00
str r1, [r0, #MDCAS00]
/* MDCAS1 */
ldr r1, mdcas1
str r1, [r0, #MDCAS1]
/* MDCAS01 */
ldr r1, mdcas01
str r1, [r0, #MDCAS01]
/* MDCAS2 */
ldr r1, mdcas2
str r1, [r0, #MDCAS2]
/* MDCAS02 */
ldr r1, mdcas02
str r1, [r0, #MDCAS02]
/* MDCNFG */
ldr r1, mdcnfg
str r1, [r0, #MDCNFG]
/* MDCAS20 */
ldr r1, mdcas20
str r1, [r0, #MDCAS20]
/* MDCAS21 */
ldr r1, mdcas21
str r1, [r0, #MDCAS21]
/* MDCAS22 */
ldr r1, mdcas22
str r1, [r0, #MDCAS22]
/* MDREFR */
ldr r1, mdrefr
str r1, [r0, #MDREFR]
/* Set up PCMCIA space */
ldr r1, mecr
str r1, [r0, #MECR]
/* Load something to activate bank */
ldr r1, MEM_START
/* Setup the flash memory and other */
ldr r1, msc0
str r1, [r0, #MSC0]
ldr r1, msc1
str r1, [r0, #MSC1]
ldr r1, msc2
str r1, [r0, #MSC2]
ldr r1, smcnfg
str r1, [r0, #SMCNFG]
/* MDCNFG */
ldr r1, mdcnfg
bic r1, r1, #0x00000001
str r1, [r0, #MDCNFG]
/* Load something to activate bank */
ldr r2, MEM_START
.rept 8
ldr r0, [r1]
ldr r1, [r2]
.endr
/* MDCNFG */
ldr r1, mdcnfg
orr r1, r1, #0x00000001
str r1, [r0, #MDCNFG]
/* everything is fine now */
mov pc, lr

View File

@@ -327,6 +327,9 @@ void flash_print_info (flash_info_t *info)
case (FLASH_WORD_SIZE)SST_MANUFACT:
info->flash_id = FLASH_MAN_SST;
break;
case (FLASH_WORD_SIZE)STM_MANUFACT:
info->flash_id = FLASH_MAN_STM;
break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
@@ -349,6 +352,11 @@ void flash_print_info (flash_info_t *info)
info->sector_count = 32;
info->size = 0x00200000;
break; /* => 2 MB */
case (FLASH_WORD_SIZE)STM_ID_F040B:
info->flash_id += FLASH_AM040;
info->sector_count = 8;
info->size = 0x0080000; /* => 512 ko */
break;
case (FLASH_WORD_SIZE)AMD_ID_F040B:
info->flash_id += FLASH_AM040;
info->sector_count = 8;

View File

@@ -103,7 +103,6 @@ int misc_init_r (void)
int status;
int index;
int i;
struct pci_config_regs *pci_regs;
unsigned int *ptr;
unsigned int *magic;

32
board/esd/pci405/pci405.h Normal file
View File

@@ -0,0 +1,32 @@
/*
* (C) Copyright 2003
* Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef _PCI405_H_
#define _PCI405_H_
#define PCI_REGS_LEN 0x100
#define PCI_REGS_ADDR ((unsigned long)0x01000000 - PCI_REGS_LEN)
#define PCI_RECONFIG_MAGIC 0x07081967
#endif /* _PCI405_H_ */

41
board/incaip/Makefile Normal file
View File

@@ -0,0 +1,41 @@
#
# (C) Copyright 2003
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
LIB = lib$(BOARD).a
OBJS = $(BOARD).o flash.o
SOBJS = memsetup.o
$(LIB): .depend $(OBJS) $(SOBJS)
$(AR) crv $@ $^
#########################################################################
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
sinclude .depend
#########################################################################

32
board/incaip/config.mk Normal file
View File

@@ -0,0 +1,32 @@
#
# (C) Copyright 2003
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
#
# INCA-IP board with MIPS 4Kc CPU core
#
# ROM version
TEXT_BASE = 0xB0000000
# RAM version
#TEXT_BASE = 0x80100000

671
board/incaip/flash.c Normal file
View File

@@ -0,0 +1,671 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/inca-ip.h>
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/* NOTE - CONFIG_FLASH_16BIT means the CPU interface is 16-bit, it
* has nothing to do with the flash chip being 8-bit or 16-bit.
*/
#ifdef CONFIG_FLASH_16BIT
typedef unsigned short FLASH_PORT_WIDTH;
typedef volatile unsigned short FLASH_PORT_WIDTHV;
#define FLASH_ID_MASK 0xFFFF
#else
typedef unsigned long FLASH_PORT_WIDTH;
typedef volatile unsigned long FLASH_PORT_WIDTHV;
#define FLASH_ID_MASK 0xFFFFFFFF
#endif
#define FPW FLASH_PORT_WIDTH
#define FPWV FLASH_PORT_WIDTHV
#define ORMASK(size) ((-size) & OR_AM_MSK)
#if 0
#define FLASH_CYCLE1 0x0555
#define FLASH_CYCLE2 0x02aa
#else
#define FLASH_CYCLE1 0x0554
#define FLASH_CYCLE2 0x02ab
#endif
/*-----------------------------------------------------------------------
* Functions
*/
static ulong flash_get_size(FPWV *addr, flash_info_t *info);
static void flash_reset(flash_info_t *info);
static int write_word_intel(flash_info_t *info, FPWV *dest, FPW data);
static int write_word_amd(flash_info_t *info, FPWV *dest, FPW data);
static void flash_get_offsets(ulong base, flash_info_t *info);
static flash_info_t *flash_get_info(ulong base);
/*-----------------------------------------------------------------------
* flash_init()
*
* sets up flash_info and returns size of FLASH (bytes)
*/
unsigned long flash_init (void)
{
unsigned long size = 0;
int i;
/* Init: no FLASHes known */
for (i=0; i < CFG_MAX_FLASH_BANKS; ++i) {
ulong flashbase = (i == 0) ? PHYS_FLASH_1 : PHYS_FLASH_2;
ulong * buscon = (ulong *)
((i == 0) ? INCA_IP_EBU_EBU_BUSCON0 : INCA_IP_EBU_EBU_BUSCON2);
/* Disable write protection */
*buscon &= ~INCA_IP_EBU_EBU_BUSCON1_WRDIS;
#if 1
memset(&flash_info[i], 0, sizeof(flash_info_t));
#endif
flash_info[i].size =
flash_get_size((FPW *)flashbase, &flash_info[i]);
if (flash_info[i].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx\n",
i, flash_info[i].size);
}
size += flash_info[i].size;
}
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
/* monitor protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
flash_get_info(CFG_MONITOR_BASE));
#endif
#ifdef CFG_ENV_IS_IN_FLASH
/* ENV protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR+CFG_ENV_SIZE-1,
flash_get_info(CFG_ENV_ADDR));
#endif
return size;
}
/*-----------------------------------------------------------------------
*/
static void flash_reset(flash_info_t *info)
{
FPWV *base = (FPWV *)(info->start[0]);
/* Put FLASH back in read mode */
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
*base = (FPW)0x00FF00FF; /* Intel Read Mode */
else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD)
*base = (FPW)0x00F000F0; /* AMD Read Mode */
}
/*-----------------------------------------------------------------------
*/
static void flash_get_offsets (ulong base, flash_info_t *info)
{
int i;
/* set up sector start address table */
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL
&& (info->flash_id & FLASH_BTYPE)) {
int bootsect_size; /* number of bytes/boot sector */
int sect_size; /* number of bytes/regular sector */
bootsect_size = 0x00002000 * (sizeof(FPW)/2);
sect_size = 0x00010000 * (sizeof(FPW)/2);
/* set sector offsets for bottom boot block type */
for (i = 0; i < 8; ++i) {
info->start[i] = base + (i * bootsect_size);
}
for (i = 8; i < info->sector_count; i++) {
info->start[i] = base + ((i - 7) * sect_size);
}
}
else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD
&& (info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U) {
int sect_size; /* number of bytes/sector */
sect_size = 0x00010000 * (sizeof(FPW)/2);
/* set up sector start address table (uniform sector type) */
for( i = 0; i < info->sector_count; i++ )
info->start[i] = base + (i * sect_size);
}
}
/*-----------------------------------------------------------------------
*/
static flash_info_t *flash_get_info(ulong base)
{
int i;
flash_info_t * info;
for (i = 0; i < CFG_MAX_FLASH_BANKS; i ++) {
info = & flash_info[i];
if (info->start[0] <= base && base < info->start[0] + info->size)
break;
}
return i == CFG_MAX_FLASH_BANKS ? 0 : info;
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t *info)
{
int i;
uchar *boottype;
uchar *bootletter;
uchar *fmt;
uchar botbootletter[] = "B";
uchar topbootletter[] = "T";
uchar botboottype[] = "bottom boot sector";
uchar topboottype[] = "top boot sector";
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
return;
}
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_AMD: printf ("AMD "); break;
case FLASH_MAN_BM: printf ("BRIGHT MICRO "); break;
case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
case FLASH_MAN_SST: printf ("SST "); break;
case FLASH_MAN_STM: printf ("STM "); break;
case FLASH_MAN_INTEL: printf ("INTEL "); break;
default: printf ("Unknown Vendor "); break;
}
/* check for top or bottom boot, if it applies */
if (info->flash_id & FLASH_BTYPE) {
boottype = botboottype;
bootletter = botbootletter;
}
else {
boottype = topboottype;
bootletter = topbootletter;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_AM640U:
fmt = "29LV641D (64 Mbit, uniform sectors)\n";
break;
case FLASH_28F800C3B:
case FLASH_28F800C3T:
fmt = "28F800C3%s (8 Mbit, %s)\n";
break;
case FLASH_INTEL800B:
case FLASH_INTEL800T:
fmt = "28F800B3%s (8 Mbit, %s)\n";
break;
case FLASH_28F160C3B:
case FLASH_28F160C3T:
fmt = "28F160C3%s (16 Mbit, %s)\n";
break;
case FLASH_INTEL160B:
case FLASH_INTEL160T:
fmt = "28F160B3%s (16 Mbit, %s)\n";
break;
case FLASH_28F320C3B:
case FLASH_28F320C3T:
fmt = "28F320C3%s (32 Mbit, %s)\n";
break;
case FLASH_INTEL320B:
case FLASH_INTEL320T:
fmt = "28F320B3%s (32 Mbit, %s)\n";
break;
case FLASH_28F640C3B:
case FLASH_28F640C3T:
fmt = "28F640C3%s (64 Mbit, %s)\n";
break;
case FLASH_INTEL640B:
case FLASH_INTEL640T:
fmt = "28F640B3%s (64 Mbit, %s)\n";
break;
default:
fmt = "Unknown Chip Type\n";
break;
}
printf (fmt, bootletter, boottype);
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20,
info->sector_count);
printf (" Sector Start Addresses:");
for (i=0; i<info->sector_count; ++i) {
if ((i % 5) == 0) {
printf ("\n ");
}
printf (" %08lX%s", info->start[i],
info->protect[i] ? " (RO)" : " ");
}
printf ("\n");
}
/*-----------------------------------------------------------------------
*/
/*
* The following code cannot be run from FLASH!
*/
ulong flash_get_size (FPWV *addr, flash_info_t *info)
{
/* Write auto select command: read Manufacturer ID */
/* Write auto select command sequence and test FLASH answer */
addr[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* for AMD, Intel ignores this */
addr[FLASH_CYCLE2] = (FPW)0x00550055; /* for AMD, Intel ignores this */
addr[FLASH_CYCLE1] = (FPW)0x00900090; /* selects Intel or AMD */
/* The manufacturer codes are only 1 byte, so just use 1 byte.
* This works for any bus width and any FLASH device width.
*/
switch (addr[1] & 0xff) {
case (uchar)AMD_MANUFACT:
info->flash_id = FLASH_MAN_AMD;
break;
case (uchar)INTEL_MANUFACT:
info->flash_id = FLASH_MAN_INTEL;
break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
break;
}
/* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
if (info->flash_id != FLASH_UNKNOWN) switch (addr[0]) {
case (FPW)AMD_ID_LV640U: /* 29LV640 and 29LV641 have same ID */
info->flash_id += FLASH_AM640U;
info->sector_count = 128;
info->size = 0x00800000 * (sizeof(FPW)/2);
break; /* => 8 or 16 MB */
case (FPW)INTEL_ID_28F800C3B:
info->flash_id += FLASH_28F800C3B;
info->sector_count = 23;
info->size = 0x00100000 * (sizeof(FPW)/2);
break; /* => 1 or 2 MB */
case (FPW)INTEL_ID_28F800B3B:
info->flash_id += FLASH_INTEL800B;
info->sector_count = 23;
info->size = 0x00100000 * (sizeof(FPW)/2);
break; /* => 1 or 2 MB */
case (FPW)INTEL_ID_28F160C3B:
info->flash_id += FLASH_28F160C3B;
info->sector_count = 39;
info->size = 0x00200000 * (sizeof(FPW)/2);
break; /* => 2 or 4 MB */
case (FPW)INTEL_ID_28F160B3B:
info->flash_id += FLASH_INTEL160B;
info->sector_count = 39;
info->size = 0x00200000 * (sizeof(FPW)/2);
break; /* => 2 or 4 MB */
case (FPW)INTEL_ID_28F320C3B:
info->flash_id += FLASH_28F320C3B;
info->sector_count = 71;
info->size = 0x00400000 * (sizeof(FPW)/2);
break; /* => 4 or 8 MB */
case (FPW)INTEL_ID_28F320B3B:
info->flash_id += FLASH_INTEL320B;
info->sector_count = 71;
info->size = 0x00400000 * (sizeof(FPW)/2);
break; /* => 4 or 8 MB */
case (FPW)INTEL_ID_28F640C3B:
info->flash_id += FLASH_28F640C3B;
info->sector_count = 135;
info->size = 0x00800000 * (sizeof(FPW)/2);
break; /* => 8 or 16 MB */
case (FPW)INTEL_ID_28F640B3B:
info->flash_id += FLASH_INTEL640B;
info->sector_count = 135;
info->size = 0x00800000 * (sizeof(FPW)/2);
break; /* => 8 or 16 MB */
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
return (0); /* => no or unknown flash */
}
flash_get_offsets((ulong)addr, info);
/* Put FLASH back in read mode */
flash_reset(info);
return (info->size);
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
FPWV *addr;
int flag, prot, sect;
int intel = (info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL;
ulong start, now, last;
int rcode = 0;
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
printf ("- missing\n");
} else {
printf ("- no sectors to erase\n");
}
return 1;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_INTEL800B:
case FLASH_INTEL160B:
case FLASH_INTEL320B:
case FLASH_INTEL640B:
case FLASH_28F800C3B:
case FLASH_28F160C3B:
case FLASH_28F320C3B:
case FLASH_28F640C3B:
case FLASH_AM640U:
break;
case FLASH_UNKNOWN:
default:
printf ("Can't erase unknown flash type %08lx - aborted\n",
info->flash_id);
return 1;
}
prot = 0;
for (sect=s_first; sect<=s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
} else {
printf ("\n");
}
last = get_timer(0);
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last && rcode == 0; sect++) {
if (info->protect[sect] != 0) /* protected, skip it */
continue;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
addr = (FPWV *)(info->start[sect]);
if (intel) {
*addr = (FPW)0x00500050; /* clear status register */
*addr = (FPW)0x00200020; /* erase setup */
*addr = (FPW)0x00D000D0; /* erase confirm */
}
else {
/* must be AMD style if not Intel */
FPWV *base; /* first address in bank */
base = (FPWV *)(info->start[0]);
base[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* unlock */
base[FLASH_CYCLE2] = (FPW)0x00550055; /* unlock */
base[FLASH_CYCLE1] = (FPW)0x00800080; /* erase mode */
base[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* unlock */
base[FLASH_CYCLE2] = (FPW)0x00550055; /* unlock */
*addr = (FPW)0x00300030; /* erase sector */
}
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
start = get_timer(0);
/* wait at least 50us for AMD, 80us for Intel.
* Let's wait 1 ms.
*/
udelay (1000);
while ((*addr & (FPW)0x00800080) != (FPW)0x00800080) {
if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
if (intel) {
/* suspend erase */
*addr = (FPW)0x00B000B0;
}
flash_reset(info); /* reset to read mode */
rcode = 1; /* failed */
break;
}
/* show that we're waiting */
if ((get_timer(last)) > CFG_HZ) {/* every second */
putc ('.');
last = get_timer(0);
}
}
/* show that we're waiting */
if ((get_timer(last)) > CFG_HZ) { /* every second */
putc ('.');
last = get_timer(0);
}
flash_reset(info); /* reset to read mode */
}
printf (" done\n");
return rcode;
}
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
FPW data = 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */
int bytes; /* number of bytes to program in current word */
int left; /* number of bytes left to program */
int i, res;
for (left = cnt, res = 0;
left > 0 && res == 0;
addr += sizeof(data), left -= sizeof(data) - bytes) {
bytes = addr & (sizeof(data) - 1);
addr &= ~(sizeof(data) - 1);
/* combine source and destination data so can program
* an entire word of 16 or 32 bits
*/
for (i = 0; i < sizeof(data); i++) {
data <<= 8;
if (i < bytes || i - bytes >= left )
data += *((uchar *)addr + i);
else
data += *src++;
}
/* write one word to the flash */
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_AMD:
res = write_word_amd(info, (FPWV *)addr, data);
break;
case FLASH_MAN_INTEL:
res = write_word_intel(info, (FPWV *)addr, data);
break;
default:
/* unknown flash type, error! */
printf ("missing or unknown FLASH type\n");
res = 1; /* not really a timeout, but gives error */
break;
}
}
return (res);
}
/*-----------------------------------------------------------------------
* Write a word to Flash for AMD FLASH
* A word is 16 or 32 bits, whichever the bus width of the flash bank
* (not an individual chip) is.
*
* returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_word_amd (flash_info_t *info, FPWV *dest, FPW data)
{
ulong start;
int flag;
int res = 0; /* result, assume success */
FPWV *base; /* first address in flash bank */
/* Check if Flash is (sufficiently) erased */
if ((*dest & data) != data) {
return (2);
}
base = (FPWV *)(info->start[0]);
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
base[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* unlock */
base[FLASH_CYCLE2] = (FPW)0x00550055; /* unlock */
base[FLASH_CYCLE1] = (FPW)0x00A000A0; /* selects program mode */
*dest = data; /* start programming the data */
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
start = get_timer (0);
/* data polling for D7 */
while (res == 0 && (*dest & (FPW)0x00800080) != (data & (FPW)0x00800080)) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
*dest = (FPW)0x00F000F0; /* reset bank */
res = 1;
}
}
return (res);
}
/*-----------------------------------------------------------------------
* Write a word to Flash for Intel FLASH
* A word is 16 or 32 bits, whichever the bus width of the flash bank
* (not an individual chip) is.
*
* returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_word_intel (flash_info_t *info, FPWV *dest, FPW data)
{
ulong start;
int flag;
int res = 0; /* result, assume success */
/* Check if Flash is (sufficiently) erased */
if ((*dest & data) != data) {
return (2);
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
*dest = (FPW)0x00500050; /* clear status register */
*dest = (FPW)0x00FF00FF; /* make sure in read mode */
*dest = (FPW)0x00400040; /* program setup */
*dest = data; /* start programming the data */
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
start = get_timer (0);
while (res == 0 && (*dest & (FPW)0x00800080) != (FPW)0x00800080) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
*dest = (FPW)0x00B000B0; /* Suspend program */
res = 1;
}
}
if (res == 0 && (*dest & (FPW)0x00100010))
res = 1; /* write failed, time out error is close enough */
*dest = (FPW)0x00500050; /* clear status register */
*dest = (FPW)0x00FF00FF; /* make sure in read mode */
return (res);
}

129
board/incaip/incaip.c Normal file
View File

@@ -0,0 +1,129 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <command.h>
#include <asm/addrspace.h>
#include <asm/inca-ip.h>
static ulong max_sdram_size(void)
{
/* The only supported SDRAM data width is 16bit.
*/
#define CFG_DW 2
/* The only supported number of SDRAM banks is 4.
*/
#define CFG_NB 4
ulong cfgpb0 = *INCA_IP_SDRAM_MC_CFGPB0;
int cols = cfgpb0 & 0xF;
int rows = (cfgpb0 & 0xF0) >> 4;
ulong size = (1 << (rows + cols)) * CFG_DW * CFG_NB;
return size;
}
/*
* Check memory range for valid RAM. A simple memory test determines
* the actually available RAM size between addresses `base' and
* `base + maxsize'. Some (not all) hardware errors are detected:
* - short between address lines
* - short between data lines
*/
static long int dram_size(long int *base, long int maxsize)
{
volatile long int *addr;
ulong cnt, val;
ulong save[32]; /* to make test non-destructive */
unsigned char i = 0;
for (cnt = (maxsize / sizeof (long)) >> 1; cnt > 0; cnt >>= 1) {
addr = base + cnt; /* pointer arith! */
save[i++] = *addr;
*addr = ~cnt;
}
/* write 0 to base address */
addr = base;
save[i] = *addr;
*addr = 0;
/* check at base address */
if ((val = *addr) != 0) {
*addr = save[i];
return (0);
}
for (cnt = 1; cnt < maxsize / sizeof (long); cnt <<= 1) {
addr = base + cnt; /* pointer arith! */
val = *addr;
*addr = save[--i];
if (val != (~cnt)) {
return (cnt * sizeof (long));
}
}
return (maxsize);
}
long int initdram(int board_type)
{
int rows, cols, best_val = *INCA_IP_SDRAM_MC_CFGPB0;
ulong size, max_size = 0;
ulong our_address;
asm volatile ("move %0, $25" : "=r" (our_address) :);
/* Can't probe for RAM size unless we are running from Flash.
*/
if (PHYSADDR(our_address) < PHYSADDR(PHYS_FLASH_1))
{
return max_sdram_size();
}
for (cols = 0x8; cols <= 0xC; cols++)
{
for (rows = 0xB; rows <= 0xD; rows++)
{
*INCA_IP_SDRAM_MC_CFGPB0 = (0x14 << 8) |
(rows << 4) | cols;
size = dram_size((ulong *)CFG_SDRAM_BASE,
max_sdram_size());
if (size > max_size)
{
best_val = *INCA_IP_SDRAM_MC_CFGPB0;
max_size = size;
}
}
}
*INCA_IP_SDRAM_MC_CFGPB0 = best_val;
return max_size;
}

151
board/incaip/memsetup.S Normal file
View File

@@ -0,0 +1,151 @@
/*
* Memory sub-system initialization code for INCA-IP development board.
*
* Copyright (c) 2003 Wolfgang Denk <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 <config.h>
#include <version.h>
#include <asm/regdef.h>
#define EBU_MODUL_BASE 0xB8000200
#define EBU_CLC(value) 0x0000(value)
#define EBU_CON(value) 0x0010(value)
#define EBU_ADDSEL0(value) 0x0020(value)
#define EBU_ADDSEL1(value) 0x0024(value)
#define EBU_ADDSEL2(value) 0x0028(value)
#define EBU_BUSCON0(value) 0x0060(value)
#define EBU_BUSCON1(value) 0x0064(value)
#define EBU_BUSCON2(value) 0x0068(value)
#define MC_MODUL_BASE 0xBF800000
#define MC_ERRCAUSE(value) 0x0100(value)
#define MC_ERRADDR(value) 0x0108(value)
#define MC_IOGP(value) 0x0800(value)
#define MC_SELFRFSH(value) 0x0A00(value)
#define MC_CTRLENA(value) 0x1000(value)
#define MC_MRSCODE(value) 0x1008(value)
#define MC_CFGDW(value) 0x1010(value)
#define MC_CFGPB0(value) 0x1018(value)
#define MC_LATENCY(value) 0x1038(value)
#define MC_TREFRESH(value) 0x1040(value)
#if CPU_CLOCK_RATE==150000000 /* 150 MHz clock for the MIPS core */
#define CGU_MODUL_BASE 0xBF107000
#define CGU_PLL1CR(value) 0x0008(value)
#define CGU_DIVCR(value) 0x0010(value)
#define CGU_MUXCR(value) 0x0014(value)
#define CGU_PLL1SR(value) 0x000C(value)
#endif
.globl memsetup
memsetup:
/* EBU Initialization for the Flash CS0 and CS2.
*/
li t0, EBU_MODUL_BASE
li t1, 0xA0000041
sw t1, EBU_ADDSEL0(t0)
#if CPU_CLOCK_RATE==150000000 /* 150 MHz clock for the MIPS core */
li t1, 0xE841417E
sw t1, EBU_BUSCON0(t0) /* value set up by magic flash word */
sw t1, EBU_BUSCON2(t0)
#else /* 100 MHz */
lw t1, EBU_BUSCON0(t0) /* value set up by magic flash word */
sw t1, EBU_BUSCON2(t0)
#endif
li t1, 0xA0800041
sw t1, EBU_ADDSEL2(t0)
/* Need to initialize CS1 too, so as to to prevent overlapping with
* Flash bank 1.
*/
li t1, 0xBE0000F1
sw t1, EBU_ADDSEL1(t0)
#if CPU_CLOCK_RATE==150000000 /* 150 MHz clock for the MIPS core */
li t1, 0x684143FD
#else /* 100 MHz */
li t1, 0x684142BD
#endif
sw t1, EBU_BUSCON1(t0)
#if CPU_CLOCK_RATE==150000000 /* 150 MHz clock for the MIPS core */
li t0, CGU_MODUL_BASE
li t1, 0x80000017
sw t1, CGU_DIVCR(t0)
li t1, 0xC00B0001
sw t1, CGU_PLL1CR(t0)
lui t2, 0x8000
b1:
lw t1, CGU_PLL1SR(t0)
and t1, t1, t2
beq t1, zero, b1
li t1, 0x80000001
sw t1, CGU_MUXCR(t0)
#endif
/* SDRAM Initialization.
*/
li t0, MC_MODUL_BASE
/* Clear Error log registers */
sw zero, MC_ERRCAUSE(t0)
sw zero, MC_ERRADDR(t0)
/* Set clock ratio to 1:1 */
li t1, 0x03 /* clkrat=1:1, rddel=3 */
sw t1, MC_IOGP(t0)
/* Clear Power-down registers */
sw zero, MC_SELFRFSH(t0)
/* Set CAS Latency */
li t1, 0x00000020 /* CL = 2 */
sw t1, MC_MRSCODE(t0)
/* Set word width to 16 bit */
li t1, 0x2
sw t1, MC_CFGDW(t0)
/* Set CS0 to SDRAM parameters */
li t1, 0x000014C9
sw t1, MC_CFGPB0(t0)
/* Set SDRAM latency parameters */
li t1, 0x00026325 /* BC PC100 */
sw t1, MC_LATENCY(t0)
/* Set SDRAM refresh rate */
li t1, 0x00000C30 /* 4K/64ms @ 100MHz */
sw t1, MC_TREFRESH(t0)
/* Finally enable the controller */
li t1, 1
sw t1, MC_CTRLENA(t0)
j ra
nop

64
board/incaip/u-boot.lds Normal file
View File

@@ -0,0 +1,64 @@
/*
* (C) Copyright 2003
* Wolfgang Denk Engineering, <wd@denx.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-bigmips")
*/
OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradbigmips")
OUTPUT_ARCH(mips)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
*(.text)
}
. = ALIGN(4);
.rodata : { *(.rodata) }
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
.sdata : { *(.sdata) }
_gp = ALIGN(16);
__got_start = .;
.got : { *(.got) }
__got_end = .;
.sdata : { *(.sdata) }
uboot_end_data = .;
num_got_entries = (__got_end - __got_start) >> 2;
. = ALIGN(4);
.sbss : { *(.sbss) }
.bss : { *(.bss) }
uboot_end = .;
}

View File

@@ -9,6 +9,9 @@
* (C) Copyright 2002
* Robert Schwebel, Pengutronix, <r.schwebel@pengutronix.de>
*
* (C) Copyright 2002
* Kai-Uwe Bloem, GDS, <kai-uwe.bloem@auerswald.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*

View File

@@ -39,20 +39,28 @@
* The Innokom board has GPIO70 connected to SCLK which can be toggled
* until all chips think that their current cycles are finished.
*/
void i2c_init_board(void)
int i2c_init_board(void)
{
int i;
int i, icr;
/* set gpio pin to output */
GPDR(70) |= GPIO_bit(70);
for (i = 0; i < 11; i++) {
/* disable I2C controller first, otherwhise it thinks we want to */
/* talk to the slave port... */
icr = ICR; ICR &= ~(ICR_SCLE | ICR_IUE);
/* set gpio pin low _before_ we change direction to output */
GPCR(70) = GPIO_bit(70);
/* now toggle between output=low and high-impedance */
for (i = 0; i < 20; i++) {
GPDR(70) |= GPIO_bit(70); /* output */
udelay(10);
GPSR(70) = GPIO_bit(70);
GPDR(70) &= ~GPIO_bit(70); /* input */
udelay(10);
}
/* set gpio pin to input */
GPDR(70) &= ~GPIO_bit(70);
ICR = icr;
return 0;
}
@@ -98,6 +106,9 @@ int board_init (void)
/* adress of boot parameters */
gd->bd->bi_boot_params = 0xa0000100;
/* baud rate */
gd->bd->bi_baudrate = CONFIG_BAUDRATE;
return 0;
}

View File

@@ -351,6 +351,7 @@ void doc_init (void)
}
#endif
#ifdef CONFIG_PCI
struct pci_controller hose;
extern void pci_mpc8250_init(struct pci_controller *);
@@ -359,3 +360,4 @@ void pci_init_board(void)
{
pci_mpc8250_init(&hose);
}
#endif

40
board/svm_sc8xx/Makefile Normal file
View File

@@ -0,0 +1,40 @@
#
# (C) Copyright 2000
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
LIB = lib$(BOARD).a
OBJS = $(BOARD).o flash.o
$(LIB): .depend $(OBJS)
$(AR) crv $@ $^
#########################################################################
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
sinclude .depend
#########################################################################

24
board/svm_sc8xx/config.mk Normal file
View File

@@ -0,0 +1,24 @@
#
# (C) Copyright 2000
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
TEXT_BASE = 0x40000000

801
board/svm_sc8xx/flash.c Normal file
View File

@@ -0,0 +1,801 @@
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <mpc8xx.h>
#ifndef CFG_ENV_ADDR
#define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
#endif
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/*-----------------------------------------------------------------------
* Functions
*/
static int write_word (flash_info_t *info, ulong dest, ulong data);
#if 0
static ulong flash_get_size (vu_long *addr, flash_info_t *info);
static void flash_get_offsets (ulong base, flash_info_t *info);
#endif
#ifdef CONFIG_BOOT_8B
static int my_in_8( unsigned char *addr);
static void my_out_8( unsigned char *addr, int val);
#endif
#ifdef CONFIG_BOOT_16B
static int my_in_be16( unsigned short *addr);
static void my_out_be16( unsigned short *addr, int val);
#endif
#ifdef CONFIG_BOOT_32B
static unsigned my_in_be32( unsigned *addr);
static void my_out_be32( unsigned *addr, int val);
#endif
/*-----------------------------------------------------------------------
*/
unsigned long flash_init (void)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile memctl8xx_t *memctl = &immap->im_memctl;
unsigned long size_b0, size_b1;
int i;
size_b0=0;
size_b1=0;
/* Init: no FLASHes known */
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
flash_info[i].flash_id = FLASH_UNKNOWN;
}
#ifdef CFG_DOC_BASE
#ifndef CONFIG_FEL8xx_AT
memctl->memc_or5 = (0xffff8000 | CFG_OR_TIMING_DOC ); /* 32k bytes */
memctl->memc_br5 = CFG_DOC_BASE | 0x401;
#else
memctl->memc_or3 = (0xffff8000 | CFG_OR_TIMING_DOC ); /* 32k bytes */
memctl->memc_br3 = CFG_DOC_BASE | 0x401;
#endif
#endif
#if defined( CONFIG_BOOT_8B)
// memctl->memc_or0 = 0xfff80ff4; /* 4MB bytes */
// memctl->memc_br0 = 0x40000401;
size_b0 = 0x80000; /* 512 K */
flash_info[0].flash_id = FLASH_MAN_AMD | FLASH_AM040;
flash_info[0].sector_count = 8;
flash_info[0].size = 0x00080000;
/* set up sector start address table */
for (i = 0; i < flash_info[0].sector_count; i++)
flash_info[0].start[i] = 0x40000000 + (i * 0x10000);
/* protect all sectors */
for (i = 0; i < flash_info[0].sector_count; i++)
flash_info[0].protect[i] = 0x1;
#elif defined (CONFIG_BOOT_16B)
// memctl->memc_or0 = 0xfff80ff4; /* 4MB bytes */
// memctl->memc_br0 = 0x40000401;
size_b0 = 0x400000; /* 4MB , assume AMD29LV320B */
flash_info[0].flash_id = FLASH_MAN_AMD | FLASH_AM320B;
flash_info[0].sector_count = 67;
flash_info[0].size = 0x00400000;
/* set up sector start address table */
flash_info[0].start[0] = 0x40000000 ;
flash_info[0].start[1] = 0x40000000 + 0x4000;
flash_info[0].start[2] = 0x40000000 + 0x6000;
flash_info[0].start[3] = 0x40000000 + 0x8000;
for (i = 4; i < flash_info[0].sector_count; i++)
flash_info[0].start[i] = 0x40000000 + 0x10000 + ((i-4) * 0x10000);
/* protect all sectors */
for (i = 0; i < flash_info[0].sector_count; i++)
flash_info[0].protect[i] = 0x1;
#endif
#ifdef CONFIG_BOOT_32B
/* Static FLASH Bank configuration here - FIXME XXX */
size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
size_b0, size_b0<<20);
}
size_b1 = flash_get_size((vu_long *)FLASH_BASE1_PRELIM, &flash_info[1]);
if (size_b1 > size_b0) {
printf ("## ERROR: "
"Bank 1 (0x%08lx = %ld MB) > Bank 0 (0x%08lx = %ld MB)\n",
size_b1, size_b1<<20,
size_b0, size_b0<<20
);
flash_info[0].flash_id = FLASH_UNKNOWN;
flash_info[1].flash_id = FLASH_UNKNOWN;
flash_info[0].sector_count = -1;
flash_info[1].sector_count = -1;
flash_info[0].size = 0;
flash_info[1].size = 0;
return (0);
}
/* Remap FLASH according to real size */
memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-size_b0 & OR_AM_MSK);
memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V;
/* Re-do sizing to get full correct info */
size_b0 = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
flash_get_offsets (CFG_FLASH_BASE, &flash_info[0]);
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
/* monitor protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
&flash_info[0]);
#endif
#ifdef CFG_ENV_IS_IN_FLASH
/* ENV protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR+CFG_ENV_SIZE-1,
&flash_info[0]);
#endif
if (size_b1) {
memctl->memc_or1 = CFG_OR_TIMING_FLASH | (-size_b1 & 0xFFFF8000);
memctl->memc_br1 = ((CFG_FLASH_BASE + size_b0) & BR_BA_MSK) |
BR_MS_GPCM | BR_V;
/* Re-do sizing to get full correct info */
size_b1 = flash_get_size((vu_long *)(CFG_FLASH_BASE + size_b0),
&flash_info[1]);
flash_get_offsets (CFG_FLASH_BASE + size_b0, &flash_info[1]);
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
/* monitor protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
&flash_info[1]);
#endif
#ifdef CFG_ENV_IS_IN_FLASH
/* ENV protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR+CFG_ENV_SIZE-1,
&flash_info[1]);
#endif
} else {
memctl->memc_br1 = 0; /* invalidate bank */
flash_info[1].flash_id = FLASH_UNKNOWN;
flash_info[1].sector_count = -1;
}
flash_info[0].size = size_b0;
flash_info[1].size = size_b1;
#endif /* CONFIG_BOOT_32B */
return (size_b0 + size_b1);
}
#if 0
/*-----------------------------------------------------------------------
*/
static void flash_get_offsets (ulong base, flash_info_t *info)
{
int i;
/* set up sector start address table */
if (info->flash_id & FLASH_BTYPE) {
/* set sector offsets for bottom boot block type */
info->start[0] = base + 0x00000000;
info->start[1] = base + 0x00008000;
info->start[2] = base + 0x0000C000;
info->start[3] = base + 0x00010000;
for (i = 4; i < info->sector_count; i++) {
info->start[i] = base + (i * 0x00020000) - 0x00060000;
}
} else {
/* set sector offsets for top boot block type */
i = info->sector_count - 1;
info->start[i--] = base + info->size - 0x00008000;
info->start[i--] = base + info->size - 0x0000C000;
info->start[i--] = base + info->size - 0x00010000;
for (; i >= 0; i--) {
info->start[i] = base + i * 0x00020000;
}
}
}
#endif
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t *info)
{
int i;
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
return;
}
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_AMD: printf ("AMD "); break;
case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
default: printf ("Unknown Vendor "); break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_AM400B: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
break;
case FLASH_AM400T: printf ("AM29LV400T (4 Mbit, top boot sector)\n");
break;
case FLASH_AM800B: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
break;
case FLASH_AM800T: printf ("AM29LV800T (8 Mbit, top boot sector)\n");
break;
case FLASH_AM160B: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
break;
case FLASH_AM160T: printf ("AM29LV160T (16 Mbit, top boot sector)\n");
break;
case FLASH_AM320B: printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
break;
case FLASH_AM320T: printf ("AM29LV320T (32 Mbit, top boot sector)\n");
break;
default: printf ("Unknown Chip Type\n");
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");
return;
}
/*-----------------------------------------------------------------------
*/
/*-----------------------------------------------------------------------
*/
/*
* The following code cannot be run from FLASH!
*/
#if 0
static ulong flash_get_size (vu_long *addr, flash_info_t *info)
{
short i;
ulong value;
ulong base = (ulong)addr;
/* Write auto select command: read Manufacturer ID */
addr[0x0555] = 0x00AA00AA;
addr[0x02AA] = 0x00550055;
addr[0x0555] = 0x00900090;
value = addr[0];
switch (value) {
case AMD_MANUFACT:
info->flash_id = FLASH_MAN_AMD;
break;
case FUJ_MANUFACT:
info->flash_id = FLASH_MAN_FUJ;
break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
return (0); /* no or unknown flash */
}
value = addr[1]; /* device ID */
switch (value) {
case AMD_ID_LV400T:
info->flash_id += FLASH_AM400T;
info->sector_count = 11;
info->size = 0x00100000;
break; /* => 1 MB */
case AMD_ID_LV400B:
info->flash_id += FLASH_AM400B;
info->sector_count = 11;
info->size = 0x00100000;
break; /* => 1 MB */
case AMD_ID_LV800T:
info->flash_id += FLASH_AM800T;
info->sector_count = 19;
info->size = 0x00200000;
break; /* => 2 MB */
case AMD_ID_LV800B:
info->flash_id += FLASH_AM800B;
info->sector_count = 19;
info->size = 0x00200000;
break; /* => 2 MB */
case AMD_ID_LV160T:
info->flash_id += FLASH_AM160T;
info->sector_count = 35;
info->size = 0x00400000;
break; /* => 4 MB */
case AMD_ID_LV160B:
info->flash_id += FLASH_AM160B;
info->sector_count = 35;
info->size = 0x00400000;
break; /* => 4 MB */
#if 0 /* enable when device IDs are available */
case AMD_ID_LV320T:
info->flash_id += FLASH_AM320T;
info->sector_count = 67;
info->size = 0x00800000;
break; /* => 8 MB */
case AMD_ID_LV320B:
info->flash_id += FLASH_AM320B;
info->sector_count = 67;
info->size = 0x00800000;
break; /* => 8 MB */
#endif
default:
info->flash_id = FLASH_UNKNOWN;
return (0); /* => no or unknown flash */
}
/* set up sector start address table */
if (info->flash_id & FLASH_BTYPE) {
/* set sector offsets for bottom boot block type */
info->start[0] = base + 0x00000000;
info->start[1] = base + 0x00008000;
info->start[2] = base + 0x0000C000;
info->start[3] = base + 0x00010000;
for (i = 4; i < info->sector_count; i++) {
info->start[i] = base + (i * 0x00020000) - 0x00060000;
}
} else {
/* set sector offsets for top boot block type */
i = info->sector_count - 1;
info->start[i--] = base + info->size - 0x00008000;
info->start[i--] = base + info->size - 0x0000C000;
info->start[i--] = base + info->size - 0x00010000;
for (; i >= 0; i--) {
info->start[i] = base + i * 0x00020000;
}
}
/* check for protected sectors */
for (i = 0; i < info->sector_count; i++) {
/* read sector protection at sector address, (A7 .. A0) = 0x02 */
/* D0 = 1 if protected */
addr = (volatile unsigned long *)(info->start[i]);
info->protect[i] = addr[2] & 1;
}
/*
* Prevent writes to uninitialized FLASH.
*/
if (info->flash_id != FLASH_UNKNOWN) {
addr = (volatile unsigned long *)info->start[0];
*addr = 0x00F000F0; /* reset bank */
}
return (info->size);
}
#endif
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
vu_long *addr = (vu_long*)(info->start[0]);
int flag, prot, sect, l_sect,in_mid,in_did;
ulong start, now, last;
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
printf ("- missing\n");
} else {
printf ("- no sectors to erase\n");
}
return 1;
}
if ((info->flash_id == FLASH_UNKNOWN) ||
(info->flash_id > FLASH_AMD_COMP)) {
printf ("Can't erase unknown flash type %08lx - aborted\n",
info->flash_id);
return 1;
}
prot = 0;
for (sect=s_first; sect<=s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
} else {
printf ("\n");
}
l_sect = -1;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
#if defined (CONFIG_BOOT_8B )
my_out_8( (unsigned char * ) ((ulong)addr+0x555) , 0xaa );
my_out_8( (unsigned char * ) ((ulong)addr+0x2aa) , 0x55 );
my_out_8( (unsigned char * ) ((ulong)addr+0x555) , 0x90 );
in_mid=my_in_8( (unsigned char * ) addr );
in_did=my_in_8( (unsigned char * ) ((ulong)addr+1) );
printf(" man ID=0x%x, dev ID=0x%x.\n",in_mid,in_did );
my_out_8( (unsigned char *)addr, 0xf0);
udelay(1);
my_out_8( (unsigned char *) ((ulong)addr+0x555),0xaa );
my_out_8( (unsigned char *) ((ulong)addr+0x2aa),0x55 );
my_out_8( (unsigned char *) ((ulong)addr+0x555),0x80 );
my_out_8( (unsigned char *) ((ulong)addr+0x555),0xaa );
my_out_8( (unsigned char *) ((ulong)addr+0x2aa),0x55 );
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
addr = (vu_long*)(info->start[sect]);
//addr[0] = 0x00300030;
my_out_8( (unsigned char *) ((ulong)addr),0x30 );
l_sect = sect;
}
}
#elif defined(CONFIG_BOOT_16B )
my_out_be16( (unsigned short * ) ((ulong)addr+ (0xaaa)) , 0xaa );
my_out_be16( (unsigned short * ) ((ulong)addr+ (0x554)) , 0x55 );
my_out_be16( (unsigned short * ) ((ulong)addr+ (0xaaa)) , 0x90 );
in_mid=my_in_be16( (unsigned short * ) addr );
in_did=my_in_be16 ( (unsigned short * ) ((ulong)addr+2) );
printf(" man ID=0x%x, dev ID=0x%x.\n",in_mid,in_did );
my_out_be16( (unsigned short *)addr, 0xf0);
udelay(1);
my_out_be16( (unsigned short *) ((ulong)addr+ 0xaaa),0xaa );
my_out_be16( (unsigned short *) ((ulong)addr+0x554),0x55 );
my_out_be16( (unsigned short *) ((ulong)addr+0xaaa),0x80 );
my_out_be16( (unsigned short *) ((ulong)addr+0xaaa),0xaa );
my_out_be16( (unsigned short *) ((ulong)addr+0x554),0x55 );
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
addr = (vu_long*)(info->start[sect]);
my_out_be16( (unsigned short *) ((ulong)addr),0x30 );
l_sect = sect;
}
}
#elif defined(CONFIG_BOOT_32B)
my_out_be32( (unsigned * ) ((ulong)addr+0x1554) , 0xaa );
my_out_be32( (unsigned * ) ((ulong)addr+0xaa8) , 0x55 );
my_out_be32( (unsigned *) ((ulong)addr+0x1554) , 0x90 );
in_mid=my_in_be32( (unsigned * ) addr );
in_did=my_in_be32( (unsigned * ) ((ulong)addr+4) );
printf(" man ID=0x%x, dev ID=0x%x.\n",in_mid,in_did );
my_out_be32( (unsigned *)addr, 0xf0);
udelay(1);
my_out_be32( (unsigned *) ((ulong)addr+0x1554),0xaa );
my_out_be32( (unsigned *) ((ulong)addr+0xaa8),0x55 );
my_out_be32( (unsigned *) ((ulong)addr+0x1554),0x80 );
my_out_be32( (unsigned *) ((ulong)addr+0x1554),0xaa );
my_out_be32( (unsigned *) ((ulong)addr+0xaa8),0x55 );
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
addr = (vu_long*)(info->start[sect]);
my_out_be32( (unsigned *) ((ulong)addr),0x00300030 );
l_sect = sect;
}
}
#else
# error CONFIG_BOOT_(size)B missing.
#endif
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* wait at least 80us - let's wait 1 ms */
udelay (1000);
/*
* We wait for the last triggered sector
*/
if (l_sect < 0)
goto DONE;
start = get_timer (0);
last = start;
addr = (vu_long*)(info->start[l_sect]);
#if defined (CONFIG_BOOT_8B)
while ( (my_in_8((unsigned char *)addr) & 0x80) != 0x80 )
#elif defined(CONFIG_BOOT_16B )
while ( (my_in_be16((unsigned short *)addr) & 0x0080) != 0x0080 )
#elif defined(CONFIG_BOOT_32B)
while ( (my_in_be32((unsigned *)addr) & 0x00800080) != 0x00800080 )
#else
# error CONFIG_BOOT_(size)B missing.
#endif
{
if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
return 1;
}
/* show that we're waiting */
if ((now - last) > 1000) { /* every second */
putc ('.');
last = now;
}
}
DONE:
/* reset to read mode */
addr = (volatile unsigned long *)info->start[0];
#if defined (CONFIG_BOOT_8B)
my_out_8( (unsigned char *)addr, 0xf0);
#elif defined(CONFIG_BOOT_16B )
my_out_be16( (unsigned short * ) addr , 0x00f0 );
#elif defined(CONFIG_BOOT_32B)
my_out_be32 ( (unsigned *)addr, 0x00F000F0 ); /* reset bank */
#else
# error CONFIG_BOOT_(size)B missing.
#endif
printf (" done\n");
return 0;
}
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
ulong cp, wp, data;
int i, l, 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);
}
for (; i<4 && cnt>0; ++i) {
data = (data << 8) | *src++;
--cnt;
++cp;
}
for (; cnt==0 && i<4; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
}
wp += 4;
}
/*
* handle word aligned part
*/
while (cnt >= 4) {
data = 0;
for (i=0; i<4; ++i) {
data = (data << 8) | *src++;
}
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
}
wp += 4;
cnt -= 4;
}
if (cnt == 0) {
return (0);
}
/*
* handle unaligned tail bytes
*/
data = 0;
for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
data = (data << 8) | *src++;
--cnt;
}
for (; i<4; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
return (write_word(info, wp, data));
}
/*-----------------------------------------------------------------------
* Write a word to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_word (flash_info_t *info, ulong dest, ulong data)
{
ulong addr = (ulong)(info->start[0]);
ulong start,last;
int flag;
ulong i;
int data_short[2];
/* Check if Flash is (sufficiently) erased */
if ( ((ulong) *(ulong *)dest & data) != data ) {
return (2);
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
#if defined(CONFIG_BOOT_8B)
#ifdef DEBUG
{
int in_mid,in_did;
my_out_8( (unsigned char * ) (addr+0x555) , 0xaa );
my_out_8( (unsigned char * ) (addr+0x2aa) , 0x55 );
my_out_8( (unsigned char * ) (addr+0x555) , 0x90 );
in_mid=my_in_8( (unsigned char * ) addr );
in_did=my_in_8( (unsigned char * ) (addr+1) );
printf(" man ID=0x%x, dev ID=0x%x.\n",in_mid,in_did );
my_out_8( (unsigned char *)addr, 0xf0);
udelay(1);
}
#endif
{
int data_ch[4];
data_ch[0]=(int ) ((data>>24) & 0xff);
data_ch[1]=(int ) ((data>>16) &0xff );
data_ch[2]=(int ) ((data >>8) & 0xff);
data_ch[3]=(int ) (data & 0xff);
for (i=0;i<4;i++ ){
my_out_8( (unsigned char *) (addr+0x555),0xaa);
my_out_8((unsigned char *) (addr+0x2aa),0x55);
my_out_8( (unsigned char *) (addr+0x555),0xa0);
my_out_8((unsigned char *) (dest+i) ,data_ch[i]);
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
start = get_timer (0);
last = start;
while( ( my_in_8((unsigned char *) (dest+i)) ) != ( data_ch[i] ) ) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT ) {
return 1;
}
}
}/* for */
}
#elif defined( CONFIG_BOOT_16B)
data_short[0]=(int) (data>>16) & 0xffff;
data_short[1]=(int ) data & 0xffff ;
for (i=0;i<2;i++ ){
my_out_be16( (unsigned short *) ((ulong)addr+ 0xaaa),0xaa );
my_out_be16( (unsigned short *) ((ulong)addr+ 0x554),0x55 );
my_out_be16( (unsigned short *) ((ulong)addr+ 0xaaa),0xa0 );
my_out_be16( (unsigned short *) (dest+(i*2)) ,data_short[i]);
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
start = get_timer (0);
last = start;
while( ( my_in_be16((unsigned short *) (dest+(i*2))) ) != ( data_short[i] ) ) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT ) {
return 1;
}
}
}
#elif defined( CONFIG_BOOT_32B)
addr[0x0555] = 0x00AA00AA;
addr[0x02AA] = 0x00550055;
addr[0x0555] = 0x00A000A0;
*((vu_long *)dest) = data;
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* data polling for D7 */
start = get_timer (0);
while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
return (1);
}
}
#endif
return (0);
}
#ifdef CONFIG_BOOT_8B
static int my_in_8 ( unsigned char *addr)
{
int ret;
__asm__ __volatile__("lbz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));
return ret;
}
static void my_out_8 ( unsigned char *addr, int val)
{
__asm__ __volatile__("stb%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
}
#endif
#ifdef CONFIG_BOOT_16B
static int my_in_be16( unsigned short *addr)
{
int ret;
__asm__ __volatile__("lhz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));
return ret;
}
static void my_out_be16( unsigned short *addr, int val)
{
__asm__ __volatile__("sth%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
}
#endif
#ifdef CONFIG_BOOT_32B
static unsigned my_in_be32( unsigned *addr)
{
unsigned ret;
__asm__ __volatile__("lwz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));
return ret;
}
static void my_out_be32( unsigned *addr, int val)
{
__asm__ __volatile__("stw%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
}
#endif

133
board/svm_sc8xx/ppcboot.lds Normal file
View File

@@ -0,0 +1,133 @@
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
OUTPUT_ARCH(powerpc)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) }
.rela.text : { *(.rela.text) }
.rel.data : { *(.rel.data) }
.rela.data : { *(.rela.data) }
.rel.rodata : { *(.rel.rodata) }
.rela.rodata : { *(.rela.rodata) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init : { *(.init) }
.plt : { *(.plt) }
.text :
{
/* WARNING - the following is hand-optimized to fit within */
/* the sector layout of our flash chips! XXX FIXME XXX */
cpu/mpc8xx/start.o (.text)
common/dlmalloc.o (.text)
ppc/ppcstring.o (.text)
ppc/vsprintf.o (.text)
ppc/crc32.o (.text)
ppc/zlib.o (.text)
. = env_offset;
common/environment.o(.text)
*(.text)
*(.fixup)
*(.got1)
}
_etext = .;
PROVIDE (etext = .);
.rodata :
{
*(.rodata)
*(.rodata1)
}
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = (. + 0x00FF) & 0xFFFFFF00;
_erotext = .;
PROVIDE (erotext = .);
.reloc :
{
*(.got)
_GOT2_TABLE_ = .;
*(.got2)
_FIXUP_TABLE_ = .;
*(.fixup)
}
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
__fixup_entries = (. - _FIXUP_TABLE_)>>2;
.data :
{
*(.data)
*(.data1)
*(.sdata)
*(.sdata2)
*(.dynamic)
CONSTRUCTORS
}
_edata = .;
PROVIDE (edata = .);
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
. = ALIGN(256);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(256);
__init_end = .;
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
}

View File

@@ -0,0 +1,131 @@
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
OUTPUT_ARCH(powerpc)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) }
.rela.text : { *(.rela.text) }
.rel.data : { *(.rel.data) }
.rela.data : { *(.rela.data) }
.rel.rodata : { *(.rel.rodata) }
.rela.rodata : { *(.rela.rodata) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init : { *(.init) }
.plt : { *(.plt) }
.text :
{
/* WARNING - the following is hand-optimized to fit within */
/* the sector layout of our flash chips! XXX FIXME XXX */
cpu/mpc8xx/start.o (.text)
common/dlmalloc.o (.text)
ppc/vsprintf.o (.text)
ppc/crc32.o (.text)
. = env_offset;
common/environment.o(.text)
*(.text)
*(.fixup)
*(.got1)
}
_etext = .;
PROVIDE (etext = .);
.rodata :
{
*(.rodata)
*(.rodata1)
}
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = (. + 0x0FFF) & 0xFFFFF000;
_erotext = .;
PROVIDE (erotext = .);
.reloc :
{
*(.got)
_GOT2_TABLE_ = .;
*(.got2)
_FIXUP_TABLE_ = .;
*(.fixup)
}
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
__fixup_entries = (. - _FIXUP_TABLE_)>>2;
.data :
{
*(.data)
*(.data1)
*(.sdata)
*(.sdata2)
*(.dynamic)
CONSTRUCTORS
}
_edata = .;
PROVIDE (edata = .);
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
. = ALIGN(4096);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(4096);
__init_end = .;
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
}

163
board/svm_sc8xx/svm_sc8xx.c Normal file
View File

@@ -0,0 +1,163 @@
/*
* (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 <common.h>
#include <mpc8xx.h>
/* ------------------------------------------------------------------------- */
const uint sdram_table[] =
{
/*-----------------
UPM A contents:
----------------- */
/*---------------------------------------------------
Read Single Beat Cycle. Offset 0 in the RAM array.
---------------------------------------------------- */
0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00 ,
0x1ff77c47, 0x1ff77c35, 0xefeabc34, 0x1fb57c35 ,
/*------------------------------------------------
Read Burst Cycle. Offset 0x8 in the RAM array.
------------------------------------------------ */
0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00,
0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
/*-------------------------------------------------------
Write Single Beat Cycle. Offset 0x18 in the RAM array
------------------------------------------------------- */
0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47 ,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff ,
/*-------------------------------------------------
Write Burst Cycle. Offset 0x20 in the RAM array
------------------------------------------------- */
0x1f07fc04, 0xeeaebc00, 0x10ad7c00, 0xf0affc00,
0xf0affc00, 0xe1bbbc04, 0x1ff77c47, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff ,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff ,
/*------------------------------------------------------------------------
Periodic Timer Expired. For DRAM refresh. Offset 0x30 in the RAM array
------------------------------------------------------------------------ */
0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
0xfffffc84, 0xfffffc07, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff ,
/*-----------
* Exception:
* ----------- */
0x7ffefc07, 0xffffffff, 0xffffffff, 0xffffffff ,
};
/* ------------------------------------------------------------------------- */
/*
* Check Board Identity:
*
* Test ID string (SVM8...)
*
* Return 1 for "SC8xx" type, 0 else.
*/
int checkboard (void)
{
unsigned char *s = getenv("serial#");
int board_type;
if (!s || strncmp(s, "SVM8", 4)) {
printf ("### No HW ID - assuming SVM SC8xx\n");
return (0);
}
board_type = 1;
for (; *s; ++s) {
if (*s == ' ')
break;
putc (*s);
}
putc ('\n');
return (0);
}
/* ------------------------------------------------------------------------- */
long int initdram (int board_type)
{
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile memctl8xx_t *memctl = &immap->im_memctl;
long int size_b0 = 0;
upmconfig(UPMA, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint));
memctl->memc_mptpr = CFG_MPTPR;
#if defined (CONFIG_SDRAM_16M)
memctl->memc_mamr = 0x00802114 | CFG_MxMR_PTx;
memctl->memc_mcr = 0x80002105; /* SDRAM bank 0 */
udelay(1);
memctl->memc_mcr = 0x80002830;
udelay(1);
memctl->memc_mar = 0x00000088;
udelay(1);
memctl->memc_mcr = 0x80002106;
udelay(1);
memctl->memc_or1 = 0xff000a00;
size_b0 = 0x01000000;
#elif defined (CONFIG_SDRAM_32M)
memctl->memc_mamr = 0x00904114 | CFG_MxMR_PTx;
memctl->memc_mcr = 0x80002105; /* SDRAM bank 0 */
udelay(1);
memctl->memc_mcr = 0x80002830;
udelay(1);
memctl->memc_mar = 0x00000088;
udelay(1);
memctl->memc_mcr = 0x80002106;
udelay(1);
memctl->memc_or1 = 0xfe000a00;
size_b0 = 0x02000000;
#elif defined (CONFIG_SDRAM_64M)
memctl->memc_mamr = 0x00a04114 | CFG_MxMR_PTx;
memctl->memc_mcr = 0x80002105; /* SDRAM bank 0 */
udelay(1);
memctl->memc_mcr = 0x80002830;
udelay(1);
memctl->memc_mar = 0x00000088;
udelay(1);
memctl->memc_mcr = 0x80002106;
udelay(1);
memctl->memc_or1 = 0xfc000a00;
size_b0 = 0x04000000;
#else
#error SDRAM size configuration missing.
#endif
memctl->memc_br1 = 0x00000081;
udelay(200);
return (size_b0 );
}
#if (CONFIG_COMMANDS & CFG_CMD_DOC)
extern void doc_probe (ulong physadr);
void doc_init (void)
{
doc_probe (CFG_DOC_BASE);
}
#endif

136
board/svm_sc8xx/u-boot.lds Normal file
View File

@@ -0,0 +1,136 @@
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
OUTPUT_ARCH(powerpc)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) }
.rela.text : { *(.rela.text) }
.rel.data : { *(.rel.data) }
.rela.data : { *(.rela.data) }
.rel.rodata : { *(.rel.rodata) }
.rela.rodata : { *(.rela.rodata) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init : { *(.init) }
.plt : { *(.plt) }
.text :
{
/* WARNING - the following is hand-optimized to fit within */
/* the sector layout of our flash chips! XXX FIXME XXX */
cpu/mpc8xx/start.o (.text)
cpu/mpc8xx/traps.o (.text)
common/dlmalloc.o (.text)
lib_ppc/ppcstring.o (.text)
lib_generic/vsprintf.o (.text)
lib_generic/crc32.o (.text)
lib_generic/zlib.o (.text)
lib_ppc/cache.o (.text)
lib_ppc/time.o (.text)
. = env_offset;
common/environment.o (.ppcenv)
*(.text)
*(.fixup)
*(.got1)
}
_etext = .;
PROVIDE (etext = .);
.rodata :
{
*(.rodata)
*(.rodata1)
}
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = (. + 0x00FF) & 0xFFFFFF00;
_erotext = .;
PROVIDE (erotext = .);
.reloc :
{
*(.got)
_GOT2_TABLE_ = .;
*(.got2)
_FIXUP_TABLE_ = .;
*(.fixup)
}
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
__fixup_entries = (. - _FIXUP_TABLE_)>>2;
.data :
{
*(.data)
*(.data1)
*(.sdata)
*(.sdata2)
*(.dynamic)
CONSTRUCTORS
}
_edata = .;
PROVIDE (edata = .);
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
. = ALIGN(256);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(256);
__init_end = .;
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
}

View File

@@ -0,0 +1,131 @@
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
OUTPUT_ARCH(powerpc)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) }
.rela.text : { *(.rela.text) }
.rel.data : { *(.rel.data) }
.rela.data : { *(.rela.data) }
.rel.rodata : { *(.rel.rodata) }
.rela.rodata : { *(.rela.rodata) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init : { *(.init) }
.plt : { *(.plt) }
.text :
{
/* WARNING - the following is hand-optimized to fit within */
/* the sector layout of our flash chips! XXX FIXME XXX */
cpu/mpc8xx/start.o (.text)
common/dlmalloc.o (.text)
lib_generic/vsprintf.o (.text)
lib_generic/crc32.o (.text)
. = env_offset;
common/environment.o(.text)
*(.text)
*(.fixup)
*(.got1)
}
_etext = .;
PROVIDE (etext = .);
.rodata :
{
*(.rodata)
*(.rodata1)
}
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = (. + 0x0FFF) & 0xFFFFF000;
_erotext = .;
PROVIDE (erotext = .);
.reloc :
{
*(.got)
_GOT2_TABLE_ = .;
*(.got2)
_FIXUP_TABLE_ = .;
*(.fixup)
}
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
__fixup_entries = (. - _FIXUP_TABLE_)>>2;
.data :
{
*(.data)
*(.data1)
*(.sdata)
*(.sdata2)
*(.dynamic)
CONSTRUCTORS
}
_edata = .;
PROVIDE (edata = .);
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
. = ALIGN(4096);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(4096);
__init_end = .;
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
}

View File

@@ -30,7 +30,7 @@ AOBJS =
COBJS = main.o altera.o bedbug.o \
cmd_autoscript.o cmd_bedbug.o cmd_boot.o \
cmd_bootm.o cmd_cache.o cmd_console.o cmd_date.o \
cmd_dcr.o cmd_diag.o cmd_doc.o cmd_dtt.o \
cmd_dcr.o cmd_diag.o cmd_doc.o cmd_nand.o cmd_dtt.o \
cmd_eeprom.o cmd_elf.o cmd_fdc.o cmd_fdos.o cmd_flash.o \
cmd_fpga.o cmd_i2c.o cmd_ide.o cmd_immap.o \
cmd_jffs2.o cmd_log.o cmd_mem.o cmd_mii.o cmd_misc.o \

View File

@@ -153,10 +153,9 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
print_num ("boot_params", (ulong)bd->bi_boot_params);
for (i=0; i<CONFIG_NR_DRAM_BANKS; ++i) {
printf ("DRAM:%02d.start = %08lX\n",
i, bd->bi_dram[i].start);
printf ("DRAM:%02d.size = %08lX\n",
i, bd->bi_dram[i].size);
print_num("DRAM bank", i);
print_num("-> start", bd->bi_dram[i].start);
print_num("-> size", bd->bi_dram[i].size);
}
printf ("ethaddr =");
@@ -200,7 +199,7 @@ int do_go (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
addr = simple_strtoul(argv[1], NULL, 16);
printf ("## Starting application at 0x%08lx ...\n", addr);
printf ("## Starting application at 0x%08lX ...\n", addr);
/*
* pass address parameter as argv[0] (aka command name),
@@ -209,7 +208,7 @@ int do_go (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
rc = ((ulong (*)(int, char *[]))addr) (--argc, &argv[1]);
if (rc != 0) rcode = 1;
printf ("## Application terminated, rc = 0x%lx\n", rc);
printf ("## Application terminated, rc = 0x%lX\n", rc);
return rcode;
}
@@ -285,7 +284,7 @@ int do_load_serial (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
printf ("## S-Record download aborted\n");
rcode = 1;
} else {
printf ("## Start Addr = 0x%08lx\n", addr);
printf ("## Start Addr = 0x%08lX\n", addr);
load_addr = addr;
}
@@ -345,9 +344,9 @@ load_serial (ulong offset)
memcpy ((char *)(store_addr), binbuf, binlen);
}
if ((store_addr) < start_addr)
start_addr = store_addr;
start_addr = store_addr;
if ((store_addr + binlen - 1) > end_addr)
end_addr = store_addr + binlen - 1;
end_addr = store_addr + binlen - 1;
break;
case SREC_END2:
case SREC_END3:
@@ -606,9 +605,17 @@ int do_load_serial_bin (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
ulong offset = 0;
ulong addr;
int i;
int load_baudrate, current_baudrate;
int rcode = 0;
char *s;
/* pre-set offset from CFG_LOAD_ADDR */
offset = CFG_LOAD_ADDR;
/* pre-set offset from $loadaddr */
if ((s = getenv("loadaddr")) != NULL) {
offset = simple_strtoul(s, NULL, 16);
}
load_baudrate = current_baudrate = gd->baudrate;
@@ -635,28 +642,19 @@ int do_load_serial_bin (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
break;
}
}
printf ("## Ready for binary (kermit) download ...\n");
printf ("## Ready for binary (kermit) download "
"to 0x%08lX at %d bps...\n",
offset,
current_baudrate);
addr = load_serial_bin (offset);
/*
* Gather any trailing characters (for instance, the ^D which
* is sent by 'cu' after sending a file), and give the
* box some time (100 * 1 ms)
*/
for (i=0; i<100; ++i) {
if (serial_tstc()) {
(void) serial_getc();
}
udelay(1000);
}
if (addr == ~0) {
load_addr = 0;
printf ("## Binary (kermit) download aborted\n");
rcode = 1;
} else {
printf ("## Start Addr = 0x%08lx\n", addr);
printf ("## Start Addr = 0x%08lX\n", addr);
load_addr = addr;
}

View File

@@ -21,6 +21,7 @@
#if (CONFIG_COMMANDS & CFG_CMD_DOC)
#include <linux/mtd/nftl.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/nand_ids.h>
#include <linux/mtd/doc2000.h>

1544
common/cmd_nand.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -514,12 +514,17 @@ static int hardware_disable(int slot)
/* -------------------------------------------------------------------- */
/* TQM8xxL Boards by TQ Components */
/* SC8xx Boards by SinoVee Microsystems */
/* -------------------------------------------------------------------- */
#if defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx)
#if defined(CONFIG_TQM8xxL)
#define PCMCIA_BOARD_MSG "TQM8xxL"
#endif
#if defined(CONFIG_SVM_SC8xx)
#define PCMCIA_BOARD_MSG "SC8xx"
#endif
static int hardware_enable(int slot)
{

View File

@@ -58,6 +58,7 @@
#include <cmd_mii.h>
#include <cmd_dcr.h> /* 4xx DCR register access */
#include <cmd_doc.h>
#include <cmd_nand.h>
#include <cmd_jffs2.h>
#include <cmd_fpga.h>
@@ -307,6 +308,8 @@ cmd_tbl_t cmd_tbl[] = {
CMD_TBL_MTEST
CMD_TBL_MUXINFO
CMD_TBL_MW
CMD_TBL_NAND
CMD_TBL_NANDBOOT
CMD_TBL_NEXT
CMD_TBL_NM
CMD_TBL_PCI

43
cpu/at91rm9200/Makefile Normal file
View File

@@ -0,0 +1,43 @@
#
# (C) Copyright 2003
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
LIB = lib$(CPU).a
START = start.o
OBJS = serial.o interrupts.o cpu.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
#########################################################################

27
cpu/at91rm9200/config.mk Normal file
View File

@@ -0,0 +1,27 @@
#
# (C) Copyright 2002
# Sysgo Real-Time Solutions, GmbH <www.elinos.com>
# Marius Groeger <mgroeger@sysgo.de>
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \
-mshort-load-bytes -msoft-float
PLATFORM_CPPFLAGS += -mapcs-32 -march=armv4 -mtune=arm7tdmi

177
cpu/at91rm9200/cpu.c Normal file
View File

@@ -0,0 +1,177 @@
/*
* (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>
*
* 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 <AT91RM9200.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");
/*printf("p15/c1 is = %08lx\n", value); */
return value;
}
/* write to co-processor 15, register #1 (control register) */
static void write_p15_c1(unsigned long value)
{
/*printf("write %08lx to p15/c1\n", value); */
__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_IDC (1<<2) /* icache and/or dcache off/on */
#define C1_WRITE_BUFFER (1<<3) /* write buffer 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_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */
int cpu_init(void)
{
/*
* setup up stack if necessary
*/
#ifdef CONFIG_USE_IRQ
IRQ_STACK_START = _armboot_end +
CONFIG_STACKSIZE + CONFIG_STACKSIZE_IRQ - 4;
FIQ_STACK_START = IRQ_STACK_START + CONFIG_STACKSIZE_FIQ;
_armboot_real_end = FIQ_STACK_START + 4;
#else
_armboot_real_end = _armboot_end + CONFIG_STACKSIZE;
#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 ...
* and we set the CPU-speed to 73 MHz - see start.S for details
*/
disable_interrupts();
return 0;
}
int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
#ifdef CFG_SOFT_RESET
extern void reset_cpu(ulong addr);
disable_interrupts();
reset_cpu(0);
#else
AT91PS_USART us = AT91C_BASE_US1;
AT91PS_PIO pio = AT91C_BASE_PIOA;
/*shutdown the console to avoid strange chars during reset */
us->US_CR = (AT91C_US_RSTRX | AT91C_US_RSTTX);
/* Clear PA19 to trigger the hard reset */
pio->PIO_CODR = 0x00080000;
pio->PIO_OER = 0x00080000;
pio->PIO_PER = 0x00080000;
/* Never reached */
#endif
return 0;
}
void icache_enable(void)
{
ulong reg;
reg = read_p15_c1();
cp_delay();
write_p15_c1(reg | C1_IDC);
}
void icache_disable(void)
{
ulong reg;
reg = read_p15_c1();
cp_delay();
write_p15_c1(reg & ~C1_IDC);
}
int icache_status(void)
{
return (read_p15_c1() & C1_IDC) != 0;
return 0;
}
void dcache_enable(void)
{
ulong reg;
reg = read_p15_c1();
cp_delay();
write_p15_c1(reg | C1_IDC);
}
void dcache_disable(void)
{
ulong reg;
reg = read_p15_c1();
cp_delay();
write_p15_c1(reg & ~C1_IDC);
}
int dcache_status(void)
{
return (read_p15_c1() & C1_IDC) != 0;
return 0;
}

236
cpu/at91rm9200/interrupts.c Normal file
View File

@@ -0,0 +1,236 @@
/*
* (C) Copyright 2002
* Lineo, Inc. <www.lineo.com>
* Bernhard Kuhn <bkuhn@lineo.com>
*
* (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>
*
* 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 <AT91RM9200.h>
#include <asm/proc-armv/ptrace.h>
extern void reset_cpu(ulong addr);
/* we always count down the max. */
#define TIMER_LOAD_VAL 0xffff
/* macro to read the 16 bit timer */
#define READ_TIMER (tmr->TC_CV)
AT91PS_TC tmr;
void enable_interrupts (void)
{
return;
}
int disable_interrupts (void)
{
return 0;
}
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 lastinc;
int interrupt_init (void)
{
tmr = AT91C_BASE_TC0;
/* enables TC1.0 clock */
*AT91C_PMC_PCER = 1 << AT91C_ID_TC0; /* enable clock */
*AT91C_TCB0_BCR = 0;
*AT91C_TCB0_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_NONE | AT91C_TCB_TC2XC2S_NONE;
tmr->TC_CCR = AT91C_TC_CLKDIS;
tmr->TC_CMR = AT91C_TC_TIMER_DIV1_CLOCK; /* set to MCLK/2 */
tmr->TC_IDR = ~0ul;
tmr->TC_RC = TIMER_LOAD_VAL;
lastinc = TIMER_LOAD_VAL;
tmr->TC_CCR = AT91C_TC_SWTRG | AT91C_TC_CLKEN;
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)
{
udelay_masked(usec);
}
void reset_timer_masked(void)
{
/* reset time */
lastinc = READ_TIMER;
timestamp = 0;
}
ulong get_timer_masked(void)
{
ulong now = READ_TIMER;
if (now >= lastinc)
{
/* normal mode */
timestamp += now - lastinc;
} else {
/* we have an overflow ... */
timestamp += now + TIMER_LOAD_VAL - lastinc;
}
lastinc = now;
return timestamp;
}
void udelay_masked(unsigned long usec)
{
ulong tmo;
tmo = usec / 1000;
tmo *= CFG_HZ;
tmo /= 1000;
reset_timer_masked();
while(get_timer_masked() < tmo);
/*NOP*/;
}

89
cpu/at91rm9200/serial.c Normal file
View File

@@ -0,0 +1,89 @@
/*
* (C) Copyright 2002
* Lineo, Inc <www.lineo.com>
* Bernhard Kuhn <bkuhn@lineo.com>
*
* (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>
*
* Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
*
* 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 <AT91RM9200.h>
/* ggi thunder */
AT91PS_USART us = (AT91PS_USART) AT91C_BASE_DBGU;
void serial_setbrg(void)
{
DECLARE_GLOBAL_DATA_PTR;
int baudrate;
if ((baudrate = gd->bd->bi_baudrate) <= 0)
baudrate = CONFIG_BAUDRATE;
us->US_BRGR = 33 /* AT91C_MASTER_CLOCK / baudrate / 16 */; /* hardcode so no __divsi3 */
}
int serial_init(void)
{
/* make any port initializations specific to this port */
*AT91C_PIOA_PDR = AT91C_PA31_DTXD | AT91C_PA30_DRXD; /* PA 31 & 30 */
*AT91C_PMC_PCER = 1 << AT91C_ID_SYS; /* enable clock */
serial_setbrg();
us->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX;
us->US_CR = AT91C_US_RXEN | AT91C_US_TXEN;
us->US_MR = ( AT91C_US_CLKS_CLOCK | AT91C_US_CHRL_8_BITS | AT91C_US_PAR_NONE | AT91C_US_NBSTOP_1_BIT );
us->US_IMR = ~0ul;
return (0);
}
void serial_putc(const char c)
{
if (c == '\n')
serial_putc('\r');
while( (us->US_CSR & AT91C_US_TXRDY) == 0 )
;
us->US_THR=c;
}
void
serial_puts (const char *s)
{
while (*s)
{
serial_putc (*s++);
}
}
int serial_getc(void)
{
while( (us->US_CSR & AT91C_US_RXRDY) == 0 );
return us->US_RHR;
}
int serial_tstc(void)
{
return ((us->US_CSR & AT91C_US_RXRDY) == AT91C_US_RXRDY);
}

347
cpu/at91rm9200/start.S Normal file
View File

@@ -0,0 +1,347 @@
/*
* armboot - Startup Code for ARM720 CPU-core
*
* Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
* Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include "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
*
*************************************************************************
*/
/*
* CFG_MEM_END is in the board dependent config-file (configs/config_BOARD.h)
*/
_TEXT_BASE:
.word TEXT_BASE
.globl _armboot_start
_armboot_start:
.word _start
/*
* Note: _armboot_end_data and _armboot_end are defined
* by the (board-dependent) linker script.
* _armboot_end_data is the first usable FLASH address after armboot
*/
.globl _armboot_end_data
_armboot_end_data:
.word armboot_end_data
/*
* Note: armboot_end is defined by the (board-dependent) linker script
*/
.globl _armboot_end
_armboot_end:
.word armboot_end
/*
* _armboot_real_end is the first usable RAM address behind armboot
* and the various stacks
*/
.globl _armboot_real_end
_armboot_real_end:
.word 0x0badc0de
#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,#0x13
msr cpsr,r0
/*
* relocate exeception table
*/
ldr r0, =_start
ldr r1, =0x0
mov r2, #16
copyex:
subs r2, r2, #1
ldr r3, [r0], #4
str r3, [r1], #4
bne copyex
/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
#ifdef CONFIG_INIT_CRITICAL
bl cpu_init_crit
#endif
/* set up the stack */
ldr r0, _armboot_end
add r0, r0, #CONFIG_STACKSIZE
sub sp, r0, #12 /* leave 3 words for abort-stack */
ldr pc,_start_armboot
_start_armboot: .word start_armboot
/*
*************************************************************************
*
* CPU_init_critical registers
*
*************************************************************************
*/
cpu_init_crit:
# actually do nothing for now!
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
add r8, sp, #S_PC
ldr r2, _armboot_end
add r2, r2, #CONFIG_STACKSIZE
sub r2, r2, #8
ldmia r2, {r2 - r4} @ get pc, cpsr, old_r0
add r0, sp, #S_FRAME_SIZE @ restore sp_SVC
add r5, sp, #S_SP
mov r1, lr
stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_r
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_end @ setup our mode stack
add r13, r13, #CONFIG_STACKSIZE @ resides at top of normal stack
sub r13, r13, #8
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
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:
mov pc, r0

44
cpu/mips/Makefile Normal file
View File

@@ -0,0 +1,44 @@
#
# (C) Copyright 2003
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
LIB = lib$(CPU).a
START = start.o
OBJS = interrupts.o cpu.o incaip_clock.o serial.o
SOBJS = incaip_wdt.o cache.o
all: .depend $(START) $(LIB)
$(LIB): $(OBJS) $(SOBJS)
$(AR) crv $@ $(OBJS) $(SOBJS)
#########################################################################
.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
sinclude .depend
#########################################################################

265
cpu/mips/cache.S Normal file
View File

@@ -0,0 +1,265 @@
/*
* Cache-handling routined for MIPS 4K CPUs
*
* Copyright (c) 2003 Wolfgang Denk <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 <config.h>
#include <version.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/addrspace.h>
#include <asm/cacheops.h>
/* 16KB is the maximum size of instruction and data caches on
* MIPS 4K.
*/
#define MIPS_MAX_CACHE_SIZE 0x4000
/*
* cacheop macro to automate cache operations
* first some helpers...
*/
#define _mincache(size, maxsize) \
bltu size,maxsize,9f ; \
move size,maxsize ; \
9:
#define _align(minaddr, maxaddr, linesize) \
.set noat ; \
subu AT,linesize,1 ; \
not AT ; \
and minaddr,AT ; \
addu maxaddr,-1 ; \
and maxaddr,AT ; \
.set at
/* general operations */
#define doop1(op1) \
cache op1,0(a0)
#define doop2(op1, op2) \
cache op1,0(a0) ; \
nop ; \
cache op2,0(a0)
/* specials for cache initialisation */
#define doop1lw(op1) \
lw zero,0(a0)
#define doop1lw1(op1) \
cache op1,0(a0) ; \
lw zero,0(a0) ; \
cache op1,0(a0)
#define doop121(op1,op2) \
cache op1,0(a0) ; \
nop; \
cache op2,0(a0) ; \
nop; \
cache op1,0(a0)
#define _oploopn(minaddr, maxaddr, linesize, tag, ops) \
.set noreorder ; \
10: doop##tag##ops ; \
bne minaddr,maxaddr,10b ; \
add minaddr,linesize ; \
.set reorder
/* finally the cache operation macros */
#define vcacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \
blez n,11f ; \
addu n,kva ; \
_align(kva, n, cacheLineSize) ; \
_oploopn(kva, n, cacheLineSize, tag, ops) ; \
11:
#define icacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \
_mincache(n, cacheSize); \
blez n,11f ; \
addu n,kva ; \
_align(kva, n, cacheLineSize) ; \
_oploopn(kva, n, cacheLineSize, tag, ops) ; \
11:
#define vcacheop(kva, n, cacheSize, cacheLineSize, op) \
vcacheopn(kva, n, cacheSize, cacheLineSize, 1, (op))
#define icacheop(kva, n, cacheSize, cacheLineSize, op) \
icacheopn(kva, n, cacheSize, cacheLineSize, 1, (op))
/*******************************************************************************
*
* mips_cache_reset - low level initialisation of the primary caches
*
* This routine initialises the primary caches to ensure that they
* have good parity. It must be called by the ROM before any cached locations
* are used to prevent the possibility of data with bad parity being written to
* memory.
* To initialise the instruction cache it is essential that a source of data
* with good parity is available. This routine
* will initialise an area of memory starting at location zero to be used as
* a source of parity.
*
* RETURNS: N/A
*
*/
.globl mips_cache_reset
.ent mips_cache_reset
mips_cache_reset:
li t2, CFG_ICACHE_SIZE
li t3, CFG_DCACHE_SIZE
li t4, CFG_CACHELINE_SIZE
move t5, t4
li v0, MIPS_MAX_CACHE_SIZE
/* Now clear that much memory starting from zero.
*/
li a0, KSEG1
addu a1, a0, v0
2: sw zero, 0(a0)
sw zero, 4(a0)
sw zero, 8(a0)
sw zero, 12(a0)
sw zero, 16(a0)
sw zero, 20(a0)
sw zero, 24(a0)
sw zero, 28(a0)
addu a0, 32
bltu a0, a1, 2b
/* Set invalid tag.
*/
mtc0 zero, CP0_TAGLO
/*
* The caches are probably in an indeterminate state,
* so we force good parity into them by doing an
* invalidate, load/fill, invalidate for each line.
*/
/* Assume bottom of RAM will generate good parity for the cache.
*/
li a0, K0BASE
move a2, t2 # icacheSize
move a3, t4 # icacheLineSize
move a1, a2
icacheopn(a0,a1,a2,a3,121,(Index_Store_Tag_I,Fill))
/* To support Orion/R4600, we initialise the data cache in 3 passes.
*/
/* 1: initialise dcache tags.
*/
li a0, K0BASE
move a2, t3 # dcacheSize
move a3, t5 # dcacheLineSize
move a1, a2
icacheop(a0,a1,a2,a3,Index_Store_Tag_D)
/* 2: fill dcache.
*/
li a0, K0BASE
move a2, t3 # dcacheSize
move a3, t5 # dcacheLineSize
move a1, a2
icacheopn(a0,a1,a2,a3,1lw,(dummy))
/* 3: clear dcache tags.
*/
li a0, K0BASE
move a2, t3 # dcacheSize
move a3, t5 # dcacheLineSize
move a1, a2
icacheop(a0,a1,a2,a3,Index_Store_Tag_D)
j ra
.end mips_cache_reset
/*******************************************************************************
*
* dcache_status - get cache status
*
* RETURNS: 0 - cache disabled; 1 - cache enabled
*
*/
.globl dcache_status
.ent dcache_status
dcache_status:
mfc0 v0, CP0_CONFIG
andi v0, v0, 1
j ra
.end dcache_status
/*******************************************************************************
*
* dcache_disable - disable cache
*
* RETURNS: N/A
*
*/
.globl dcache_disable
.ent dcache_disable
dcache_disable:
mfc0 t0, CP0_CONFIG
li t1, -8
and t0, t0, t1
ori t0, t0, CONF_CM_UNCACHED
mtc0 t0, CP0_CONFIG
j ra
.end dcache_disable
/*******************************************************************************
*
* mips_cache_lock - lock RAM area pointed to by a0 in cache.
*
* RETURNS: N/A
*
*/
.globl mips_cache_lock
.ent mips_cache_lock
mips_cache_lock:
li a1, K0BASE - CFG_DCACHE_SIZE
addu a0, a1
li a2, CFG_DCACHE_SIZE
li a3, CFG_CACHELINE_SIZE
move a1, a2
icacheop(a0,a1,a2,a3,0x1d)
j ra
.end mips_cache_lock

25
cpu/mips/config.mk Normal file
View File

@@ -0,0 +1,25 @@
#
# (C) Copyright 2003
# Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
PLATFORM_CPPFLAGS += -mcpu=4kc -EB -mabicalls

41
cpu/mips/cpu.c Normal file
View File

@@ -0,0 +1,41 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <command.h>
#include <asm/inca-ip.h>
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
#ifdef CONFIG_INCA_IP
*INCA_IP_WDT_RST_REQ = 0x3f;
#endif
fprintf(stderr, "*** reset failed ***\n");
return 0;
}
void flush_cache (ulong start_addr, ulong size)
{
}

107
cpu/mips/incaip_clock.c Normal file
View File

@@ -0,0 +1,107 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/inca-ip.h>
/*******************************************************************************
*
* get_cpuclk - returns the frequency of the CPU.
*
* Gets the value directly from the INCA-IP hardware.
*
* RETURNS:
* 150.000.000 for 150 MHz
* 130.000.000. for 130 Mhz
* 100.000.000. for 100 Mhz
* NOTE:
* This functions should be used by the hardware driver to get the correct
* frequency of the CPU. Don't use the macros, which are set to init the CPU
* frequency in the ROM code.
*/
uint incaip_get_cpuclk(void)
{
/*-------------------------------------------------------------------------*/
/* CPU Clock Input Multiplexer (MUX I) */
/* Multiplexer MUX I selects the maximum input clock to the CPU. */
/*-------------------------------------------------------------------------*/
if (*((volatile ulong*)INCA_IP_CGU_CGU_MUXCR) & INCA_IP_CGU_CGU_MUXCR_MUXI)
{
/* MUX I set to 150 MHz clock */
return 150000000;
}
else
{
/* MUX I set to 100/133 MHz clock */
if (*((volatile ulong*)INCA_IP_CGU_CGU_DIVCR) & 0x40)
{
/* Division value is 1/3, maximum CPU operating */
/* frequency is 133.3 MHz */
return 130000000;
}
else
{
/* Division value is 1/4, maximum CPU operating */
/* frequency is 100 MHz */
return 100000000;
}
}
}
/*******************************************************************************
*
* get_fpiclk - returns the frequency of the FPI bus.
*
* Gets the value directly from the INCA-IP hardware.
*
* RETURNS: Frquency in Hz
*
* NOTE:
* This functions should be used by the hardware driver to get the correct
* frequency of the CPU. Don't use the macros, which are set to init the CPU
* frequency in the ROM code.
* The calculation for the
*/
uint incaip_get_fpiclk(void)
{
uint clkCPU;
clkCPU = incaip_get_cpuclk();
switch (*((volatile ulong*)INCA_IP_CGU_CGU_DIVCR) & 0xC)
{
case 0x4:
return clkCPU >> 1; /* devided by 2 */
break;
case 0x8:
return clkCPU >> 2; /* devided by 4 */
break;
default:
return clkCPU;
break;
}
}

73
cpu/mips/incaip_wdt.S Normal file
View File

@@ -0,0 +1,73 @@
/*
* INCA-IP Watchdog timer management code.
*
* Copyright (c) 2003 Wolfgang Denk <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 <config.h>
#include <version.h>
#include <asm/regdef.h>
#define WD_BASE 0xb8000000
#define WD_CON0(value) 0x0020(value)
#define WD_CON1(value) 0x0024(value)
#define WD_DISABLE 0x00000008
#define WD_ENABLE 0x00000000
#define WD_WRITE_PW 0xFFFC00F8
#define WD_WRITE_ENDINIT 0xFFFC00F3
#define WD_WRITE_INIT 0xFFFC00F2
.globl disable_incaip_wdt
disable_incaip_wdt:
li t0, WD_BASE
/* Calculate password.
*/
lw t2, WD_CON1(t0)
and t2, 0xC
lw t3, WD_CON0(t0)
and t3, 0xFFFFFF01
or t3, t2
or t3, 0xF0
sw t3, WD_CON0(t0) /* write password */
/* Clear ENDINIT.
*/
li t1, WD_WRITE_INIT
sw t1, WD_CON0(t0)
li t1, WD_DISABLE
sw t1, WD_CON1(t0) /* disable watchdog */
li t1, WD_WRITE_PW
sw t1, WD_CON0(t0) /* write password */
li t1, WD_WRITE_ENDINIT
sw t1, WD_CON0(t0) /* end command */
j ra
nop

34
cpu/mips/interrupts.c Normal file
View File

@@ -0,0 +1,34 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
void enable_interrupts(void)
{
}
int disable_interrupts(void)
{
return 0;
}

282
cpu/mips/serial.c Normal file
View File

@@ -0,0 +1,282 @@
/*
* (INCA) ASC UART support
*/
#include <common.h>
#include <asm/inca-ip.h>
#include "serial.h"
#define SET_BIT(reg, mask) reg |= (mask)
#define CLEAR_BIT(reg, mask) reg &= (~mask)
#define CLEAR_BITS(reg, mask) CLEAR_BIT(reg, mask)
#define SET_BITS(reg, mask) SET_BIT(reg, mask)
#define SET_BITFIELD(reg, mask, off, val) {reg &= (~mask); reg |= (val << off);}
extern uint incaip_get_fpiclk(void);
static int serial_setopt (void);
/* pointer to ASC register base address */
static volatile incaAsc_t *pAsc = (incaAsc_t *)INCA_IP_ASC;
/******************************************************************************
*
* serial_init - initialize a INCAASC channel
*
* This routine initializes the number of data bits, parity
* and set the selected baud rate. Interrupts are disabled.
* Set the modem control signals if the option is selected.
*
* RETURNS: N/A
*/
int serial_init (void)
{
/* we have to set PMU.EN13 bit to enable an ASC device*/
INCAASC_PMU_ENABLE(13);
/* and we have to set CLC register*/
CLEAR_BIT(pAsc->asc_clc, ASCCLC_DISS);
SET_BITFIELD(pAsc->asc_clc, ASCCLC_RMCMASK, ASCCLC_RMCOFFSET, 0x0001);
/* initialy we are in async mode */
pAsc->asc_con = ASCCON_M_8ASYNC;
/* select input port */
pAsc->asc_pisel = (CONSOLE_TTY & 0x1);
/* TXFIFO's filling level */
SET_BITFIELD(pAsc->asc_txfcon, ASCTXFCON_TXFITLMASK,
ASCTXFCON_TXFITLOFF, INCAASC_TXFIFO_FL);
/* enable TXFIFO */
SET_BIT(pAsc->asc_txfcon, ASCTXFCON_TXFEN);
/* RXFIFO's filling level */
SET_BITFIELD(pAsc->asc_txfcon, ASCRXFCON_RXFITLMASK,
ASCRXFCON_RXFITLOFF, INCAASC_RXFIFO_FL);
/* enable RXFIFO */
SET_BIT(pAsc->asc_rxfcon, ASCRXFCON_RXFEN);
/* enable error signals */
SET_BIT(pAsc->asc_con, ASCCON_FEN);
SET_BIT(pAsc->asc_con, ASCCON_OEN);
/* acknowledge ASC interrupts */
ASC_INTERRUPTS_CLEAR(INCAASC_IRQ_LINE_ALL);
/* disable ASC interrupts */
ASC_INTERRUPTS_DISABLE(INCAASC_IRQ_LINE_ALL);
/* set FIFOs into the transparent mode */
SET_BIT(pAsc->asc_txfcon, ASCTXFCON_TXTMEN);
SET_BIT(pAsc->asc_rxfcon, ASCRXFCON_RXTMEN);
/* set baud rate */
serial_setbrg();
/* set the options */
serial_setopt();
return 0;
}
void serial_setbrg (void)
{
ulong uiReloadValue, fdv;
ulong f_ASC;
f_ASC = incaip_get_fpiclk();
#ifndef INCAASC_USE_FDV
fdv = 2;
uiReloadValue = (f_ASC / (fdv * 16 * CONFIG_BAUDRATE)) - 1;
#else
fdv = INCAASC_FDV_HIGH_BAUDRATE;
uiReloadValue = (f_ASC / (8192 * CONFIG_BAUDRATE / fdv)) - 1;
#endif /* INCAASC_USE_FDV */
if ( (uiReloadValue < 0) || (uiReloadValue > 8191) )
{
#ifndef INCAASC_USE_FDV
fdv = 3;
uiReloadValue = (f_ASC / (fdv * 16 * CONFIG_BAUDRATE)) - 1;
#else
fdv = INCAASC_FDV_LOW_BAUDRATE;
uiReloadValue = (f_ASC / (8192 * CONFIG_BAUDRATE / fdv)) - 1;
#endif /* INCAASC_USE_FDV */
if ( (uiReloadValue < 0) || (uiReloadValue > 8191) )
{
return; /* can't impossibly generate that baud rate */
}
}
/* Disable Baud Rate Generator; BG should only be written when R=0 */
CLEAR_BIT(pAsc->asc_con, ASCCON_R);
#ifndef INCAASC_USE_FDV
/*
* Disable Fractional Divider (FDE)
* Divide clock by reload-value + constant (BRS)
*/
/* FDE = 0 */
CLEAR_BIT(pAsc->asc_con, ASCCON_FDE);
if ( fdv == 2 )
CLEAR_BIT(pAsc->asc_con, ASCCON_BRS); /* BRS = 0 */
else
SET_BIT(pAsc->asc_con, ASCCON_BRS); /* BRS = 1 */
#else /* INCAASC_USE_FDV */
/* Enable Fractional Divider */
SET_BIT(pAsc->asc_con, ASCCON_FDE); /* FDE = 1 */
/* Set fractional divider value */
pAsc->asc_fdv = fdv & ASCFDV_VALUE_MASK;
#endif /* INCAASC_USE_FDV */
/* Set reload value in BG */
pAsc->asc_bg = uiReloadValue;
/* Enable Baud Rate Generator */
SET_BIT(pAsc->asc_con, ASCCON_R); /* R = 1 */
}
/*******************************************************************************
*
* serial_setopt - set the serial options
*
* Set the channel operating mode to that specified. Following options
* are supported: CREAD, CSIZE, PARENB, and PARODD.
*
* Note, this routine disables the transmitter. The calling routine
* may have to re-enable it.
*
* RETURNS:
* Returns 0 to indicate success, otherwise -1 is returned
*/
static int serial_setopt (void)
{
ulong con;
switch ( ASC_OPTIONS & ASCOPT_CSIZE )
{
/* 7-bit-data */
case ASCOPT_CS7:
con = ASCCON_M_7ASYNCPAR; /* 7-bit-data and parity bit */
break;
/* 8-bit-data */
case ASCOPT_CS8:
if ( ASC_OPTIONS & ASCOPT_PARENB )
con = ASCCON_M_8ASYNCPAR; /* 8-bit-data and parity bit */
else
con = ASCCON_M_8ASYNC; /* 8-bit-data no parity */
break;
/*
* only 7 and 8-bit frames are supported
* if we don't use IOCTL extensions
*/
default:
return -1;
}
if ( ASC_OPTIONS & ASCOPT_STOPB )
SET_BIT(con, ASCCON_STP); /* 2 stop bits */
else
CLEAR_BIT(con, ASCCON_STP); /* 1 stop bit */
if ( ASC_OPTIONS & ASCOPT_PARENB )
SET_BIT(con, ASCCON_PEN); /* enable parity checking */
else
CLEAR_BIT(con, ASCCON_PEN); /* disable parity checking */
if ( ASC_OPTIONS & ASCOPT_PARODD )
SET_BIT(con, ASCCON_ODD); /* odd parity */
else
CLEAR_BIT(con, ASCCON_ODD); /* even parity */
if ( ASC_OPTIONS & ASCOPT_CREAD )
SET_BIT(pAsc->asc_whbcon, ASCWHBCON_SETREN); /* Receiver enable */
pAsc->asc_con |= con;
return 0;
}
void serial_putc (const char c)
{
uint txFl = 0;
if (c == '\n') serial_putc ('\r');
/* check do we have a free space in the TX FIFO */
/* get current filling level */
do
{
txFl = ( pAsc->asc_fstat & ASCFSTAT_TXFFLMASK ) >> ASCFSTAT_TXFFLOFF;
}
while ( txFl == INCAASC_TXFIFO_FULL );
pAsc->asc_tbuf = c; /* write char to Transmit Buffer Register */
/* check for errors */
if ( pAsc->asc_con & ASCCON_OE )
{
SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLROE);
return;
}
}
void serial_puts (const char *s)
{
while (*s)
{
serial_putc (*s++);
}
}
int serial_getc (void)
{
ulong symbol_mask;
char c;
while (!serial_tstc());
symbol_mask =
((ASC_OPTIONS & ASCOPT_CSIZE) == ASCOPT_CS7) ? (0x7f) : (0xff);
c = (char)(pAsc->asc_rbuf & symbol_mask);
return c;
}
int serial_tstc (void)
{
int res = 1;
if ( (pAsc->asc_fstat & ASCFSTAT_RXFFLMASK) == 0 )
{
res = 0;
}
else if ( pAsc->asc_con & ASCCON_FE )
{
SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLRFE);
res = 0;
}
else if ( pAsc->asc_con & ASCCON_PE )
{
SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLRPE);
res = 0;
}
else if ( pAsc->asc_con & ASCCON_OE )
{
SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLROE);
res = 0;
}
return res;
}

178
cpu/mips/serial.h Normal file
View File

@@ -0,0 +1,178 @@
/* incaAscSio.h - (INCA) ASC UART tty driver header */
#ifndef __INCincaAscSioh
#define __INCincaAscSioh
#include <asm/inca-ip.h>
/* channel operating modes */
#define ASCOPT_CSIZE 0x00000003
#define ASCOPT_CS7 0x00000001
#define ASCOPT_CS8 0x00000002
#define ASCOPT_PARENB 0x00000004
#define ASCOPT_STOPB 0x00000008
#define ASCOPT_PARODD 0x00000010
#define ASCOPT_CREAD 0x00000020
#define ASC_OPTIONS (ASCOPT_CREAD | ASCOPT_CS8)
/* ASC input select (0 or 1) */
#define CONSOLE_TTY 0
/* use fractional divider for baudrate settings */
#define INCAASC_USE_FDV
#ifdef INCAASC_USE_FDV
#define INCAASC_FDV_LOW_BAUDRATE 71
#define INCAASC_FDV_HIGH_BAUDRATE 453
#endif /*INCAASC_USE_FDV*/
#define INCAASC_TXFIFO_FL 1
#define INCAASC_RXFIFO_FL 1
#define INCAASC_TXFIFO_FULL 16
/* interrupt lines masks for the ASC device interrupts*/
/* change these macroses if it's necessary */
#define INCAASC_IRQ_LINE_ALL 0x000F0000 /* all IRQs */
#define INCAASC_IRQ_LINE_TIR 0x00010000 /* TIR - Tx */
#define INCAASC_IRQ_LINE_RIR 0x00020000 /* RIR - Rx */
#define INCAASC_IRQ_LINE_EIR 0x00040000 /* EIR - Err */
#define INCAASC_IRQ_LINE_TBIR 0x00080000 /* TBIR - Tx Buf*/
/* interrupt controller access macros */
#define ASC_INTERRUPTS_ENABLE(X) \
*((volatile unsigned int*) INCA_IP_ICU_IM2_IER) |= X;
#define ASC_INTERRUPTS_DISABLE(X) \
*((volatile unsigned int*) INCA_IP_ICU_IM2_IER) &= ~X;
#define ASC_INTERRUPTS_CLEAR(X) \
*((volatile unsigned int*) INCA_IP_ICU_IM2_ISR) = X;
/* CLC register's bits and bitfields */
#define ASCCLC_DISR 0x00000001
#define ASCCLC_DISS 0x00000002
#define ASCCLC_RMCMASK 0x0000FF00
#define ASCCLC_RMCOFFSET 8
/* CON register's bits and bitfields */
#define ASCCON_MODEMASK 0x0007
#define ASCCON_M_8SYNC 0x0
#define ASCCON_M_8ASYNC 0x1
#define ASCCON_M_8IRDAASYNC 0x2
#define ASCCON_M_7ASYNCPAR 0x3
#define ASCCON_M_9ASYNC 0x4
#define ASCCON_M_8WAKEUPASYNC 0x5
#define ASCCON_M_8ASYNCPAR 0x7
#define ASCCON_STP 0x0008
#define ASCCON_REN 0x0010
#define ASCCON_PEN 0x0020
#define ASCCON_FEN 0x0040
#define ASCCON_OEN 0x0080
#define ASCCON_PE 0x0100
#define ASCCON_FE 0x0200
#define ASCCON_OE 0x0400
#define ASCCON_FDE 0x0800
#define ASCCON_ODD 0x1000
#define ASCCON_BRS 0x2000
#define ASCCON_LB 0x4000
#define ASCCON_R 0x8000
/* WHBCON register's bits and bitfields */
#define ASCWHBCON_CLRREN 0x0010
#define ASCWHBCON_SETREN 0x0020
#define ASCWHBCON_CLRPE 0x0100
#define ASCWHBCON_CLRFE 0x0200
#define ASCWHBCON_CLROE 0x0400
#define ASCWHBCON_SETPE 0x0800
#define ASCWHBCON_SETFE 0x1000
#define ASCWHBCON_SETOE 0x2000
/* ABCON register's bits and bitfields */
#define ASCABCON_ABEN 0x0001
#define ASCABCON_AUREN 0x0002
#define ASCABCON_ABSTEN 0x0004
#define ASCABCON_ABDETEN 0x0008
#define ASCABCON_FCDETEN 0x0010
#define ASCABCON_EMMASK 0x0300
#define ASCABCON_EMOFF 8
#define ASCABCON_EM_DISAB 0x0
#define ASCABCON_EM_DURAB 0x1
#define ASCABCON_EM_ALWAYS 0x2
#define ASCABCON_TXINV 0x0400
#define ASCABCON_RXINV 0x0800
/* FDV register mask, offset and bitfields*/
#define ASCFDV_VALUE_MASK 0x000001FF
/* WHBABCON register's bits and bitfields */
#define ASCWHBABCON_SETABEN 0x0001
#define ASCWHBABCON_CLRABEN 0x0002
/* ABSTAT register's bits and bitfields */
#define ASCABSTAT_FCSDET 0x0001
#define ASCABSTAT_FCCDET 0x0002
#define ASCABSTAT_SCSDET 0x0004
#define ASCABSTAT_SCCDET 0x0008
#define ASCABSTAT_DETWAIT 0x0010
/* WHBABSTAT register's bits and bitfields */
#define ASCWHBABSTAT_CLRFCSDET 0x0001
#define ASCWHBABSTAT_SETFCSDET 0x0002
#define ASCWHBABSTAT_CLRFCCDET 0x0004
#define ASCWHBABSTAT_SETFCCDET 0x0008
#define ASCWHBABSTAT_CLRSCSDET 0x0010
#define ASCWHBABSTAT_SETSCSDET 0x0020
#define ASCWHBABSTAT_SETSCCDET 0x0040
#define ASCWHBABSTAT_CLRSCCDET 0x0080
#define ASCWHBABSTAT_CLRDETWAIT 0x0100
#define ASCWHBABSTAT_SETDETWAIT 0x0200
/* TXFCON register's bits and bitfields */
#define ASCTXFCON_TXFEN 0x0001
#define ASCTXFCON_TXFFLU 0x0002
#define ASCTXFCON_TXTMEN 0x0004
#define ASCTXFCON_TXFITLMASK 0x3F00
#define ASCTXFCON_TXFITLOFF 8
/* RXFCON register's bits and bitfields */
#define ASCRXFCON_RXFEN 0x0001
#define ASCRXFCON_RXFFLU 0x0002
#define ASCRXFCON_RXTMEN 0x0004
#define ASCRXFCON_RXFITLMASK 0x3F00
#define ASCRXFCON_RXFITLOFF 8
/* FSTAT register's bits and bitfields */
#define ASCFSTAT_RXFFLMASK 0x003F
#define ASCFSTAT_TXFFLMASK 0x3F00
#define ASCFSTAT_TXFFLOFF 8
#define INCAASC_PMU_ENABLE(BIT) *((volatile ulong*)0xBF102000) |= (0x1 << BIT);
typedef struct /* incaAsc_t */
{
volatile unsigned long asc_clc; /*0x0000*/
volatile unsigned long asc_pisel; /*0x0004*/
volatile unsigned long asc_rsvd1[2]; /* for mapping */ /*0x0008*/
volatile unsigned long asc_con; /*0x0010*/
volatile unsigned long asc_bg; /*0x0014*/
volatile unsigned long asc_fdv; /*0x0018*/
volatile unsigned long asc_pmw; /* not used */ /*0x001C*/
volatile unsigned long asc_tbuf; /*0x0020*/
volatile unsigned long asc_rbuf; /*0x0024*/
volatile unsigned long asc_rsvd2[2]; /* for mapping */ /*0x0028*/
volatile unsigned long asc_abcon; /*0x0030*/
volatile unsigned long asc_abstat; /* not used */ /*0x0034*/
volatile unsigned long asc_rsvd3[2]; /* for mapping */ /*0x0038*/
volatile unsigned long asc_rxfcon; /*0x0040*/
volatile unsigned long asc_txfcon; /*0x0044*/
volatile unsigned long asc_fstat; /*0x0048*/
volatile unsigned long asc_rsvd4; /* for mapping */ /*0x004C*/
volatile unsigned long asc_whbcon; /*0x0050*/
volatile unsigned long asc_whbabcon; /*0x0054*/
volatile unsigned long asc_whbabstat; /* not used */ /*0x0058*/
} incaAsc_t;
#endif /* __INCincaAscSioh */

350
cpu/mips/start.S Normal file
View File

@@ -0,0 +1,350 @@
/*
* Startup Code for MIPS32 CPU-core
*
* Copyright (c) 2003 Wolfgang Denk <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 <config.h>
#include <version.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#define RVECENT(f,n) \
b f; nop
#define XVECENT(f,bev) \
b f ; \
li k0,bev
.set noreorder
.globl _start
.text
_start:
RVECENT(reset,0) /* U-boot entry point */
RVECENT(reset,1) /* software reboot */
#ifdef CONFIG_INCA_IP
.word 0x000020C4 /* EBU init code, fetched during booting */
.word 0x00000000 /* phase of the flash */
#else
RVECENT(romReserved,2)
#endif
RVECENT(romReserved,3)
RVECENT(romReserved,4)
RVECENT(romReserved,5)
RVECENT(romReserved,6)
RVECENT(romReserved,7)
RVECENT(romReserved,8)
RVECENT(romReserved,9)
RVECENT(romReserved,10)
RVECENT(romReserved,11)
RVECENT(romReserved,12)
RVECENT(romReserved,13)
RVECENT(romReserved,14)
RVECENT(romReserved,15)
RVECENT(romReserved,16)
RVECENT(romReserved,17)
RVECENT(romReserved,18)
RVECENT(romReserved,19)
RVECENT(romReserved,20)
RVECENT(romReserved,21)
RVECENT(romReserved,22)
RVECENT(romReserved,23)
RVECENT(romReserved,24)
RVECENT(romReserved,25)
RVECENT(romReserved,26)
RVECENT(romReserved,27)
RVECENT(romReserved,28)
RVECENT(romReserved,29)
RVECENT(romReserved,30)
RVECENT(romReserved,31)
RVECENT(romReserved,32)
RVECENT(romReserved,33)
RVECENT(romReserved,34)
RVECENT(romReserved,35)
RVECENT(romReserved,36)
RVECENT(romReserved,37)
RVECENT(romReserved,38)
RVECENT(romReserved,39)
RVECENT(romReserved,40)
RVECENT(romReserved,41)
RVECENT(romReserved,42)
RVECENT(romReserved,43)
RVECENT(romReserved,44)
RVECENT(romReserved,45)
RVECENT(romReserved,46)
RVECENT(romReserved,47)
RVECENT(romReserved,48)
RVECENT(romReserved,49)
RVECENT(romReserved,50)
RVECENT(romReserved,51)
RVECENT(romReserved,52)
RVECENT(romReserved,53)
RVECENT(romReserved,54)
RVECENT(romReserved,55)
RVECENT(romReserved,56)
RVECENT(romReserved,57)
RVECENT(romReserved,58)
RVECENT(romReserved,59)
RVECENT(romReserved,60)
RVECENT(romReserved,61)
RVECENT(romReserved,62)
RVECENT(romReserved,63)
XVECENT(romExcHandle,0x200) /* bfc00200: R4000 tlbmiss vector */
RVECENT(romReserved,65)
RVECENT(romReserved,66)
RVECENT(romReserved,67)
RVECENT(romReserved,68)
RVECENT(romReserved,69)
RVECENT(romReserved,70)
RVECENT(romReserved,71)
RVECENT(romReserved,72)
RVECENT(romReserved,73)
RVECENT(romReserved,74)
RVECENT(romReserved,75)
RVECENT(romReserved,76)
RVECENT(romReserved,77)
RVECENT(romReserved,78)
RVECENT(romReserved,79)
XVECENT(romExcHandle,0x280) /* bfc00280: R4000 xtlbmiss vector */
RVECENT(romReserved,81)
RVECENT(romReserved,82)
RVECENT(romReserved,83)
RVECENT(romReserved,84)
RVECENT(romReserved,85)
RVECENT(romReserved,86)
RVECENT(romReserved,87)
RVECENT(romReserved,88)
RVECENT(romReserved,89)
RVECENT(romReserved,90)
RVECENT(romReserved,91)
RVECENT(romReserved,92)
RVECENT(romReserved,93)
RVECENT(romReserved,94)
RVECENT(romReserved,95)
XVECENT(romExcHandle,0x300) /* bfc00300: R4000 cache vector */
RVECENT(romReserved,97)
RVECENT(romReserved,98)
RVECENT(romReserved,99)
RVECENT(romReserved,100)
RVECENT(romReserved,101)
RVECENT(romReserved,102)
RVECENT(romReserved,103)
RVECENT(romReserved,104)
RVECENT(romReserved,105)
RVECENT(romReserved,106)
RVECENT(romReserved,107)
RVECENT(romReserved,108)
RVECENT(romReserved,109)
RVECENT(romReserved,110)
RVECENT(romReserved,111)
XVECENT(romExcHandle,0x380) /* bfc00380: R4000 general vector */
RVECENT(romReserved,113)
RVECENT(romReserved,114)
RVECENT(romReserved,115)
RVECENT(romReserved,116)
RVECENT(romReserved,116)
RVECENT(romReserved,118)
RVECENT(romReserved,119)
RVECENT(romReserved,120)
RVECENT(romReserved,121)
RVECENT(romReserved,122)
RVECENT(romReserved,123)
RVECENT(romReserved,124)
RVECENT(romReserved,125)
RVECENT(romReserved,126)
RVECENT(romReserved,127)
/* We hope there are no more reserved vectors!
* 128 * 8 == 1024 == 0x400
* so this is address R_VEC+0x400 == 0xbfc00400
*/
.align 4
reset:
/* Clear watch registers.
*/
mtc0 zero, CP0_WATCHLO
mtc0 zero, CP0_WATCHHI
/* STATUS register */
mfc0 k0, CP0_STATUS
li k1, ~ST0_IE
and k0, k1
mtc0 k0, CP0_STATUS
/* CAUSE register */
mtc0 zero, CP0_CAUSE
/* Init Timer */
mtc0 zero, CP0_COUNT
mtc0 zero, CP0_COMPARE
/* CONFIG0 register */
li t0, CONF_CM_UNCACHED
mtc0 t0, CP0_CONFIG
#ifdef CONFIG_INCA_IP
/* Disable INCA-IP Watchdog.
*/
bal disable_incaip_wdt
nop
#endif
/* Initialize any external memory.
*/
bal memsetup
nop
/* Initialize caches...
*/
bal mips_cache_reset
nop
/* ... and enable them.
*/
li t0, CONF_CM_CACHABLE_NONCOHERENT
mtc0 t0, CP0_CONFIG
/* Set up temporary stack.
*/
li a0, CFG_INIT_SP_OFFSET
bal mips_cache_lock
nop
li t0, CFG_SDRAM_BASE + CFG_INIT_SP_OFFSET
la sp, 0(t0)
/* Initialize GOT pointer.
*/
bal 1f
nop
.word _GLOBAL_OFFSET_TABLE_ - 1f + 4
1:
move gp, ra
lw t1, 0(ra)
add gp, t1
la t9, board_init_f
j t9
nop
/*
* void relocate_code (addr_sp, gd, addr_moni)
*
* This "function" does not return, instead it continues in RAM
* after relocating the monitor code.
*
* a0 = addr_sp
* a1 = gd
* a2 = destination address
*/
.globl relocate_code
.ent relocate_code
relocate_code:
move sp, a0 /* Set new stack pointer */
/*
* Fix GOT pointer:
*
* New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
*/
move t6, gp
sub gp, CFG_MONITOR_BASE
add gp, a2 /* gp now adjusted */
sub t6, gp, t6 /* t6 <-- relocation offset */
li t0, CFG_MONITOR_BASE
add t2, t0, CFG_MONITOR_LEN
move t1, a2
/*
* t0 = source address
* t1 = target address
* t2 = source end address
*/
1:
lw t3, 0(t0)
sw t3, 0(t1)
addu t0, 4
ble t0, t2, 1b
addu t1, 4 /* delay slot */
/* If caches were enabled, we would have to flush them here.
*/
/* Jump to where we've relocated ourselves.
*/
addi t0, a2, in_ram - _start
j t0
nop
.word uboot_end_data
.word uboot_end
.word num_got_entries
in_ram:
/* Now we want to update GOT.
*/
lw t3, -4(t0) /* t3 <-- num_got_entries */
addi t4, gp, 8 /* Skipping first two entries. */
li t2, 2
1:
lw t1, 0(t4)
beqz t1, 2f
add t1, t6
sw t1, 0(t4)
2:
addi t2, 1
blt t2, t3, 1b
addi t4, 4 /* delay slot */
/* Clear BSS.
*/
lw t1, -12(t0) /* t1 <-- uboot_end_data */
lw t2, -8(t0) /* t2 <-- uboot_end */
add t1, t6 /* adjust pointers */
add t2, t6
sub t1, 4
1: addi t1, 4
bltl t1, t2, 1b
sw zero, 0(t1) /* delay slot */
move a0, a1
la t9, board_init_r
j t9
move a1, a2 /* delay slot */
.end relocate_code
/* Exception handlers.
*/
romReserved:
b romReserved
romExcHandle:
b romExcHandle

View File

@@ -54,9 +54,11 @@ void cpu_init_f (volatile immap_t * immr)
#endif /* CONFIG_WATCHDOG */
/* SIUMCR - contains debug pin configuration (11-6) */
#ifndef CONFIG_SVM_SC8xx
immr->im_siu_conf.sc_siumcr |= CFG_SIUMCR;
#else
immr->im_siu_conf.sc_siumcr = CFG_SIUMCR;
#endif
/* initialize timebase status and control register (11-26) */
/* unlock TBSCRK */

View File

@@ -53,17 +53,19 @@ void serial_setbrg (void)
hang ();
#ifdef CONFIG_SERIAL1
/* SA1110 uart function */
Ser1SDCR0 |= SDCR0_SUS;
/* Wait until port is ready ... */
while (Ser1UTSR1 & UTSR1_TBY) {
}
while(Ser1UTSR1 & UTSR1_TBY) {}
/* init serial serial 1 */
Ser1UTCR3 = 0x00;
Ser1UTSR0 = 0xff;
Ser1UTCR0 = (UTCR0_1StpBit | UTCR0_8BitData);
Ser1UTCR0 = ( UTCR0_1StpBit | UTCR0_8BitData );
Ser1UTCR1 = 0;
Ser1UTCR2 = (u32) reg;
Ser1UTCR3 = (UTCR3_RXE | UTCR3_TXE);
Ser1UTCR2 = (u32)reg;
Ser1UTCR3 = ( UTCR3_RXE | UTCR3_TXE );
#elif CONFIG_SERIAL3
/* Wait until port is ready ... */
while (Ser3UTSR1 & UTSR1_TBY) {

View File

@@ -27,7 +27,8 @@ include $(TOPDIR)/config.mk
LIB = libdrivers.a
OBJS = 3c589.o 5701rls.o bcm570x.o bcm570x_autoneg.o \
OBJS = 3c589.o 5701rls.o at91rm9200_ether.o \
bcm570x.o bcm570x_autoneg.o \
cfb_console.o cs8900.o ct69000.o dc2114x.o \
eepro100.o i8042.o inca-ip_sw.o \
natsemi.o ns16550.o ns8382x.o ns87308.o \

251
drivers/at91rm9200_ether.c Normal file
View File

@@ -0,0 +1,251 @@
#include <common.h>
#include <command.h>
#include <AT91RM9200.h>
#include <net.h>
/* ----- Ethernet Buffer definitions ----- */
typedef struct {
unsigned long addr,size;
} rbf_t;
#define RBF_ADDR 0xfffffffc
#define RBF_OWNER (1<<0)
#define RBF_WRAP (1<<1)
#define RBF_BROADCAST (1<<31)
#define RBF_MULTICAST (1<<30)
#define RBF_UNICAST (1<<29)
#define RBF_EXTERNAL (1<<28)
#define RBF_UNKOWN (1<<27)
#define RBF_SIZE 0x07ff
#define RBF_LOCAL4 (1<<26)
#define RBF_LOCAL3 (1<<25)
#define RBF_LOCAL2 (1<<24)
#define RBF_LOCAL1 (1<<23)
#define RBF_FRAMEMAX 10
#define RBF_FRAMEMEM 0x200000
#define RBF_FRAMELEN 0x600
#define RBF_FRAMEBTD RBF_FRAMEMEM
#define RBF_FRAMEBUF (RBF_FRAMEMEM + RBF_FRAMEMAX*sizeof(rbf_t))
/* stolen from mii.h */
/* Generic MII registers. */
#define MII_BMCR 0x00 /* Basic mode control register */
#define MII_BMSR 0x01 /* Basic mode status register */
#define BMSR_JCD 0x0002 /* Jabber detected */
#define BMSR_LSTATUS 0x0004 /* Link status */
#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
#define MII_STS2_REG 17 /* Davicom specific */
#define MII_MDINTR_REG 21 /* Davicom specific */
#ifdef CONFIG_DRIVER_ETHER
#if (CONFIG_COMMANDS & CFG_CMD_NET)
AT91PS_EMAC p_mac;
int MII_ReadPhy(unsigned char addr, unsigned short *ret)
{
p_mac->EMAC_MAN = 0x60020000 | (addr << 18);
udelay(10000);
*ret = (unsigned short)p_mac->EMAC_MAN;
return 1;
}
int MII_GetLinkSpeed(void)
{
unsigned short stat1, stat2;
int ret;
if (!(ret = MII_ReadPhy(MII_BMSR, &stat1)))
return 0;
if (stat1 & BMSR_JCD)
{
#ifdef DEBUG
printf("MII: jabber condition detected\n");
#endif /*jabber detected re-read the register*/
}
if (!(ret = MII_ReadPhy(MII_BMSR, &stat1)))
return 0;
if (!(stat1 & BMSR_LSTATUS)) /* link status up? */
{
printf("MII: no Link\n");
return 0;
}
if (!(ret = MII_ReadPhy(MII_STS2_REG, &stat2)))
return 0;
if ((stat1 & BMSR_100FULL) && (stat2 & 0x8000) )
{
/* set MII for 100BaseTX and Full Duplex */
p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
#ifdef DEBUG
printf("MII: 100BaseTX and Full Duplex detected\n");
#endif
return 1;
}
else
if ((stat1 & BMSR_10FULL) && (stat2 & 0x2000))
{
/* set MII for 10BaseT and Full Duplex */
p_mac->EMAC_CFG = (p_mac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD));
#ifdef DEBUG
printf("MII: 10BaseT and Full Duplex detected\n");
#endif
return 1;
}
else
if ((stat1 & BMSR_100HALF) && (stat2 & 0x4000))
{
/* set MII for 100BaseTX and Half Duplex */
p_mac->EMAC_CFG = (p_mac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD));
#ifdef DEBUG
printf("MII: 100BaseTX and Hall Duplex detected\n");
#endif
return 1;
}
else
if ((stat1 & BMSR_10HALF) && (stat2 & 0x1000))
{
/*set MII for 10BaseT and Half Duplex */
p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
#ifdef DEBUG
printf("MII: 10BaseT and Hall Duplex detected\n");
#endif
return 1;
}
return 0;
}
int MDIO_StartupPhy(void)
{
int ret;
if(p_mac->EMAC_SR & AT91C_EMAC_LINK)
{
printf("MDIO_StartupPhy: no link\n");
return 0;
};
p_mac->EMAC_CTL |= AT91C_EMAC_MPE;
ret = MII_GetLinkSpeed();
if (ret == 0)
{
printf("MDIO_StartupPhy: MII_GetLinkSpeed failed\n");
ret = 0;
}
else
{
ret = 1;
}
p_mac->EMAC_CTL &= ~AT91C_EMAC_MPE;
return ret;
}
rbf_t* rbfdt;
rbf_t* rbfp;
int eth_init( bd_t *bd )
{
int ret;
int i;
p_mac = AT91C_BASE_EMAC;
*AT91C_PIOA_PDR = AT91C_PA16_EMDIO |
AT91C_PA15_EMDC | AT91C_PA14_ERXER | AT91C_PA13_ERX1 | AT91C_PA12_ERX0 |
AT91C_PA11_ECRS_ECRSDV | AT91C_PA10_ETX1 | AT91C_PA9_ETX0 | AT91C_PA8_ETXEN |
AT91C_PA7_ETXCK_EREFCK; /* PIO Disable Register */
*AT91C_PIOB_PDR = AT91C_PB25_EF100 |
AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV | AT91C_PB16_ERX3 |
AT91C_PB15_ERX2 | AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2;
*AT91C_PIOB_BSR = AT91C_PB25_EF100 |
AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV | AT91C_PB16_ERX3 |
AT91C_PB15_ERX2 | AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2; /* Select B Register */
*AT91C_PMC_PCER = 1 << AT91C_ID_EMAC; /* Peripheral Clock Enable Register */
p_mac->EMAC_CFG |= AT91C_EMAC_CSR; /* Clear statistics */
rbfdt=(rbf_t *)RBF_FRAMEBTD;
for(i = 0; i < RBF_FRAMEMAX; i++)
{
rbfdt[i].addr=RBF_FRAMEBUF+RBF_FRAMELEN*i;
rbfdt[i].size=0;
}
rbfdt[RBF_FRAMEMAX-1].addr|=RBF_WRAP;
rbfp=&rbfdt[0];
if (!(ret = MDIO_StartupPhy()))
{
printf("MAC: error during MII initialization\n");
return 0;
}
p_mac->EMAC_SA2L = (bd->bi_enetaddr[3] << 24) | (bd->bi_enetaddr[2] << 16)
| (bd->bi_enetaddr[1] << 8) | (bd->bi_enetaddr[0]);
p_mac->EMAC_SA2H = (bd->bi_enetaddr[5] << 8) | (bd->bi_enetaddr[4]);
p_mac->EMAC_RBQP = (long)(&rbfdt[0]);
p_mac->EMAC_RSR &= ~(AT91C_EMAC_RSR_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
p_mac->EMAC_CFG = (p_mac->EMAC_CFG | AT91C_EMAC_CAF | AT91C_EMAC_NBC | AT91C_EMAC_RMII) & ~AT91C_EMAC_CLK;
p_mac->EMAC_CTL |= AT91C_EMAC_TE | AT91C_EMAC_RE ;
return 0;
}
int eth_send(volatile void *packet, int length)
{
while(!(p_mac->EMAC_TSR & AT91C_EMAC_BNQ))
;
p_mac->EMAC_TAR = (long)packet;
p_mac->EMAC_TCR = length;
while(p_mac->EMAC_TCR & 0x7ff)
;
p_mac->EMAC_TSR |= AT91C_EMAC_COMP;
return 0;
}
int eth_rx(void)
{
int size;
if(!(rbfp->addr & RBF_OWNER))
return 0;
size=rbfp->size & RBF_SIZE;
NetReceive((volatile uchar *) (rbfp->addr & RBF_ADDR), size);
rbfp->addr &= ~RBF_OWNER;
if(rbfp->addr & RBF_WRAP)
rbfp = &rbfdt[0];
else
rbfp++;
p_mac->EMAC_RSR |= AT91C_EMAC_REC;
return size;
}
void eth_halt( void )
{};
#endif
#endif

View File

@@ -0,0 +1,646 @@
/*
* INCA-IP internal switch ethernet driver.
*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) \
&& defined(CONFIG_INCA_IP_SWITCH)
#include <malloc.h>
#include <net.h>
#include <asm/inca-ip.h>
#include <asm/addrspace.h>
#define NUM_RX_DESC PKTBUFSRX
#define NUM_TX_DESC 3
#define TOUT_LOOP 1000000
#define DELAY udelay(10000)
#define DMA_WRITE_REG(reg, value) *((volatile u32 *)reg) = (u32)value;
#define DMA_READ_REG(reg, value) value = (u32)*((volatile u32*)reg)
#define SW_WRITE_REG(reg, value) \
*((volatile u32*)reg) = (u32)value;\
DELAY;\
*((volatile u32*)reg) = (u32)value;
#define SW_READ_REG(reg, value) \
value = (u32)*((volatile u32*)reg);\
DELAY;\
value = (u32)*((volatile u32*)reg);
#define INCA_DMA_TX_POLLING_TIME 0x07
#define INCA_DMA_RX_POLLING_TIME 0x07
#define INCA_DMA_TX_HOLD 0x80000000
#define INCA_DMA_TX_EOP 0x40000000
#define INCA_DMA_TX_SOP 0x20000000
#define INCA_DMA_TX_ICPT 0x10000000
#define INCA_DMA_TX_IEOP 0x08000000
#define INCA_DMA_RX_C 0x80000000
#define INCA_DMA_RX_SOP 0x40000000
#define INCA_DMA_RX_EOP 0x20000000
typedef struct
{
union
{
struct
{
volatile u32 HOLD :1;
volatile u32 ICpt :1;
volatile u32 IEop :1;
volatile u32 offset :3;
volatile u32 reserved0 :4;
volatile u32 NFB :22;
}field;
volatile u32 word;
}params;
volatile u32 nextRxDescPtr;
volatile u32 RxDataPtr;
union
{
struct
{
volatile u32 C :1;
volatile u32 Sop :1;
volatile u32 Eop :1;
volatile u32 reserved3 :12;
volatile u32 NBT :17;
}field;
volatile u32 word;
}status;
} inca_rx_descriptor_t;
typedef struct
{
union
{
struct
{
volatile u32 HOLD :1;
volatile u32 Eop :1;
volatile u32 Sop :1;
volatile u32 ICpt :1;
volatile u32 IEop :1;
volatile u32 reserved0 :5;
volatile u32 NBA :22;
}field;
volatile u32 word;
}params;
volatile u32 nextTxDescPtr;
volatile u32 TxDataPtr;
volatile u32 C :1;
volatile u32 reserved3 :31;
} inca_tx_descriptor_t;
static inca_rx_descriptor_t rx_ring[NUM_RX_DESC] __attribute__ ((aligned(16)));
static inca_tx_descriptor_t tx_ring[NUM_TX_DESC] __attribute__ ((aligned(16)));
static int tx_new, rx_new, tx_hold, rx_hold;
static int tx_old_hold = -1;
static int initialized = 0;
static int inca_switch_init(struct eth_device *dev, bd_t * bis);
static int inca_switch_send(struct eth_device *dev, volatile void *packet,
int length);
static int inca_switch_recv(struct eth_device *dev);
static void inca_switch_halt(struct eth_device *dev);
static void inca_init_switch_chip(void);
static void inca_dma_init(void);
int inca_switch_initialize(bd_t * bis)
{
struct eth_device *dev;
#if 0
printf("Entered inca_switch_initialize()\n");
#endif
if (!(dev = (struct eth_device *) malloc (sizeof *dev)))
{
printf("Failed to allocate memory\n");
return 0;
}
memset(dev, 0, sizeof(*dev));
inca_dma_init();
inca_init_switch_chip();
sprintf(dev->name, "INCA-IP Switch");
dev->init = inca_switch_init;
dev->halt = inca_switch_halt;
dev->send = inca_switch_send;
dev->recv = inca_switch_recv;
eth_register(dev);
#if 0
printf("Leaving inca_switch_initialize()\n");
#endif
return 1;
}
static int inca_switch_init(struct eth_device *dev, bd_t * bis)
{
int i;
u32 v, regValue;
u16 wTmp;
#if 0
printf("Entering inca_switch_init()\n");
#endif
/* Set MAC address.
*/
wTmp = (u16)dev->enetaddr[0];
regValue = (wTmp << 8) | dev->enetaddr[1];
SW_WRITE_REG(INCA_IP_Switch_PMAC_SA1, regValue);
wTmp = (u16)dev->enetaddr[2];
regValue = (wTmp << 8) | dev->enetaddr[3];
regValue = regValue << 16;
wTmp = (u16)dev->enetaddr[4];
regValue |= (wTmp<<8) | dev->enetaddr[5];
SW_WRITE_REG(INCA_IP_Switch_PMAC_SA2, regValue);
/* Initialize the descriptor rings.
*/
for (i = 0; i < NUM_RX_DESC; i++)
{
inca_rx_descriptor_t * rx_desc = KSEG1ADDR(&rx_ring[i]);
memset(rx_desc, 0, sizeof(rx_ring[i]));
/* Set maximum size of receive buffer.
*/
rx_desc->params.field.NFB = PKTSIZE_ALIGN;
/* Set the offset of the receive buffer. Zero means
* that the offset mechanism is not used.
*/
rx_desc->params.field.offset = 0;
/* Check if it is the last descriptor.
*/
if (i == (NUM_RX_DESC - 1))
{
/* Let the last descriptor point to the first
* one.
*/
rx_desc->nextRxDescPtr = KSEG1ADDR((u32)rx_ring);
}
else
{
/* Set the address of the next descriptor.
*/
rx_desc->nextRxDescPtr = (u32)KSEG1ADDR(&rx_ring[i+1]);
}
rx_desc->RxDataPtr = (u32)KSEG1ADDR(NetRxPackets[i]);
}
#if 0
printf("rx_ring = 0x%08X 0x%08X\n", (u32)rx_ring, (u32)&rx_ring[0]);
printf("tx_ring = 0x%08X 0x%08X\n", (u32)tx_ring, (u32)&tx_ring[0]);
#endif
for (i = 0; i < NUM_TX_DESC; i++)
{
inca_tx_descriptor_t * tx_desc = KSEG1ADDR(&tx_ring[i]);
memset(tx_desc, 0, sizeof(tx_ring[i]));
tx_desc->params.word = 0;
tx_desc->params.field.HOLD = 1;
tx_desc->C = 1;
/* Check if it is the last descriptor.
*/
if (i == (NUM_TX_DESC - 1))
{
/* Let the last descriptor point to the
* first one.
*/
tx_desc->nextTxDescPtr = KSEG1ADDR((u32)tx_ring);
}
else
{
/* Set the address of the next descriptor.
*/
tx_desc->nextTxDescPtr = (u32)KSEG1ADDR(&tx_ring[i+1]);
}
}
/* Initialize RxDMA.
*/
DMA_READ_REG(INCA_IP_DMA_DMA_RXISR, v);
#if 0
printf("RX status = 0x%08X\n", v);
#endif
/* Writing to the FRDA of CHANNEL.
*/
DMA_WRITE_REG(INCA_IP_DMA_DMA_RXFRDA0, (u32)rx_ring);
/* Writing to the COMMAND REG.
*/
DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR0,
INCA_IP_DMA_DMA_RXCCR0_INIT);
/* Initialize TxDMA.
*/
DMA_READ_REG(INCA_IP_DMA_DMA_TXISR, v);
#if 0
printf("TX status = 0x%08X\n", v);
#endif
/* Writing to the FRDA of CHANNEL.
*/
DMA_WRITE_REG(INCA_IP_DMA_DMA_TXFRDA0, (u32)tx_ring);
tx_new = rx_new = 0;
tx_hold = NUM_TX_DESC - 1;
rx_hold = NUM_RX_DESC - 1;
#if 0
rx_ring[rx_hold].params.field.HOLD = 1;
#endif
/* enable spanning tree forwarding, enable the CPU port */
/* ST_PT:
CPS (CPU port status) 0x3 (forwarding)
LPS (LAN port status) 0x3 (forwarding)
PPS (PC port status) 0x3 (forwarding)
*/
SW_WRITE_REG(INCA_IP_Switch_ST_PT,0x3f);
#if 0
printf("Leaving inca_switch_init()\n");
#endif
return 0;
}
static int inca_switch_send(struct eth_device *dev, volatile void *packet,
int length)
{
int i;
int res = -1;
u32 command;
u32 regValue;
inca_tx_descriptor_t * tx_desc = KSEG1ADDR(&tx_ring[tx_new]);
#if 0
printf("Entered inca_switch_send()\n");
#endif
if (length <= 0)
{
printf ("%s: bad packet size: %d\n", dev->name, length);
goto Done;
}
for(i = 0; tx_desc->C == 0; i++)
{
if (i >= TOUT_LOOP)
{
printf("%s: tx error buffer not ready\n", dev->name);
goto Done;
}
}
if (tx_old_hold >= 0)
{
KSEG1ADDR(&tx_ring[tx_old_hold])->params.field.HOLD = 1;
}
tx_old_hold = tx_hold;
tx_desc->params.word =
(INCA_DMA_TX_SOP | INCA_DMA_TX_EOP | INCA_DMA_TX_HOLD);
tx_desc->C = 0;
tx_desc->TxDataPtr = (u32)packet;
tx_desc->params.field.NBA = length;
KSEG1ADDR(&tx_ring[tx_hold])->params.field.HOLD = 0;
tx_hold = tx_new;
tx_new = (tx_new + 1) % NUM_TX_DESC;
if (! initialized)
{
command = INCA_IP_DMA_DMA_TXCCR0_INIT;
initialized = 1;
}
else
{
command = INCA_IP_DMA_DMA_TXCCR0_HR;
}
DMA_READ_REG(INCA_IP_DMA_DMA_TXCCR0, regValue);
regValue |= command;
#if 0
printf("regValue = 0x%x\n", regValue);
#endif
DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR0, regValue);
#if 1
for(i = 0; KSEG1ADDR(&tx_ring[tx_hold])->C == 0; i++)
{
if (i >= TOUT_LOOP)
{
printf("%s: tx buffer not ready\n", dev->name);
goto Done;
}
}
#endif
res = length;
Done:
#if 0
printf("Leaving inca_switch_send()\n");
#endif
return res;
}
static int inca_switch_recv(struct eth_device *dev)
{
int length = 0;
inca_rx_descriptor_t * rx_desc;
#if 0
printf("Entered inca_switch_recv()\n");
#endif
for (;;)
{
rx_desc = KSEG1ADDR(&rx_ring[rx_new]);
if (rx_desc->status.field.C == 0)
{
break;
}
#if 0
rx_ring[rx_new].params.field.HOLD = 1;
#endif
if (! rx_desc->status.field.Eop)
{
printf("Partly received packet!!!\n");
break;
}
length = rx_desc->status.field.NBT;
rx_desc->status.word &=
~(INCA_DMA_RX_EOP | INCA_DMA_RX_SOP | INCA_DMA_RX_C);
#if 0
{
int i;
for (i=0;i<length - 4;i++) {
if (i % 16 == 0) printf("\n%04x: ", i);
printf("%02X ", NetRxPackets[rx_new][i]);
}
printf("\n");
}
#endif
if (length)
{
#if 0
printf("Received %d bytes\n", length);
#endif
NetReceive((void*)KSEG1ADDR(NetRxPackets[rx_new]),
length - 4);
}
else
{
#if 1
printf("Zero length!!!\n");
#endif
}
KSEG1ADDR(&rx_ring[rx_hold])->params.field.HOLD = 0;
rx_hold = rx_new;
rx_new = (rx_new + 1) % NUM_RX_DESC;
}
#if 0
printf("Leaving inca_switch_recv()\n");
#endif
return length;
}
static void inca_switch_halt(struct eth_device *dev)
{
#if 0
printf("Entered inca_switch_halt()\n");
#endif
#if 1
initialized = 0;
#endif
#if 1
/* Disable forwarding to the CPU port.
*/
SW_WRITE_REG(INCA_IP_Switch_ST_PT,0xf);
/* Close RxDMA channel.
*/
DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR0, INCA_IP_DMA_DMA_RXCCR0_OFF);
/* Close TxDMA channel.
*/
DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR0, INCA_IP_DMA_DMA_TXCCR0_OFF);
#endif
#if 0
printf("Leaving inca_switch_halt()\n");
#endif
}
static void inca_init_switch_chip(void)
{
u32 regValue;
/* To workaround a problem with collision counter
* (see Errata sheet).
*/
SW_WRITE_REG(INCA_IP_Switch_PC_TX_CTL, 0x00000001);
SW_WRITE_REG(INCA_IP_Switch_LAN_TX_CTL, 0x00000001);
#if 1
/* init MDIO configuration:
MDS (Poll speed): 0x01 (4ms)
PHY_LAN_ADDR: 0x06
PHY_PC_ADDR: 0x05
UEP (Use External PHY): 0x00 (Internal PHY is used)
PS (Port Select): 0x00 (PT/UMM for LAN)
PT (PHY Test): 0x00 (no test mode)
UMM (Use MDIO Mode): 0x00 (state machine is disabled)
*/
SW_WRITE_REG(INCA_IP_Switch_MDIO_CFG, 0x4c50);
/* init PHY:
SL (Auto Neg. Speed for LAN)
SP (Auto Neg. Speed for PC)
LL (Link Status for LAN)
LP (Link Status for PC)
DL (Duplex Status for LAN)
DP (Duplex Status for PC)
PL (Auto Neg. Pause Status for LAN)
PP (Auto Neg. Pause Status for PC)
*/
SW_WRITE_REG (INCA_IP_Switch_EPHY, 0xff);
/* MDIO_ACC:
RA (Request/Ack) 0x01 (Request)
RW (Read/Write) 0x01 (Write)
PHY_ADDR 0x05 (PC)
REG_ADDR 0x00 (PHY_BCR: basic control register)
PHY_DATA 0x8000
Reset - software reset
LB (loop back) - normal
SS (speed select) - 10 Mbit/s
ANE (auto neg. enable) - disable
PD (power down) - normal
ISO (isolate) - normal
RAN (restart auto neg.) - normal
DM (duplex mode) - half duplex
CT (collision test) - enable
*/
SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC, 0xc0a08000);
/* MDIO_ACC:
RA (Request/Ack) 0x01 (Request)
RW (Read/Write) 0x01 (Write)
PHY_ADDR 0x06 (LAN)
REG_ADDR 0x00 (PHY_BCR: basic control register)
PHY_DATA 0x8000
Reset - software reset
LB (loop back) - normal
SS (speed select) - 10 Mbit/s
ANE (auto neg. enable) - disable
PD (power down) - normal
ISO (isolate) - normal
RAN (restart auto neg.) - normal
DM (duplex mode) - half duplex
CT (collision test) - enable
*/
SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC, 0xc0c08000);
#endif
/* Make sure the CPU port is disabled for now. We
* don't want packets to get stacked for us until
* we enable DMA and are prepared to receive them.
*/
SW_WRITE_REG(INCA_IP_Switch_ST_PT,0xf);
SW_READ_REG(INCA_IP_Switch_ARL_CTL, regValue);
/* CRC GEN is enabled.
*/
regValue |= 0x00000200;
SW_WRITE_REG(INCA_IP_Switch_ARL_CTL, regValue);
/* ADD TAG is disabled.
*/
SW_READ_REG(INCA_IP_Switch_PMAC_HD_CTL, regValue);
regValue &= ~0x00000002;
SW_WRITE_REG(INCA_IP_Switch_PMAC_HD_CTL, regValue);
}
static void inca_dma_init(void)
{
/* Switch off all DMA channels.
*/
DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR0, INCA_IP_DMA_DMA_RXCCR0_OFF);
DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR1, INCA_IP_DMA_DMA_RXCCR1_OFF);
DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR0, INCA_IP_DMA_DMA_RXCCR0_OFF);
DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR1, INCA_IP_DMA_DMA_TXCCR1_OFF);
DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR2, INCA_IP_DMA_DMA_TXCCR2_OFF);
/* Setup TX channel polling time.
*/
DMA_WRITE_REG(INCA_IP_DMA_DMA_TXPOLL, INCA_DMA_TX_POLLING_TIME);
/* Setup RX channel polling time.
*/
DMA_WRITE_REG(INCA_IP_DMA_DMA_RXPOLL, INCA_DMA_RX_POLLING_TIME);
/* ERRATA: write reset value into the DMA RX IMR register.
*/
DMA_WRITE_REG(INCA_IP_DMA_DMA_RXIMR, 0xFFFFFFFF);
/* Just in case: disable all transmit interrupts also.
*/
DMA_WRITE_REG(INCA_IP_DMA_DMA_TXIMR, 0xFFFFFFFF);
DMA_WRITE_REG(INCA_IP_DMA_DMA_TXISR, 0xFFFFFFFF);
DMA_WRITE_REG(INCA_IP_DMA_DMA_RXISR, 0xFFFFFFFF);
}
#endif
/* End of file.
*/

View File

@@ -493,6 +493,13 @@ static int smc_send_packet(volatile void *packet, int packet_length)
SMC_SELECT_BANK( 2 );
SMC_outw( MC_ALLOC | numPages, MMU_CMD_REG );
/* FIXME: the ALLOC_INT bit never gets set *
* so the following will always give a *
* memory allocation error. *
* same code works in armboot though *
* -ro
*/
again:
try++;
time_out = MEMORY_WAIT_TIME;

View File

@@ -26,9 +26,11 @@ LOAD_ADDR = 0x40000
include $(TOPDIR)/config.mk
SREC = hello_world.srec
BIN = hello_world.bin
ifeq ($(CPU),mips)
SREC =
BIN =
endif
# The following example is pretty 8xx specific...
@@ -50,7 +52,7 @@ LIBOBJS = $(LIBAOBJS) $(LIBCOBJS)
CPPFLAGS += -I..
all: .depend $(LIB) $(SREC)
all: .depend $(LIB) $(SREC) $(BIN)
#########################################################################
$(LIB): .depend $(LIBOBJS)
@@ -60,6 +62,9 @@ $(LIB): .depend $(LIBOBJS)
$(LD) -g -Ttext $(LOAD_ADDR) -o $(<:.o=) -e $(<:.o=) $< $(LIB)
$(OBJCOPY) -O srec $(<:.o=) $@
%.bin: %.srec
$(OBJCOPY) -O binary $< $@ 2>/dev/null
#########################################################################
.depend: Makefile $(OBJS:.o=.c) $(LIBCOBJS:.o=.c) $(LIBAOBJS:.o=.S)

349
include/AT91RM9200.h Normal file
View File

@@ -0,0 +1,349 @@
/* ---------------------------------------------------------------------------- */
/* ATMEL Microcontroller Software Support - ROUSSET - */
/* ---------------------------------------------------------------------------- */
/* The software is delivered "AS IS" without warranty or condition of any */
/* kind, either express, implied or statutory. This includes without */
/* limitation any warranty or condition with respect to merchantability or */
/* fitness for any particular purpose, or against the infringements of */
/* intellectual property rights of others. */
/* ---------------------------------------------------------------------------- */
/* File Name : AT91RM9200.h */
/* Object : AT91RM9200 definitions */
/* Generated : AT91 SW Application Group 10/29/2002 (16:10:51) */
#ifndef AT91RM9200_H
#define AT91RM9200_H
typedef volatile unsigned int AT91_REG;/* Hardware register definition */
/* ***************************************************************************** */
/* SOFTWARE API DEFINITION FOR Timer Counter Channel Interface */
/* ***************************************************************************** */
typedef struct _AT91S_TC {
AT91_REG TC_CCR; /* Channel Control Register */
AT91_REG TC_CMR; /* Channel Mode Register */
AT91_REG Reserved0[2]; /* */
AT91_REG TC_CV; /* Counter Value */
AT91_REG TC_RA; /* Register A */
AT91_REG TC_RB; /* Register B */
AT91_REG TC_RC; /* Register C */
AT91_REG TC_SR; /* Status Register */
AT91_REG TC_IER; /* Interrupt Enable Register */
AT91_REG TC_IDR; /* Interrupt Disable Register */
AT91_REG TC_IMR; /* Interrupt Mask Register */
} AT91S_TC, *AT91PS_TC;
/* ***************************************************************************** */
/* SOFTWARE API DEFINITION FOR Usart */
/* ***************************************************************************** */
typedef struct _AT91S_USART {
AT91_REG US_CR; /* Control Register */
AT91_REG US_MR; /* Mode Register */
AT91_REG US_IER; /* Interrupt Enable Register */
AT91_REG US_IDR; /* Interrupt Disable Register */
AT91_REG US_IMR; /* Interrupt Mask Register */
AT91_REG US_CSR; /* Channel Status Register */
AT91_REG US_RHR; /* Receiver Holding Register */
AT91_REG US_THR; /* Transmitter Holding Register */
AT91_REG US_BRGR; /* Baud Rate Generator Register */
AT91_REG US_RTOR; /* Receiver Time-out Register */
AT91_REG US_TTGR; /* Transmitter Time-guard Register */
AT91_REG Reserved0[5]; /* */
AT91_REG US_FIDI; /* FI_DI_Ratio Register */
AT91_REG US_NER; /* Nb Errors Register */
AT91_REG US_XXR; /* XON_XOFF Register */
AT91_REG US_IF; /* IRDA_FILTER Register */
AT91_REG Reserved1[44]; /* */
AT91_REG US_RPR; /* Receive Pointer Register */
AT91_REG US_RCR; /* Receive Counter Register */
AT91_REG US_TPR; /* Transmit Pointer Register */
AT91_REG US_TCR; /* Transmit Counter Register */
AT91_REG US_RNPR; /* Receive Next Pointer Register */
AT91_REG US_RNCR; /* Receive Next Counter Register */
AT91_REG US_TNPR; /* Transmit Next Pointer Register */
AT91_REG US_TNCR; /* Transmit Next Counter Register */
AT91_REG US_PTCR; /* PDC Transfer Control Register */
AT91_REG US_PTSR; /* PDC Transfer Status Register */
} AT91S_USART, *AT91PS_USART;
/* ***************************************************************************** */
/* SOFTWARE API DEFINITION FOR Parallel Input Output Controler */
/* ***************************************************************************** */
typedef struct _AT91S_PIO {
AT91_REG PIO_PER; /* PIO Enable Register */
AT91_REG PIO_PDR; /* PIO Disable Register */
AT91_REG PIO_PSR; /* PIO Status Register */
AT91_REG Reserved0[1]; /* */
AT91_REG PIO_OER; /* Output Enable Register */
AT91_REG PIO_ODR; /* Output Disable Registerr */
AT91_REG PIO_OSR; /* Output Status Register */
AT91_REG Reserved1[1]; /* */
AT91_REG PIO_IFER; /* Input Filter Enable Register */
AT91_REG PIO_IFDR; /* Input Filter Disable Register */
AT91_REG PIO_IFSR; /* Input Filter Status Register */
AT91_REG Reserved2[1]; /* */
AT91_REG PIO_SODR; /* Set Output Data Register */
AT91_REG PIO_CODR; /* Clear Output Data Register */
AT91_REG PIO_ODSR; /* Output Data Status Register */
AT91_REG PIO_PDSR; /* Pin Data Status Register */
AT91_REG PIO_IER; /* Interrupt Enable Register */
AT91_REG PIO_IDR; /* Interrupt Disable Register */
AT91_REG PIO_IMR; /* Interrupt Mask Register */
AT91_REG PIO_ISR; /* Interrupt Status Register */
AT91_REG PIO_MDER; /* Multi-driver Enable Register */
AT91_REG PIO_MDDR; /* Multi-driver Disable Register */
AT91_REG PIO_MDSR; /* Multi-driver Status Register */
AT91_REG Reserved3[1]; /* */
AT91_REG PIO_PPUDR; /* Pull-up Disable Register */
AT91_REG PIO_PPUER; /* Pull-up Enable Register */
AT91_REG PIO_PPUSR; /* Pad Pull-up Status Register */
AT91_REG Reserved4[1]; /* */
AT91_REG PIO_ASR; /* Select A Register */
AT91_REG PIO_BSR; /* Select B Register */
AT91_REG PIO_ABSR; /* AB Select Status Register */
AT91_REG Reserved5[9]; /* */
AT91_REG PIO_OWER; /* Output Write Enable Register */
AT91_REG PIO_OWDR; /* Output Write Disable Register */
AT91_REG PIO_OWSR; /* Output Write Status Register */
} AT91S_PIO, *AT91PS_PIO;
/* ***************************************************************************** */
/* SOFTWARE API DEFINITION FOR Debug Unit */
/* ***************************************************************************** */
typedef struct _AT91S_DBGU {
AT91_REG DBGU_CR; /* Control Register */
AT91_REG DBGU_MR; /* Mode Register */
AT91_REG DBGU_IER; /* Interrupt Enable Register */
AT91_REG DBGU_IDR; /* Interrupt Disable Register */
AT91_REG DBGU_IMR; /* Interrupt Mask Register */
AT91_REG DBGU_CSR; /* Channel Status Register */
AT91_REG DBGU_RHR; /* Receiver Holding Register */
AT91_REG DBGU_THR; /* Transmitter Holding Register */
AT91_REG DBGU_BRGR; /* Baud Rate Generator Register */
AT91_REG Reserved0[7]; /* */
AT91_REG DBGU_C1R; /* Chip ID1 Register */
AT91_REG DBGU_C2R; /* Chip ID2 Register */
AT91_REG DBGU_FNTR; /* Force NTRST Register */
AT91_REG Reserved1[45]; /* */
AT91_REG DBGU_RPR; /* Receive Pointer Register */
AT91_REG DBGU_RCR; /* Receive Counter Register */
AT91_REG DBGU_TPR; /* Transmit Pointer Register */
AT91_REG DBGU_TCR; /* Transmit Counter Register */
AT91_REG DBGU_RNPR; /* Receive Next Pointer Register */
AT91_REG DBGU_RNCR; /* Receive Next Counter Register */
AT91_REG DBGU_TNPR; /* Transmit Next Pointer Register */
AT91_REG DBGU_TNCR; /* Transmit Next Counter Register */
AT91_REG DBGU_PTCR; /* PDC Transfer Control Register */
AT91_REG DBGU_PTSR; /* PDC Transfer Status Register */
} AT91S_DBGU, *AT91PS_DBGU;
/* ***************************************************************************** */
/* SOFTWARE API DEFINITION FOR Static Memory Controller 2 Interface */
/* ***************************************************************************** */
typedef struct _AT91S_SMC2 {
AT91_REG SMC2_CSR[8]; /* SMC2 Chip Select Register */
} AT91S_SMC2, *AT91PS_SMC2;
/* ***************************************************************************** */
/* SOFTWARE API DEFINITION FOR Ethernet MAC */
/* ***************************************************************************** */
typedef struct _AT91S_EMAC {
AT91_REG EMAC_CTL; /* Network Control Register */
AT91_REG EMAC_CFG; /* Network Configuration Register */
AT91_REG EMAC_SR; /* Network Status Register */
AT91_REG EMAC_TAR; /* Transmit Address Register */
AT91_REG EMAC_TCR; /* Transmit Control Register */
AT91_REG EMAC_TSR; /* Transmit Status Register */
AT91_REG EMAC_RBQP; /* Receive Buffer Queue Pointer */
AT91_REG Reserved0[1]; /* */
AT91_REG EMAC_RSR; /* Receive Status Register */
AT91_REG EMAC_ISR; /* Interrupt Status Register */
AT91_REG EMAC_IER; /* Interrupt Enable Register */
AT91_REG EMAC_IDR; /* Interrupt Disable Register */
AT91_REG EMAC_IMR; /* Interrupt Mask Register */
AT91_REG EMAC_MAN; /* PHY Maintenance Register */
AT91_REG Reserved1[2]; /* */
AT91_REG EMAC_FRA; /* Frames Transmitted OK Register */
AT91_REG EMAC_SCOL; /* Single Collision Frame Register */
AT91_REG EMAC_MCOL; /* Multiple Collision Frame Register */
AT91_REG EMAC_OK; /* Frames Received OK Register */
AT91_REG EMAC_SEQE; /* Frame Check Sequence Error Register */
AT91_REG EMAC_ALE; /* Alignment Error Register */
AT91_REG EMAC_DTE; /* Deferred Transmission Frame Register */
AT91_REG EMAC_LCOL; /* Late Collision Register */
AT91_REG EMAC_ECOL; /* Excessive Collision Register */
AT91_REG EMAC_CSE; /* Carrier Sense Error Register */
AT91_REG EMAC_TUE; /* Transmit Underrun Error Register */
AT91_REG EMAC_CDE; /* Code Error Register */
AT91_REG EMAC_ELR; /* Excessive Length Error Register */
AT91_REG EMAC_RJB; /* Receive Jabber Register */
AT91_REG EMAC_USF; /* Undersize Frame Register */
AT91_REG EMAC_SQEE; /* SQE Test Error Register */
AT91_REG EMAC_DRFC; /* Discarded RX Frame Register */
AT91_REG Reserved2[3]; /* */
AT91_REG EMAC_HSH; /* Hash Address High[63:32] */
AT91_REG EMAC_HSL; /* Hash Address Low[31:0] */
AT91_REG EMAC_SA1L; /* Specific Address 1 Low, First 4 bytes */
AT91_REG EMAC_SA1H; /* Specific Address 1 High, Last 2 bytes */
AT91_REG EMAC_SA2L; /* Specific Address 2 Low, First 4 bytes */
AT91_REG EMAC_SA2H; /* Specific Address 2 High, Last 2 bytes */
AT91_REG EMAC_SA3L; /* Specific Address 3 Low, First 4 bytes */
AT91_REG EMAC_SA3H; /* Specific Address 3 High, Last 2 bytes */
AT91_REG EMAC_SA4L; /* Specific Address 4 Low, First 4 bytes */
AT91_REG EMAC_SA4H; /* Specific Address 4 High, Last 2 bytesr */
} AT91S_EMAC, *AT91PS_EMAC;
/* -------- DBGU_IER : (DBGU Offset: 0x8) Debug Unit Interrupt Enable Register -------- */
#define AT91C_US_RXRDY ((unsigned int) 0x1 << 0) /* (DBGU) RXRDY Interrupt */
#define AT91C_US_TXRDY ((unsigned int) 0x1 << 1) /* (DBGU) TXRDY Interrupt */
#define AT91C_US_ENDRX ((unsigned int) 0x1 << 3) /* (DBGU) End of Receive Transfer Interrupt */
#define AT91C_US_ENDTX ((unsigned int) 0x1 << 4) /* (DBGU) End of Transmit Interrupt */
#define AT91C_US_OVRE ((unsigned int) 0x1 << 5) /* (DBGU) Overrun Interrupt */
#define AT91C_US_FRAME ((unsigned int) 0x1 << 6) /* (DBGU) Framing Error Interrupt */
#define AT91C_US_PARE ((unsigned int) 0x1 << 7) /* (DBGU) Parity Error Interrupt */
#define AT91C_US_TXEMPTY ((unsigned int) 0x1 << 9) /* (DBGU) TXEMPTY Interrupt */
#define AT91C_US_TXBUFE ((unsigned int) 0x1 << 11) /* (DBGU) TXBUFE Interrupt */
#define AT91C_US_RXBUFF ((unsigned int) 0x1 << 12) /* (DBGU) RXBUFF Interrupt */
#define AT91C_US_COMM_TX ((unsigned int) 0x1 << 30) /* (DBGU) COMM_TX Interrupt */
#define AT91C_US_COMM_RX ((unsigned int) 0x1 << 31) /* (DBGU) COMM_RX Interrupt */
/* -------- DBGU_CR : (DBGU Offset: 0x0) Debug Unit Control Register -------- */
#define AT91C_US_RSTRX ((unsigned int) 0x1 << 2) /* (DBGU) Reset Receiver */
#define AT91C_US_RSTTX ((unsigned int) 0x1 << 3) /* (DBGU) Reset Transmitter */
#define AT91C_US_RXEN ((unsigned int) 0x1 << 4) /* (DBGU) Receiver Enable */
#define AT91C_US_RXDIS ((unsigned int) 0x1 << 5) /* (DBGU) Receiver Disable */
#define AT91C_US_TXEN ((unsigned int) 0x1 << 6) /* (DBGU) Transmitter Enable */
#define AT91C_US_TXDIS ((unsigned int) 0x1 << 7) /* (DBGU) Transmitter Disable */
#define AT91C_US_CLKS_CLOCK ((unsigned int) 0x0 << 4) /* (USART) Clock */
#define AT91C_US_CHRL_8_BITS ((unsigned int) 0x3 << 6) /* (USART) Character Length: 8 bits */
#define AT91C_US_PAR_NONE ((unsigned int) 0x4 << 9) /* (DBGU) No Parity */
#define AT91C_US_NBSTOP_1_BIT ((unsigned int) 0x0 << 12) /* (USART) 1 stop bit */
#define AT91C_PMC_PCER ((AT91_REG *) 0xFFFFFC10) /* (PMC) Peripheral Clock Enable Register */
#define AT91C_PIOA_PDR ((AT91_REG *) 0xFFFFF404) /* (PIOA) PIO Disable Register */
#define AT91C_PIO_PA30 ((unsigned int) 1 << 30) /* Pin Controlled by PA30 */
#define AT91C_PIO_PC0 ((unsigned int) 1 << 0) /* Pin Controlled by PC0 */
#define AT91C_PC0_BFCK ((unsigned int) AT91C_PIO_PC0) /* Burst Flash Clock */
#define AT91C_PA30_DRXD ((unsigned int) AT91C_PIO_PA30) /* DBGU Debug Receive Data */
#define AT91C_PIO_PA31 ((unsigned int) 1 << 31) /* Pin Controlled by PA31 */
#define AT91C_PA31_DTXD ((unsigned int) AT91C_PIO_PA31) /* DBGU Debug Transmit Data */
#define AT91C_ID_SYS ((unsigned int) 1) /* System Peripheral */
#define AT91C_ID_TC0 ((unsigned int) 17) /* Timer Counter 0 */
#define AT91C_ID_EMAC ((unsigned int) 24) /* Ethernet MAC */
#define AT91C_PIO_PC1 ((unsigned int) 1 << 1) /* Pin Controlled by PC1 */
#define AT91C_PC1_BFRDY_SMOE ((unsigned int) AT91C_PIO_PC1) /* Burst Flash Ready */
#define AT91C_PIO_PC3 ((unsigned int) 1 << 3) /* Pin Controlled by PC3 */
#define AT91C_PC3_BFBAA_SMWE ((unsigned int) AT91C_PIO_PC3) /* Burst Flash Address Advance / SmartMedia Write Enable */
#define AT91C_PIO_PC2 ((unsigned int) 1 << 2) /* Pin Controlled by PC2 */
#define AT91C_PC2_BFAVD ((unsigned int) AT91C_PIO_PC2) /* Burst Flash Address Valid */
#define AT91C_PIO_PB1 ((unsigned int) 1 << 1) /* Pin Controlled by PB1 */
#define AT91C_TC_TIMER_DIV1_CLOCK ((unsigned int) 0x0 << 0) /* (TC) MCK/2 */
#define AT91C_TC_TIMER_DIV2_CLOCK ((unsigned int) 0x1 << 0) /* (TC) MCK/8 */
#define AT91C_TC_TIMER_DIV3_CLOCK ((unsigned int) 0x2 << 0) /* (TC) MCK/32 */
#define AT91C_TC_TIMER_DIV4_CLOCK ((unsigned int) 0x3 << 0) /* (TC) MCK/128 */
#define AT91C_TC_SLOW_CLOCK ((unsigned int) 0x4 << 0) /* (TC) SLOW CLK */
#define AT91C_TC_XC0_CLOCK ((unsigned int) 0x5 << 0) /* (TC) XC0 */
#define AT91C_TC_XC1_CLOCK ((unsigned int) 0x6 << 0) /* (TC) XC1 */
#define AT91C_TC_XC2_CLOCK ((unsigned int) 0x7 << 0) /* (TC) XC2 */
#define AT91C_TCB_TC0XC0S_NONE ((unsigned int) 0x1) /* (TCB) None signal connected to XC0 */
#define AT91C_TCB_TC1XC1S_NONE ((unsigned int) 0x1 << 2) /* (TCB) None signal connected to XC1 */
#define AT91C_TCB_TC2XC2S_NONE ((unsigned int) 0x1 << 4) /* (TCB) None signal connected to XC2 */
#define AT91C_TC_CLKDIS ((unsigned int) 0x1 << 1) /* (TC) Counter Clock Disable Command */
#define AT91C_TC_SWTRG ((unsigned int) 0x1 << 2) /* (TC) Software Trigger Command */
#define AT91C_TC_CLKEN ((unsigned int) 0x1 << 0) /* (TC) Counter Clock Enable Command */
#define AT91C_EMAC_BNQ ((unsigned int) 0x1 << 4) /* (EMAC) */
#define AT91C_EMAC_COMP ((unsigned int) 0x1 << 5) /* (EMAC) */
#define AT91C_EMAC_REC ((unsigned int) 0x1 << 1) /* (EMAC) */
#define AT91C_EMAC_RE ((unsigned int) 0x1 << 2) /* (EMAC) Receive enable. */
#define AT91C_EMAC_TE ((unsigned int) 0x1 << 3) /* (EMAC) Transmit enable. */
#define AT91C_EMAC_CLK ((unsigned int) 0x3 << 10) /* (EMAC) */
#define AT91C_EMAC_RMII ((unsigned int) 0x1 << 13) /* (EMAC) */
#define AT91C_EMAC_NBC ((unsigned int) 0x1 << 5) /* (EMAC) No broadcast. */
#define AT91C_EMAC_CAF ((unsigned int) 0x1 << 4) /* (EMAC) Copy all frames. */
#define AT91C_EMAC_BNA ((unsigned int) 0x1 << 0) /* (EMAC) */
#define AT91C_EMAC_REC ((unsigned int) 0x1 << 1) /* (EMAC) */
#define AT91C_EMAC_RSR_OVR ((unsigned int) 0x1 << 2) /* (EMAC) */
#define AT91C_EMAC_CSR ((unsigned int) 0x1 << 5) /* (EMAC) Clear statistics registers. */
#define AT91C_EMAC_SPD ((unsigned int) 0x1 << 0) /* (EMAC) Speed. */
#define AT91C_EMAC_FD ((unsigned int) 0x1 << 1) /* (EMAC) Full duplex. */
#define AT91C_EMAC_LINK ((unsigned int) 0x1 << 0) /* (EMAC) */
#define AT91C_EMAC_MPE ((unsigned int) 0x1 << 4) /* (EMAC) Management port enable. */
#define AT91C_PIO_PA16 ((unsigned int) 1 << 16) /* Pin Controlled by PA16 */
#define AT91C_PA16_EMDIO ((unsigned int) AT91C_PIO_PA16) /* Ethernet MAC Management Data Input/Output */
#define AT91C_PIO_PA15 ((unsigned int) 1 << 15) /* Pin Controlled by PA15 */
#define AT91C_PA15_EMDC ((unsigned int) AT91C_PIO_PA15) /* Ethernet MAC Management Data Clock */
#define AT91C_PIO_PA14 ((unsigned int) 1 << 14) /* Pin Controlled by PA14 */
#define AT91C_PA14_ERXER ((unsigned int) AT91C_PIO_PA14) /* Ethernet MAC Receive Error */
#define AT91C_PIO_PA13 ((unsigned int) 1 << 13) /* Pin Controlled by PA13 */
#define AT91C_PA13_ERX1 ((unsigned int) AT91C_PIO_PA13) /* Ethernet MAC Receive Data 1 */
#define AT91C_PIO_PA12 ((unsigned int) 1 << 12) /* Pin Controlled by PA12 */
#define AT91C_PA12_ERX0 ((unsigned int) AT91C_PIO_PA12) /* Ethernet MAC Receive Data 0 */
#define AT91C_PIO_PA11 ((unsigned int) 1 << 11) /* Pin Controlled by PA11 */
#define AT91C_PA11_ECRS_ECRSDV ((unsigned int) AT91C_PIO_PA11) /* Ethernet MAC Carrier Sense/Carrier Sense and Data Valid */
#define AT91C_PIO_PA10 ((unsigned int) 1 << 10) /* Pin Controlled by PA10 */
#define AT91C_PA10_ETX1 ((unsigned int) AT91C_PIO_PA10) /* Ethernet MAC Transmit Data 1 */
#define AT91C_PIO_PA9 ((unsigned int) 1 << 9) /* Pin Controlled by PA9 */
#define AT91C_PA9_ETX0 ((unsigned int) AT91C_PIO_PA9) /* Ethernet MAC Transmit Data 0 */
#define AT91C_PIO_PA8 ((unsigned int) 1 << 8) /* Pin Controlled by PA8 */
#define AT91C_PA8_ETXEN ((unsigned int) AT91C_PIO_PA8) /* Ethernet MAC Transmit Enable */
#define AT91C_PIO_PA7 ((unsigned int) 1 << 7) /* Pin Controlled by PA7 */
#define AT91C_PA7_ETXCK_EREFCK ((unsigned int) AT91C_PIO_PA7) /* Ethernet MAC Transmit Clock/Reference Clock */
#define AT91C_PIO_PB25 ((unsigned int) 1 << 25) /* Pin Controlled by PB25 */
#define AT91C_PB25_DSR1 ((unsigned int) AT91C_PIO_PB25) /* USART 1 Data Set ready */
#define AT91C_PB25_EF100 ((unsigned int) AT91C_PIO_PB25) /* Ethernet MAC Force 100 Mbits */
#define AT91C_PIO_PB19 ((unsigned int) 1 << 19) /* Pin Controlled by PB19 */
#define AT91C_PB19_DTR1 ((unsigned int) AT91C_PIO_PB19) /* USART 1 Data Terminal ready */
#define AT91C_PB19_ERXCK ((unsigned int) AT91C_PIO_PB19) /* Ethernet MAC Receive Clock */
#define AT91C_PIO_PB18 ((unsigned int) 1 << 18) /* Pin Controlled by PB18 */
#define AT91C_PB18_RI1 ((unsigned int) AT91C_PIO_PB18) /* USART 1 Ring Indicator */
#define AT91C_PB18_ECOL ((unsigned int) AT91C_PIO_PB18) /* Ethernet MAC Collision Detected */
#define AT91C_PIO_PB17 ((unsigned int) 1 << 17) /* Pin Controlled by PB17 */
#define AT91C_PB17_RF2 ((unsigned int) AT91C_PIO_PB17) /* SSC Receive Frame Sync 2 */
#define AT91C_PB17_ERXDV ((unsigned int) AT91C_PIO_PB17) /* Ethernet MAC Receive Data Valid */
#define AT91C_PIO_PB16 ((unsigned int) 1 << 16) /* Pin Controlled by PB16 */
#define AT91C_PB16_RK2 ((unsigned int) AT91C_PIO_PB16) /* SSC Receive Clock 2 */
#define AT91C_PB16_ERX3 ((unsigned int) AT91C_PIO_PB16) /* Ethernet MAC Receive Data 3 */
#define AT91C_PIO_PB15 ((unsigned int) 1 << 15) /* Pin Controlled by PB15 */
#define AT91C_PB15_RD2 ((unsigned int) AT91C_PIO_PB15) /* SSC Receive Data 2 */
#define AT91C_PB15_ERX2 ((unsigned int) AT91C_PIO_PB15) /* Ethernet MAC Receive Data 2 */
#define AT91C_PIO_PB14 ((unsigned int) 1 << 14) /* Pin Controlled by PB14 */
#define AT91C_PB14_TD2 ((unsigned int) AT91C_PIO_PB14) /* SSC Transmit Data 2 */
#define AT91C_PB14_ETXER ((unsigned int) AT91C_PIO_PB14) /* Ethernet MAC Transmikt Coding Error */
#define AT91C_PIO_PB13 ((unsigned int) 1 << 13) /* Pin Controlled by PB13 */
#define AT91C_PB13_TK2 ((unsigned int) AT91C_PIO_PB13) /* SSC Transmit Clock 2 */
#define AT91C_PB13_ETX3 ((unsigned int) AT91C_PIO_PB13) /* Ethernet MAC Transmit Data 3 */
#define AT91C_PIO_PB12 ((unsigned int) 1 << 12) /* Pin Controlled by PB12 */
#define AT91C_PB12_TF2 ((unsigned int) AT91C_PIO_PB12) /* SSC Transmit Frame Sync 2 */
#define AT91C_PB12_ETX2 ((unsigned int) AT91C_PIO_PB12) /* Ethernet MAC Transmit Data 2 */
#define AT91C_PIOB_BSR ((AT91_REG *) 0xFFFFF674) /* (PIOB) Select B Register */
#define AT91C_BASE_EMAC ((AT91PS_EMAC) 0xFFFBC000) /* (EMAC) Base Address */
#define AT91C_PIOB_PDR ((AT91_REG *) 0xFFFFF604) /* (PIOB) PIO Disable Register */
#define AT91C_EBI_CS3A_SMC_SmartMedia ((unsigned int) 0x1 << 3) /* (EBI) Chip Select 3 is assigned to the Static Memory Controller and the SmartMedia Logic is activated. */
#define AT91C_SMC2_ACSS_STANDARD ((unsigned int) 0x0 << 16) /* (SMC2) Standard, asserted at the beginning of the access and deasserted at the end. */
#define AT91C_SMC2_DBW_8 ((unsigned int) 0x2 << 13) /* (SMC2) 8-bit. */
#define AT91C_SMC2_WSEN ((unsigned int) 0x1 << 7) /* (SMC2) Wait State Enable */
#define AT91C_PIOC_ASR ((AT91_REG *) 0xFFFFF870) /* (PIOC) Select A Register */
#define AT91C_BASE_TC0 ((AT91PS_TC) 0xFFFA0000) /* (TC0) Base Address */
#define AT91C_BASE_DBGU ((AT91PS_DBGU) 0xFFFFF200) /* (DBGU) Base Address */
#define AT91C_BASE_PIOA ((AT91PS_PIO) 0xFFFFF400) /* (PIOA) Base Address */
#define AT91C_EBI_CSA ((AT91_REG *) 0xFFFFFF60) /* (EBI) Chip Select Assignment Register */
#define AT91C_BASE_SMC2 ((AT91PS_SMC2) 0xFFFFFF70) /* (SMC2) Base Address */
#define AT91C_BASE_US1 ((AT91PS_USART) 0xFFFC4000) /* (US1) Base Address */
#define AT91C_TCB0_BMR ((AT91_REG *) 0xFFFA00C4) /* (TCB0) TC Block Mode Register */
#define AT91C_TCB0_BCR ((AT91_REG *) 0xFFFA00C0) /* (TCB0) TC Block Control Register */
#define AT91C_PIOC_PDR ((AT91_REG *) 0xFFFFF804) /* (PIOC) PIO Disable Register */
#define AT91C_PIOC_PER ((AT91_REG *) 0xFFFFF800) /* (PIOC) PIO Enable Register */
#define AT91C_PIOC_ODR ((AT91_REG *) 0xFFFFF814) /* (PIOC) Output Disable Registerr */
#define AT91C_PIOB_PER ((AT91_REG *) 0xFFFFF600) /* (PIOB) PIO Enable Register */
#define AT91C_PIOB_ODR ((AT91_REG *) 0xFFFFF614) /* (PIOB) Output Disable Registerr */
#define AT91C_PIOB_PDSR ((AT91_REG *) 0xFFFFF63C) /* (PIOB) Pin Data Status Register */
#endif

2431
include/asm-mips/inca-ip.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -68,11 +68,11 @@ typedef struct bd_info {
#if defined(CONFIG_HYMOD)
hymod_conf_t bi_hymod_conf; /* hymod configuration information */
#endif
#if defined(CONFIG_EVB64260) || defined(CONFIG_PN62)
#if defined(CONFIG_EVB64260) || defined(CONFIG_PN62) || defined(CONFIG_SVM_SC8xx)
/* second onboard ethernet port */
unsigned char bi_enet1addr[6];
#endif
#if defined(CONFIG_EVB64260)
#if defined(CONFIG_EVB64260) || defined(CONFIG_SVM_SC8xx)
/* third onboard ethernet port */
unsigned char bi_enet2addr[6];
#endif

View File

@@ -78,6 +78,7 @@
#define CFG_CMD_SPI 0x0000100000000000 /* SPI utility */
#define CFG_CMD_FDOS 0x0000200000000000 /* Floppy DOS support */
#define CFG_CMD_VFD 0x0000400000000000 /* VFD support (TRAB) */
#define CFG_CMD_NAND 0x0000800000000000 /* NAND support */
#define CFG_CMD_ALL 0xFFFFFFFFFFFFFFFF /* ALL commands */
@@ -106,6 +107,7 @@
CFG_CMD_JFFS2 | \
CFG_CMD_KGDB | \
CFG_CMD_MII | \
CFG_CMD_NAND | \
CFG_CMD_PCI | \
CFG_CMD_PCMCIA | \
CFG_CMD_REGINFO | \

55
include/cmd_nand.h Normal file
View File

@@ -0,0 +1,55 @@
/*
* 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
*/
/*
* NAND support
*/
#ifndef _CMD_NAND_H
#define _CMD_NAND_H
#include <common.h>
#include <command.h>
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
#define CMD_TBL_NAND MK_CMD_TBL_ENTRY( \
"nand", 3, 5, 1, do_nand, \
"nand - NAND sub-system\n", \
"info - show available NAND devices\n" \
"nand device [dev] - show or set current device\n" \
"nand read addr off size\n" \
"nand write addr off size - read/write `size'" \
" bytes starting at offset `off'\n" \
" to/from memory address `addr'\n" \
"nand erase off size - erase `size' bytes of NAND from offset `off'\n" \
),
#define CMD_TBL_NANDBOOT MK_CMD_TBL_ENTRY( \
"nboot", 4, 4, 1, do_nandboot, \
"nboot - boot from NAND device\n", \
"loadAddr dev\n" \
),
int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
#else
#define CMD_TBL_NAND
#define CMD_TBL_NANDBOOT
#endif
#endif /* _CMD_NAND_H */

View File

@@ -1128,6 +1128,57 @@ typedef struct scc_enet {
/*** NETVIA *******************************************************/
/* SinoVee Microsystems SC8xx series FEL8xx-AT,SC823,SC850,SC855T,SC860T */
#if ( defined CONFIG_SVM_SC8xx )
# ifndef CONFIG_FEC_ENET
#define PROFF_ENET PROFF_SCC2
#define CPM_CR_ENET CPM_CR_CH_SCC2
#define SCC_ENET 1
/* Bits in parallel I/O port registers that have to be set/cleared
* * * * to configure the pins for SCC2 use.
* * * */
#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */
#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */
#define PA_ENET_RCLK ((ushort)0x0400) /* PA 5 */
#define PA_ENET_TCLK ((ushort)0x0800) /* PA 4 */
#define PB_ENET_TENA ((uint)0x00002000) /* PB 18 */
#define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */
#define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */
/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to
* * * * SCC2. Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero.
* * * */
#define SICR_ENET_MASK ((uint)0x0000ff00)
#define SICR_ENET_CLKRT ((uint)0x00003700)
# else /* Use FEC for Fast Ethernet */
#undef SCC_ENET
#define FEC_ENET
#define PD_MII_TXD1 ((ushort)0x1000) /* PD 3 */
#define PD_MII_TXD2 ((ushort)0x0800) /* PD 4 */
#define PD_MII_TXD3 ((ushort)0x0400) /* PD 5 */
#define PD_MII_RX_DV ((ushort)0x0200) /* PD 6 */
#define PD_MII_RX_ERR ((ushort)0x0100) /* PD 7 */
#define PD_MII_RX_CLK ((ushort)0x0080) /* PD 8 */
#define PD_MII_TXD0 ((ushort)0x0040) /* PD 9 */
#define PD_MII_RXD0 ((ushort)0x0020) /* PD 10 */
#define PD_MII_TX_ERR ((ushort)0x0010) /* PD 11 */
#define PD_MII_MDC ((ushort)0x0008) /* PD 12 */
#define PD_MII_RXD1 ((ushort)0x0004) /* PD 13 */
#define PD_MII_RXD2 ((ushort)0x0002) /* PD 14 */
#define PD_MII_RXD3 ((ushort)0x0001) /* PD 15 */
#define PD_MII_MASK ((ushort)0x1FFF) /* PD 3...15 */
# endif /* CONFIG_FEC_ENET */
#endif /* CONFIG_SVM_SC8xx */
#if defined(CONFIG_NETVIA)
/* Bits in parallel I/O port registers that have to be set/cleared
* to configure the pins for SCC2 use.

View File

@@ -303,7 +303,7 @@
#define CFG_EBC_PB3CR 0xF011A000 /* BAS=0xF01,BS=1MB,BU=R/W,BW=16bit */
/* Memory Bank 4 (NVRAM/RTC) initialization */
//#define CFG_EBC_PB4AP 0x01805280 /* TWT=3,WBN=1,WBF=1,TH=1,SOR=1 */
/*#define CFG_EBC_PB4AP 0x01805280 / * TWT=3,WBN=1,WBF=1,TH=1,SOR=1 */
#define CFG_EBC_PB4AP 0x01805680 /* TWT=3,WBN=1,WBF=1,TH=3,SOR=1 */
#define CFG_EBC_PB4CR 0xF0218000 /* BAS=0xF02,BS=1MB,BU=R/W,BW=8bit */

View File

@@ -98,6 +98,7 @@
& ~CFG_CMD_JFFS2 \
& ~CFG_CMD_KGDB \
& ~CFG_CMD_MII \
& ~CFG_CMD_NAND \
& ~CFG_CMD_PCI \
& ~CFG_CMD_PCMCIA \
& ~CFG_CMD_SCSI \

View File

@@ -126,6 +126,7 @@
CFG_CMD_IDE | \
CFG_CMD_JFFS2 | \
CFG_CMD_KGDB | \
CFG_CMD_NAND | \
CFG_CMD_MII | \
CFG_CMD_PCI | \
CFG_CMD_PCMCIA | \

View File

@@ -125,6 +125,7 @@
CFG_CMD_IDE | \
CFG_CMD_JFFS2 | \
CFG_CMD_KGDB | \
CFG_CMD_NAND | \
CFG_CMD_MII | \
CFG_CMD_PCI | \
CFG_CMD_PCMCIA | \

View File

@@ -276,7 +276,7 @@
/* Memory Bank 2 (CAN0, 1) initialization */
#define CFG_EBC_PB2AP 0x010053C0 /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
//#define CFG_EBC_PB2AP 0x038056C0 /* BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
/*#define CFG_EBC_PB2AP 0x038056C0 / * BWT=2,WBN=1,WBF=1,TH=1,RE=1,SOR=1,BEM=1 */
#define CFG_EBC_PB2CR 0xF0018000 /* BAS=0xF00,BS=1MB,BU=R/W,BW=8bit */
/* Memory Bank 3 (FPGA internal) initialization */

View File

@@ -198,7 +198,7 @@
#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
#define CFG_RESET_ADDRESS 0xFFFFFFFC /* "bad" address */
#define CFG_RESET_ADDRESS 0xFDFFFFFC /* "bad" address */
/*
* For booting Linux, the board info and command line data

View File

@@ -0,0 +1,153 @@
/*
* Rick Bronson <rick@efn.org>
*
* Configuation settings for the AT91RM9200DK board.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef __CONFIG_H
#define __CONFIG_H
/* ARM asynchronous clock */
#define AT91C_MAIN_CLOCK 179712000 /* from 18.432 MHz crystal (18432000 / 4 * 39) */
#define AT91C_MASTER_CLOCK 59904000 /* peripheral clock (AT91C_MASTER_CLOCK / 3) */
#define CONFIG_AT91RM9200DK 1 /* on an AT91RM9200DK Board */
#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
#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 CONFIG_BAUDRATE 115200
/*
* Hardware drivers
*/
/*
* select serial console configuration
*/
#define CONFIG_SERIAL3 1 /* we use SERIAL 3 */
#undef CONFIG_HWFLOW /* don't include RTS/CTS flow control support */
#undef CONFIG_MODEM_SUPPORT /* disable modem initialization stuff */
#define CONFIG_COMMANDS \
(CONFIG_CMD_DFL | \
CFG_CMD_DHCP | \
CFG_CMD_NAND )
/* CFG_CMD_EEPROM | \ might consider these
CFG_CMD_I2C | \
CFG_CMD_USB | \
CFG_CMD_MII | \
CFG_CMD_SDRAM | \ */
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
#define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */
#define SECTORSIZE 512
#define ADDR_COLUMN 1
#define ADDR_PAGE 2
#define ADDR_COLUMN_PAGE 3
#define NAND_ChipID_UNKNOWN 0x00
#define NAND_MAX_FLOORS 1
#define NAND_MAX_CHIPS 1
#define AT91_SMART_MEDIA_ALE (1 << 22) /* our ALE is AD22 */
#define AT91_SMART_MEDIA_CLE (1 << 21) /* our CLE is AD21 */
#define NAND_DISABLE_CE(nand) do { *AT91C_PIOC_SODR = AT91C_PIO_PC0;} while(0)
#define NAND_ENABLE_CE(nand) do { *AT91C_PIOC_CODR = AT91C_PIO_PC0;} while(0)
#define NAND_WAIT_READY(nand) while (!(*AT91C_PIOC_PDSR & AT91C_PIO_PC2))
#define WRITE_NAND_COMMAND(d, adr) do{ *(volatile __u8 *)((unsigned long)adr | AT91_SMART_MEDIA_CLE) = (__u8)(d); } while(0)
#define WRITE_NAND_ADDRESS(d, adr) do{ *(volatile __u8 *)((unsigned long)adr | AT91_SMART_MEDIA_ALE) = (__u8)(d); } while(0)
#define WRITE_NAND(d, adr) do{ *(volatile __u8 *)((unsigned long)adr) = (__u8)d; } while(0)
#define READ_NAND(adr) ((volatile unsigned char)(*(volatile __u8 *)(unsigned long)adr))
/* the following are NOP's in our implementation */
#define NAND_CTL_CLRALE(nandptr)
#define NAND_CTL_SETALE(nandptr)
#define NAND_CTL_CLRCLE(nandptr)
#define NAND_CTL_SETCLE(nandptr)
#define CONFIG_NR_DRAM_BANKS 1
#define PHYS_SDRAM 0x20000000
#define PHYS_SDRAM_SIZE 0x2000000 /* 32 megs */
#define CFG_MEMTEST_START PHYS_SDRAM
#define CFG_MEMTEST_END CFG_MEMTEST_START + PHYS_SDRAM_SIZE - 262144
#define CONFIG_DRIVER_ETHER
#define PHYS_FLASH_1 0x10000000
#define PHYS_FLASH_SIZE 0x200000 /* 2 megs main flash */
#define CFG_FLASH_BASE PHYS_FLASH_1
#define CFG_MAX_FLASH_BANKS 1
#define CFG_MAX_FLASH_SECT 40
#define CFG_FLASH_ERASE_TOUT (2*CFG_HZ) /* Timeout for Flash Erase */
#define CFG_FLASH_WRITE_TOUT (2*CFG_HZ) /* Timeout for Flash Write */
#define CFG_ENV_IS_IN_FLASH 1
#define CFG_ENV_ADDR (PHYS_FLASH_1 + 0xe000)
#define CFG_ENV_SIZE 0x2000
#define CFG_LOAD_ADDR 0x21000000 /* default load address */
#define CFG_BAUDRATE_TABLE {115200 , 19200, 38400, 57600, 9600 }
#define CFG_PROMPT "Uboot> " /* Monitor Command Prompt */
#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
#define CFG_MAXARGS 16 /* max number of command args */
#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
#ifndef __ASSEMBLY__
/*-----------------------------------------------------------------------
* Board specific extension for bd_info
*
* This structure is embedded in the global bd_info (bd_t) structure
* and can be used by the board specific code (eg board/...)
*/
struct bd_info_ext
{
/* helper variable for board environment handling
*
* env_crc_valid == 0 => uninitialised
* env_crc_valid > 0 => environment crc in flash is valid
* env_crc_valid < 0 => environment crc in flash is invalid
*/
int env_crc_valid;
};
#endif
#define CFG_HZ AT91C_MASTER_CLOCK/2 /* AT91C_TC0_CMR is implicitly set to
AT91C_TC_TIMER_DIV1_CLOCK */
#define CONFIG_STACKSIZE (32*1024) /* regular stack */
#ifdef CONFIG_USE_IRQ
#error CONFIG_USE_IRQ not supported
#endif
#endif

View File

@@ -76,7 +76,7 @@
#define CONFIG_NETMASK 255.255.0.0
#define CONFIG_IPADDR 172.22.2.23
#define CONFIG_SERVERIP 172.22.2.22
#define CONFIG_BOOTFILE "elinos-dnp1110"
#define CONFIG_BOOTFILE "dnp1110"
#define CONFIG_BOOTCOMMAND "tftp; bootm"
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
@@ -128,21 +128,23 @@
#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */
#define PHYS_FLASH_SIZE 0x01000000 /* 16 MB */
#define PHYS_FLASH_BANK_SIZE 0x01000000 /* 32 MB Banks */
#define PHYS_FLASH_SECT_SIZE 0x00020000 /* 256 KB sectors (x2) */
#define CFG_FLASH_BASE PHYS_FLASH_1
/*-----------------------------------------------------------------------
* FLASH and environment organization
*/
#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
#define CFG_MAX_FLASH_SECT (31+8) /* max number of sectors on one chip */
#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
#define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */
/* timeout values are in ticks */
#define CFG_FLASH_ERASE_TOUT (2*CFG_HZ) /* Timeout for Flash Erase */
#define CFG_FLASH_WRITE_TOUT (2*CFG_HZ) /* Timeout for Flash Write */
#define CFG_ENV_IS_IN_FLASH 1
#define CFG_ENV_ADDR (PHYS_FLASH_1 + 0x1C000) /* Addr of Environment Sector */
#define CFG_ENV_SIZE 0x4000 /* Total Size of Environment Sector */
#define CFG_ENV_ADDR (PHYS_FLASH_1 + 0xF80000) /* Addr of Environment Sector */
#define CFG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
#endif /* __CONFIG_H */

View File

@@ -282,6 +282,7 @@
~CFG_CMD_JFFS2 & \
~CFG_CMD_KGDB & \
~CFG_CMD_MII & \
~CFG_CMD_NAND & \
~CFG_CMD_PCI & \
~CFG_CMD_PCMCIA & \
~CFG_CMD_SCSI & \

View File

@@ -145,6 +145,7 @@
CFG_CMD_HWFLOW | \
CFG_CMD_IDE | \
CFG_CMD_JFFS2 | \
CFG_CMD_NAND | \
CFG_CMD_MII | \
CFG_CMD_PCMCIA | \
CFG_CMD_PCI | \

107
include/configs/incaip.h Normal file
View File

@@ -0,0 +1,107 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* This file contains the configuration parameters for the INCA-IP board.
*/
#ifndef __CONFIG_H
#define __CONFIG_H
#define CONFIG_MIPS32 1 /* MIPS 4Kc CPU core */
#define CONFIG_INCA_IP 1 /* on a INCA-IP Board */
/* allowed values: 100000000 and 150000000 */
#define CPU_CLOCK_RATE 150000000 /* 150 MHz clock for the MIPS core */
#define CONFIG_BAUDRATE 115200
#define CFG_SDRAM_BASE 0x80000000
#define CFG_MALLOC_LEN 128*1024
#define CFG_BOOTPARAMS_LEN 128*1024
/* valid baudrates */
#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
#define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_ELF)
#include <cmd_confdefs.h>
/*
* Miscellaneous configurable options
*/
#define CFG_LONGHELP /* undef to save memory */
#define CFG_PROMPT "INCA-IP # " /* 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_HZ (CPU_CLOCK_RATE/2)
#define CFG_MAXARGS 16 /* max number of command args*/
#define CFG_LOAD_ADDR 0x80100000 /* default load address */
#define CFG_MEMTEST_START 0x80200000
#define CFG_MEMTEST_END 0x80800000
/*-----------------------------------------------------------------------
* FLASH and environment organization
*/
#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */
#define CFG_MAX_FLASH_SECT (128) /* max number of sectors on one chip */
#define PHYS_FLASH_1 0xb0000000 /* Flash Bank #1 */
#define PHYS_FLASH_2 0xb0800000 /* Flash Bank #2 */
/* The following #defines are needed to get flash environment right */
#define CFG_MONITOR_BASE TEXT_BASE
#define CFG_MONITOR_LEN (192 << 10)
#define CFG_INIT_SP_OFFSET 0x400000
#define CFG_FLASH_BASE PHYS_FLASH_1
/* timeout values are in ticks */
#define CFG_FLASH_ERASE_TOUT (2 * CFG_HZ) /* Timeout for Flash Erase */
#define CFG_FLASH_WRITE_TOUT (2 * CFG_HZ) /* Timeout for Flash Write */
#define CFG_ENV_IS_IN_FLASH 1
/* Address and size of Primary Environment Sector */
#define CFG_ENV_ADDR 0xB0030000
#define CFG_ENV_SIZE 0x10000
#define CONFIG_FLASH_16BIT
#define CONFIG_NR_DRAM_BANKS 1
#define CONFIG_INCA_IP_SWITCH
#define CONFIG_NET_MULTI
/*-----------------------------------------------------------------------
* Cache Configuration
*/
#define CFG_DCACHE_SIZE 4096
#define CFG_ICACHE_SIZE 4096
#define CFG_CACHELINE_SIZE 16
#endif /* __CONFIG_H */

470
include/configs/svm_sc8xx.h Normal file
View File

@@ -0,0 +1,470 @@
/*
* (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
*/
/*
* board/config.h - configuration options, board specific,
* for SinoVee Microsystems SC8xx series SBC
* http://www.fel.com.cn (Chinese)
* http://www.sinovee.com (English)
*/
#ifndef __CONFIG_H
#define __CONFIG_H
/* Custom configuration */
/* SC823,SC850,SC860SAR, FEL8xx-AT(823/850/860) */
/* SC85T,SC860T, FEL8xx-AT(855T/860T) */
/*#define CONFIG_FEL8xx_AT */
/*#define CONFIG_LCD */
/* if core > 50MHz , un-comment CONFIG_BUS_DIV2 */
/* #define CONFIG_50MHz */
/* #define CONFIG_66MHz */
/* #define CONFIG_75MHz */
#define CONFIG_80MHz
/*#define CONFIG_100MHz */
/* #define CONFIG_BUS_DIV2 1 */
/* for BOOT device port size */
/* #define CONFIG_BOOT_8B */
#define CONFIG_BOOT_16B
/* #define CONFIG_BOOT_32B */
/* #define CONFIG_CAN_DRIVER */
/* #define DEBUG */
#define CONFIG_FEC_ENET
/* #define CONFIG_SDRAM_16M */
#define CONFIG_SDRAM_32M
/* #define CONFIG_SDRAM_64M */
#define CFG_RESET_ADDRESS 0xffffffff
/*
* High Level Configuration Options
* (easy to change)
*/
/* #define CONFIG_MPC823 1 */
/* #define CONFIG_MPC850 1 */
#define CONFIG_MPC855 1
/* #define CONFIG_MPC860 1 */
/* #define CONFIG_MPC860T 1 */
#undef CONFIG_WATCHDOG /* watchdog */
#define CONFIG_SVM_SC8xx 1 /* ...on SVM SC8xx series */
#ifdef CONFIG_LCD /* with LCD controller ? */
/* #define CONFIG_NEC_NL6648BC20 1 / * use NEC NL6648BC20 display */
#endif
#define CONFIG_8xx_CONS_SMC1 1 /* Console is on SMC1 */
#undef CONFIG_8xx_CONS_SMC2
#undef CONFIG_8xx_CONS_NONE
#define CONFIG_BAUDRATE 19200 /* console baudrate = 115kbps */
#if 0
#define CONFIG_BOOTDELAY -1 /* autoboot disabled */
#else
#define CONFIG_BOOTDELAY 1 /* autoboot after 5 seconds */
#endif
#define CONFIG_CLOCKS_IN_MHZ 1 /* clocks passsed to Linux in MHz */
#define CONFIG_BOARD_TYPES 1 /* support board types */
#define CONFIG_PREBOOT "echo;echo Welcome to U-Boot SVM port;echo;echo Type \"? or help\" to get on-line help;echo"
#undef CONFIG_BOOTARGS
#define CONFIG_EXTRA_ENV_SETTINGS \
"nfsargs=setenv bootargs root=/dev/nfs rw " \
"nfsroot=$(serverip):$(rootpath)\0" \
"ramargs=setenv bootargs root=/dev/ram rw\0" \
"addip=setenv bootargs $(bootargs) " \
"ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask)" \
":$(hostname):$(netdev):off panic=1\0" \
"flash_nfs=run nfsargs addip;" \
"bootm $(kernel_addr)\0" \
"flash_self=run ramargs addip;" \
"bootm $(kernel_addr) $(ramdisk_addr)\0" \
"net_nfs=tftp 0x210000 $(bootfile);run nfsargs addip;bootm\0" \
"rootpath=/opt/sinovee/ppc8xx-linux-2.0/target\0" \
"bootfile=pImage-sc855t\0" \
"kernel_addr=48000000\0" \
"ramdisk_addr=48100000\0" \
""
#define CONFIG_BOOTCOMMAND \
"setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) " \
"ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off; " \
"tftpboot 0x210000 pImage-sc855t;bootm 0x210000"
#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
#undef CFG_LOADS_BAUD_CHANGE /* don't allow baudrate change */
#ifdef CONFIG_LCD
# undef CONFIG_STATUS_LED /* disturbs display */
#else
# define CONFIG_STATUS_LED 1 /* Status LED enabled */
#endif /* CONFIG_LCD */
#undef CONFIG_CAN_DRIVER /* CAN Driver support disabled */
#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT | CONFIG_BOOTP_BOOTFILESIZE)
#define CONFIG_MAC_PARTITION
#define CONFIG_DOS_PARTITION
#define CONFIG_RTC_MPC8xx /* use internal RTC of MPC8xx */
#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \
CFG_CMD_ASKENV | \
CFG_CMD_DHCP | \
CFG_CMD_DOC | \
/* CFG_CMD_IDE |*/ \
CFG_CMD_DATE )
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
/*
* Miscellaneous configurable options
*/
#define CFG_LONGHELP /* undef to save memory */
#define CFG_PROMPT "=> " /* Monitor Command Prompt */
#ifdef CFG_HUSH_PARSER
#define CFG_PROMPT_HUSH_PS2 "> "
#endif
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
#else
#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
#endif
#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
#define CFG_MAXARGS 16 /* max number of command args */
#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
#define CFG_MEMTEST_START 0x0400000 /* memtest works on */
#define CFG_MEMTEST_END 0x0C00000 /* 4 ... 12 MB in DRAM */
#define CFG_LOAD_ADDR 0x100000 /* default load address */
#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
/*
* Low Level Configuration Settings
* (address mappings, register initial values, etc.)
* You should know what you are doing if you make changes here.
*/
/*-----------------------------------------------------------------------
* Internal Memory Mapped Register
*/
#define CFG_IMMR 0xFF000000
/*-----------------------------------------------------------------------
* Definitions for initial stack pointer and data area (in DPRAM)
*/
#define CFG_INIT_RAM_ADDR CFG_IMMR
#define CFG_INIT_RAM_END 0x2F00 /* End of used area in DPRAM */
#define CFG_GBL_DATA_SIZE 64 /* size in bytes reserved for initial data */
#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
/*-----------------------------------------------------------------------
* Start addresses for the final memory configuration
* (Set up by the startup code)
* Please note that CFG_SDRAM_BASE _must_ start at 0
*/
#define CFG_SDRAM_BASE 0x00000000
#define CFG_FLASH_BASE 0x40000000
#define CFG_MONITOR_LEN (384 << 10) /* Reserve 192 kB for Monitor */
#define CFG_MONITOR_BASE CFG_FLASH_BASE
#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */
/*
* For booting Linux, the board info and command line data
* have to be in the first 8 MB of memory, since this is
* the maximum mapped by the Linux kernel during initialization.
*/
#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
/*-----------------------------------------------------------------------
* FLASH organization
*/
#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */
#define CFG_MAX_FLASH_SECT 67 /* max number of sectors on one chip */
#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
#define CFG_ENV_IS_IN_FLASH 1
#ifdef CONFIG_BOOT_8B
#define CFG_ENV_OFFSET 0x10000 /* Offset of Environment Sector */
#define CFG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */
#elif defined (CONFIG_BOOT_16B)
#define CFG_ENV_OFFSET 0x10000 /* Offset of Environment Sector */
#define CFG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */
#elif defined (CONFIG_BOOT_32B)
#define CFG_ENV_OFFSET 0x8000 /* Offset of Environment Sector */
#define CFG_ENV_SIZE 0x4000 /* Total Size of Environment Sector */
#endif
/* Address and size of Redundant Environment Sector */
#define CFG_ENV_OFFSET_REDUND (CFG_ENV_OFFSET+CFG_ENV_SIZE)
#define CFG_ENV_SIZE_REDUND (CFG_ENV_SIZE)
/*-----------------------------------------------------------------------
* Hardware Information Block
*/
#define CFG_HWINFO_OFFSET 0x0003FFC0 /* offset of HW Info block */
#define CFG_HWINFO_SIZE 0x00000040 /* size of HW Info block */
#define CFG_HWINFO_MAGIC 0x46454C38 /* 'SVM8' */
/*-----------------------------------------------------------------------
* Cache Configuration
*/
#define CFG_CACHELINE_SIZE 16 /* For all MPC8xx CPUs */
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#define CFG_CACHELINE_SHIFT 4 /* log base 2 of the above value */
#endif
/*-----------------------------------------------------------------------
* SYPCR - System Protection Control 11-9
* SYPCR can only be written once after reset!
*-----------------------------------------------------------------------
* Software & Bus Monitor Timer max, Bus Monitor enable, SW Watchdog freeze
*/
#if defined(CONFIG_WATCHDOG)
/*#define CFG_SYPCR (SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | SYPCR_SWF | \
SYPCR_SWE | SYPCR_SWRI| SYPCR_SWP)
*/
#define CFG_SYPCR (SYPCR_SWTC | SYPCR_BMT | SYPCR_SWF | \
SYPCR_SWE | SYPCR_SWRI| SYPCR_SWP)
#else
#define CFG_SYPCR 0xffffff88
#endif
/*-----------------------------------------------------------------------
* SIUMCR - SIU Module Configuration 11-6
*-----------------------------------------------------------------------
* PCMCIA config., multi-function pin tri-state
*/
#ifndef CONFIG_CAN_DRIVER
/*#define CFG_SIUMCR 0x00610c00 */
#define CFG_SIUMCR 0x00000000
#else /* we must activate GPL5 in the SIUMCR for CAN */
#define CFG_SIUMCR (SIUMCR_DBGC11 | SIUMCR_DBPC00 | SIUMCR_MLRC01)
#endif /* CONFIG_CAN_DRIVER */
/*-----------------------------------------------------------------------
* TBSCR - Time Base Status and Control 11-26
*-----------------------------------------------------------------------
* Clear Reference Interrupt Status, Timebase freezing enabled
*/
#define CFG_TBSCR 0x0001
/*-----------------------------------------------------------------------
* RTCSC - Real-Time Clock Status and Control Register 11-27
*-----------------------------------------------------------------------
*/
#define CFG_RTCSC 0x00c3
/*-----------------------------------------------------------------------
* PISCR - Periodic Interrupt Status and Control 11-31
*-----------------------------------------------------------------------
* Clear Periodic Interrupt Status, Interrupt Timer freezing enabled
*/
#define CFG_PISCR 0x0000
/*-----------------------------------------------------------------------
* PLPRCR - PLL, Low-Power, and Reset Control Register 15-30
*-----------------------------------------------------------------------
* Reset PLL lock status sticky bit, timer expired status bit and timer
* interrupt status bit
*/
#if defined (CONFIG_100MHz)
#define CFG_PLPRCR 0x06301000
#define CONFIG_8xx_GCLK_FREQ 100000000
#elif defined (CONFIG_80MHz)
#define CFG_PLPRCR 0x04f01000
#define CONFIG_8xx_GCLK_FREQ 80000000
#elif defined(CONFIG_75MHz)
#define CFG_PLPRCR 0x04a00100
#define CONFIG_8xx_GCLK_FREQ 75000000
#elif defined(CONFIG_66MHz)
#define CFG_PLPRCR 0x04101000
#define CONFIG_8xx_GCLK_FREQ 66000000
#elif defined(CONFIG_50MHz)
#define CFG_PLPRCR 0x03101000
#define CONFIG_8xx_GCLK_FREQ 50000000
#endif
/*-----------------------------------------------------------------------
* SCCR - System Clock and reset Control Register 15-27
*-----------------------------------------------------------------------
* Set clock output, timebase and RTC source and divider,
* power management and some other internal clocks
*/
#define SCCR_MASK SCCR_EBDF11
#ifdef CONFIG_BUS_DIV2
#define CFG_SCCR 0x02020000 | SCCR_RTSEL
#else /* up to 50 MHz we use a 1:1 clock */
#define CFG_SCCR 0x02000000 | SCCR_RTSEL
#endif
/*-----------------------------------------------------------------------
* PCMCIA stuff
*-----------------------------------------------------------------------
*
*/
#define CFG_PCMCIA_MEM_ADDR (0xE0000000)
#define CFG_PCMCIA_MEM_SIZE ( 64 << 20 )
#define CFG_PCMCIA_DMA_ADDR (0xE4000000)
#define CFG_PCMCIA_DMA_SIZE ( 64 << 20 )
#define CFG_PCMCIA_ATTRB_ADDR (0xE8000000)
#define CFG_PCMCIA_ATTRB_SIZE ( 64 << 20 )
#define CFG_PCMCIA_IO_ADDR (0xEC000000)
#define CFG_PCMCIA_IO_SIZE ( 64 << 20 )
/*-----------------------------------------------------------------------
* IDE/ATA stuff (Supports IDE harddisk on PCMCIA Adapter)
*-----------------------------------------------------------------------
*/
#undef CONFIG_IDE_8xx_PCCARD /* Use IDE with PC Card Adapter */
#define CONFIG_IDE_8xx_DIRECT 1 /* Direct IDE not supported */
#undef CONFIG_IDE_LED /* LED for ide not supported */
#undef CONFIG_IDE_RESET /* reset for ide not supported */
#define CFG_IDE_MAXBUS 1 /* max. 1 IDE bus */
#define CFG_IDE_MAXDEVICE 1 /* max. 1 drive per IDE bus */
#define CFG_ATA_BASE_ADDR 0xFE100010
#define CFG_ATA_IDE0_OFFSET 0x0000
/*#define CFG_ATA_IDE1_OFFSET 0x0C00 */
#define CFG_ATA_DATA_OFFSET 0x0000 /* Offset for data I/O
*/
#define CFG_ATA_REG_OFFSET 0x0200 /* Offset for normal register accesses
*/
#define CFG_ATA_ALT_OFFSET 0x0210 /* Offset for alternate registers
*/
#define CONFIG_ATAPI
#define CFG_PIO_MODE 0
/*-----------------------------------------------------------------------
*
*-----------------------------------------------------------------------
*
*/
/*#define CFG_DER 0x2002000F*/
#define CFG_DER 0x0
/*
* Init Memory Controller:
*
* BR0/1 and OR0/1 (FLASH)
*/
#define FLASH_BASE0_PRELIM 0x40000000 /* FLASH bank #0 */
#define FLASH_BASE1_PRELIM 0x60000000 /* FLASH bank #0 */
/* used to re-map FLASH both when starting from SRAM or FLASH:
* restrict access enough to keep SRAM working (if any)
* but not too much to meddle with FLASH accesses
*/
#define CFG_REMAP_OR_AM 0x80000000 /* OR addr mask */
#define CFG_PRELIM_OR_AM 0xE0000000 /* OR addr mask */
/*
* FLASH timing:
*/
#if defined(CONFIG_100MHz)
#define CFG_OR_TIMING_FLASH 0x000002f4
#define CFG_OR_TIMING_DOC 0x000002f4
#define CFG_MxMR_PTx 0x61000000
#define CFG_MPTPR 0x400
#elif defined(CONFIG_80MHz)
#define CFG_OR_TIMING_FLASH 0x00000ff4
#define CFG_OR_TIMING_DOC 0x000001f4
#define CFG_MxMR_PTx 0x4e000000
#define CFG_MPTPR 0x400
#elif defined(CONFIG_75MHz)
#define CFG_OR_TIMING_FLASH 0x000008f4
#define CFG_OR_TIMING_DOC 0x000002f4
#define CFG_MxMR_PTx 0x49000000
#define CFG_MPTPR 0x400
#elif defined(CONFIG_66MHz)
#define CFG_OR_TIMING_FLASH (OR_ACS_DIV1 | OR_TRLX | OR_CSNT_SAM | \
OR_SCY_3_CLK | OR_EHTR | OR_BI)
/*#define CFG_OR_TIMING_FLASH 0x000001f4 */
#define CFG_OR_TIMING_DOC 0x000003f4
#define CFG_MxMR_PTx 0x40000000
#define CFG_MPTPR 0x400
#else /* 50 MHz */
#define CFG_OR_TIMING_FLASH 0x00000ff4
#define CFG_OR_TIMING_DOC 0x000001f4
#define CFG_MxMR_PTx 0x30000000
#define CFG_MPTPR 0x400
#endif /*CONFIG_??MHz */
#if defined (CONFIG_BOOT_8B) /* 512K X 8 ,29F040 , 2MB space */
#define CFG_OR0_PRELIM (0xffe00000 | CFG_OR_TIMING_FLASH)
#define CFG_BR0_PRELIM ((FLASH_BASE0_PRELIM & BR_BA_MSK) | BR_V | BR_PS_8)
#elif defined (CONFIG_BOOT_16B) /* 29lv160 X 16 , 4MB space */
#define CFG_OR0_PRELIM (0xffc00000 | CFG_OR_TIMING_FLASH)
#define CFG_BR0_PRELIM ((FLASH_BASE0_PRELIM & BR_BA_MSK) | BR_V | BR_PS_16)
#elif defined( CONFIG_BOOT_32B ) /* 29lv160 X 2 X 32, 4/8/16MB , 64MB space */
#define CFG_OR0_PRELIM (0xfc000000 | CFG_OR_TIMING_FLASH)
#define CFG_BR0_PRELIM ((FLASH_BASE0_PRELIM & BR_BA_MSK) | BR_V )
#else
#error Boot device port size missing.
#endif
/*
* Disk-On-Chip configuration
*/
#define CFG_DOC_SHORT_TIMEOUT
#define CFG_MAX_DOC_DEVICE 1 /* Max number of DOC devices */
#define CFG_DOC_SUPPORT_2000
#define CFG_DOC_SUPPORT_MILLENNIUM
#define CFG_DOC_BASE 0x80000000
/*
* Internal Definitions
*
* Boot Flags
*/
#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
#define BOOTFLAG_WARM 0x02 /* Software reboot */
#endif /* __CONFIG_H */

View File

@@ -105,6 +105,7 @@ extern int flash_real_protect(flash_info_t *info, long sector, int prot);
#define AMD_MANUFACT 0x00010001 /* AMD manuf. ID in D23..D16, D7..D0 */
#define FUJ_MANUFACT 0x00040004 /* FUJITSU manuf. ID in D23..D16, D7..D0 */
#define ATM_MANUFACT 0x001F001F /* ATMEL */
#define STM_MANUFACT 0x00200020 /* STM (Thomson) manuf. ID in D23.. -"- */
#define SST_MANUFACT 0x00BF00BF /* SST manuf. ID in D23..D16, D7..D0 */
#define MT_MANUFACT 0x00890089 /* MT manuf. ID in D23..D16, D7..D0 */
@@ -156,6 +157,8 @@ extern int flash_real_protect(flash_info_t *info, long sector, int prot);
#define AMD_ID_DL640 0x227E227E /* 29DL640D ID (64 M, dual boot sectors)*/
#define AMD_ID_LV640U 0x22D722D7 /* 29LV640U ID (64 M, uniform sectors) */
#define ATM_ID_BV1614 0x000000C0 /* 49BV1614 ID */
#define FUJI_ID_29F800BA 0x22582258 /* MBM29F800BA ID (8M) */
#define FUJI_ID_29F800TA 0x22D622D6 /* MBM29F800TA ID (8M) */

View File

@@ -81,13 +81,6 @@ struct DiskOnChip;
#define DOC_ECC_EN (DOC_ECC__EN | DOC_ECC_RESV)
#define DOC_ECC_DIS (DOC_ECC_RESV)
struct Nand {
char floor, chip;
unsigned long curadr;
unsigned char curmode;
/* Also some erase/write/pipeline info when we get that far */
};
#define MAX_FLOORS 4
#define MAX_CHIPS 4

View File

@@ -1,10 +1,11 @@
/*
* u-boot/include/linux/mtd/nand.h
* linux/include/linux/mtd/nand.h
*
* Copyright (c) 2000 David Woodhouse <dwmw2@mvhi.com>
* Steven J. Hill <sjhill@cotw.com>
* Thomas Gleixner <gleixner@autronix.de>
*
* $Id: nand.h,v 1.8 2000/10/30 17:16:17 sjhill Exp $
* $Id: nand.h,v 1.13 2002/04/28 13:40:41 gleixner Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -23,6 +24,14 @@
* bat later if I did something naughty.
* 10-11-2000 SJH Added private NAND flash structure for driver
* 10-24-2000 SJH Added prototype for 'nand_scan' function
* 10-29-2001 TG changed nand_chip structure to support
* hardwarespecific function for accessing control lines
* 02-21-2002 TG added support for different read/write adress and
* ready/busy line access function
* 02-26-2002 TG added chip_delay to nand_chip structure to optimize
* command delay times for different chips
* 04-28-2002 TG OOB config defines moved from nand.c to avoid duplicate
* defines in jffs2/wbuf.c
*/
#ifndef __LINUX_MTD_NAND_H
#define __LINUX_MTD_NAND_H
@@ -41,6 +50,82 @@
#define NAND_CMD_ERASE2 0xd0
#define NAND_CMD_RESET 0xff
/*
* Enumeration for NAND flash chip state
*/
typedef enum {
FL_READY,
FL_READING,
FL_WRITING,
FL_ERASING,
FL_SYNCING
} nand_state_t;
/*
* NAND Private Flash Chip Data
*
* Structure overview:
*
* IO_ADDR - address to access the 8 I/O lines of the flash device
*
* hwcontrol - hardwarespecific function for accesing control-lines
*
* dev_ready - hardwarespecific function for accesing device ready/busy line
*
* chip_lock - spinlock used to protect access to this structure
*
* wq - wait queue to sleep on if a NAND operation is in progress
*
* state - give the current state of the NAND device
*
* page_shift - number of address bits in a page (column address bits)
*
* data_buf - data buffer passed to/from MTD user modules
*
* data_cache - data cache for redundant page access and shadow for
* ECC failure
*
* ecc_code_buf - used only for holding calculated or read ECCs for
* a page read or written when ECC is in use
*
* reserved - padding to make structure fall on word boundary if
* when ECC is in use
*/
struct Nand {
char floor, chip;
unsigned long curadr;
unsigned char curmode;
/* Also some erase/write/pipeline info when we get that far */
};
struct nand_chip {
int page_shift;
u_char *data_buf;
u_char *data_cache;
int cache_page;
u_char ecc_code_buf[6];
u_char reserved[2];
char ChipID; /* Type of DiskOnChip */
struct Nand *chips;
int chipshift;
char* chips_name;
unsigned long erasesize;
unsigned long mfr; /* Flash IDs - only one type of flash per device */
unsigned long id;
char* name;
struct NFTLrecord nftl;
int nftl_found;
int numchips;
char page256;
char pageadrlen;
unsigned long IO_ADDR; /* address to access the 8 I/O lines to the flash device */
unsigned long totlen;
uint oobblock; // Size of OOB blocks (e.g. 512)
uint oobsize; // Amount of OOB data per block (e.g. 16)
uint eccsize;
};
/*
* NAND Flash Manufacturer ID Codes
*/
@@ -84,4 +169,30 @@ struct nand_flash_dev {
unsigned long erasesize;
};
/*
* Constants for oob configuration
*/
#define NAND_NOOB_ECCPOS0 0
#define NAND_NOOB_ECCPOS1 1
#define NAND_NOOB_ECCPOS2 2
#define NAND_NOOB_ECCPOS3 3
#define NAND_NOOB_ECCPOS4 4
#define NAND_NOOB_ECCPOS5 5
#define NAND_NOOB_BADBPOS -1
#define NAND_NOOB_ECCVPOS -1
#define NAND_JFFS2_OOB_ECCPOS0 0
#define NAND_JFFS2_OOB_ECCPOS1 1
#define NAND_JFFS2_OOB_ECCPOS2 2
#define NAND_JFFS2_OOB_ECCPOS3 3
#define NAND_JFFS2_OOB_ECCPOS4 6
#define NAND_JFFS2_OOB_ECCPOS5 7
#define NAND_JFFS2_OOB_BADBPOS 5
#define NAND_JFFS2_OOB_ECCVPOS 4
#define NAND_JFFS2_OOB8_FSDAPOS 6
#define NAND_JFFS2_OOB16_FSDAPOS 8
#define NAND_JFFS2_OOB8_FSDALEN 2
#define NAND_JFFS2_OOB16_FSDALEN 8
#endif /* __LINUX_MTD_NAND_H */

View File

@@ -48,7 +48,7 @@
# else
# define CONFIG_PCMCIA_SLOT_B
# endif
#elif defined(CONFIG_TQM8xxL)
#elif defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx)
# define CONFIG_PCMCIA_SLOT_B /* The TQM8xxL use SLOT_B */
#elif defined(CONFIG_SPD823TS) /* The SPD8xx use SLOT_B */
# define CONFIG_PCMCIA_SLOT_B

View File

@@ -269,6 +269,20 @@ void status_led_set (int led, int state);
# define STATUS_LED_BOOT 0 /* LED 0 used for boot status */
#elif defined(CONFIG_SVM_SC8xx)
# define STATUS_LED_PAR im_cpm.cp_pbpar
# define STATUS_LED_DIR im_cpm.cp_pbdir
# define STATUS_LED_ODR im_cpm.cp_pbodr
# define STATUS_LED_DAT im_cpm.cp_pbdat
# define STATUS_LED_BIT 0x00000001
# define STATUS_LED_PERIOD (CFG_HZ / 2)
# define STATUS_LED_STATE STATUS_LED_BLINKING
# define STATUS_LED_ACTIVE 1 /* LED on for bit == 1 */
# define STATUS_LED_BOOT 0 /* LED 0 used for boot status */
/************************************************************************/
#else
# error Status LED configuration missing

View File

@@ -5,10 +5,10 @@ dividend .req r0
divisor .req r1
result .req r2
curbit .req r3
ip .req r12
sp .req r13
lr .req r14
pc .req r15
/* ip .req r12 */
/* sp .req r13 */
/* lr .req r14 */
/* pc .req r15 */
.text
.globl __udivsi3
.type __udivsi3 ,function

View File

@@ -6,10 +6,10 @@ dividend .req r0
divisor .req r1
overdone .req r2
curbit .req r3
ip .req r12
sp .req r13
lr .req r14
pc .req r15
/* ip .req r12 */
/* sp .req r13 */
/* lr .req r14 */
/* pc .req r15 */
.text
.globl __umodsi3
.type __umodsi3 ,function

View File

@@ -31,6 +31,9 @@
#include <version.h>
#include <net.h>
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
void nand_init (void);
#endif
const char version_string[] =
U_BOOT_VERSION" (" __DATE__ " - " __TIME__ ")";
@@ -227,6 +230,10 @@ void start_armboot (void)
mem_malloc_init (_armboot_real_end);
#endif /* CONFIG_VFD */
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
nand_init(); /* go init the NAND */
#endif
/* initialize environment */
env_relocate ();

44
lib_mips/Makefile Normal file
View File

@@ -0,0 +1,44 @@
#
# (C) Copyright 2003
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
LIB = lib$(ARCH).a
AOBJS =
COBJS = board.o time.o mips_linux.o
OBJS = $(AOBJS) $(COBJS)
$(LIB): .depend $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
.depend: Makefile $(AOBJS:.o=.S) $(COBJS:.o=.c)
$(CC) -M $(CFLAGS) $(AOBJS:.o=.S) $(COBJS:.o=.c) > $@
sinclude .depend
#########################################################################

403
lib_mips/board.c Normal file
View File

@@ -0,0 +1,403 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <command.h>
#include <malloc.h>
#include <devices.h>
#include <syscall.h>
#include <version.h>
#include <net.h>
#include <environment.h>
#if ( ((CFG_ENV_ADDR+CFG_ENV_SIZE) < CFG_MONITOR_BASE) || \
(CFG_ENV_ADDR >= (CFG_MONITOR_BASE + CFG_MONITOR_LEN)) ) || \
defined(CFG_ENV_IS_IN_NVRAM)
#define TOTAL_MALLOC_LEN (CFG_MALLOC_LEN + CFG_ENV_SIZE)
#else
#define TOTAL_MALLOC_LEN CFG_MALLOC_LEN
#endif
#undef DEBUG
extern int timer_init(void);
const char version_string[] =
U_BOOT_VERSION" (" __DATE__ " - " __TIME__ ")";
static char *failed = "*** failed ***\n";
/*
* Begin and End of memory area for malloc(), and current "brk"
*/
static ulong mem_malloc_start;
static ulong mem_malloc_end;
static ulong mem_malloc_brk;
/*
* The Malloc area is immediately below the monitor copy in DRAM
*/
static void mem_malloc_init (void)
{
DECLARE_GLOBAL_DATA_PTR;
ulong dest_addr = CFG_MONITOR_BASE + gd->reloc_off;
mem_malloc_end = dest_addr;
mem_malloc_start = dest_addr - TOTAL_MALLOC_LEN;
mem_malloc_brk = mem_malloc_start;
memset ((void *) mem_malloc_start,
0,
mem_malloc_end - mem_malloc_start);
}
void *sbrk (ptrdiff_t increment)
{
ulong old = mem_malloc_brk;
ulong new = old + increment;
if ((new < mem_malloc_start) || (new > mem_malloc_end)) {
return (NULL);
}
mem_malloc_brk = new;
return ((void *) old);
}
static int init_func_ram (void)
{
DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_BOARD_TYPES
int board_type = gd->board_type;
#else
int board_type = 0; /* use dummy arg */
#endif
puts ("DRAM: ");
if ((gd->ram_size = initdram (board_type)) > 0) {
print_size (gd->ram_size, "\n");
return (0);
}
puts (failed);
return (1);
}
static int display_banner(void)
{
printf ("\n\n%s\n\n", version_string);
return (0);
}
static void display_flash_config(ulong size)
{
puts ("Flash: ");
print_size (size, "\n");
}
static int init_baudrate (void)
{
DECLARE_GLOBAL_DATA_PTR;
uchar tmp[64]; /* long enough for environment variables */
int i = getenv_r ("baudrate", tmp, sizeof (tmp));
gd->baudrate = (i > 0)
? (int) simple_strtoul (tmp, NULL, 10)
: CONFIG_BAUDRATE;
return (0);
}
/*
* Breath some life into the board...
*
* The first part of initialization is running from Flash memory;
* its main purpose is to initialize the RAM so that we
* can relocate the monitor code to RAM.
*/
/*
* All attempts to come up with a "common" initialization sequence
* that works for all boards and architectures failed: some of the
* requirements are just _too_ different. To get rid of the resulting
* mess of board dependend #ifdef'ed code we now make the whole
* initialization sequence configurable to the user.
*
* The requirements for any new initalization function is simple: it
* receives a pointer to the "global data" structure as it's only
* argument, and returns an integer return code, where 0 means
* "continue" and != 0 means "fatal error, hang the system".
*/
typedef int (init_fnc_t) (void);
init_fnc_t *init_sequence[] = {
timer_init,
env_init, /* initialize environment */
init_baudrate, /* initialze baudrate settings */
serial_init, /* serial communications setup */
console_init_f,
display_banner, /* say that we are here */
init_func_ram,
NULL,
};
void board_init_f(ulong bootflag)
{
DECLARE_GLOBAL_DATA_PTR;
gd_t gd_data, *id;
bd_t *bd;
init_fnc_t **init_fnc_ptr;
ulong addr, addr_sp, len = CFG_MONITOR_LEN;
/* Pointer is writable since we allocated a register for it.
*/
gd = &gd_data;
memset (gd, 0, sizeof (gd_t));
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
hang ();
}
}
/*
* Now that we have DRAM mapped and working, we can
* relocate the code and continue running from DRAM.
*/
addr = CFG_SDRAM_BASE + gd->ram_size;
/* We can reserve some RAM "on top" here.
*/
/* round down to next 4 kB limit.
*/
addr &= ~(4096 - 1);
#ifdef DEBUG
printf ("Top of RAM usable for U-Boot at: %08lx\n", addr);
#endif
/* Reserve memory for U-Boot code, data & bss
* round down to next 4 kB limit
*/
addr -= len;
addr &= ~(4096 - 1);
#ifdef DEBUG
printf ("Reserving %ldk for U-Boot at: %08lx\n", len >> 10, addr);
#endif
/* Reserve memory for malloc() arena.
*/
addr_sp = addr - TOTAL_MALLOC_LEN;
#ifdef DEBUG
printf ("Reserving %dk for malloc() at: %08lx\n",
TOTAL_MALLOC_LEN >> 10, addr_sp);
#endif
/*
* (permanently) allocate a Board Info struct
* and a permanent copy of the "global" data
*/
addr_sp -= sizeof(bd_t);
bd = (bd_t *)addr_sp;
gd->bd = bd;
#ifdef DEBUG
printf ("Reserving %d Bytes for Board Info at: %08lx\n",
sizeof(bd_t), addr_sp);
#endif
addr_sp -= sizeof(gd_t);
id = (gd_t *)addr_sp;
#ifdef DEBUG
printf ("Reserving %d Bytes for Global Data at: %08lx\n",
sizeof (gd_t), addr_sp);
#endif
/* Reserve memory for boot params.
*/
addr_sp -= CFG_BOOTPARAMS_LEN;
bd->bi_boot_params = addr_sp;
#ifdef DEBUG
printf ("Reserving %dk for malloc() at: %08lx\n",
CFG_BOOTPARAMS_LEN >> 10, addr_sp);
#endif
/*
* Finally, we set up a new (bigger) stack.
*
* Leave some safety gap for SP, force alignment on 16 byte boundary
* Clear initial stack frame
*/
addr_sp -= 16;
addr_sp &= ~0xF;
*((ulong *) addr_sp)-- = 0;
*((ulong *) addr_sp)-- = 0;
#ifdef DEBUG
printf ("Stack Pointer at: %08lx\n", addr_sp);
#endif
/*
* Save local variables to board info struct
*/
bd->bi_memstart = CFG_SDRAM_BASE; /* start of DRAM memory */
bd->bi_memsize = gd->ram_size; /* size of DRAM memory in bytes */
bd->bi_baudrate = gd->baudrate; /* Console Baudrate */
memcpy (id, gd, sizeof (gd_t));
relocate_code (addr_sp, id, addr);
/* NOTREACHED - relocate_code() does not return */
}
/************************************************************************
*
* This is the next part if the initialization sequence: we are now
* running from RAM and have a "normal" C environment, i. e. global
* data can be written, BSS has been cleared, the stack size in not
* that critical any more, etc.
*
************************************************************************
*/
void board_init_r (gd_t *id, ulong dest_addr)
{
DECLARE_GLOBAL_DATA_PTR;
cmd_tbl_t *cmdtp;
ulong size;
extern void malloc_bin_reloc (void);
#ifndef CFG_ENV_IS_NOWHERE
extern char * env_name_spec;
#endif
char *s, *e;
bd_t *bd;
int i;
gd = id;
gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */
#ifdef DEBUG
printf ("Now running in RAM - U-Boot at: %08lx\n", dest_addr);
#endif
gd->reloc_off = dest_addr - CFG_MONITOR_BASE;
/*
* We have to relocate the command table manually
*/
for (cmdtp = &cmd_tbl[0]; cmdtp->name; cmdtp++) {
ulong addr;
addr = (ulong) (cmdtp->cmd) + gd->reloc_off;
#if 0
printf ("Command \"%s\": 0x%08lx => 0x%08lx\n",
cmdtp->name, (ulong) (cmdtp->cmd), addr);
#endif
cmdtp->cmd =
(int (*)(struct cmd_tbl_s *, int, int, char *[]))addr;
addr = (ulong)(cmdtp->name) + gd->reloc_off;
cmdtp->name = (char *)addr;
if (cmdtp->usage) {
addr = (ulong)(cmdtp->usage) + gd->reloc_off;
cmdtp->usage = (char *)addr;
}
#ifdef CFG_LONGHELP
if (cmdtp->help) {
addr = (ulong)(cmdtp->help) + gd->reloc_off;
cmdtp->help = (char *)addr;
}
#endif
}
/* there are some other pointer constants we must deal with */
#ifndef CFG_ENV_IS_NOWHERE
env_name_spec += gd->reloc_off;
#endif
/* configure available FLASH banks */
size = flash_init();
display_flash_config (size);
bd = gd->bd;
bd->bi_flashstart = CFG_FLASH_BASE;
bd->bi_flashsize = size;
#if CFG_MONITOR_BASE == CFG_FLASH_BASE
bd->bi_flashoffset = CFG_MONITOR_LEN; /* reserved area for U-Boot */
#else
bd->bi_flashoffset = 0;
#endif
/* initialize malloc() area */
mem_malloc_init();
malloc_bin_reloc();
/* relocate environment function pointers etc. */
env_relocate();
/* board MAC address */
s = getenv ("ethaddr");
for (i = 0; i < 6; ++i) {
bd->bi_enetaddr[i] = s ? simple_strtoul (s, &e, 16) : 0;
if (s)
s = (*e) ? e + 1 : e;
}
/* IP Address */
bd->bi_ip_addr = getenv_IPaddr("ipaddr");
/** leave this here (after malloc(), environment and PCI are working) **/
/* Initialize devices */
devices_init ();
/* allocate syscalls table (console_init_r will fill it in */
syscall_tbl = (void **) malloc (NR_SYSCALLS * sizeof (void *));
/* Initialize the console (after the relocation and devices init) */
console_init_r ();
/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI)
puts ("Net: ");
eth_initialize(gd->bd);
#endif
/* main_loop() can return to retry autoboot, if so just run it again. */
for (;;) {
main_loop ();
}
/* NOTREACHED - no way out of command loop except booting */
}
void hang (void)
{
puts ("### ERROR ### Please RESET the board ###\n");
for (;;);
}

276
lib_mips/mips_linux.c Normal file
View File

@@ -0,0 +1,276 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <common.h>
#include <command.h>
#include <cmd_boot.h>
#include <image.h>
#include <zlib.h>
#include <asm/byteorder.h>
#include <asm/addrspace.h>
#define LINUX_MAX_ENVS 256
#define LINUX_MAX_ARGS 256
#ifdef CONFIG_SHOW_BOOT_PROGRESS
# include <status_led.h>
# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
#else
# define SHOW_BOOT_PROGRESS(arg)
#endif
extern image_header_t header; /* from cmd_bootm.c */
static int linux_argc;
static char ** linux_argv;
static char ** linux_env;
static char * linux_env_p;
static int linux_env_idx;
static void linux_params_init (ulong start, char * commandline);
static void linux_env_set (char * env_name, char * env_val);
void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
ulong addr, ulong *len_ptr, int verify)
{
DECLARE_GLOBAL_DATA_PTR;
ulong len = 0, checksum;
ulong initrd_start, initrd_end;
ulong data;
void (*theKernel)(int, char **, char **, int *);
image_header_t *hdr = &header;
char *commandline = getenv("bootargs");
char env_buf[12];
theKernel = (void (*)(int, char **, char **, int *))ntohl(hdr->ih_ep);
/*
* Check if there is an initrd image
*/
if (argc >= 3) {
SHOW_BOOT_PROGRESS (9);
addr = simple_strtoul(argv[2], NULL, 16);
printf ("## Loading Ramdisk Image at %08lx ...\n", addr);
/* Copy header so we can blank CRC field for re-calculation */
memcpy (&header, (char *)addr, sizeof(image_header_t));
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
printf ("Bad Magic Number\n");
SHOW_BOOT_PROGRESS (-10);
do_reset (cmdtp, flag, argc, argv);
}
data = (ulong)&header;
len = sizeof(image_header_t);
checksum = ntohl(hdr->ih_hcrc);
hdr->ih_hcrc = 0;
if (crc32 (0, (char *)data, len) != checksum) {
printf ("Bad Header Checksum\n");
SHOW_BOOT_PROGRESS (-11);
do_reset (cmdtp, flag, argc, argv);
}
SHOW_BOOT_PROGRESS (10);
print_image_hdr (hdr);
data = addr + sizeof(image_header_t);
len = ntohl(hdr->ih_size);
if (verify) {
ulong csum = 0;
printf (" Verifying Checksum ... ");
csum = crc32 (0, (char *)data, len);
if (csum != ntohl(hdr->ih_dcrc)) {
printf ("Bad Data CRC\n");
SHOW_BOOT_PROGRESS (-12);
do_reset (cmdtp, flag, argc, argv);
}
printf ("OK\n");
}
SHOW_BOOT_PROGRESS (11);
if ((hdr->ih_os != IH_OS_LINUX) ||
(hdr->ih_arch != IH_CPU_MIPS) ||
(hdr->ih_type != IH_TYPE_RAMDISK) ) {
printf ("No Linux MIPS Ramdisk Image\n");
SHOW_BOOT_PROGRESS (-13);
do_reset (cmdtp, flag, argc, argv);
}
/*
* Now check if we have a multifile image
*/
} else if ((hdr->ih_type==IH_TYPE_MULTI) && (len_ptr[1])) {
ulong tail = ntohl(len_ptr[0]) % 4;
int i;
SHOW_BOOT_PROGRESS (13);
/* skip kernel length and terminator */
data = (ulong)(&len_ptr[2]);
/* skip any additional image length fields */
for (i=1; len_ptr[i]; ++i)
data += 4;
/* add kernel length, and align */
data += ntohl(len_ptr[0]);
if (tail) {
data += 4 - tail;
}
len = ntohl(len_ptr[1]);
} else {
/*
* no initrd image
*/
SHOW_BOOT_PROGRESS (14);
data = 0;
}
#ifdef DEBUG
if (!data) {
printf ("No initrd\n");
}
#endif
if (data) {
initrd_start = data;
initrd_end = initrd_start + len;
} else {
initrd_start = 0;
initrd_end = 0;
}
SHOW_BOOT_PROGRESS (15);
#ifdef DEBUG
printf ("## Transferring control to Linux (at address %08lx) ...\n",
(ulong)theKernel);
#endif
linux_params_init (PHYSADDR(gd->bd->bi_boot_params), commandline);
sprintf (env_buf, "%lu", gd->ram_size >> 20);
linux_env_set ("memsize", env_buf);
sprintf (env_buf, "0x%08X", (uint)PHYSADDR(initrd_start));
linux_env_set ("initrd_start", env_buf);
sprintf (env_buf, "0x%X", (uint)(initrd_end - initrd_start));
linux_env_set ("initrd_size", env_buf);
sprintf (env_buf, "0x%08X", (uint)(gd->bd->bi_flashstart));
linux_env_set ("flash_start", env_buf);
sprintf (env_buf, "0x%X", (uint)(gd->bd->bi_flashsize));
linux_env_set ("flash_size", env_buf);
/* we assume that the kernel is in place */
printf("\nStarting kernel ...\n\n");
theKernel(linux_argc, linux_argv, linux_env, 0);
}
static void linux_params_init (ulong start, char * line)
{
char * next, * quote, * argp;
linux_argc = 1;
linux_argv = (char **) start;
linux_argv[0] = 0;
argp = (char *)(linux_argv + LINUX_MAX_ARGS);
next = line;
while (line && *line && linux_argc < LINUX_MAX_ARGS)
{
quote = strchr (line, '"');
next = strchr (line, ' ');
while (next != NULL && quote != NULL && quote < next)
{
/* we found a left quote before the next blank
* now we have to find the matching right quote
*/
next = strchr (quote + 1, '"');
if (next != NULL)
{
quote = strchr (next + 1, '"');
next = strchr (next + 1, ' ');
}
}
if (next == NULL)
{
next = line + strlen (line);
}
linux_argv [linux_argc] = argp;
memcpy (argp, line, next - line);
argp [next - line] = 0;
argp += next - line + 1;
linux_argc ++;
if (*next) next ++;
line = next;
}
linux_env = (char **)(((ulong)argp + 15) & ~15);
linux_env [0] = 0;
linux_env_p = (char *)(linux_env + LINUX_MAX_ENVS);
linux_env_idx = 0;
}
static void linux_env_set (char * env_name, char * env_val)
{
if (linux_env_idx < LINUX_MAX_ENVS - 1)
{
linux_env [linux_env_idx] = linux_env_p;
strcpy (linux_env_p, env_name);
linux_env_p += strlen (env_name);
strcpy (linux_env_p, "=");
linux_env_p += 1;
strcpy (linux_env_p, env_val);
linux_env_p += strlen (env_val);
linux_env_p ++;
linux_env [++ linux_env_idx] = 0;
}
}

103
lib_mips/time.c Normal file
View File

@@ -0,0 +1,103 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
static inline void mips_compare_set(u32 v)
{
asm volatile ("mtc0 %0, $11" : : "r" (v));
}
static inline void mips_count_set(u32 v)
{
asm volatile ("mtc0 %0, $9" : : "r" (v));
}
static inline u32 mips_count_get(void)
{
u32 count;
asm volatile ("mfc0 %0, $9" : "=r" (count) :);
return count;
}
/*
* timer without interrupts
*/
int timer_init(void)
{
mips_compare_set(0);
mips_count_set(0);
return 0;
}
void reset_timer(void)
{
mips_count_set(0);
}
ulong get_timer(ulong base)
{
return mips_count_get() - base;
}
void set_timer(ulong t)
{
mips_count_set(t);
}
void udelay (unsigned long usec)
{
ulong tmo;
ulong start = get_timer(0);
tmo = usec * CFG_HZ / 1000;
tmo /= 1000;
while ((ulong)((mips_count_get() - start)) < tmo)
/*NOP*/;
}
/*
* This function is derived from PowerPC code (read timebase as long long).
* On MIPS it just returns the timer value.
*/
unsigned long long get_ticks(void)
{
return mips_count_get();
}
/*
* This function is derived from PowerPC code (timebase clock frequency).
* On MIPS it returns the number of timer ticks per second.
*/
ulong get_tbclk(void)
{
return CFG_HZ;
}