- Add support for Innokom board - Don't complain if "install" fails - README cleanup (remove duplicated lines) - Update PXA header files * Add documentation for existing POST code (doc/README.POST) * Patch by Laudney Ren, 15 Jan 2003: Fix handling of redundand environment in "tools/envcrc.c" * Patch by Detlev Zundel, 28 Feb 2003: Add bedbug support for 824x systems * Add support for 16 MB flash configuration of TRAB board * Patch by Erwin Rol, 27 Feb 2003: Add support for RTEMS * Add image information to README * Fix dual PCMCIA slot support (when running with just one slot populated) * Add VFD type detection to trab board * extend drivers/cs8900.c driver to synchronize ethaddr environment variable with value in the EEPROMmaster
parent
6069ff2653
commit
43d9616cff
@ -0,0 +1,47 @@ |
||||
#
|
||||
# (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 := innokom.o flash.o
|
||||
SOBJS := memsetup.o
|
||||
|
||||
$(LIB): $(OBJS) $(SOBJS) |
||||
$(AR) crv $@ $^
|
||||
|
||||
clean: |
||||
rm -f $(SOBJS) $(OBJS)
|
||||
|
||||
distclean: clean |
||||
rm -f $(LIB) core *.bak .depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) |
||||
$(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
|
||||
|
||||
-include .depend |
||||
|
||||
#########################################################################
|
@ -0,0 +1,16 @@ |
||||
#
|
||||
# Linux-Kernel is expected to be at c000'8000, entry c000'8000
|
||||
#
|
||||
# we load ourself to c170'0000, the upper 1 MB of second bank
|
||||
#
|
||||
# download areas is c800'0000
|
||||
#
|
||||
|
||||
# This is the address where U-Boot lives in flash:
|
||||
#TEXT_BASE = 0
|
||||
|
||||
# FIXME: armboot does only work correctly when being compiled
|
||||
# for the addresses _after_ relocation to RAM!! Otherwhise the
|
||||
# .bss segment is assumed in flash...
|
||||
TEXT_BASE = 0xa1fe0000
|
||||
|
@ -0,0 +1,377 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net |
||||
* |
||||
* (C) Copyright 2002 |
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com> |
||||
* Marius Groeger <mgroeger@sysgo.de> |
||||
* |
||||
* (C) Copyright 2002 |
||||
* Robert Schwebel, Pengutronix, <r.schwebel@pengutronix.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/arch/pxa-regs.h> |
||||
|
||||
#define FLASH_BANK_SIZE 0x02000000 |
||||
#define MAIN_SECT_SIZE 0x40000 /* 2x16 = 256k per sector */ |
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; |
||||
|
||||
|
||||
/**
|
||||
* flash_init: - initialize data structures for flash chips |
||||
* |
||||
* @return: size of the flash |
||||
*/ |
||||
|
||||
ulong flash_init(void) |
||||
{ |
||||
int i, j; |
||||
ulong size = 0; |
||||
|
||||
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { |
||||
ulong flashbase = 0; |
||||
flash_info[i].flash_id = |
||||
(INTEL_MANUFACT & FLASH_VENDMASK) | |
||||
(INTEL_ID_28F128J3 & 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); |
||||
|
||||
switch (i) { |
||||
case 0: |
||||
flashbase = PHYS_FLASH_1; |
||||
break; |
||||
default: |
||||
panic("configured to many flash banks!\n"); |
||||
break; |
||||
} |
||||
for (j = 0; j < flash_info[i].sector_count; j++) { |
||||
flash_info[i].start[j] = flashbase + j*MAIN_SECT_SIZE; |
||||
} |
||||
size += flash_info[i].size; |
||||
} |
||||
|
||||
/* Protect monitor and environment sectors */ |
||||
flash_protect(FLAG_PROTECT_SET, |
||||
CFG_FLASH_BASE, |
||||
CFG_FLASH_BASE + _armboot_end_data - _armboot_start, |
||||
&flash_info[0]); |
||||
|
||||
#ifdef CFG_ENV_IS_IN_FLASH |
||||
flash_protect(FLAG_PROTECT_SET, |
||||
CFG_ENV_ADDR, |
||||
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, |
||||
&flash_info[0]); |
||||
#endif |
||||
|
||||
return size; |
||||
} |
||||
|
||||
|
||||
/**
|
||||
* flash_print_info: - print information about the flash situation |
||||
* |
||||
* @param info: |
||||
*/ |
||||
|
||||
void flash_print_info (flash_info_t *info) |
||||
{ |
||||
int i, j; |
||||
|
||||
for (j=0; j<CFG_MAX_FLASH_BANKS; j++) { |
||||
|
||||
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_28F128J3 & FLASH_TYPEMASK): |
||||
printf("28F128J3 (128Mbit)\n"); |
||||
break; |
||||
default: |
||||
printf("Unknown Chip Type\n"); |
||||
return; |
||||
} |
||||
|
||||
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"); |
||||
info++; |
||||
} |
||||
} |
||||
|
||||
|
||||
/**
|
||||
* flash_erase: - erase flash sectors |
||||
* |
||||
*/ |
||||
|
||||
int flash_erase(flash_info_t *info, int s_first, int s_last) |
||||
{ |
||||
int flag, prot, sect; |
||||
int rc = ERR_OK; |
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) |
||||
return ERR_UNKNOWN_FLASH_TYPE; |
||||
|
||||
if ((s_first < 0) || (s_first > s_last)) { |
||||
return ERR_INVAL; |
||||
} |
||||
|
||||
if ((info->flash_id & FLASH_VENDMASK) != (INTEL_MANUFACT & FLASH_VENDMASK)) |
||||
return ERR_UNKNOWN_FLASH_VENDOR; |
||||
|
||||
prot = 0; |
||||
for (sect=s_first; sect<=s_last; ++sect) { |
||||
if (info->protect[sect]) prot++; |
||||
} |
||||
|
||||
if (prot) 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. |
||||
*/ |
||||
|
||||
flag = 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 */ |
||||
u32 * volatile addr = (u32 * volatile)(info->start[sect]); |
||||
|
||||
/* erase sector: */ |
||||
/* The strata flashs are aligned side by side on */ |
||||
/* the data bus, so we have to write the commands */ |
||||
/* to both chips here: */ |
||||
|
||||
*addr = 0x00200020; /* erase setup */ |
||||
*addr = 0x00D000D0; /* erase confirm */ |
||||
|
||||
while ((*addr & 0x00800080) != 0x00800080) { |
||||
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) { |
||||
*addr = 0x00B000B0; /* suspend erase*/ |
||||
*addr = 0x00FF00FF; /* read mode */ |
||||
rc = ERR_TIMOUT; |
||||
goto outahere; |
||||
} |
||||
} |
||||
|
||||
*addr = 0x00500050; /* clear status register cmd. */ |
||||
*addr = 0x00FF00FF; /* resest to read mode */ |
||||
|
||||
} |
||||
|
||||
printf("ok.\n"); |
||||
} |
||||
|
||||
if (ctrlc()) printf("User Interrupt!\n"); |
||||
|
||||
outahere: |
||||
|
||||
/* allow flash to settle - wait 10 ms */ |
||||
udelay_masked(10000); |
||||
|
||||
if (flag) enable_interrupts(); |
||||
|
||||
return rc; |
||||
} |
||||
|
||||
|
||||
/**
|
||||
* write_word: - copy memory to flash |
||||
* |
||||
* @param info: |
||||
* @param dest: |
||||
* @param data: |
||||
* @return: |
||||
*/ |
||||
|
||||
static int write_word (flash_info_t *info, ulong dest, ushort data) |
||||
{ |
||||
ushort *addr = (ushort *)dest, val; |
||||
int rc = ERR_OK; |
||||
int flag; |
||||
|
||||
/* Check if Flash is (sufficiently) erased */ |
||||
if ((*addr & 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. |
||||
*/ |
||||
flag = disable_interrupts(); |
||||
|
||||
/* clear status register command */ |
||||
*addr = 0x50; |
||||
|
||||
/* program set-up command */ |
||||
*addr = 0x40; |
||||
|
||||
/* latch address/data */ |
||||
*addr = data; |
||||
|
||||
/* arm simple, non interrupt dependent timer */ |
||||
reset_timer_masked(); |
||||
|
||||
/* wait while polling the status register */ |
||||
while(((val = *addr) & 0x80) != 0x80) { |
||||
if (get_timer_masked() > CFG_FLASH_WRITE_TOUT) { |
||||
rc = ERR_TIMOUT; |
||||
*addr = 0xB0; /* suspend program command */ |
||||
goto outahere; |
||||
} |
||||
} |
||||
|
||||
if(val & 0x1A) { /* check for error */ |
||||
printf("\nFlash write error %02x at address %08lx\n", |
||||
(int)val, (unsigned long)dest); |
||||
if(val & (1<<3)) { |
||||
printf("Voltage range error.\n"); |
||||
rc = ERR_PROG_ERROR; |
||||
goto outahere; |
||||
} |
||||
if(val & (1<<1)) { |
||||
printf("Device protect error.\n"); |
||||
rc = ERR_PROTECTED; |
||||
goto outahere; |
||||
} |
||||
if(val & (1<<4)) { |
||||
printf("Programming error.\n"); |
||||
rc = ERR_PROG_ERROR; |
||||
goto outahere; |
||||
} |
||||
rc = ERR_PROG_ERROR; |
||||
goto outahere; |
||||
} |
||||
|
||||
outahere: |
||||
|
||||
*addr = 0xFF; /* read array command */ |
||||
if (flag) enable_interrupts(); |
||||
|
||||
return rc; |
||||
} |
||||
|
||||
|
||||
/**
|
||||
* write_buf: - Copy memory to flash. |
||||
* |
||||
* @param info: |
||||
* @param src: source of copy transaction |
||||
* @param addr: where to copy to |
||||
* @param cnt: number of bytes to copy |
||||
* |
||||
* @return error code |
||||
*/ |
||||
|
||||
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) |
||||
{ |
||||
ulong cp, wp; |
||||
ushort data; |
||||
int l; |
||||
int i, rc; |
||||
|
||||
wp = (addr & ~1); /* get lower word aligned address */ |
||||
|
||||
/*
|
||||
* handle unaligned start bytes |
||||
*/ |
||||
if ((l = addr - wp) != 0) { |
||||
data = 0; |
||||
for (i=0, cp=wp; i<l; ++i, ++cp) { |
||||
data = (data >> 8) | (*(uchar *)cp << 8); |
||||
} |
||||
for (; i<2 && cnt>0; ++i) { |
||||
data = (data >> 8) | (*src++ << 8); |
||||
--cnt; |
||||
++cp; |
||||
} |
||||
for (; cnt==0 && i<2; ++i, ++cp) { |
||||
data = (data >> 8) | (*(uchar *)cp << 8); |
||||
} |
||||
|
||||
if ((rc = write_word(info, wp, data)) != 0) { |
||||
return (rc); |
||||
} |
||||
wp += 2; |
||||
} |
||||
|
||||
/*
|
||||
* handle word aligned part |
||||
*/ |
||||
while (cnt >= 2) { |
||||
/* data = *((vushort*)src); */ |
||||
data = *((ushort*)src); |
||||
if ((rc = write_word(info, wp, data)) != 0) { |
||||
return (rc); |
||||
} |
||||
src += 2; |
||||
wp += 2; |
||||
cnt -= 2; |
||||
} |
||||
|
||||
if (cnt == 0) return ERR_OK; |
||||
|
||||
/*
|
||||
* handle unaligned tail bytes |
||||
*/ |
||||
data = 0; |
||||
for (i=0, cp=wp; i<2 && cnt>0; ++i, ++cp) { |
||||
data = (data >> 8) | (*src++ << 8); |
||||
--cnt; |
||||
} |
||||
for (; i<2; ++i, ++cp) { |
||||
data = (data >> 8) | (*(uchar *)cp << 8); |
||||
} |
||||
|
||||
return write_word(info, wp, data); |
||||
} |
||||
|
@ -0,0 +1,139 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* Robert Schwebel, Pengutronix, r.schwebel@pengutronix.de |
||||
* Kyle Harris, Nexus Technologies, Inc., kharris@nexus-tech.net |
||||
* Marius Groeger, Sysgo Real-Time Solutions GmbH, 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 <asm/arch/pxa-regs.h> |
||||
|
||||
#ifdef CONFIG_SHOW_BOOT_PROGRESS |
||||
# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) |
||||
#else |
||||
# define SHOW_BOOT_PROGRESS(arg) |
||||
#endif |
||||
|
||||
/*
|
||||
* Miscelaneous platform dependent initialisations |
||||
*/ |
||||
|
||||
|
||||
/**
|
||||
* board_init: - setup some data structures |
||||
* |
||||
* @return: 0 in case of success |
||||
*/ |
||||
|
||||
int board_init (void) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
/* memory and cpu-speed are setup before relocation */ |
||||
/* so we do _nothing_ here */ |
||||
|
||||
/* arch number of Innokom board */ |
||||
gd->bd->bi_arch_number = 258; |
||||
|
||||
/* adress of boot parameters */ |
||||
gd->bd->bi_boot_params = 0xa0000100; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
/**
|
||||
* dram_init: - setup dynamic RAM |
||||
* |
||||
* @return: 0 in case of success |
||||
*/ |
||||
|
||||
int dram_init (void) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
gd->bd->bi_dram[0].start = PHYS_SDRAM_1; |
||||
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
/**
|
||||
* innokom_set_led: - switch LEDs on or off |
||||
* |
||||
* @param led: LED to switch (0,1,2) |
||||
* @param state: switch on (1) or off (0) |
||||
*/ |
||||
|
||||
void innokom_set_led(int led, int state) |
||||
{ |
||||
switch(led) { |
||||
/*
|
||||
case 0: if (state==1) { |
||||
GPCR0 |= CSB226_USER_LED0; |
||||
} else if (state==0) { |
||||
GPSR0 |= CSB226_USER_LED0; |
||||
} |
||||
break; |
||||
|
||||
case 1: if (state==1) { |
||||
GPCR0 |= CSB226_USER_LED1; |
||||
} else if (state==0) { |
||||
GPSR0 |= CSB226_USER_LED1; |
||||
} |
||||
break; |
||||
|
||||
case 2: if (state==1) { |
||||
GPCR0 |= CSB226_USER_LED2; |
||||
} else if (state==0) { |
||||
GPSR0 |= CSB226_USER_LED2; |
||||
} |
||||
break; |
||||
*/ |
||||
} |
||||
|
||||
return; |
||||
} |
||||
|
||||
|
||||
/**
|
||||
* show_boot_progress: - indicate state of the boot process |
||||
* |
||||
* @param status: Status number - see README for details. |
||||
* |
||||
* The CSB226 does only have 3 LEDs, so we switch them on at the most |
||||
* important states (1, 5, 15). |
||||
*/ |
||||
|
||||
void show_boot_progress (int status) |
||||
{ |
||||
switch(status) { |
||||
/*
|
||||
case 1: csb226_set_led(0,1); break; |
||||
case 5: csb226_set_led(1,1); break; |
||||
case 15: csb226_set_led(2,1); break; |
||||
*/ |
||||
} |
||||
|
||||
return; |
||||
} |
||||
|
@ -0,0 +1,429 @@ |
||||
/* |
||||
* Most of this taken from Redboot hal_platform_setup.h with cleanup |
||||
* |
||||
* NOTE: I haven't clean this up considerably, just enough to get it |
||||
* running. See hal_platform_setup.h for the source. See |
||||
* board/cradle/memsetup.S for another PXA250 setup that is |
||||
* much cleaner. |
||||
* |
||||
* 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/arch/pxa-regs.h> |
||||
|
||||
DRAM_SIZE: .long CFG_DRAM_SIZE |
||||
|
||||
/* wait for coprocessor write complete */ |
||||
.macro CPWAIT reg |
||||
mrc p15,0,\reg,c2,c0,0 |
||||
mov \reg,\reg |
||||
sub pc,pc,#4 |
||||
.endm |
||||
|
||||
|
||||
/* |
||||
* Memory setup |
||||
*/ |
||||
|
||||
.globl memsetup
|
||||
memsetup: |
||||
|
||||
mov r10, lr |
||||
|
||||
/* Set up GPIO pins first ----------------------------------------- */ |
||||
|
||||
ldr r0, =GPSR0 |
||||
ldr r1, =CFG_GPSR0_VAL |
||||
str r1, [r0] |
||||
|
||||
ldr r0, =GPSR1 |
||||
ldr r1, =CFG_GPSR1_VAL |
||||
str r1, [r0] |
||||
|
||||
ldr r0, =GPSR2 |
||||
ldr r1, =CFG_GPSR2_VAL |
||||
str r1, [r0] |
||||
|
||||
ldr r0, =GPCR0 |
||||
ldr r1, =CFG_GPCR0_VAL |
||||
str r1, [r0] |
||||
|
||||
ldr r0, =GPCR1 |
||||
ldr r1, =CFG_GPCR1_VAL |
||||
str r1, [r0] |
||||
|
||||
ldr r0, =GPCR2 |
||||
ldr r1, =CFG_GPCR2_VAL |
||||
str r1, [r0] |
||||
|
||||
ldr r0, =GPDR0 |
||||
ldr r1, =CFG_GPDR0_VAL |
||||
str r1, [r0] |
||||
|
||||
ldr r0, =GPDR1 |
||||
ldr r1, =CFG_GPDR1_VAL |
||||
str r1, [r0] |
||||
|
||||
ldr r0, =GPDR2 |
||||
ldr r1, =CFG_GPDR2_VAL |
||||
str r1, [r0] |
||||
|
||||
ldr r0, =GAFR0_L |
||||
ldr r1, =CFG_GAFR0_L_VAL |
||||
str r1, [r0] |
||||
|
||||
ldr r0, =GAFR0_U |
||||
ldr r1, =CFG_GAFR0_U_VAL |
||||
str r1, [r0] |
||||
|
||||
ldr r0, =GAFR1_L |
||||
ldr r1, =CFG_GAFR1_L_VAL |
||||
str r1, [r0] |
||||
|
||||
ldr r0, =GAFR1_U |
||||
ldr r1, =CFG_GAFR1_U_VAL |
||||
str r1, [r0] |
||||
|
||||
ldr r0, =GAFR2_L |
||||
ldr r1, =CFG_GAFR2_L_VAL |
||||
str r1, [r0] |
||||
|
||||
ldr r0, =GAFR2_U |
||||
ldr r1, =CFG_GAFR2_U_VAL |
||||
str r1, [r0] |
||||
|
||||
ldr r0, =PSSR /* enable GPIO pins */ |
||||
ldr r1, =CFG_PSSR_VAL |
||||
str r1, [r0] |
||||
|
||||
/* ldr r3, =MSC1 / low - bank 2 Lubbock Registers / SRAM */ |
||||
/* ldr r2, =CFG_MSC1_VAL / high - bank 3 Ethernet Controller */ |
||||
/* str r2, [r3] / need to set MSC1 before trying to write to the HEX LEDs */ |
||||
/* ldr r2, [r3] / need to read it back to make sure the value latches (see MSC section of manual) */ |
||||
/* */ |
||||
/* ldr r1, =LED_BLANK */ |
||||
/* mov r0, #0xFF */ |
||||
/* str r0, [r1] / turn on hex leds */ |
||||
/* */ |
||||
/*loop: */ |
||||
/* */ |
||||
/* ldr r0, =0xB0070001 */ |
||||
/* ldr r1, =_LED */ |
||||
/* str r0, [r1] / hex display */ |
||||
|
||||
|
||||
/* ---------------------------------------------------------------- */ |
||||
/* Enable memory interface */ |
||||
/* */ |
||||
/* The sequence below is based on the recommended init steps */ |
||||
/* detailed in the Intel PXA250 Operating Systems Developers Guide, */ |
||||
/* Chapter 10. */ |
||||
/* ---------------------------------------------------------------- */ |
||||
|
||||
/* ---------------------------------------------------------------- */ |
||||
/* Step 1: Wait for at least 200 microsedonds to allow internal */ |
||||
/* clocks to settle. Only necessary after hard reset... */ |
||||
/* FIXME: can be optimized later */ |
||||
/* ---------------------------------------------------------------- */ |
||||
|
||||
ldr r3, =OSCR /* reset the OS Timer Count to zero */ |
||||
mov r2, #0 |
||||
str r2, [r3] |
||||
ldr r4, =0x300 /* really 0x2E1 is about 200usec, */ |
||||
/* so 0x300 should be plenty */ |
||||
1: |
||||
ldr r2, [r3] |
||||
cmp r4, r2 |
||||
bgt 1b |
||||
|
||||
mem_init: |
||||
|
||||
ldr r1, =MEMC_BASE /* get memory controller base addr. */ |
||||
|
||||
/* ---------------------------------------------------------------- */ |
||||
/* Step 2a: Initialize Asynchronous static memory controller */ |
||||
/* ---------------------------------------------------------------- */ |
||||
|
||||
/* MSC registers: timing, bus width, mem type */ |
||||
|
||||
/* MSC0: nCS(0,1) */ |
||||
ldr r2, =CFG_MSC0_VAL |
||||
str r2, [r1, #MSC0_OFFSET] |
||||
ldr r2, [r1, #MSC0_OFFSET] /* read back to ensure */ |
||||
/* that data latches */ |
||||
/* MSC1: nCS(2,3) */ |
||||
ldr r2, =CFG_MSC1_VAL |
||||
str r2, [r1, #MSC1_OFFSET] |
||||
ldr r2, [r1, #MSC1_OFFSET] |
||||
|
||||
/* MSC2: nCS(4,5) */ |
||||
ldr r2, =CFG_MSC2_VAL |
||||
str r2, [r1, #MSC2_OFFSET] |
||||
ldr r2, [r1, #MSC2_OFFSET] |
||||
|
||||
/* ---------------------------------------------------------------- */ |
||||
/* Step 2b: Initialize Card Interface */ |
||||
/* ---------------------------------------------------------------- */ |
||||
|
||||
/* MECR: Memory Expansion Card Register */ |
||||
ldr r2, =CFG_MECR_VAL |
||||
str r2, [r1, #MECR_OFFSET] |
||||
ldr r2, [r1, #MECR_OFFSET] |
||||
|
||||
/* MCMEM0: Card Interface slot 0 timing */ |
||||
ldr r2, =CFG_MCMEM0_VAL |
||||
str r2, [r1, #MCMEM0_OFFSET] |
||||
ldr r2, [r1, #MCMEM0_OFFSET] |
||||
|
||||
/* MCMEM1: Card Interface slot 1 timing */ |
||||
ldr r2, =CFG_MCMEM1_VAL |
||||
str r2, [r1, #MCMEM1_OFFSET] |
||||
ldr r2, [r1, #MCMEM1_OFFSET] |
||||
|
||||
/* MCATT0: Card Interface Attribute Space Timing, slot 0 */ |
||||
ldr r2, =CFG_MCATT0_VAL |
||||
str r2, [r1, #MCATT0_OFFSET] |
||||
ldr r2, [r1, #MCATT0_OFFSET] |
||||
|
||||
/* MCATT1: Card Interface Attribute Space Timing, slot 1 */ |
||||
ldr r2, =CFG_MCATT1_VAL |
||||
str r2, [r1, #MCATT1_OFFSET] |
||||
ldr r2, [r1, #MCATT1_OFFSET] |
||||
|
||||
/* MCIO0: Card Interface I/O Space Timing, slot 0 */ |
||||
ldr r2, =CFG_MCIO0_VAL |
||||
str r2, [r1, #MCIO0_OFFSET] |
||||
ldr r2, [r1, #MCIO0_OFFSET] |
||||
|
||||
/* MCIO1: Card Interface I/O Space Timing, slot 1 */ |
||||
ldr r2, =CFG_MCIO1_VAL |
||||
str r2, [r1, #MCIO1_OFFSET] |
||||
ldr r2, [r1, #MCIO1_OFFSET] |
||||
|
||||
/* ---------------------------------------------------------------- */ |
||||
/* Step 2c: Write FLYCNFG FIXME: what's that??? */ |
||||
/* ---------------------------------------------------------------- */ |
||||
|
||||
|
||||
/* ---------------------------------------------------------------- */ |
||||
/* Step 2d: Initialize Timing for Sync Memory (SDCLK0) */ |
||||
/* ---------------------------------------------------------------- */ |
||||
|
||||
/* Before accessing MDREFR we need a valid DRI field, so we set */ |
||||
/* this to power on defaults + DIR field. */ |
||||
|
||||
ldr r4, =0x03ca4fff |
||||
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */ |
||||
ldr r4, [r1, #MDREFR_OFFSET] |
||||
|
||||
ldr r4, =0x03ca4030 |
||||
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */ |
||||
ldr r4, [r1, #MDREFR_OFFSET] |
||||
|
||||
/* Note: preserve the mdrefr value in r4 */ |
||||
|
||||
|
||||
/* ---------------------------------------------------------------- */ |
||||
/* Step 3: Initialize Synchronous Static Memory (Flash/Peripherals) */ |
||||
/* ---------------------------------------------------------------- */ |
||||
|
||||
/* Initialize SXCNFG register. Assert the enable bits */ |
||||
|
||||
/* Write SXMRS to cause an MRS command to all enabled banks of */ |
||||
/* synchronous static memory. Note that SXLCR need not be written */ |
||||
/* at this time. */ |
||||
|
||||
/* FIXME: we use async mode for now */ |
||||
|
||||
|
||||
/* ---------------------------------------------------------------- */ |
||||
/* Step 4: Initialize SDRAM */ |
||||
/* ---------------------------------------------------------------- */ |
||||
|
||||
/* Step 4a: assert MDREFR:K1RUN and MDREFR:K2RUN and configure */ |
||||
/* MDREFR:K1DB2 and MDREFR:K2DB2 as desired. */ |
||||
|
||||
orr r4, r4, #(MDREFR_K1RUN|MDREFR_K0RUN) |
||||
|
||||
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */ |
||||
ldr r4, [r1, #MDREFR_OFFSET] |
||||
|
||||
|
||||
/* Step 4b: de-assert MDREFR:SLFRSH. */ |
||||
|
||||
bic r4, r4, #(MDREFR_SLFRSH) |
||||
|
||||
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */ |
||||
ldr r4, [r1, #MDREFR_OFFSET] |
||||
|
||||
|
||||
/* Step 4c: assert MDREFR:E1PIN and E0PIO */ |
||||
|
||||
orr r4, r4, #(MDREFR_E1PIN|MDREFR_E0PIN) |
||||
|
||||
str r4, [r1, #MDREFR_OFFSET] /* write back MDREFR */ |
||||
ldr r4, [r1, #MDREFR_OFFSET] |
||||
|
||||
|
||||
/* Step 4d: write MDCNFG with MDCNFG:DEx deasserted (set to 0), to */ |
||||
/* configure but not enable each SDRAM partition pair. */ |
||||
|
||||
ldr r4, =CFG_MDCNFG_VAL |
||||
bic r4, r4, #(MDCNFG_DE0|MDCNFG_DE1) |
||||
|
||||
str r4, [r1, #MDCNFG_OFFSET] /* write back MDCNFG */ |
||||
ldr r4, [r1, #MDCNFG_OFFSET] |
||||
|
||||
|
||||
/* Step 4e: Wait for the clock to the SDRAMs to stabilize, */ |
||||
/* 100..200 µsec. */ |
||||
|
||||
ldr r3, =OSCR /* reset the OS Timer Count to zero */ |
||||
mov r2, #0 |
||||
str r2, [r3] |
||||
ldr r4, =0x300 /* really 0x2E1 is about 200usec, */ |
||||
/* so 0x300 should be plenty */ |
||||
1: |
||||
ldr r2, [r3] |
||||
cmp r4, r2 |
||||
bgt 1b |
||||
|
||||
|
||||
/* Step 4f: Trigger a number (usually 8) refresh cycles by */ |
||||
/* attempting non-burst read or write accesses to disabled */ |
||||
/* SDRAM, as commonly specified in the power up sequence */ |
||||
/* documented in SDRAM data sheets. The address(es) used */ |
||||
/* for this purpose must not be cacheable. */ |
||||
|
||||
ldr r3, =CFG_DRAM_BASE |
||||
str r2, [r3] |
||||
str r2, [r3] |
||||
str r2, [r3] |
||||
str r2, [r3] |
||||
str r2, [r3] |
||||
str r2, [r3] |
||||
str r2, [r3] |
||||
str r2, [r3] |
||||
|
||||
|
||||
/* Step 4g: Write MDCNFG with enable bits asserted */ |
||||
/* (MDCNFG:DEx set to 1). */ |
||||
|
||||
ldr r3, [r1, #MDCNFG_OFFSET] |
||||
orr r3, r3, #(MDCNFG_DE0|MDCNFG_DE1) |
||||
str r3, [r1, #MDCNFG_OFFSET] |
||||
|
||||
/* Step 4h: Write MDMRS. */ |
||||
|
||||
ldr r2, =CFG_MDMRS_VAL |
||||
str r2, [r1, #MDMRS_OFFSET] |
||||
|
||||
|
||||
/* We are finished with Intel's memory controller initialisation */ |
||||
|
||||
|
||||
/* ---------------------------------------------------------------- */ |
||||
/* Disable (mask) all interrupts at interrupt controller */ |
||||
/* ---------------------------------------------------------------- */ |
||||
|
||||
initirqs: |
||||
|
||||
mov r1, #0 /* clear int. level register (IRQ, not FIQ) */ |
||||
ldr r2, =ICLR |
||||
str r1, [r2] |
||||
|
||||
ldr r2, =ICMR /* mask all interrupts at the controller */ |
||||
str r1, [r2] |
||||
|
||||
|
||||
/* ---------------------------------------------------------------- */ |
||||
/* Clock initialisation */ |
||||
/* ---------------------------------------------------------------- */ |
||||
|
||||
initclks: |
||||
|
||||
/* Disable the peripheral clocks, and set the core clock frequency */ |
||||
/* (hard-coding at 398.12MHz for now). */ |
||||
|
||||
/* Turn Off ALL on-chip peripheral clocks for re-configuration */ |
||||
/* Note: See label 'ENABLECLKS' for the re-enabling */ |
||||
ldr r1, =CKEN |
||||
mov r2, #0 |
||||
str r2, [r1] |
||||
|
||||
|
||||
/* default value in case no valid rotary switch setting is found */ |
||||
ldr r2, =(CCCR_L27|CCCR_M2|CCCR_N10) /* DEFAULT: {200/200/100} */ |
||||
|
||||
/* ... and write the core clock config register */ |
||||
ldr r1, =CCCR |
||||
str r2, [r1] |
||||
|
||||
/* enable the 32Khz oscillator for RTC and PowerManager */ |
||||
/* |
||||
ldr r1, =OSCC |
||||
mov r2, #OSCC_OON |
||||
str r2, [r1] |
||||
*/ |
||||
/* NOTE: spin here until OSCC.OOK get set, meaning the PLL */ |
||||
/* has settled. */ |
||||
60: |
||||
ldr r2, [r1] |
||||
ands r2, r2, #1 |
||||
beq 60b |
||||
|
||||
/* ---------------------------------------------------------------- */ |
||||
/* */ |
||||
/* ---------------------------------------------------------------- */ |
||||
|
||||
/* Save SDRAM size */ |
||||
ldr r1, =DRAM_SIZE |
||||
str r8, [r1] |
||||
|
||||
/* Interrupt init: Mask all interrupts */ |
||||
ldr r0, =ICMR /* enable no sources */ |
||||
mov r1, #0 |
||||
str r1, [r0] |
||||
|
||||
/* FIXME */ |
||||
|
||||
#define NODEBUG |
||||
#ifdef NODEBUG |
||||
/*Disable software and data breakpoints */ |
||||
mov r0,#0 |
||||
mcr p15,0,r0,c14,c8,0 /* ibcr0 */ |
||||
mcr p15,0,r0,c14,c9,0 /* ibcr1 */ |
||||
mcr p15,0,r0,c14,c4,0 /* dbcon */ |
||||
|
||||
/*Enable all debug functionality */ |
||||
mov r0,#0x80000000 |
||||
mcr p14,0,r0,c10,c0,0 /* dcsr */ |
||||
|
||||
#endif |
||||
|
||||
/* ---------------------------------------------------------------- */ |
||||
/* End memsetup */ |
||||
/* ---------------------------------------------------------------- */ |
||||
|
||||
endmemsetup: |
||||
|
||||
mov pc, lr |
||||
|
@ -0,0 +1,53 @@ |
||||
/* |
||||
* (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_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") |
||||
OUTPUT_ARCH(arm) |
||||
ENTRY(_start) |
||||
SECTIONS |
||||
{ |
||||
. = 0x00000000; |
||||
|
||||
. = ALIGN(4); |
||||
.text : |
||||
{ |
||||
cpu/xscale/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 = .; |
||||
} |
@ -0,0 +1,453 @@ |
||||
/*
|
||||
* (C) Copyright 2000 |
||||
* Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it |
||||
* |
||||
* (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com> |
||||
* Marius Groeger <mgroeger@sysgo.de> |
||||
* |
||||
* (C) Copyright 2003 Pengutronix e.K. |
||||
* Robert Schwebel <r.schwebel@pengutronix.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 |
||||
* |
||||
* Back ported to the 8xx platform (from the 8260 platform) by |
||||
* Murray.Jensen@cmst.csiro.au, 27-Jan-01. |
||||
*/ |
||||
|
||||
/* FIXME: this file is PXA255 specific! What about other XScales? */ |
||||
|
||||
#include <common.h> |
||||
|
||||
#ifdef CONFIG_HARD_I2C |
||||
|
||||
/*
|
||||
* - CFG_I2C_SPEED
|
||||
* - I2C_PXA_SLAVE_ADDR
|
||||
*/ |
||||
|
||||
#include <asm/arch/pxa-regs.h> |
||||
#include <i2c.h> |
||||
|
||||
//#define DEBUG_I2C 1 /* activate local debugging output */
|
||||
#define I2C_PXA_SLAVE_ADDR 0x1 /* slave pxa unit address */ |
||||
#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE) |
||||
#define I2C_ISR_INIT 0x7FF |
||||
|
||||
#ifdef DEBUG_I2C |
||||
#define PRINTD(x) printf x |
||||
#else |
||||
#define PRINTD(x) |
||||
#endif |
||||
|
||||
|
||||
/* Shall the current transfer have a start/stop condition? */ |
||||
#define I2C_COND_NORMAL 0 |
||||
#define I2C_COND_START 1 |
||||
#define I2C_COND_STOP 2 |
||||
|
||||
/* Shall the current transfer be ack/nacked or being waited for it? */ |
||||
#define I2C_ACKNAK_WAITACK 1 |
||||
#define I2C_ACKNAK_SENDACK 2 |
||||
#define I2C_ACKNAK_SENDNAK 4 |
||||
|
||||
/* Specify who shall transfer the data (master or slave) */ |
||||
#define I2C_READ 0 |
||||
#define I2C_WRITE 1 |
||||
|
||||
/* All transfers are described by this data structure */ |
||||
struct i2c_msg { |
||||
u8 condition; |
||||
u8 acknack;
|
||||
u8 direction;
|
||||
u8 data; |
||||
}; |
||||
|
||||
|
||||
/**
|
||||
* i2c_pxa_reset: - reset the host controller
|
||||
* |
||||
*/ |
||||
|
||||
static void i2c_reset( void ) |
||||
{ |
||||
ICR &= ~ICR_IUE; /* disable unit */ |
||||
ICR |= ICR_UR; /* reset the unit */ |
||||
udelay(100); |
||||
ICR &= ~ICR_IUE; /* disable unit */ |
||||
CKEN |= CKEN14_I2C; /* set the global I2C clock on */ |
||||
ISAR = I2C_PXA_SLAVE_ADDR; /* set our slave address */ |
||||
ICR = I2C_ICR_INIT; /* set control register values */ |
||||
ISR = I2C_ISR_INIT; /* set clear interrupt bits */ |
||||
ICR |= ICR_IUE; /* enable unit */ |
||||
udelay(100); |
||||
} |
||||
|
||||
|
||||
/**
|
||||
* i2c_isr_set_cleared: - wait until certain bits of the I2C status register
|
||||
* are set and cleared |
||||
* |
||||
* @return: 0 in case of success, 1 means timeout (no match within 10 ms).
|
||||
*/ |
||||
|
||||
static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask ) |
||||
{ |
||||
int timeout = 10000; |
||||
|
||||
while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){ |
||||
udelay( 10 ); |
||||
if( timeout-- < 0 ) return 0; |
||||
} |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
|
||||
/**
|
||||
* i2c_transfer: - Transfer one byte over the i2c bus |
||||
* |
||||
* This function can tranfer a byte over the i2c bus in both directions.
|
||||
* It is used by the public API functions.
|
||||
* |
||||
* @return: 0: transfer successful |
||||
* -1: message is empty |
||||
* -2: transmit timeout |
||||
* -3: ACK missing |
||||
* -4: receive timeout |
||||
* -5: illegal parameters |
||||
* -6: bus is busy and couldn't be aquired |
||||
*/
|
||||
int i2c_transfer(struct i2c_msg *msg) |
||||
{ |
||||
int ret; |
||||
|
||||
if (!msg)
|
||||
goto transfer_error_msg_empty; |
||||
|
||||
switch(msg->direction) { |
||||
|
||||
case I2C_WRITE: |
||||
|
||||
/* check if bus is not busy */ |
||||
if (!i2c_isr_set_cleared(0,ISR_IBB)) |
||||
goto transfer_error_bus_busy; |
||||
|
||||
/* start transmission */ |
||||
ICR &= ~ICR_START; |
||||
ICR &= ~ICR_STOP; |
||||
IDBR = msg->data; |
||||
if (msg->condition == I2C_COND_START) ICR |= ICR_START; |
||||
if (msg->condition == I2C_COND_STOP) ICR |= ICR_STOP;
|
||||
if (msg->acknack == I2C_ACKNAK_SENDNAK) ICR |= ICR_ACKNAK; |
||||
if (msg->acknack == I2C_ACKNAK_SENDACK) ICR &= ~ICR_ACKNAK; |
||||
ICR &= ~ICR_ALDIE; |
||||
ICR |= ICR_TB;
|
||||
|
||||
/* transmit register empty? */ |
||||
if (!i2c_isr_set_cleared(ISR_ITE,0))
|
||||
goto transfer_error_transmit_timeout; |
||||
|
||||
/* clear 'transmit empty' state */ |
||||
ISR |= ISR_ITE; |
||||
|
||||
/* wait for ACK from slave */ |
||||
if (msg->acknack == I2C_ACKNAK_WAITACK) |
||||
if (!i2c_isr_set_cleared(0,ISR_ACKNAK))
|
||||
goto transfer_error_ack_missing; |
||||
break; |
||||
|
||||
case I2C_READ: |
||||
|
||||
/* check if bus is not busy */ |
||||
if (!i2c_isr_set_cleared(0,ISR_IBB)) |
||||
goto transfer_error_bus_busy; |
||||
|
||||
/* start receive */ |
||||
ICR &= ~ICR_START; |
||||
ICR &= ~ICR_STOP; |
||||
if (msg->condition == I2C_COND_START) ICR |= ICR_START; |
||||
if (msg->condition == I2C_COND_STOP) ICR |= ICR_STOP; |
||||
if (msg->acknack == I2C_ACKNAK_SENDNAK) ICR |= ICR_ACKNAK; |
||||
if (msg->acknack == I2C_ACKNAK_SENDACK) ICR &= ~ICR_ACKNAK; |
||||
ICR &= ~ICR_ALDIE; |
||||
ICR |= ICR_TB; |
||||
|
||||
/* receive register full? */ |
||||
if (!i2c_isr_set_cleared(ISR_IRF,0))
|
||||
goto transfer_error_receive_timeout;
|
||||
|
||||
msg->data = IDBR; |
||||
|
||||
/* clear 'receive empty' state */ |
||||
ISR |= ISR_IRF; |
||||
|
||||
break; |
||||
|
||||
default: |
||||
|
||||
goto transfer_error_illegal_param; |
||||
|
||||
} |
||||
|
||||
return 0;
|
||||
|
||||
transfer_error_msg_empty:
|
||||
PRINTD(("i2c_transfer: error: 'msg' is empty\n")); |
||||
ret = -1; goto i2c_transfer_finish; |
||||
|
||||
transfer_error_transmit_timeout: |
||||
PRINTD(("i2c_transfer: error: transmit timeout\n")); |
||||
ret = -2; goto i2c_transfer_finish; |
||||
|
||||
transfer_error_ack_missing: |
||||
PRINTD(("i2c_transfer: error: ACK missing\n")); |
||||
ret = -3; goto i2c_transfer_finish; |
||||
|
||||
transfer_error_receive_timeout: |
||||
PRINTD(("i2c_transfer: error: receive timeout\n")); |
||||
ret = -4; goto i2c_transfer_finish; |
||||
|
||||
transfer_error_illegal_param: |
||||
PRINTD(("i2c_transfer: error: illegal parameters\n")); |
||||
ret = -5; goto i2c_transfer_finish; |
||||
|
||||
transfer_error_bus_busy: |
||||
PRINTD(("i2c_transfer: error: bus is busy\n")); |
||||
ret = -6; goto i2c_transfer_finish; |
||||
|
||||
i2c_transfer_finish: |
||||
PRINTD(("i2c_transfer: ISR: 0x%04x\n",ISR)); |
||||
i2c_reset(); |
||||
return ret; |
||||
|
||||
} |
||||
|
||||
/* ------------------------------------------------------------------------ */ |
||||
/* API Functions */ |
||||
/* ------------------------------------------------------------------------ */ |
||||
|
||||
void i2c_init(int speed, int slaveaddr) |
||||
{ |
||||
} |
||||
|
||||
|
||||
/**
|
||||
* i2c_probe: - Test if a chip answers for a given i2c address |
||||
* |
||||
* @chip: address of the chip which is searched for
|
||||
* @return: 0 if a chip was found, -1 otherwhise |
||||
*/ |
||||
|
||||
int i2c_probe(uchar chip) |
||||
{ |
||||
struct i2c_msg msg; |
||||
|
||||
i2c_reset(); |
||||
|
||||
msg.condition = I2C_COND_START; |
||||
msg.acknack = I2C_ACKNAK_WAITACK; |
||||
msg.direction = I2C_WRITE; |
||||
msg.data = (chip << 1) + 1; |
||||
if (i2c_transfer(&msg)) return -1; |
||||
|
||||
msg.condition = I2C_COND_STOP; |
||||
msg.acknack = I2C_ACKNAK_SENDNAK; |
||||
msg.direction = I2C_READ; |
||||
msg.data = 0x00; |
||||
if (i2c_transfer(&msg)) return -1; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
/**
|
||||
* i2c_read: - Read multiple bytes from an i2c device |
||||
* |
||||
* The higher level routines take into account that this function is only |
||||
* called with len < page length of the device (see configuration file)
|
||||
* |
||||
* @chip: address of the chip which is to be read |
||||
* @addr: i2c data address within the chip |
||||
* @alen: length of the i2c data address (1..2 bytes) |
||||
* @buffer: where to write the data |
||||
* @len: how much byte do we want to read |
||||
* @return: 0 in case of success |
||||
*/ |
||||
|
||||
int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) |
||||
{ |
||||
struct i2c_msg msg; |
||||
u8 addr_bytes[3]; /* lowest...highest byte of data address */ |
||||
int ret; |
||||
|
||||
PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len)); |
||||
|
||||
i2c_reset(); |
||||
|
||||
/* dummy chip address write */ |
||||
PRINTD(("i2c_read: dummy chip address write\n")); |
||||
msg.condition = I2C_COND_START; |
||||
msg.acknack = I2C_ACKNAK_WAITACK; |
||||
msg.direction = I2C_WRITE; |
||||
msg.data = (chip << 1); |
||||
msg.data &= 0xFE; |
||||
if ((ret=i2c_transfer(&msg))) return -1; |
||||
|
||||
/*
|
||||
* send memory address bytes;
|
||||
* alen defines how much bytes we have to send.
|
||||
*/ |
||||
//addr &= ((1 << CFG_EEPROM_PAGE_WRITE_BITS)-1);
|
||||
addr_bytes[0] = (u8)((addr >> 0) & 0x000000FF); |
||||
addr_bytes[1] = (u8)((addr >> 8) & 0x000000FF); |
||||
addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF); |
||||
|
||||
while (--alen >= 0) { |
||||
|
||||
PRINTD(("i2c_read: send memory word address byte %1d\n",alen)); |
||||
msg.condition = I2C_COND_NORMAL; |
||||
msg.acknack = I2C_ACKNAK_WAITACK; |
||||
msg.direction = I2C_WRITE; |
||||
msg.data = addr_bytes[alen]; |
||||
if ((ret=i2c_transfer(&msg))) return -1; |
||||
} |
||||
|
||||
|
||||
/* start read sequence */ |
||||
PRINTD(("i2c_read: start read sequence\n")); |
||||
msg.condition = I2C_COND_START; |
||||
msg.acknack = I2C_ACKNAK_WAITACK; |
||||
msg.direction = I2C_WRITE; |
||||
msg.data = (chip << 1); |
||||
msg.data |= 0x01; |
||||
if ((ret=i2c_transfer(&msg))) return -1; |
||||
|
||||
/* read bytes; send NACK at last byte */ |
||||
while (len--) { |
||||
|
||||
if (len==0) {
|
||||
msg.condition = I2C_COND_STOP; |
||||
msg.acknack = I2C_ACKNAK_SENDNAK; |
||||
} else { |
||||
msg.condition = I2C_COND_NORMAL; |
||||
msg.acknack = I2C_ACKNAK_SENDACK; |
||||
} |
||||
|
||||
msg.direction = I2C_READ; |
||||
msg.data = 0x00; |
||||
if ((ret=i2c_transfer(&msg))) return -1; |
||||
|
||||
*(buffer++) = msg.data; |
||||
|
||||
PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer)); |
||||
|
||||
} |
||||
|
||||
i2c_reset(); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
/**
|
||||
* i2c_write: - Write multiple bytes to an i2c device |
||||
* |
||||
* The higher level routines take into account that this function is only |
||||
* called with len < page length of the device (see configuration file)
|
||||
* |
||||
* @chip: address of the chip which is to be written |
||||
* @addr: i2c data address within the chip |
||||
* @alen: length of the i2c data address (1..2 bytes) |
||||
* @buffer: where to find the data to be written
|
||||
* @len: how much byte do we want to read |
||||
* @return: 0 in case of success |
||||
*/ |
||||
|
||||
int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) |
||||
{ |
||||
struct i2c_msg msg; |
||||
u8 addr_bytes[3]; /* lowest...highest byte of data address */ |
||||
|
||||
PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len)); |
||||
|
||||
i2c_reset(); |
||||
|
||||
/* chip address write */ |
||||
PRINTD(("i2c_write: chip address write\n")); |
||||
msg.condition = I2C_COND_START; |
||||
msg.acknack = I2C_ACKNAK_WAITACK; |
||||
msg.direction = I2C_WRITE; |
||||
msg.data = (chip << 1); |
||||
msg.data &= 0xFE; |
||||
if (i2c_transfer(&msg)) return -1; |
||||
|
||||
/*
|
||||
* send memory address bytes;
|
||||
* alen defines how much bytes we have to send.
|
||||
*/ |
||||
addr_bytes[0] = (u8)((addr >> 0) & 0x000000FF); |
||||
addr_bytes[1] = (u8)((addr >> 8) & 0x000000FF); |
||||
addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF); |
||||
|
||||
while (--alen >= 0) { |
||||
|
||||
PRINTD(("i2c_write: send memory word address\n")); |
||||
msg.condition = I2C_COND_NORMAL; |
||||
msg.acknack = I2C_ACKNAK_WAITACK; |
||||
msg.direction = I2C_WRITE; |
||||
msg.data = addr_bytes[alen]; |
||||
if (i2c_transfer(&msg)) return -1; |
||||
} |
||||
|
||||
/* write bytes; send NACK at last byte */ |
||||
while (len--) { |
||||
|
||||
PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer)); |
||||
|
||||
if (len==0)
|
||||
msg.condition = I2C_COND_STOP; |
||||
else |
||||
msg.condition = I2C_COND_NORMAL; |
||||
|
||||
msg.acknack = I2C_ACKNAK_WAITACK; |
||||
msg.direction = I2C_WRITE; |
||||
msg.data = *(buffer++); |
||||
|
||||
if (i2c_transfer(&msg)) return -1; |
||||
|
||||
} |
||||
|
||||
i2c_reset(); |
||||
|
||||
return 0; |
||||
|
||||
} |
||||
|
||||
uchar i2c_reg_read (uchar chip, uchar reg) |
||||
{ |
||||
PRINTD(("i2c_reg_read(chip=0x%02x, reg=0x%02x)\n",chip,reg)); |
||||
return 0; |
||||
} |
||||
|
||||
void i2c_reg_write(uchar chip, uchar reg, uchar val) |
||||
{ |
||||
PRINTD(("i2c_reg_write(chip=0x%02x, reg=0x%02x, val=0x%02x)\n",chip,reg,val)); |
||||
} |
||||
|
||||
#endif /* CONFIG_HARD_I2C */ |
@ -0,0 +1,732 @@ |
||||
Power-On-Self-Test support in U-Boot |
||||
------------------------------------ |
||||
|
||||
This project is to support Power-On-Self-Test (POST) in U-Boot. |
||||
|
||||
1. High-level requirements |
||||
|
||||
The key rquirements for this project are as follows: |
||||
|
||||
1) The project shall develop a flexible framework for implementing |
||||
and running Power-On-Self-Test in U-Boot. This framework shall |
||||
possess the following features: |
||||
|
||||
o) Extensibility |
||||
|
||||
The framework shall allow adding/removing/replacing POST tests. |
||||
Also, standalone POST tests shall be supported. |
||||
|
||||
o) Configurability |
||||
|
||||
The framework shall allow run-time configuration of the lists |
||||
of tests running on normal/power-fail booting. |
||||
|
||||
o) Controllability |
||||
|
||||
The framework shall support manual running of the POST tests. |
||||
|
||||
2) The results of tests shall be saved so that it will be possible to |
||||
retrieve them from Linux. |
||||
|
||||
3) The following POST tests shall be developed for MPC823E-based |
||||
boards: |
||||
|
||||
o) CPU test |
||||
o) Cache test |
||||
o) Memory test |
||||
o) Ethernet test |
||||
o) Serial channels test |
||||
o) Watchdog timer test |
||||
o) RTC test |
||||
o) I2C test |
||||
o) SPI test |
||||
o) USB test |
||||
|
||||
4) The LWMON board shall be used for reference. |
||||
|
||||
2. Design |
||||
|
||||
This section details the key points of the design for the project. |
||||
The whole project can be divided into two independent tasks: |
||||
enhancing U-Boot/Linux to provide a common framework for running POST |
||||
tests and developing such tests for particular hardware. |
||||
|
||||
2.1. Hardware-independent POST layer |
||||
|
||||
A new optional module will be added to U-Boot, which will run POST |
||||
tests and collect their results at boot time. Also, U-Boot will |
||||
support running POST tests manually at any time by executing a |
||||
special command from the system console. |
||||
|
||||
The list of available POST tests will be configured at U-Boot build |
||||
time. The POST layer will allow the developer to add any custom POST |
||||
tests. All POST tests will be divided into the following groups: |
||||
|
||||
1) Tests running on power-on booting only |
||||
|
||||
This group will contain those tests that run only once on |
||||
power-on reset (e.g. watchdog test) |
||||
|
||||
2) Tests running on normal booting only |
||||
|
||||
This group will contain those tests that do not take much |
||||
time and can be run on the regular basis (e.g. CPU test) |
||||
|
||||
3) Tests running on power-fail booting only |
||||
|
||||
This group will contain POST tests that consume much time |
||||
and cannot be run regularly (e.g. I2C test) |
||||
|
||||
4) Manually executed tests |
||||
|
||||
This group will contain those tests that can be run manually. |
||||
|
||||
If necessary, some tests may belong to several groups simultaneously. |
||||
For example, SDRAM test may run on both noarmal and power-fail |
||||
booting. On normal booting, SDRAM test may perform a fast superficial |
||||
memory test only, while running on power-fail booting it may perform |
||||
a full memory check-up. |
||||
|
||||
Also, all tests will be discriminated by the moment they run at. |
||||
Specifically, the following groups will be singled out: |
||||
|
||||
1) Tests running before relocating to RAM |
||||
|
||||
These tests will run immediatelly after initializing RAM |
||||
as to enable modifying it without taking care of its |
||||
contents. Basically, this group will contain memory tests |
||||
only. |
||||
|
||||
2) Tests running after relocating to RAM |
||||
|
||||
These tests will run immediately before entering the main |
||||
loop as to guarantee full hardware initialization. |
||||
|
||||
The POST layer will also distinguish a special group of tests that |
||||
may cause system rebooting (e.g. watchdog test). For such tests, the |
||||
layer will automatically detect rebooting and will notify the test |
||||
about it. |
||||
|
||||
2.1.1. POST layer interfaces |
||||
|
||||
This section details the interfaces between the POST layer and the |
||||
rest of U-Boot. |
||||
|
||||
The following flags will be defined: |
||||
|
||||
#define POST_ROM 0x01 /* test runs in ROM */ |
||||
#define POST_RAM 0x02 /* test runs in RAM */ |
||||
#define POST_POWERON 0x04 /* test runs on power-on booting */ |
||||
#define POST_NORMAL 0x08 /* test runs on normal booting */ |
||||
#define POST_SHUTDOWN 0x10 /* test runs on power-fail booting */ |
||||
#define POST_MANUAL 0x20 /* test can be executed manually */ |
||||
#define POST_REBOOT 0x80 /* test may cause rebooting */ |
||||
|
||||
The POST layer will export the following interface routines: |
||||
|
||||
o) int post_run(bd_t *bd, char *name, int flags); |
||||
|
||||
This routine will run the test (or the group of tests) specified |
||||
by the name and flag arguments. More specifically, if the name |
||||
argument is not NULL, the test with this name will be performed, |
||||
otherwise all tests running in ROM/RAM (depending on the flag |
||||
argument) will be executed. This routine will be called at least |
||||
twice with name set to NULL, once from board_init_f() and once |
||||
from board_init_r(). The flags argument will also specify the |
||||
mode the test is executed in (power-on, normal, power-fail, |
||||
manual). |
||||
|
||||
o) void post_reloc(ulong offset); |
||||
|
||||
This routine will be called from board_init_r() and will |
||||
relocate the POST test table. |
||||
|
||||
o) int post_info(char *name); |
||||
|
||||
This routine will print the list of all POST tests that can be |
||||
executed manually if name is NULL, and the description of a |
||||
particular test if name is not NULL. |
||||
|
||||
o) int post_log(char *format, ...); |
||||
|
||||
This routine will be called from POST tests to log their |
||||
results. Basically, this routine will print the results to |
||||
stderr. The format of the arguments and the return value |
||||
will be identical to the printf() routine. |
||||
|
||||
Also, the following board-specific routines will be called from the |
||||
U-Boot common code: |
||||
|
||||
o) int board_power_mode(void) |
||||
|
||||
This routine will return the mode the system is running in |
||||
(POST_POWERON, POST_NORMAL or POST_SHUTDOWN). |
||||
|
||||
o) void board_poweroff(void) |
||||
|
||||
This routine will turn off the power supply of the board. It |
||||
will be called on power-fail booting after running all POST |
||||
tests. |
||||
|
||||
The list of available POST tests be kept in the post_tests array |
||||
filled at U-Boot build time. The format of entry in this array will |
||||
be as follows: |
||||
|
||||
struct post_test { |
||||
char *name; |
||||
char *cmd; |
||||
char *desc; |
||||
int flags; |
||||
int (*test)(bd_t *bd, int flags); |
||||
}; |
||||
|
||||
o) name |
||||
|
||||
This field will contain a short name of the test, which will be |
||||
used in logs and on listing POST tests (e.g. CPU test). |
||||
|
||||
o) cmd |
||||
|
||||
This field will keep a name for identifying the test on manual |
||||
testing (e.g. cpu). For more information, refer to section |
||||
"Command line interface". |
||||
|
||||
o) desc |
||||
|
||||
This field will contain a detailed description of the test, |
||||
which will be printed on user request. For more information, see |
||||
section "Command line interface". |
||||
|
||||
o) flags |
||||
|
||||
This field will contain a combination of the bit flags described |
||||
above, which will specify the mode the test is running in |
||||
(power-on, normal, power-fail or manual mode), the moment it |
||||
should be run at (before or after relocating to RAM), whether it |
||||
can cause system rebooting or not. |
||||
|
||||
o) test |
||||
|
||||
This field will contain a pointer to the routine that will |
||||
perform the test, which will take 2 arguments. The first |
||||
argument will be a pointer to the board info structure, while |
||||
the second will be a combination of bit flags specifying the |
||||
mode the test is running in (POST_POWERON, POST_NORMAL, |
||||
POST_POWERFAIL, POST_MANUAL) and whether the last execution of |
||||
the test caused system rebooting (POST_REBOOT). The routine will |
||||
return 0 on successful execution of the test, and 1 if the test |
||||
failed. |
||||
|
||||
The lists of the POST tests that should be run at power-on/normal/ |
||||
power-fail booting will be kept in the environment. Namely, the |
||||
following environment variables will be used: post_poweron, |
||||
powet_normal, post_shutdown. |
||||
|
||||
2.1.2. Test results |
||||
|
||||
The results of tests will be collected by the POST layer. The POST |
||||
log will have the following format: |
||||
|
||||
... |
||||
-------------------------------------------- |
||||
START <name> |
||||
<test-specific output> |
||||
[PASSED|FAILED] |
||||
-------------------------------------------- |
||||
... |
||||
|
||||
Basically, the results of tests will be printed to stderr. This |
||||
feature may be enhanced in future to spool the log to a serial line, |
||||
save it in non-volatile RAM (NVRAM), transfer it to a dedicated |
||||
storage server and etc. |
||||
|
||||
2.1.3. Integration issues |
||||
|
||||
All POST-related code will be #ifdef'ed with the CONFIG_POST macro. |
||||
This macro will be defined in the config_<board>.h file for those |
||||
boards that need POST. The CONFIG_POST macro will contain the list of |
||||
POST tests for the board. The macro will have the format of array |
||||
composed of post_test structures: |
||||
|
||||
#define CONFIG_POST \ |
||||
{ |
||||
"On-board peripherals test", "board", \ |
||||
" This test performs full check-up of the " \ |
||||
"on-board hardware.", \ |
||||
POST_RAM | POST_POWERFAIL, \ |
||||
&board_post_test \ |
||||
} |
||||
|
||||
A new file, post.h, will be created in the include/ directory. This |
||||
file will contain common POST declarations and will define a set of |
||||
macros that will be reused for defining CONFIG_POST. As an example, |
||||
the following macro may be defined: |
||||
|
||||
#define POST_CACHE \ |
||||
{ |
||||
"Cache test", "cache", \ |
||||
" This test verifies the CPU cache operation.", \ |
||||
POST_RAM | POST_NORMAL, \ |
||||
&cache_post_test \ |
||||
} |
||||
|
||||
A new subdirectory will be created in the U-Boot root directory. It |
||||
will contain the source code of the POST layer and most of POST |
||||
tests. Each POST test in this directory will be placed into a |
||||
separate file (it will be needed for building standalone tests). Some |
||||
POST tests (mainly those for testing peripheral devices) will be |
||||
located in the source files of the drivers for those devices. This |
||||
way will be used only if the test subtantially uses the driver. |
||||
|
||||
2.1.4. Standalone tests |
||||
|
||||
The POST framework will allow to develop and run standalone tests. A |
||||
user-space library will be developed to provide the POST interface |
||||
functions to standalone tests. |
||||
|
||||
2.1.5. Command line interface |
||||
|
||||
A new command, diag, will be added to U-Boot. This command will be |
||||
used for listing all available hardware tests, getting detailed |
||||
descriptions of them and running these tests. |
||||
|
||||
More specifically, being run without any arguments, this command will |
||||
print the list of all available hardware tests: |
||||
|
||||
=> diag |
||||
Available hardware tests: |
||||
cache - cache test |
||||
cpu - CPU test |
||||
enet - SCC/FCC ethernet test |
||||
Use 'diag [<test1> [<test2>]] ... ' to get more info. |
||||
Use 'diag run [<test1> [<test2>]] ... ' to run tests. |
||||
=> |
||||
|
||||
If the first argument to the diag command is not 'run', detailed |
||||
descriptions of the specified tests will be printed: |
||||
|
||||
=> diag cpu cache |
||||
cpu - CPU test |
||||
This test verifies the arithmetic logic unit of CPU. |
||||
cache - cache test |
||||
This test verifies the CPU cache operation. |
||||
=> |
||||
|
||||
If the first argument to diag is 'run', the specified tests will be |
||||
executed. If no tests are specified, all available tests will be |
||||
executed. |
||||
|
||||
It will be prohibited to execute tests running in ROM manually. The |
||||
'diag' command will not display such tests and/or run them. |
||||
|
||||
2.1.6. Power failure handling |
||||
|
||||
The Linux kernel will be modified to detect power failures and |
||||
automatically reboot the system in such cases. It will be assumed |
||||
that the power failure causes a system interrupt. |
||||
|
||||
To perform correct system shutdown, the kernel will register a |
||||
handler of the power-fail IRQ on booting. Being called, the handler |
||||
will run /sbin/reboot using the call_usermodehelper() routine. |
||||
/sbin/reboot will automatically bring the system down in a secure |
||||
way. This feature will be configured in/out from the kernel |
||||
configuration file. |
||||
|
||||
The POST layer of U-Boot will check whether the system runs in |
||||
power-fail mode. If it does, the system will be powered off after |
||||
executing all hardware tests. |
||||
|
||||
2.1.7. Hazardous tests |
||||
|
||||
Some tests may cause system rebooting during their execution. For |
||||
some tests, this will indicate a failure, while for the Watchdog |
||||
test, this means successful operation of the timer. |
||||
|
||||
In order to support such tests, the following scheme will be |
||||
implemented. All the tests that may cause system rebooting will have |
||||
the POST_REBOOT bit flag set in the flag field of the correspondent |
||||
post_test structure. Before starting tests marked with this bit flag, |
||||
the POST layer will store an identification number of the test in a |
||||
location in IMMR. On booting, the POST layer will check the value of |
||||
this variable and if it is set will skip over the tests preceding the |
||||
failed one. On second execution of the failed test, the POST_REBOOT |
||||
bit flag will be set in the flag argument to the test routine. This |
||||
will allow to detect system rebooting on the previous iteration. For |
||||
example, the watchdog timer test may have the following |
||||
declaration/body: |
||||
|
||||
... |
||||
#define POST_WATCHDOG \ |
||||
{ |
||||
"Watchdog timer test", "watchdog", \ |
||||
" This test checks the watchdog timer.", \ |
||||
POST_RAM | POST_POWERON | POST_REBOOT, \ |
||||
&watchdog_post_test \ |
||||
} |
||||
... |
||||
|
||||
... |
||||
int watchdog_post_test(bd_t *bd, int flags) |
||||
{ |
||||
unsigned long start_time; |
||||
|
||||
if (flags & POST_REBOOT) { |
||||
/* Test passed */ |
||||
return 0; |
||||
} else { |
||||
/* disable interrupts */ |
||||
disable_interrupts(); |
||||
/* 10-second delay */ |
||||
... |
||||
/* if we've reached this, the watchdog timer does not work */ |
||||
enable_interrupts(); |
||||
return 1; |
||||
} |
||||
} |
||||
... |
||||
|
||||
2.2. Hardware-specific details |
||||
|
||||
This project will also develop a set of POST tests for MPC8xx- based |
||||
systems. This section provides technical details of how it will be |
||||
done. |
||||
|
||||
2.2.1. Generic PPC tests |
||||
|
||||
The following generic POST tests will be developed: |
||||
|
||||
o) CPU test |
||||
|
||||
This test will check the arithmetic logic unit (ALU) of CPU. The |
||||
test will take several milliseconds and will run on normal |
||||
booting. |
||||
|
||||
o) Cache test |
||||
|
||||
This test will verify the CPU cache (L1 cache). The test will |
||||
run on normal booting. |
||||
|
||||
o) Memory test |
||||
|
||||
This test will examine RAM and check it for errors. The test |
||||
will always run on booting. On normal booting, only a limited |
||||
amount of RAM will be checked. On power-fail booting a fool |
||||
memory check-up will be performed. |
||||
|
||||
2.2.1.1. CPU test |
||||
|
||||
This test will verify the following ALU instructions: |
||||
|
||||
o) Condition register istructions |
||||
|
||||
This group will contain: mtcrf, mfcr, mcrxr, crand, crandc, |
||||
cror, crorc, crxor, crnand, crnor, creqv, mcrf. |
||||
|
||||
The mtcrf/mfcr instructions will be tested by loading different |
||||
values into the condition register (mtcrf), moving its value to |
||||
a general-purpose register (mfcr) and comparing this value with |
||||
the expected one. The mcrxr instruction will be tested by |
||||
loading a fixed value into the XER register (mtspr), moving XER |
||||
value to the condition register (mcrxr), moving it to a |
||||
general-purpose register (mfcr) and comparing the value of this |
||||
register with the expected one. The rest of instructions will be |
||||
tested by loading a fixed value into the condition register |
||||
(mtcrf), executing each instruction several times to modify all |
||||
4-bit condition fields, moving the value of the conditional |
||||
register to a general-purpose register (mfcr) and comparing it |
||||
with the expected one. |
||||
|
||||
o) Integer compare instructions |
||||
|
||||
This group will contain: cmp, cmpi, cmpl, cmpli. |
||||
|
||||
To verify these instructions the test will run them with |
||||
different combinations of operands, read the condition register |
||||
value and compare it with the expected one. More specifically, |
||||
the test will contain a pre-built table containing the |
||||
description of each test case: the instruction, the values of |
||||
the operands, the condition field to save the result in and the |
||||
expected result. |
||||
|
||||
o) Arithmetic instructions |
||||
|
||||
This group will contain: add, addc, adde, addme, addze, subf, |
||||
subfc, subfe, subme, subze, mullw, mulhw, mulhwu, divw, divwu, |
||||
extsb, extsh. |
||||
|
||||
The test will contain a pre-built table of instructions, |
||||
operands, expected results and expected states of the condition |
||||
register. For each table entry, the test will cyclically use |
||||
different sets of operand registers and result registers. For |
||||
example, for instructions that use 3 registers on the first |
||||
iteration r0/r1 will be used as operands and r2 for result. On |
||||
the second iteration, r1/r2 will be used as operands and r3 as |
||||
for result and so on. This will enable to verify all |
||||
general-purpose registers. |
||||
|
||||
o) Logic instructions |
||||
|
||||
This group will contain: and, andc, andi, andis, or, orc, ori, |
||||
oris, xor, xori, xoris, nand, nor, neg, eqv, cntlzw. |
||||
|
||||
The test scheme will be identical to that from the previous |
||||
point. |
||||
|
||||
o) Shift instructions |
||||
|
||||
This group will contain: slw, srw, sraw, srawi, rlwinm, rlwnm, |
||||
rlwimi |
||||
|
||||
The test scheme will be identical to that from the previous |
||||
point. |
||||
|
||||
o) Branch instructions |
||||
|
||||
This group will contain: b, bl, bc. |
||||
|
||||
The first 2 instructions (b, bl) will be verified by jumping to |
||||
a fixed address and checking whether control was transfered to |
||||
that very point. For the bl instruction the value of the link |
||||
register will be checked as well (using mfspr). To verify the bc |
||||
instruction various combinations of the BI/BO fields, the CTR |
||||
and the condition register values will be checked. The list of |
||||
such combinations will be pre-built and linked in U-Boot at |
||||
build time. |
||||
|
||||
o) Load/store instructions |
||||
|
||||
This group will contain: lbz(x)(u), lhz(x)(u), lha(x)(u), |
||||
lwz(x)(u), stb(x)(u), sth(x)(u), stw(x)(u). |
||||
|
||||
All operations will be performed on a 16-byte array. The array |
||||
will be 4-byte aligned. The base register will point to offset |
||||
8. The immediate offset (index register) will range in [-8 ... |
||||
+7]. The test cases will be composed so that they will not cause |
||||
alignment exceptions. The test will contain a pre-built table |
||||
describing all test cases. For store instructions, the table |
||||
entry will contain: the instruction opcode, the value of the |
||||
index register and the value of the source register. After |
||||
executing the instruction, the test will verify the contents of |
||||
the array and the value of the base register (it must change for |
||||
"store with update" instructions). For load instructions, the |
||||
table entry will contain: the instruction opcode, the array |
||||
contents, the value of the index register and the expected value |
||||
of the destination register. After executing the instruction, |
||||
the test will verify the value of the destination register and |
||||
the value of the base register (it must change for "load with |
||||
update" instructions). |
||||
|
||||
o) Load/store multiple/string instructions |
||||
|
||||
|
||||
The CPU test will run in RAM in order to allow run-time modification |
||||
of the code to reduce the memory footprint. |
||||
|
||||
2.2.1.2 Special-Purpose Registers Tests |
||||
|
||||
TBD. |
||||
|
||||
2.2.1.3. Cache test |
||||
|
||||
To verify the data cache operation the following test scenarios will |
||||
be used: |
||||
|
||||
1) Basic test #1 |
||||
|
||||
- turn on the data cache |
||||
- switch the data cache to write-back or write-through mode |
||||
- invalidate the data cache |
||||
- write the negative pattern to a cached area |
||||
- read the area |
||||
|
||||
The negative pattern must be read at the last step |
||||
|
||||
2) Basic test #2 |
||||
|
||||
- turn on the data cache |
||||
- switch the data cache to write-back or write-through mode |
||||
- invalidate the data cache |
||||
- write the zero pattern to a cached area |
||||
- turn off the data cache |
||||
- write the negative pattern to the area |
||||
- turn on the data cache |
||||
- read the area |
||||
|
||||
The negative pattern must be read at the last step |
||||
|
||||
3) Write-through mode test |
||||
|
||||
- turn on the data cache |
||||
- switch the data cache to write-through mode |
||||
- invalidate the data cache |
||||
- write the zero pattern to a cached area |
||||
- flush the data cache |
||||
- write the negative pattern to the area |
||||
- turn off the data cache |
||||
- read the area |
||||
|
||||
The negative pattern must be read at the last step |
||||
|
||||
4) Write-back mode test |
||||
|
||||
- turn on the data cache |
||||
- switch the data cache to write-back mode |
||||
- invalidate the data cache |
||||
- write the negative pattern to a cached area |
||||
- flush the data cache |
||||
- write the zero pattern to the area |
||||
- invalidate the data cache |
||||
- read the area |
||||
|
||||
The negative pattern must be read at the last step |
||||
|
||||
To verify the instruction cache operation the following test |
||||
scenarios will be used: |
||||
|
||||
1) Basic test #1 |
||||
|
||||
- turn on the instruction cache |
||||
- unlock the entire instruction cache |
||||
- invalidate the instruction cache |
||||
- lock a branch instruction in the instruction cache |
||||
- replace the branch instruction with "nop" |
||||
- jump to the branch instruction |
||||
- check that the branch instruction was executed |
||||
|
||||
2) Basic test #2 |
||||
|
||||
- turn on the instruction cache |
||||
- unlock the entire instruction cache |
||||
- invalidate the instruction cache |
||||
- jump to a branch instruction |
||||
- check that the branch instruction was executed |
||||
- replace the branch instruction with "nop" |
||||
- invalidate the instruction cache |
||||
- jump to the branch instruction |
||||
- check that the "nop" instruction was executed |
||||
|
||||
The CPU test will run in RAM in order to allow run-time modification |
||||
of the code. |
||||
|
||||
2.2.1.4. Memory test |
||||
|
||||
The memory test will verify RAM using sequential writes and reads |
||||
to/from RAM. Specifically, there will be several test cases that will |
||||
use different patterns to verify RAM. Each test case will first fill |
||||
a region of RAM with one pattern and then read the region back and |
||||
compare its contents with the pattern. The following patterns will be |
||||
used: |
||||
|
||||
1) zero pattern (0x00000000) |
||||
2) negative pattern (0xffffffff) |
||||
3) checkerboard pattern (0x55555555, 0xaaaaaaaa) |
||||
4) bit-flip pattern ((1 << (offset % 32)), ~(1 << (offset % 32))) |
||||
5) address pattern (offset, ~offset) |
||||
|
||||
Patterns #1, #2 will help to find unstable bits. Patterns #3, #4 will |
||||
be used to detect adherent bits, i.e. bits whose state may randomly |
||||
change if adjacent bits are modified. The last pattern will be used |
||||
to detect far-located errors, i.e. situations when writing to one |
||||
location modifies an area located far from it. Also, usage of the |
||||
last pattern will help to detect memory controller misconfigurations |
||||
when RAM represents a cyclically repeated portion of a smaller size. |
||||
|
||||
Being run in normal mode, the test will verify only small 4Kb regions |
||||
of RAM around each 1Mb boundary. For example, for 64Mb RAM the |
||||
following areas will be verified: 0x00000000-0x00000800, |
||||
0x000ff800-0x00100800, 0x001ff800-0x00200800, ..., 0x03fff800- |
||||
0x04000000. If the test is run in power-fail mode, it will verify the |
||||
whole RAM. |
||||
|
||||
The memory test will run in ROM before relocating U-Boot to RAM in |
||||
order to allow RAM modification without saving its contents. |
||||
|
||||
2.2.2. Common tests |
||||
|
||||
This section describes tests that are not based on any hardware |
||||
peculiarities and use common U-Boot interfaces only. These tests do |
||||
not need any modifications for porting them to another board/CPU. |
||||
|
||||
2.2.2.1. I2C test |
||||
|
||||
For verifying the I2C bus, a full I2C bus scanning will be performed |
||||
using the i2c_probe() routine. If any I2C device is found, the test |
||||
will be considered as passed, otherwise failed. This particular way |
||||
will be used because it provides the most common method of testing. |
||||
For example, using the internal loopback mode of the CPM I2C |
||||
controller for testing would not work on boards where the software |
||||
I2C driver (also known as bit-banged driver) is used. |
||||
|
||||
2.2.2.2. Watchdog timer test |
||||
|
||||
To test the watchdog timer the scheme mentioned above (refer to |
||||
section "Hazardous tests") will be used. Namely, this test will be |
||||
marked with the POST_REBOOT bit flag. On the first iteration, the |
||||
test routine will make a 10-second delay. If the system does not |
||||
reboot during this delay, the watchdog timer is not operational and |
||||
the test fails. If the system reboots, on the second iteration the |
||||
POST_REBOOT bit will be set in the flag argument to the test routine. |
||||
The test routine will check this bit and report a success if it is |
||||
set. |
||||
|
||||
2.2.2.3. RTC test |
||||
|
||||
The RTC test will use the rtc_get()/rtc_set() routines. The following |
||||
features will be verified: |
||||
|
||||
o) Time uniformity |
||||
|
||||
This will be verified by reading RTC in polling within a short |
||||
period of time (5-10 seconds). |
||||
|
||||
o) Passing month boundaries |
||||
|
||||
This will be checked by setting RTC to a second before a month |
||||
boundary and reading it after its passing the boundary. The test |
||||
will be performed for both leap- and nonleap-years. |
||||
|
||||
2.2.3. MPC8xx peripherals tests |
||||
|
||||
This project will develop a set of tests verifying the peripheral |
||||
units of MPC8xx processors. Namely, the following controllers of the |
||||
MPC8xx communication processor module (CPM) will be tested: |
||||
|
||||
o) Serial Management Controllers (SMC) |
||||
|
||||
o) Serial Communication Controllers (SCC) |
||||
|
||||
2.2.3.1. Ethernet tests (SCC) |
||||
|
||||
The internal (local) loopback mode will be used to test SCC. To do |
||||
that the controllers will be configured accordingly and several |
||||
packets will be transmitted. These tests may be enhanced in future to |
||||
use external loopback for testing. That will need appropriate |
||||
reconfiguration of the physical interface chip. |
||||
|
||||
The test routines for the SCC ethernet tests will be located in |
||||
cpu/mpc8xx/scc.c. |
||||
|
||||
2.2.3.2. UART tests (SMC/SCC) |
||||
|
||||
To perform these tests the internal (local) loopback mode will be |
||||
used. The SMC/SCC controllers will be configured to connect the |
||||
transmitter output to the receiver input. After that, several bytes |
||||
will be transmitted. These tests may be enhanced to make to perform |
||||
"external" loopback test using a loopback cable. In this case, the |
||||
test will be executed manually. |
||||
|
||||
The test routine for the SMC/SCC UART tests will be located in |
||||
cpu/mpc8xx/serial.c. |
||||
|
||||
2.2.3.3. USB test |
||||
|
||||
TBD |
||||
|
||||
2.2.3.4. SPI test |
||||
|
||||
TBD |
||||
|
||||
2.3. Design notes |
||||
|
||||
Currently it is unknown how we will power off the board after running |
||||
all power-fail POST tests. This point needs further clarification. |
@ -0,0 +1,444 @@ |
||||
/*
|
||||
* (C) Copyright 2000, 2001, 2002 |
||||
* Robert Schwebel, Pengutronix, r.schwebel@pengutronix.de. |
||||
* |
||||
* Configuration for the Auerswald Innokom CPU 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 |
||||
*/ |
||||
|
||||
/*
|
||||
* include/configs/innokom.h - configuration options, board specific |
||||
*/ |
||||
|
||||
#ifndef __CONFIG_H |
||||
#define __CONFIG_H |
||||
|
||||
#define DEBUG 1 |
||||
|
||||
/*
|
||||
* If we are developing, we might want to start U-Boot from ram |
||||
* so we MUST NOT initialize critical regs like mem-timing ... |
||||
*/ |
||||
#define CONFIG_INIT_CRITICAL /* undef for developing */ |
||||
|
||||
/*
|
||||
* High Level Configuration Options |
||||
* (easy to change) |
||||
*/ |
||||
#define CONFIG_PXA250 1 /* This is an PXA250 CPU */ |
||||
#define CONFIG_INNOKOM 1 /* on an Auerswald Innokom board */ |
||||
|
||||
#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ |
||||
/* for timer/console/ethernet */ |
||||
/*
|
||||
* Hardware drivers |
||||
*/ |
||||
|
||||
/*
|
||||
* select serial console configuration |
||||
*/ |
||||
#define CONFIG_FFUART 1 /* we use FFUART on CSB226 */ |
||||
|
||||
/* allow to overwrite serial and ethaddr */ |
||||
#define CONFIG_ENV_OVERWRITE |
||||
|
||||
#define CONFIG_BAUDRATE 19200 |
||||
|
||||
#define CONFIG_COMMANDS ((CONFIG_CMD_DFL | CFG_CMD_I2C | CFG_CMD_EEPROM) & ~CFG_CMD_NET) |
||||
|
||||
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ |
||||
#include <cmd_confdefs.h> |
||||
|
||||
#define CONFIG_BOOTDELAY 3 |
||||
/* #define CONFIG_BOOTARGS "root=/dev/nfs ip=bootp console=ttyS0,19200" */ |
||||
#define CONFIG_BOOTARGS "console=ttyS0,19200" |
||||
#define CONFIG_ETHADDR FF:FF:FF:FF:FF:FF |
||||
#define CONFIG_NETMASK 255.255.255.0 |
||||
#define CONFIG_IPADDR 192.168.1.56 |
||||
#define CONFIG_SERVERIP 192.168.1.2 |
||||
#define CONFIG_BOOTCOMMAND "bootm 0x40000" |
||||
#define CONFIG_SHOW_BOOT_PROGRESS |
||||
|
||||
#define CONFIG_CMDLINE_TAG 1 |
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB) |
||||
#define CONFIG_KGDB_BAUDRATE 19200 /* speed to run kgdb serial port */ |
||||
#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */ |
||||
#endif |
||||
|
||||
/*
|
||||
* Miscellaneous configurable options |
||||
*/ |
||||
|
||||
/*
|
||||
* Size of malloc() pool; this lives below the uppermost 128 KiB which are |
||||
* used for the RAM copy of the uboot code |
||||
*/ |
||||
/* #define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024) */ |
||||
#define CFG_MALLOC_LEN (128*1024) |
||||
|
||||
#define CFG_LONGHELP /* undef to save memory */ |
||||
#define CFG_PROMPT "uboot> " /* Monitor Command Prompt */ |
||||
#define CFG_CBSIZE 128 /* Console I/O Buffer Size */ |
||||
#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ |
||||
#define CFG_MAXARGS 16 /* max number of command args */ |
||||
#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ |
||||
|
||||
#define CFG_MEMTEST_START 0xa0400000 /* memtest works on */ |
||||
#define CFG_MEMTEST_END 0xa0800000 /* 4 ... 8 MB in DRAM */ |
||||
|
||||
#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ |
||||
|
||||
#define CFG_LOAD_ADDR 0xa7fe0000 /* default load address */ |
||||
/* RS: where is this documented? */ |
||||
/* RS: is this where U-Boot is */ |
||||
/* RS: relocated to in RAM? */ |
||||
|
||||
#define CFG_HZ 3686400 /* incrementer freq: 3.6864 MHz */ |
||||
/* RS: the oscillator is actually 3680130?? */ |
||||
|
||||
#define CFG_CPUSPEED 0x141 /* set core clock to 200/200/100 MHz */ |
||||
/* 0101000001 */ |
||||
/* ^^^^^ Memory Speed 99.53 MHz */ |
||||
/* ^^ Run Mode Speed = 2x Mem Speed */ |
||||
/* ^^ Turbo Mode Sp. = 1x Run M. Sp. */ |
||||
|
||||
#define CFG_MONITOR_LEN 0x20000 /* 128 KiB */ |
||||
|
||||
/* valid baudrates */ |
||||
#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } |
||||
|
||||
/*
|
||||
* I2C bus |
||||
*/ |
||||
#define CONFIG_HARD_I2C 1 |
||||
#define CFG_I2C_SPEED 50000 |
||||
#define CFG_I2C_SLAVE 0xfe |
||||
|
||||
#define CFG_ENV_IS_IN_EEPROM 1 |
||||
|
||||
#define CFG_ENV_OFFSET 0x00 /* environment starts here */ |
||||
#define CFG_ENV_SIZE 1024 /* 1 KiB */ |
||||
#define CFG_I2C_EEPROM_ADDR 0x50 /* A0 = 0 (hardwired) */ |
||||
#define CFG_EEPROM_PAGE_WRITE_BITS 5 /* 5 bits = 32 octets */ |
||||
#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 /* between stop and start */ |
||||
#define CFG_I2C_EEPROM_ADDR_LEN 2 /* length of address */ |
||||
#define CFG_EEPROM_SIZE 4096 /* size in bytes */ |
||||
|
||||
/*
|
||||
* Stack sizes |
||||
* |
||||
* The stack sizes are set up in start.S using the settings below |
||||
*/ |
||||
#define CONFIG_STACKSIZE (128*1024) /* regular stack */ |
||||
#ifdef CONFIG_USE_IRQ |
||||
#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */ |
||||
#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */ |
||||
#endif |
||||
|
||||
/*
|
||||
* Physical Memory Map |
||||
*/ |
||||
#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */ |
||||
#define PHYS_SDRAM_1 0xa0000000 /* SDRAM Bank #1 */ |
||||
#define PHYS_SDRAM_1_SIZE 0x04000000 /* 64 MB */ |
||||
|
||||
#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */ |
||||
#define PHYS_FLASH_SIZE 0x01000000 /* 16 MB */ |
||||
|
||||
#define CFG_DRAM_BASE 0xa0000000 /* RAM starts here */ |
||||
#define CFG_DRAM_SIZE 0x04000000 |
||||
|
||||
#define CFG_FLASH_BASE PHYS_FLASH_1 |
||||
|
||||
/*
|
||||
* GPIO settings; |
||||
*/ |
||||
|
||||
/* GP15 == nCS1 is 1
|
||||
* GP24 == SFRM is 1 |
||||
* GP25 == TXD is 1 |
||||
* GP33 == nCS5 is 1 |
||||
* GP39 == FFTXD is 1 |
||||
* GP41 == RTS is 1 |
||||
* GP47 == TXD is 1 |
||||
* GP49 == nPWE is 1 |
||||
* GP62 == LED_B is 1 |
||||
* GP63 == TDM_OE is 1 |
||||
* GP78 == nCS2 is 1 |
||||
* GP79 == nCS3 is 1 |
||||
* GP80 == nCS4 is 1 |
||||
*/ |
||||
#define CFG_GPSR0_VAL 0x03008000 |
||||
#define CFG_GPSR1_VAL 0xC0028282 |
||||
#define CFG_GPSR2_VAL 0x0001C000 |
||||
|
||||
/* GP02 == DON_RST is 0
|
||||
* GP23 == SCLK is 0 |
||||
* GP45 == USB_ACT is 0 |
||||
* GP60 == PLLEN is 0 |
||||
* GP61 == LED_A is 0 |
||||
* GP73 == SWUPD_LED is 0 |
||||
*/ |
||||
#define CFG_GPCR0_VAL 0x00800004 |
||||
#define CFG_GPCR1_VAL 0x30002000 |
||||
#define CFG_GPCR2_VAL 0x00000100 |
||||
|
||||
/* GP00 == DON_READY is input
|
||||
* GP01 == DON_OK is input |
||||
* GP02 == DON_RST is output |
||||
* GP03 == RESET_IND is input |
||||
* GP07 == RES11 is input |
||||
* GP09 == RES12 is input |
||||
* GP11 == SWUPDATE is input |
||||
* GP14 == nPOWEROK is input |
||||
* GP15 == nCS1 is output |
||||
* GP17 == RES22 is input |
||||
* GP18 == RDY is input |
||||
* GP23 == SCLK is output |
||||
* GP24 == SFRM is output |
||||
* GP25 == TXD is output |
||||
* GP26 == RXD is input |
||||
* GP32 == RES21 is input |
||||
* GP33 == nCS5 is output |
||||
* GP34 == FFRXD is input |
||||
* GP35 == CTS is input |
||||
* GP39 == FFTXD is output |
||||
* GP41 == RTS is output |
||||
* GP42 == USB_OK is input |
||||
* GP45 == USB_ACT is output |
||||
* GP46 == RXD is input |
||||
* GP47 == TXD is output |
||||
* GP49 == nPWE is output |
||||
* GP58 == nCPUBUSINT is input |
||||
* GP59 == LANINT is input |
||||
* GP60 == PLLEN is output |
||||
* GP61 == LED_A is output |
||||
* GP62 == LED_B is output |
||||
* GP63 == TDM_OE is output |
||||
* GP64 == nDSPINT is input |
||||
* GP65 == STRAP0 is input |
||||
* GP67 == STRAP1 is input |
||||
* GP69 == STRAP2 is input |
||||
* GP70 == STRAP3 is input |
||||
* GP71 == STRAP4 is input |
||||
* GP73 == SWUPD_LED is output |
||||
* GP78 == nCS2 is output |
||||
* GP79 == nCS3 is output |
||||
* GP80 == nCS4 is output |
||||
*/ |
||||
#define CFG_GPDR0_VAL 0x03808004 |
||||
#define CFG_GPDR1_VAL 0xF002A282 |
||||
#define CFG_GPDR2_VAL 0x0001C200 |
||||
|
||||
/* GP15 == nCS1 is AF10
|
||||
* GP18 == RDY is AF01 |
||||
* GP23 == SCLK is AF10 |
||||
* GP24 == SFRM is AF10 |
||||
* GP25 == TXD is AF10 |
||||
* GP26 == RXD is AF01 |
||||
* GP33 == nCS5 is AF10 |
||||
* GP34 == FFRXD is AF01 |
||||
* GP35 == CTS is AF01 |
||||
* GP39 == FFTXD is AF10 |
||||
* GP41 == RTS is AF10 |
||||
* GP46 == RXD is AF10 |
||||
* GP47 == TXD is AF01 |
||||
* GP49 == nPWE is AF10 |
||||
* GP78 == nCS2 is AF10 |
||||
* GP79 == nCS3 is AF10 |
||||
* GP80 == nCS4 is AF10 |
||||
*/ |
||||
#define CFG_GAFR0_L_VAL 0x80000000 |
||||
#define CFG_GAFR0_U_VAL 0x001A8010 |
||||
#define CFG_GAFR1_L_VAL 0x60088058 |
||||
#define CFG_GAFR1_U_VAL 0x00000008 |
||||
#define CFG_GAFR2_L_VAL 0xA0000000 |
||||
#define CFG_GAFR2_U_VAL 0x00000002 |
||||
|
||||
/* FIXME: set GPIO_RER/FER */ |
||||
|
||||
/* RDH = 1
|
||||
* PH = 1 |
||||
* VFS = 1 |
||||
* BFS = 1 |
||||
* SSS = 1 |
||||
*/ |
||||
#define CFG_PSSR_VAL 0x37 |
||||
|
||||
/*
|
||||
* Memory settings |
||||
*/ |
||||
|
||||
/* This is the configuration for nCS0/1 -> flash banks
|
||||
* configuration for nCS1: |
||||
* [31] 0 - Slower Device |
||||
* [30:28] 010 - CS deselect to CS time: 2*(2*MemClk) = 40 ns |
||||
* [27:24] 0101 - Address to data valid in bursts: (5+1)*MemClk = 60 ns |
||||
* [23:20] 1011 - " for first access: (11+2)*MemClk = 130 ns |
||||
* [19] 1 - 16 Bit bus width |
||||
* [18:16] 000 - nonburst RAM or FLASH |
||||
* configuration for nCS0: |
||||
* [15] 0 - Slower Device |
||||
* [14:12] 010 - CS deselect to CS time: 2*(2*MemClk) = 40 ns |
||||
* [11:08] 0101 - Address to data valid in bursts: (5+1)*MemClk = 60 ns |
||||
* [07:04] 1011 - " for first access: (11+2)*MemClk = 130 ns |
||||
* [03] 1 - 16 Bit bus width |
||||
* [02:00] 000 - nonburst RAM or FLASH |
||||
*/ |
||||
#define CFG_MSC0_VAL 0x25b825b8 /* flash banks */ |
||||
|
||||
/* This is the configuration for nCS2/3 -> TDM-Switch, DSP
|
||||
* configuration for nCS3: DSP |
||||
* [31] 0 - Slower Device |
||||
* [30:28] 001 - RRR3: CS deselect to CS time: 1*(2*MemClk) = 20 ns |
||||
* [27:24] 0010 - RDN3: Address to data valid in bursts: (2+1)*MemClk = 30 ns |
||||
* [23:20] 0011 - RDF3: Address for first access: (3+1)*MemClk = 40 ns |
||||
* [19] 1 - 16 Bit bus width |
||||
* [18:16] 100 - variable latency I/O |
||||
* configuration for nCS2: TDM-Switch |
||||
* [15] 0 - Slower Device |
||||
* [14:12] 101 - RRR2: CS deselect to CS time: 5*(2*MemClk) = 100 ns |
||||
* [11:08] 1001 - RDN2: Address to data valid in bursts: (9+1)*MemClk = 100 ns |
||||
* [07:04] 0011 - RDF2: Address for first access: (3+1)*MemClk = 40 ns |
||||
* [03] 1 - 16 Bit bus width |
||||
* [02:00] 100 - variable latency I/O |
||||
*/ |
||||
#define CFG_MSC1_VAL 0x132C593C /* TDM switch, DSP */ |
||||
|
||||
/* This is the configuration for nCS4/5 -> ExtBus, LAN Controller
|
||||
* |
||||
* configuration for nCS5: LAN Controller |
||||
* [31] 0 - Slower Device |
||||
* [30:28] 001 - RRR5: CS deselect to CS time: 1*(2*MemClk) = 20 ns |
||||
* [27:24] 0010 - RDN5: Address to data valid in bursts: (2+1)*MemClk = 30 ns |
||||
* [23:20] 0011 - RDF5: Address for first access: (3+1)*MemClk = 40 ns |
||||
* [19] 1 - 16 Bit bus width |
||||
* [18:16] 100 - variable latency I/O |
||||
* configuration for nCS4: ExtBus |
||||
* [15] 0 - Slower Device |
||||
* [14:12] 110 - RRR4: CS deselect to CS time: 6*(2*MemClk) = 120 ns |
||||
* [11:08] 1100 - RDN4: Address to data valid in bursts: (12+1)*MemClk = 130 ns |
||||
* [07:04] 1101 - RDF4: Address for first access: 13->(15+1)*MemClk = 160 ns |
||||
* [03] 1 - 16 Bit bus width |
||||
* [02:00] 100 - variable latency I/O |
||||
*/ |
||||
#define CFG_MSC2_VAL 0x132C6CDC /* extra bus, LAN controller */ |
||||
|
||||
/* MDCNFG: SDRAM Configuration Register
|
||||
* |
||||
* [31:29] 000 - reserved |
||||
* [28] 0 - no SA1111 compatiblity mode |
||||
* [27] 0 - latch return data with return clock |
||||
* [26] 0 - alternate addressing for pair 2/3 |
||||
* [25:24] 00 - timings |
||||
* [23] 0 - internal banks in lower partition 2/3 (not used) |
||||
* [22:21] 00 - row address bits for partition 2/3 (not used) |
||||
* [20:19] 00 - column address bits for partition 2/3 (not used) |
||||
* [18] 0 - SDRAM partition 2/3 width is 32 bit |
||||
* [17] 0 - SDRAM partition 3 disabled |
||||
* [16] 0 - SDRAM partition 2 disabled |
||||
* [15:13] 000 - reserved |
||||
* [12] 1 - SA1111 compatiblity mode |
||||
* [11] 1 - latch return data with return clock |
||||
* [10] 0 - no alternate addressing for pair 0/1 |
||||
* [09:08] 01 - tRP=2*MemClk; CL=2; tRCD=2*MemClk; tRAS=5*MemClk; tRC=8*MemClk |
||||
* [7] 1 - 4 internal banks in lower partition pair |
||||
* [06:05] 10 - 13 row address bits for partition 0/1 |
||||
* [04:03] 01 - 9 column address bits for partition 0/1 |
||||
* [02] 0 - SDRAM partition 0/1 width is 32 bit |
||||
* [01] 0 - disable SDRAM partition 1 |
||||
* [00] 1 - enable SDRAM partition 0 |
||||
* |
||||
* use the configuration above but disable partition 0 |
||||
*/ |
||||
#define CFG_MDCNFG_VAL 0x000019c8 |
||||
|
||||
/* MDREFR: SDRAM Refresh Control Register
|
||||
* |
||||
* [32:26] 0 - reserved |
||||
* [25] 0 - K2FREE: not free running |
||||
* [24] 0 - K1FREE: not free running |
||||
* [23] 0 - K0FREE: not free running |
||||
* [22] 0 - SLFRSH: self refresh disabled |
||||
* [21] 0 - reserved |
||||
* [20] 0 - APD: no auto power down |
||||
* [19] 0 - K2DB2: SDCLK2 is MemClk |
||||
* [18] 0 - K2RUN: disable SDCLK2 |
||||
* [17] 0 - K1DB2: SDCLK1 is MemClk |
||||
* [16] 1 - K1RUN: enable SDCLK1 |
||||
* [15] 1 - E1PIN: SDRAM clock enable |
||||
* [14] 1 - K0DB2: SDCLK0 is MemClk |
||||
* [13] 1 - K0RUN: disable SDCLK0 |
||||
* [12] 1 - E0PIN: disable SDCKE0 |
||||
* [11:00] 000000011000 - (64ms/8192)*MemClkFreq/32 = 24 |
||||
*/ |
||||
#define CFG_MDREFR_VAL 0x0001F018 |
||||
|
||||
/* MDMRS: Mode Register Set Configuration Register
|
||||
* |
||||
* [31] 0 - reserved |
||||
* [30:23] 00000000- MDMRS2: SDRAM2/3 MRS Value. (not used) |
||||
* [22:20] 000 - MDCL2: SDRAM2/3 Cas Latency. (not used) |
||||
* [19] 0 - MDADD2: SDRAM2/3 burst Type. Fixed to sequential. (not used) |
||||
* [18:16] 010 - MDBL2: SDRAM2/3 burst Length. Fixed to 4. (not used) |
||||
* [15] 0 - reserved |
||||
* [14:07] 00000000- MDMRS0: SDRAM0/1 MRS Value. |
||||
* [06:04] 010 - MDCL0: SDRAM0/1 Cas Latency. |
||||
* [03] 0 - MDADD0: SDRAM0/1 burst Type. Fixed to sequential. |
||||
* [02:00] 010 - MDBL0: SDRAM0/1 burst Length. Fixed to 4. |
||||
*/ |
||||
#define CFG_MDMRS_VAL 0x00020022 |
||||
|
||||
/*
|
||||
* PCMCIA and CF Interfaces |
||||
*/ |
||||
#define CFG_MECR_VAL 0x00000000 |
||||
#define CFG_MCMEM0_VAL 0x00000000 |
||||
#define CFG_MCMEM1_VAL 0x00000000 |
||||
#define CFG_MCATT0_VAL 0x00000000 |
||||
#define CFG_MCATT1_VAL 0x00000000 |
||||
#define CFG_MCIO0_VAL 0x00000000 |
||||
#define CFG_MCIO1_VAL 0x00000000 |
||||
|
||||
/*
|
||||
#define CSB226_USER_LED0 0x00000008 |
||||
#define CSB226_USER_LED1 0x00000010 |
||||
#define CSB226_USER_LED2 0x00000020 |
||||
*/ |
||||
|
||||
/*
|
||||
* FLASH and environment organization |
||||
*/ |
||||
#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ |
||||
#define CFG_MAX_FLASH_SECT 128 /* max number of sect. 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 */ |
||||
|
||||
#if 0 |
||||
#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 */ |
||||
#endif |
||||
|
||||
#endif /* __CONFIG_H */ |
Loading…
Reference in new issue