Your ROOT_URL in app.ini is https://src.whiteboxsystems.nl/ but you are visiting http://src.whiteboxsystems.nl/Whitebox/u-boot/commit/7521af1c7d95ff087a4f7636ed050f4d4be91b59 You should set ROOT_URL correctly, otherwise the web may not work correctly.

Add support for AP1000 board.

Patch by James MacAulay, 07 Oct 2005
master
Wolfgang Denk 20 years ago
parent 95f9dda216
commit 7521af1c7d
  1. 3
      CHANGELOG
  2. 5
      CREDITS
  3. 24
      MAKEALL
  4. 3
      Makefile
  5. 77
      README
  6. 47
      board/amirix/ap1000/Makefile
  7. 672
      board/amirix/ap1000/ap1000.c
  8. 173
      board/amirix/ap1000/ap1000.h
  9. 27
      board/amirix/ap1000/config.mk
  10. 853
      board/amirix/ap1000/flash.c
  11. 34
      board/amirix/ap1000/init.S
  12. 346
      board/amirix/ap1000/pci.c
  13. 712
      board/amirix/ap1000/powerspan.c
  14. 170
      board/amirix/ap1000/powerspan.h
  15. 128
      board/amirix/ap1000/serial.c
  16. 144
      board/amirix/ap1000/u-boot.lds
  17. 7
      cpu/ppc4xx/speed.c
  18. 37
      drivers/e1000.c
  19. 255
      include/configs/AP1000.h
  20. 2
      net/eth.c

@ -2,6 +2,9 @@
Changes for U-Boot 1.1.4:
======================================================================
* Add support for AP1000 board.
Patch by James MacAulay, 07 Oct 2005
* Eliminate hard-coded address of Ethernet transfer buffer on at91rm9200
Patch by Anders Larsen, 07 Oct 2005

@ -443,3 +443,8 @@ N: Alex Zuepke
E: azu@sysgo.de
D: Overall improvements on StrongARM, ARM720TDMI; Support for Tuxscreen; initial PCMCIA support for ARM
W: www.elinos.com
N: James MacAulay
E: james.macaulay@amirix.com
D: Suppport for Amirix AP1000
W: www.amirix.com

@ -61,18 +61,18 @@ LIST_8xx=" \
#########################################################################
LIST_4xx=" \
ADCIOP AR405 ASH405 bubinga \
CANBT CPCI2DP CPCI405 CPCI4052 \
CPCI405AB CPCI440 CPCIISER4 CRAYL1 \
csb272 csb472 DASA_SIM DP405 \
DU405 ebony ERIC EXBITGEN \
G2000 HUB405 JSE KAREF \
METROBOX MIP405 MIP405T ML2 \
ml300 ocotea OCRTC ORSG \
PCI405 PIP405 PLU405 PMC405 \
PPChameleonEVB sbc405 VOH405 W7OLMC \
W7OLMG walnut WUH405 XPEDITE1K \
yellowstone yosemite \
ADCIOP AP1000 AR405 ASH405 \
bubinga CANBT CPCI2DP CPCI405 \
CPCI4052 CPCI405AB CPCI440 CPCIISER4 \
CRAYL1 csb272 csb472 DASA_SIM \
DP405 DU405 ebony ERIC \
EXBITGEN G2000 HUB405 JSE \
KAREF METROBOX MIP405 MIP405T \
ML2 ml300 ocotea OCRTC \
ORSG PCI405 PIP405 PLU405 \
PMC405 PPChameleonEVB sbc405 VOH405 \
W7OLMC W7OLMG walnut WUH405 \
XPEDITE1K yellowstone yosemite \
"
#########################################################################

@ -721,6 +721,9 @@ xtract_4xx = $(subst _25,,$(subst _33,,$(subst _BA,,$(subst _ME,,$(subst _HI,,$(
ADCIOP_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx adciop esd
AP1000_config:unconfig
@./mkconfig $(@:_config=) ppc ppc4xx ap1000 amirix
APC405_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx apc405 esd

@ -261,44 +261,45 @@ The following options need to be configured:
PowerPC based boards:
---------------------
CONFIG_ADCIOP CONFIG_GEN860T CONFIG_PCI405
CONFIG_ADS860 CONFIG_GENIETV CONFIG_PCIPPC2
CONFIG_AMX860 CONFIG_GTH CONFIG_PCIPPC6
CONFIG_AR405 CONFIG_gw8260 CONFIG_pcu_e
CONFIG_BAB7xx CONFIG_hermes CONFIG_PIP405
CONFIG_c2mon CONFIG_hymod CONFIG_PM826
CONFIG_CANBT CONFIG_IAD210 CONFIG_ppmc8260
CONFIG_CCM CONFIG_ICU862 CONFIG_QS823
CONFIG_CMI CONFIG_IP860 CONFIG_QS850
CONFIG_cogent_mpc8260 CONFIG_IPHASE4539 CONFIG_QS860T
CONFIG_cogent_mpc8xx CONFIG_IVML24 CONFIG_RBC823
CONFIG_CPCI405 CONFIG_IVML24_128 CONFIG_RPXClassic
CONFIG_CPCI4052 CONFIG_IVML24_256 CONFIG_RPXlite
CONFIG_CPCIISER4 CONFIG_IVMS8 CONFIG_RPXsuper
CONFIG_CPU86 CONFIG_IVMS8_128 CONFIG_rsdproto
CONFIG_CRAYL1 CONFIG_IVMS8_256 CONFIG_sacsng
CONFIG_CSB272 CONFIG_JSE CONFIG_Sandpoint8240
CONFIG_CU824 CONFIG_LANTEC CONFIG_Sandpoint8245
CONFIG_DASA_SIM CONFIG_lwmon CONFIG_sbc8260
CONFIG_DB64360 CONFIG_MBX CONFIG_sbc8560
CONFIG_DB64460 CONFIG_MBX860T CONFIG_SM850
CONFIG_DU405 CONFIG_MHPC CONFIG_SPD823TS
CONFIG_DUET_ADS CONFIG_MIP405 CONFIG_STXGP3
CONFIG_EBONY CONFIG_MOUSSE CONFIG_SXNI855T
CONFIG_ELPPC CONFIG_MPC8260ADS CONFIG_TQM823L
CONFIG_ELPT860 CONFIG_MPC8540ADS CONFIG_TQM8260
CONFIG_ep8260 CONFIG_MPC8540EVAL CONFIG_TQM850L
CONFIG_ERIC CONFIG_MPC8560ADS CONFIG_TQM855L
CONFIG_ESTEEM192E CONFIG_MUSENKI CONFIG_TQM860L
CONFIG_ETX094 CONFIG_MVS1 CONFIG_TTTech
CONFIG_EVB64260 CONFIG_NETPHONE CONFIG_UTX8245
CONFIG_FADS823 CONFIG_NETTA CONFIG_V37
CONFIG_FADS850SAR CONFIG_NETVIA CONFIG_W7OLMC
CONFIG_FADS860T CONFIG_NX823 CONFIG_W7OLMG
CONFIG_FLAGADM CONFIG_OCRTC CONFIG_WALNUT
CONFIG_FPS850L CONFIG_ORSG CONFIG_ZPC1900
CONFIG_FPS860L CONFIG_OXC CONFIG_ZUMA
CONFIG_ADCIOP CONFIG_GEN860T CONFIG_PCIPPC2
CONFIG_ADS860 CONFIG_GENIETV CONFIG_PCIPPC6
CONFIG_AMX860 CONFIG_GTH CONFIG_pcu_e
CONFIG_AP1000 CONFIG_gw8260 CONFIG_PIP405
CONFIG_AR405 CONFIG_hermes CONFIG_PM826
CONFIG_BAB7xx CONFIG_hymod CONFIG_ppmc8260
CONFIG_c2mon CONFIG_IAD210 CONFIG_QS823
CONFIG_CANBT CONFIG_ICU862 CONFIG_QS850
CONFIG_CCM CONFIG_IP860 CONFIG_QS860T
CONFIG_CMI CONFIG_IPHASE4539 CONFIG_RBC823
CONFIG_cogent_mpc8260 CONFIG_IVML24 CONFIG_RPXClassic
CONFIG_cogent_mpc8xx CONFIG_IVML24_128 CONFIG_RPXlite
CONFIG_CPCI405 CONFIG_IVML24_256 CONFIG_RPXsuper
CONFIG_CPCI4052 CONFIG_IVMS8 CONFIG_rsdproto
CONFIG_CPCIISER4 CONFIG_IVMS8_128 CONFIG_sacsng
CONFIG_CPU86 CONFIG_IVMS8_256 CONFIG_Sandpoint8240
CONFIG_CRAYL1 CONFIG_JSE CONFIG_Sandpoint8245
CONFIG_CSB272 CONFIG_LANTEC CONFIG_sbc8260
CONFIG_CU824 CONFIG_lwmon CONFIG_sbc8560
CONFIG_DASA_SIM CONFIG_MBX CONFIG_SM850
CONFIG_DB64360 CONFIG_MBX860T CONFIG_SPD823TS
CONFIG_DB64460 CONFIG_MHPC CONFIG_STXGP3
CONFIG_DU405 CONFIG_MIP405 CONFIG_SXNI855T
CONFIG_DUET_ADS CONFIG_MOUSSE CONFIG_TQM823L
CONFIG_EBONY CONFIG_MPC8260ADS CONFIG_TQM8260
CONFIG_ELPPC CONFIG_MPC8540ADS CONFIG_TQM850L
CONFIG_ELPT860 CONFIG_MPC8540EVAL CONFIG_TQM855L
CONFIG_ep8260 CONFIG_MPC8560ADS CONFIG_TQM860L
CONFIG_ERIC CONFIG_MUSENKI CONFIG_TTTech
CONFIG_ESTEEM192E CONFIG_MVS1 CONFIG_UTX8245
CONFIG_ETX094 CONFIG_NETPHONE CONFIG_V37
CONFIG_EVB64260 CONFIG_NETTA CONFIG_W7OLMC
CONFIG_FADS823 CONFIG_NETVIA CONFIG_W7OLMG
CONFIG_FADS850SAR CONFIG_NX823 CONFIG_WALNUT
CONFIG_FADS860T CONFIG_OCRTC CONFIG_ZPC1900
CONFIG_FLAGADM CONFIG_ORSG CONFIG_ZUMA
CONFIG_FPS850L CONFIG_OXC
CONFIG_FPS860L CONFIG_PCI405
ARM based boards:
-----------------

@ -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 = $(BOARD).o flash.o serial.o pci.o powerspan.o
SOBJS = init.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 $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
sinclude .depend
#########################################################################

@ -0,0 +1,672 @@
/*
* amirix.c: ppcboot platform support for AMIRIX board
*
* Copyright 2002 Mind NV
* Copyright 2003 AMIRIX Systems Inc.
*
* http://www.mind.be/
* http://www.amirix.com/
*
* Author : Peter De Schrijver (p2@mind.be)
* Frank Smith (smith@amirix.com)
*
* Derived from : Other platform support files in this tree, ml2
*
* This software may be used and distributed according to the terms of
* the GNU General Public License (GPL) version 2, incorporated herein by
* reference. Drivers based on or derived from this code fall under the GPL
* and must retain the authorship, copyright and this license notice. This
* file is not a complete program and may only be used when the entire
* program is licensed under the GPL.
*
*/
#include <common.h>
#include <command.h>
#include <asm/processor.h>
#include "powerspan.h"
#include "ap1000.h"
int board_pre_init (void)
{
return 0;
}
/** serial number and platform display at startup */
int checkboard (void)
{
unsigned char *s = getenv ("serial#");
unsigned char *e;
/* After a loadace command, the SystemAce control register is left in a wonky state. */
/* this code did not work in board_pre_init */
unsigned char* p = (unsigned char*)AP1000_SYSACE_REGBASE;
p[SYSACE_CTRLREG0] = 0x0;
/* add platform and device to banner */
switch(get_device()){
case AP1xx_AP107_TARGET:{
puts(AP1xx_AP107_TARGET_STR);
break;
}
case AP1xx_AP120_TARGET:{
puts(AP1xx_AP120_TARGET_STR);
break;
}
case AP1xx_AP130_TARGET:{
puts(AP1xx_AP130_TARGET_STR);
break;
}
case AP1xx_AP1070_TARGET:{
puts(AP1xx_AP1070_TARGET_STR);
break;
}
case AP1xx_AP1100_TARGET:{
puts(AP1xx_AP1100_TARGET_STR);
break;
}
default:{
puts(AP1xx_UNKNOWN_STR);
break;
}
}
puts(AP1xx_TARGET_STR);
puts(" with ");
switch(get_platform()){
case AP100_BASELINE_PLATFORM:
case AP1000_BASELINE_PLATFORM:{
puts(AP1xx_BASELINE_PLATFORM_STR);
break;
}
case AP1xx_QUADGE_PLATFORM:{
puts(AP1xx_QUADGE_PLATFORM_STR);
break;
}
case AP1xx_MGT_REF_PLATFORM:{
puts(AP1xx_MGT_REF_PLATFORM_STR);
break;
}
case AP1xx_STANDARD_PLATFORM:{
puts(AP1xx_STANDARD_PLATFORM_STR);
break;
}
case AP1xx_DUAL_PLATFORM:{
puts(AP1xx_DUAL_PLATFORM_STR);
break;
}
case AP1xx_BASE_SRAM_PLATFORM:{
puts(AP1xx_BASE_SRAM_PLATFORM_STR);
break;
}
case AP1xx_PCI_PCB_TESTPLATFORM:
case AP1000_PCI_PCB_TESTPLATFORM:{
puts(AP1xx_PCI_PCB_TESTPLATFORM_STR);
break;
}
case AP1xx_DUAL_GE_MEZZ_TESTPLATFORM:{
puts(AP1xx_DUAL_GE_MEZZ_TESTPLATFORM_STR);
break;
}
case AP1xx_SFP_MEZZ_TESTPLATFORM:{
puts(AP1xx_SFP_MEZZ_TESTPLATFORM_STR);
break;
}
default:{
puts(AP1xx_UNKNOWN_STR);
break;
}
}
if((get_platform() & AP1xx_TESTPLATFORM_MASK) != 0){
puts(AP1xx_TESTPLATFORM_STR);
}
else{
puts(AP1xx_PLATFORM_STR);
}
putc('\n');
puts ("Serial#: ");
if (!s) {
printf ("### No HW ID - assuming AMIRIX");
} else {
for (e = s; *e; ++e) {
if (*e == ' ')
break;
}
for (; s < e; ++s) {
putc (*s);
}
}
putc ('\n');
return (0);
}
long int initdram (int board_type)
{
unsigned char *s = getenv ("dramsize");
if(s != NULL){
if((s[0] == '0') && ((s[1] == 'x') || (s[1] == 'X'))){
s += 2;
}
return simple_strtoul(s, NULL, 16);
}
else{
/* give all 64 MB */
return 64 * 1024 * 1024;
}
}
unsigned int get_platform(void){
unsigned int *revision_reg_ptr = (unsigned int *)AP1xx_FPGA_REV_ADDR;
return (*revision_reg_ptr & AP1xx_PLATFORM_MASK);
}
unsigned int get_device(void){
unsigned int *revision_reg_ptr = (unsigned int *)AP1xx_FPGA_REV_ADDR;
return (*revision_reg_ptr & AP1xx_TARGET_MASK);
}
#if 0 // loadace is not working; it appears to be a hardware issue with the system ace.
/*
This function loads FPGA configurations from the SystemACE CompactFlash
*/
int do_loadace (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
unsigned char *p = (unsigned char *)AP1000_SYSACE_REGBASE;
int cfg;
if((p[SYSACE_STATREG0] & 0x10) == 0) {
p[SYSACE_CTRLREG0] = 0x80;
printf ("\nNo CompactFlash Detected\n\n");
p[SYSACE_CTRLREG0] = 0x00;
return 1;
}
// reset configuration controller: | 0x80
// select cpflash & ~0x40
// cfg start | 0x20
// wait for cfgstart & ~0x10
// force cfgmode: | 0x08
// do no force cfgaddr: & ~0x04
// clear mpulock: & ~0x02
// do not force lock request & ~0x01
p[SYSACE_CTRLREG0] = 0x80 | 0x20 | 0x08;
p[SYSACE_CTRLREG1] = 0x00;
// force config address if arg2 exists
if (argc == 2) {
cfg = simple_strtoul(argv[1], NULL, 10);
if(cfg > 7) {
printf ("\nInvalid Configuration\n\n");
p[SYSACE_CTRLREG0] = 0x00;
return 1;
}
// Set config address
p[SYSACE_CTRLREG1] = (cfg << 5);
// force cfgaddr
p[SYSACE_CTRLREG0] |= 0x04;
} else {
cfg = (p[SYSACE_STATREG1] & 0xE0) >> 5;
}
/* release configuration controller */
printf("\nLoading V2PRO with config %d...\n", cfg);
p[SYSACE_CTRLREG0] &= ~0x80;
while((p[SYSACE_STATREG1] & 0x01) == 0) {
if(p[SYSACE_ERRREG0] & 0x80) {
// attempting to load an invalid configuration makes the cpflash
// appear to be removed. Reset here to avoid that problem
p[SYSACE_CTRLREG0] = 0x80;
printf("\nConfiguration %d Read Error\n\n", cfg);
p[SYSACE_CTRLREG0] = 0x00;
return 1;
}
}
p[SYSACE_CTRLREG0] |= 0x20;
return 0;
}
#endif
/** Console command to display and set the software reconfigure byte
* <pre>
* swconfig - display the current value of the software reconfigure byte
* swconfig [#] - change the software reconfigure byte to #
* </pre>
* @param *cmdtp [IN] as passed by run_command (ignored)
* @param flag [IN] as passed by run_command (ignored)
* @param argc [IN] as passed by run_command if 1, display, if 2 change
* @param *argv[] [IN] contains the parameters to use
* @return
* <pre>
* 0 if passed
* -1 if failed
* </pre>
*/
int do_swconfigbyte(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
unsigned char *sector_buffer = NULL;
unsigned char input_char;
int write_result;
unsigned int input_uint;
/* display value if no argument */
if(argc < 2){
printf("Software configuration byte is currently: 0x%02x\n",
*((unsigned char *) (SW_BYTE_SECTOR_ADDR + SW_BYTE_SECTOR_OFFSET)));
return 0;
}
else if(argc > 3){
printf("Too many arguments\n");
return -1;
}
/* if 3 arguments, 3rd argument is the address to use */
if(argc == 3){
input_uint = simple_strtoul(argv[1], NULL, 16);
sector_buffer = (unsigned char *)input_uint;
}
else{
sector_buffer = (unsigned char *)DEFAULT_TEMP_ADDR;
}
input_char = simple_strtoul(argv[1], NULL, 0);
if((input_char & ~SW_BYTE_MASK) != 0){
printf("Input of 0x%02x will be masked to 0x%02x\n",
input_char, (input_char & SW_BYTE_MASK));
input_char = input_char & SW_BYTE_MASK;
}
memcpy(sector_buffer, (void *)SW_BYTE_SECTOR_ADDR, SW_BYTE_SECTOR_SIZE);
sector_buffer[SW_BYTE_SECTOR_OFFSET] = input_char;
printf("Erasing Flash...");
if (flash_sect_erase (SW_BYTE_SECTOR_ADDR, (SW_BYTE_SECTOR_ADDR + SW_BYTE_SECTOR_OFFSET))){
return -1;
}
printf("Writing to Flash... ");
write_result = flash_write(sector_buffer, SW_BYTE_SECTOR_ADDR, SW_BYTE_SECTOR_SIZE);
if (write_result != 0) {
flash_perror (write_result);
return -1;
}
else{
printf("done\n");
printf("Software configuration byte is now: 0x%02x\n",
*((unsigned char *) (SW_BYTE_SECTOR_ADDR + SW_BYTE_SECTOR_OFFSET)));
}
return 0;
}
#define ONE_SECOND 1000000
int do_pause(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
int pause_time;
unsigned int delay_time;
int break_loop = 0;
/* display value if no argument */
if(argc < 2){
pause_time = 1;
}
else if(argc > 2){
printf("Too many arguments\n");
return -1;
}
else{
pause_time = simple_strtoul(argv[1], NULL, 0);
}
printf("Pausing with a poll time of %d, press any key to reactivate\n", pause_time);
delay_time = pause_time * ONE_SECOND;
while(break_loop == 0){
udelay(delay_time);
if(serial_tstc() != 0){
break_loop = 1;
/* eat user key presses */
while(serial_tstc() != 0){
serial_getc();
}
}
}
return 0;
}
int do_swreconfig(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
printf("Triggering software reconfigure (software config byte is 0x%02x)...\n",
*((unsigned char *) (SW_BYTE_SECTOR_ADDR + SW_BYTE_SECTOR_OFFSET)));
udelay (1000);
*((unsigned char*)AP1000_CPLD_BASE) = 1;
return 0;
}
#define GET_DECIMAL(low_byte) ((low_byte >> 5) * 125)
#define TEMP_BUSY_BIT 0x80
#define TEMP_LHIGH_BIT 0x40
#define TEMP_LLOW_BIT 0x20
#define TEMP_EHIGH_BIT 0x10
#define TEMP_ELOW_BIT 0x08
#define TEMP_OPEN_BIT 0x04
#define TEMP_ETHERM_BIT 0x02
#define TEMP_LTHERM_BIT 0x01
int do_temp_sensor(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
char cmd;
int ret_val = 0;
unsigned char temp_byte;
int temp;
int temp_low;
int low;
int low_low;
int high;
int high_low;
int therm;
unsigned char user_data[4] = { 0 };
int user_data_count = 0;
int ii;
if(argc > 1){
cmd = argv[1][0];
}
else{
cmd = 's'; /* default to status */
}
user_data_count = argc - 2;
for(ii = 0;ii < user_data_count;ii++){
user_data[ii] = simple_strtoul(argv[2 + ii], NULL, 0);
}
switch (cmd){
case 's':{
if(I2CAccess(0x2, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
goto fail;
}
printf("Status : 0x%02x ", temp_byte);
if(temp_byte & TEMP_BUSY_BIT){
printf("BUSY ");
}
if(temp_byte & TEMP_LHIGH_BIT){
printf("LHIGH ");
}
if(temp_byte & TEMP_LLOW_BIT){
printf("LLOW ");
}
if(temp_byte & TEMP_EHIGH_BIT){
printf("EHIGH ");
}
if(temp_byte & TEMP_ELOW_BIT){
printf("ELOW ");
}
if(temp_byte & TEMP_OPEN_BIT){
printf("OPEN ");
}
if(temp_byte & TEMP_ETHERM_BIT){
printf("ETHERM ");
}
if(temp_byte & TEMP_LTHERM_BIT){
printf("LTHERM");
}
printf("\n");
if(I2CAccess(0x3, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
goto fail;
}
printf("Config : 0x%02x ", temp_byte);
if(I2CAccess(0x4, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
printf("\n");
goto fail;
}
printf("Conversion: 0x%02x\n", temp_byte);
if(I2CAccess(0x22, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
goto fail;
}
printf("Cons Alert: 0x%02x ", temp_byte);
if(I2CAccess(0x21, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
printf("\n");
goto fail;
}
printf("Therm Hyst: %d\n", temp_byte);
if(I2CAccess(0x0, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
goto fail;
}
temp = temp_byte;
if(I2CAccess(0x6, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
goto fail;
}
low = temp_byte;
if(I2CAccess(0x5, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
goto fail;
}
high = temp_byte;
if(I2CAccess(0x20, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
goto fail;
}
therm = temp_byte;
printf("Local Temp: %2d Low: %2d High: %2d THERM: %2d\n", temp, low, high, therm);
if(I2CAccess(0x1, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
goto fail;
}
temp = temp_byte;
if(I2CAccess(0x10, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
goto fail;
}
temp_low = temp_byte;
if(I2CAccess(0x8, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
goto fail;
}
low = temp_byte;
if(I2CAccess(0x14, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
goto fail;
}
low_low = temp_byte;
if(I2CAccess(0x7, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
goto fail;
}
high = temp_byte;
if(I2CAccess(0x13, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
goto fail;
}
high_low = temp_byte;
if(I2CAccess(0x19, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
goto fail;
}
therm = temp_byte;
if(I2CAccess(0x11, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
goto fail;
}
printf("Ext Temp : %2d.%03d Low: %2d.%03d High: %2d.%03d THERM: %2d Offset: %2d\n", temp, GET_DECIMAL(temp_low), low, GET_DECIMAL(low_low), high, GET_DECIMAL(high_low), therm, temp_byte);
break;
}
case 'l':{ /* alter local limits : low, high, therm */
if(argc < 3){
goto usage;
}
/* low */
if(I2CAccess(0xC, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[0], I2C_WRITE) != 0){
goto fail;
}
if(user_data_count > 1){
/* high */
if(I2CAccess(0xB, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[1], I2C_WRITE) != 0){
goto fail;
}
}
if(user_data_count > 2){
/* therm */
if(I2CAccess(0x20, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[2], I2C_WRITE) != 0){
goto fail;
}
}
break;
}
case 'e':{ /* alter external limits: low, high, therm, offset */
if(argc < 3){
goto usage;
}
/* low */
if(I2CAccess(0xE, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[0], I2C_WRITE) != 0){
goto fail;
}
if(user_data_count > 1){
/* high */
if(I2CAccess(0xD, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[1], I2C_WRITE) != 0){
goto fail;
}
}
if(user_data_count > 2){
/* therm */
if(I2CAccess(0x19, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[2], I2C_WRITE) != 0){
goto fail;
}
}
if(user_data_count > 3){
/* offset */
if(I2CAccess(0x11, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[3], I2C_WRITE) != 0){
goto fail;
}
}
break;
}
case 'c':{ /* alter config settings: config, conv, cons alert, therm hyst */
if(argc < 3){
goto usage;
}
/* config */
if(I2CAccess(0x9, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[0], I2C_WRITE) != 0){
goto fail;
}
if(user_data_count > 1){
/* conversion */
if(I2CAccess(0xA, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[1], I2C_WRITE) != 0){
goto fail;
}
}
if(user_data_count > 2){
/* cons alert */
if(I2CAccess(0x22, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[2], I2C_WRITE) != 0){
goto fail;
}
}
if(user_data_count > 3){
/* therm hyst */
if(I2CAccess(0x21, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[3], I2C_WRITE) != 0){
goto fail;
}
}
break;
}
default:{
goto usage;
}
}
goto done;
fail:
printf("Access to sensor failed\n");
ret_val = -1;
goto done;
usage:
printf ("Usage:\n%s\n", cmdtp->help);
done:
return ret_val;
}
U_BOOT_CMD(
temp, 6, 0, do_temp_sensor,
"temp - interact with the temperature sensor\n",
"temp [s]\n"
" - Show status.\n"
"temp l LOW [HIGH] [THERM]\n"
" - Set local limits.\n"
"temp e LOW [HIGH] [THERM] [OFFSET]\n"
" - Set external limits.\n"
"temp c CONFIG [CONVERSION] [CONS. ALERT] [THERM HYST]\n"
" - Set config options.\n"
"\n"
"All values can be decimal or hex (hex preceded with 0x).\n"
"Only whole numbers are supported for external limits.\n"
);
#if 0
U_BOOT_CMD(
loadace, 2, 0, do_loadace,
"loadace - load fpga configuration from System ACE compact flash\n",
"N\n"
" - Load configuration N (0-7) from System ACE compact flash\n"
"loadace\n"
" - loads default configuration\n"
);
#endif
U_BOOT_CMD(
swconfig, 2, 0, do_swconfigbyte,
"swconfig- display or modify the software configuration byte\n",
"N [ADDRESS]\n"
" - set software configuration byte to N, optionally use ADDRESS as\n"
" location of buffer for flash copy\n"
"swconfig\n"
" - display software configuration byte\n"
);
U_BOOT_CMD(
pause, 2, 0, do_pause,
"pause - sleep processor until any key is pressed with poll time of N seconds\n",
"N\n"
" - sleep processor until any key is pressed with poll time of N seconds\n"
"pause\n"
" - sleep processor until any key is pressed with poll time of 1 second\n"
);
U_BOOT_CMD(
swrecon, 1, 0, do_swreconfig,
"swrecon - trigger a board reconfigure to the software selected configuration\n",
"\n"
" - trigger a board reconfigure to the software selected configuration\n"
);

@ -0,0 +1,173 @@
/*
* ap1000.h: AP1000 (e.g. AP1070, AP1100) board specific definitions and functions that are needed globally
*
* Author : James MacAulay
*
* This software may be used and distributed according to the terms of
* the GNU General Public License (GPL) version 2, incorporated herein by
* reference. Drivers based on or derived from this code fall under the GPL
* and must retain the authorship, copyright and this license notice. This
* file is not a complete program and may only be used when the entire
* program is licensed under the GPL.
*
*/
#ifndef __AP1000_H
#define __AP1000_H
/*
* Revision Register stuff
*/
#define AP1xx_FPGA_REV_ADDR 0x29000000
#define AP1xx_PLATFORM_MASK 0xFF000000
#define AP100_BASELINE_PLATFORM 0x01000000
#define AP1xx_QUADGE_PLATFORM 0x02000000
#define AP1xx_MGT_REF_PLATFORM 0x03000000
#define AP1xx_STANDARD_PLATFORM 0x04000000
#define AP1xx_DUAL_PLATFORM 0x05000000
#define AP1xx_BASE_SRAM_PLATFORM 0x06000000
#define AP1000_BASELINE_PLATFORM 0x21000000
#define AP1xx_TESTPLATFORM_MASK 0xC0000000
#define AP1xx_PCI_PCB_TESTPLATFORM 0xC0000000
#define AP1xx_DUAL_GE_MEZZ_TESTPLATFORM 0xC1000000
#define AP1xx_SFP_MEZZ_TESTPLATFORM 0xC2000000
#define AP1000_PCI_PCB_TESTPLATFORM 0xC3000000
#define AP1xx_TARGET_MASK 0x00FF0000
#define AP1xx_AP107_TARGET 0x00010000
#define AP1xx_AP120_TARGET 0x00020000
#define AP1xx_AP130_TARGET 0x00030000
#define AP1xx_AP1070_TARGET 0x00040000
#define AP1xx_AP1100_TARGET 0x00050000
#define AP1xx_UNKNOWN_STR "Unknown"
#define AP1xx_PLATFORM_STR " Platform"
#define AP1xx_BASELINE_PLATFORM_STR "Baseline"
#define AP1xx_QUADGE_PLATFORM_STR "Quad GE"
#define AP1xx_MGT_REF_PLATFORM_STR "MGT Reference"
#define AP1xx_STANDARD_PLATFORM_STR "Standard"
#define AP1xx_DUAL_PLATFORM_STR "Dual"
#define AP1xx_BASE_SRAM_PLATFORM_STR "Baseline with SRAM"
#define AP1xx_TESTPLATFORM_STR " Test Platform"
#define AP1xx_PCI_PCB_TESTPLATFORM_STR "Base"
#define AP1xx_DUAL_GE_MEZZ_TESTPLATFORM_STR "Dual GE Mezzanine"
#define AP1xx_SFP_MEZZ_TESTPLATFORM_STR "SFP Mezzanine"
#define AP1xx_TARGET_STR " Board"
#define AP1xx_AP107_TARGET_STR "AP107"
#define AP1xx_AP120_TARGET_STR "AP120"
#define AP1xx_AP130_TARGET_STR "AP130"
#define AP1xx_AP1070_TARGET_STR "AP1070"
#define AP1xx_AP1100_TARGET_STR "AP1100"
/*
* Flash Stuff
*/
#define AP1xx_PROGRAM_FLASH_INDEX 0
#define AP1xx_CONFIG_FLASH_INDEX 1
/*
* System Ace Stuff
*/
#define AP1000_SYSACE_REGBASE 0x28000000
#define SYSACE_STATREG0 0x04 // 7:0
#define SYSACE_STATREG1 0x05 // 15:8
#define SYSACE_STATREG2 0x06 // 23:16
#define SYSACE_STATREG3 0x07 // 31:24
#define SYSACE_ERRREG0 0x08 // 7:0
#define SYSACE_ERRREG1 0x09 // 15:8
#define SYSACE_ERRREG2 0x0a // 23:16
#define SYSACE_ERRREG3 0x0b // 31:24
#define SYSACE_CTRLREG0 0x18 // 7:0
#define SYSACE_CTRLREG1 0x19 // 15:8
#define SYSACE_CTRLREG2 0x1A // 23:16
#define SYSACE_CTRLREG3 0x1B // 31:24
/*
* Software reconfig thing
*/
#define SW_BYTE_SECTOR_ADDR 0x24FE0000
#define SW_BYTE_SECTOR_OFFSET 0x0001FFFF
#define SW_BYTE_SECTOR_SIZE 0x00020000
#define SW_BYTE_MASK 0x00000003
#define DEFAULT_TEMP_ADDR 0x00100000
#define AP1000_CPLD_BASE 0x26000000
/* PowerSpan II Stuff */
#define PSII_SYNC() asm("eieio")
#define PSPAN_BASEADDR 0x30000000
#define EEPROM_DEFAULT { 0x01, /* Byte 0 - Long Load = 0x02, short = 01, use 0xff for try no load */ \
0x0,0x0,0x0, /* Bytes 1 - 3 Power span reserved */ \
0x0, /* Byte 4 - Powerspan reserved - start of short load */ \
0x0F, /* Byte 5 - Enable PCI 1 & 2 as Bus masters and Memory targets. */ \
0x0E, /* Byte 6 - PCI 1 Target image prefetch - on for image 0,1,2, off for i20 & 3. */ \
0x00, 0x00, /* Byte 7,8 - PCI-1 Subsystem ID - */ \
0x00, 0x00, /* Byte 9,10 - PCI-1 Subsystem Vendor Id - */ \
0x00, /* Byte 11 - No PCI interrupt generation on PCI-1 PCI-2 int A */ \
0x1F, /* Byte 12 - PCI-1 enable bridge registers, all target images */ \
0xBA, /* Byte 13 - Target 0 image 128 Meg(Ram), Target 1 image 64 Meg. (config Flash/CPLD )*/ \
0xA0, /* Byte 14 - Target 2 image 64 Meg(program Flash), target 3 64k. */ \
0x00, /* Byte 15 - Vital Product Data Disabled. */ \
0x88, /* Byte 16 - PCI arbiter config complete, all requests routed through PCI-1, Unlock PCI-1 */ \
0x40, /* Byte 17 - Interrupt direction control - PCI-1 Int A out, everything else in. */ \
0x00, /* Byte 18 - I2O disabled */ \
0x00, /* Byte 19 - PCI-2 Target image prefetch - off for all images. */ \
0x00,0x00, /* Bytes 20,21 - PCI 2 Subsystem Id */ \
0x00,0x00, /* Bytes 22,23 - PCI 2 Subsystem Vendor id */ \
0x0C, /* Byte 24 - PCI-2 BAR enables, target image 0, & 1 */ \
0xBB, /* Byte 25 - PCI-2 target 0 - 128 Meg(Ram), target 1 - 128 Meg (program/config flash) */ \
0x00, /* Byte 26 - PCI-2 target 2 & 3 unused. */ \
0x00,0x00,0x00,0x00,0x00, /* Bytes 27,28,29,30, 31 - Reserved */ \
/* Long Load Information */ \
0x82,0x60, /* Bytes 32,33 - PCI-1 Device ID - Powerspan II */ \
0x10,0xE3, /* Bytes 24,35 - PCI-1 Vendor ID - Tundra */ \
0x06, /* Byte 36 - PCI-1 Class Base - Bridge device. */ \
0x80, /* Byte 37 - PCI-1 Class sub class - Other bridge. */ \
0x00, /* Byte 38 - PCI-1 Class programing interface - Other bridge */ \
0x01, /* Byte 39 - Power span revision 1. */ \
0x6E, /* Byte 40 - PB SI0 enabled, translation enabled, decode enabled, 64 Meg */ \
0x40, /* Byte 41 - PB SI0 memory command mode, PCI-1 dest */ \
0x22, /* Byte 42 - Prefetch discard after read, PCI-little endian conversion, 32 byte prefetch */ \
0x00,0x00, /* Bytes 43, 44 - Translation address for SI0, set to zero for now. */ \
0x0E, /* Byte 45 - Translation address (0) and PB bus master enables - all. */ \
0x2c,00,00, /* Bytes 46,47,48 - PB SI0 processor base address - 0x2C000000 */ \
0x30,00,00, /* Bytes 49,50,51 - PB Address for Powerspan registers - 0x30000000, big Endian */ \
0x82,0x60, /* Bytes 52, 53 - PCI-2 Device ID - Powerspan II */ \
0x10,0xE3, /* Bytes 54,55 - PCI 2 Vendor Id - Tundra */ \
0x06, /* Byte 56 - PCI-2 Class Base - Bridge device */ \
0x80, /* Byte 57 - PCI-2 Class sub class - Other Bridge. */ \
0x00, /* Byte 58 - PCI-2 class programming interface - Other bridge */ \
0x01, /* Byte 59 - PCI-2 class revision 1 */ \
0x00,0x00,0x00,0x00 }; /* Bytes 60,61, 62, 63 - Powerspan reserved */
#define EEPROM_LENGTH 64 /* Long Load */
#define I2C_SENSOR_DEV 0x9
#define I2C_SENSOR_CHIP_SEL 0x4
/*
* Board Functions
*/
void set_eat_machine_checks(int a_flag);
int get_eat_machine_checks(void);
unsigned int get_platform(void);
unsigned int get_device(void);
void* memcpyb(void * dest,const void *src,size_t count);
int process_bootflag(ulong bootflag);
void user_led_on(void);
void user_led_off(void);
#endif /* __COMMON_H_ */

@ -0,0 +1,27 @@
#
# (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
#
# Start at bottom of RAM, but at an aliased address so that it looks
# like it's not in RAM. This is a bit of voodoo to allow it to be
# run from RAM instead of Flash.
TEXT_BASE = 0x08000000

@ -0,0 +1,853 @@
/**
* @file flash.c
*/
/*
* (C) Copyright 2003
* AMIRIX Systems Inc.
*
* Originated from ppcboot-2.0.0/board/esd/cpci440/strataflash.c
*
* (C) Copyright 2002
* Brad Kemp, Seranoa Networks, Brad.Kemp@seranoa.com
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/processor.h>
#undef DEBUG_FLASH
/*
* This file implements a Common Flash Interface (CFI) driver for ppcboot.
* The width of the port and the width of the chips are determined at initialization.
* These widths are used to calculate the address for access CFI data structures.
* It has been tested on an Intel Strataflash implementation.
*
* References
* JEDEC Standard JESD68 - Common Flash Interface (CFI)
* JEDEC Standard JEP137-A Common Flash Interface (CFI) ID Codes
* Intel Application Note 646 Common Flash Interface (CFI) and Command Sets
* Intel 290667-008 3 Volt Intel StrataFlash Memory datasheet
*
* TODO
* Use Primary Extended Query table (PRI) and Alternate Algorithm Query Table (ALT) to determine if protection is available
* Add support for other command sets Use the PRI and ALT to determine command set
* Verify erase and program timeouts.
*/
#define FLASH_CMD_CFI 0x98
#define FLASH_CMD_READ_ID 0x90
#define FLASH_CMD_RESET 0xff
#define FLASH_CMD_BLOCK_ERASE 0x20
#define FLASH_CMD_ERASE_CONFIRM 0xD0
#define FLASH_CMD_WRITE 0x40
#define FLASH_CMD_PROTECT 0x60
#define FLASH_CMD_PROTECT_SET 0x01
#define FLASH_CMD_PROTECT_CLEAR 0xD0
#define FLASH_CMD_CLEAR_STATUS 0x50
#define FLASH_CMD_WRITE_TO_BUFFER 0xE8
#define FLASH_CMD_WRITE_BUFFER_CONFIRM 0xD0
#define FLASH_STATUS_DONE 0x80
#define FLASH_STATUS_ESS 0x40
#define FLASH_STATUS_ECLBS 0x20
#define FLASH_STATUS_PSLBS 0x10
#define FLASH_STATUS_VPENS 0x08
#define FLASH_STATUS_PSS 0x04
#define FLASH_STATUS_DPS 0x02
#define FLASH_STATUS_R 0x01
#define FLASH_STATUS_PROTECT 0x01
#define FLASH_OFFSET_CFI 0x55
#define FLASH_OFFSET_CFI_RESP 0x10
#define FLASH_OFFSET_WTOUT 0x1F
#define FLASH_OFFSET_WBTOUT 0x20
#define FLASH_OFFSET_ETOUT 0x21
#define FLASH_OFFSET_CETOUT 0x22
#define FLASH_OFFSET_WMAX_TOUT 0x23
#define FLASH_OFFSET_WBMAX_TOUT 0x24
#define FLASH_OFFSET_EMAX_TOUT 0x25
#define FLASH_OFFSET_CEMAX_TOUT 0x26
#define FLASH_OFFSET_SIZE 0x27
#define FLASH_OFFSET_INTERFACE 0x28
#define FLASH_OFFSET_BUFFER_SIZE 0x2A
#define FLASH_OFFSET_NUM_ERASE_REGIONS 0x2C
#define FLASH_OFFSET_ERASE_REGIONS 0x2D
#define FLASH_OFFSET_PROTECT 0x02
#define FLASH_OFFSET_USER_PROTECTION 0x85
#define FLASH_OFFSET_INTEL_PROTECTION 0x81
#define FLASH_MAN_CFI 0x01000000
typedef union {
unsigned char c;
unsigned short w;
unsigned long l;
} cfiword_t;
typedef union {
unsigned char * cp;
unsigned short *wp;
unsigned long *lp;
} cfiptr_t;
#define NUM_ERASE_REGIONS 4
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/*-----------------------------------------------------------------------
* Functions
*/
static void flash_add_byte(flash_info_t *info, cfiword_t * cword, uchar c);
static void flash_make_cmd(flash_info_t * info, uchar cmd, void * cmdbuf);
static void flash_write_cmd(flash_info_t * info, int sect, uchar offset, uchar cmd);
static int flash_isequal(flash_info_t * info, int sect, uchar offset, uchar cmd);
static int flash_isset(flash_info_t * info, int sect, uchar offset, uchar cmd);
static int flash_detect_cfi(flash_info_t * info);
static ulong flash_get_size (ulong base, int banknum);
static int flash_write_cfiword (flash_info_t *info, ulong dest, cfiword_t cword);
static int flash_full_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt);
#ifdef CFG_FLASH_USE_BUFFER_WRITE
static int flash_write_cfibuffer(flash_info_t * info, ulong dest, uchar * cp, int len);
#endif
/*-----------------------------------------------------------------------
* create an address based on the offset and the port width
*/
uchar * flash_make_addr(flash_info_t * info, int sect, int offset)
{
return ((uchar *)(info->start[sect] + (offset * info->chipwidth)));
}
/*-----------------------------------------------------------------------
* read a character at a port width address
*/
uchar flash_read_uchar(flash_info_t * info, uchar offset)
{
if (info->portwidth == FLASH_CFI_8BIT) {
volatile uchar *cp;
uchar c;
cp = flash_make_addr(info, 0, offset);
c = *cp;
#ifdef DEBUG_FLASH
printf("flash_read_uchar offset=%04x ptr=%08x c=%02x\n",
offset, (unsigned int)cp, c);
#endif
return (c);
} else if (info->portwidth == FLASH_CFI_16BIT) {
volatile ushort *sp;
ushort s;
uchar c;
sp = (ushort*)flash_make_addr(info, 0, offset);
s = *sp;
c = (uchar)s;
#ifdef DEBUG_FLASH
printf("flash_read_uchar offset=%04x ptr=%08x s=%04x c=%02x\n",
offset, (unsigned int)sp, s, c);
#endif
return (c);
}
return 0;
}
/*-----------------------------------------------------------------------
* read a short word by swapping for ppc format.
*/
ushort flash_read_ushort(flash_info_t * info, int sect, uchar offset)
{
if (info->portwidth == FLASH_CFI_8BIT) {
volatile uchar *cp;
uchar c0, c1;
ushort s;
cp = flash_make_addr(info, 0, offset);
c1 = cp[2];
c0 = cp[0];
s = c1<<8 | c0;
#ifdef DEBUG_FLASH
printf("flash_read_ushort offset=%04x ptr=%08x c1=%02x c0=%02x s=%04x\n",
offset, (unsigned int)cp, c1, c0, s);
#endif
return (s);
} else if (info->portwidth == FLASH_CFI_16BIT) {
volatile ushort *sp;
ushort s;
uchar c0, c1;
sp = (ushort*)flash_make_addr(info, 0, offset);
s = *sp;
c1 = (uchar)sp[1];
c0 = (uchar)sp[0];
s = c1<<8 | c0;
#ifdef DEBUG_FLASH
printf("flash_read_ushort offset=%04x ptr=%08x c1=%02x c0=%02x s=%04x\n",
offset, (unsigned int)sp, c1, c0, s);
#endif
return (s);
}
return 0;
}
/*-----------------------------------------------------------------------
* read a long word by picking the least significant byte of each maiximum
* port size word. Swap for ppc format.
*/
ulong flash_read_long(flash_info_t * info, int sect, uchar offset)
{
if (info->portwidth == FLASH_CFI_8BIT) {
volatile uchar *cp;
uchar c0, c1, c2, c3;
ulong l;
cp = flash_make_addr(info, 0, offset);
c3 = cp[6];
c2 = cp[4];
c1 = cp[2];
c0 = cp[0];
l = c3<<24 | c2<<16 | c1<<8 | c0;
#ifdef DEBUG_FLASH
printf("flash_read_long offset=%04x ptr=%08x c3=%02x c2=%02x c1=%02x c0=%02x l=%08x\n",
offset, (unsigned int)cp, c3, c2, c1, c0, l);
#endif
return (l);
} else if (info->portwidth == FLASH_CFI_16BIT) {
volatile ushort *sp;
uchar c0, c1, c2, c3;
ulong l;
sp = (ushort*)flash_make_addr(info, 0, offset);
c3 = (uchar)sp[3];
c2 = (uchar)sp[2];
c1 = (uchar)sp[1];
c0 = (uchar)sp[0];
l = c3<<24 | c2<<16 | c1<<8 | c0;
#ifdef DEBUG_FLASH
printf("flash_read_long offset=%04x ptr=%08x c3=%02x c2=%02x c1=%02x c0=%02x l=%08x\n",
offset, (unsigned int)sp, c3, c2, c1, c0, l);
#endif
return (l);
}
return 0;
}
/*-----------------------------------------------------------------------
*/
unsigned long flash_init (void)
{
unsigned long size;
size = 0;
flash_info[0].flash_id = FLASH_UNKNOWN;
flash_info[0].portwidth = FLASH_CFI_16BIT;
flash_info[0].chipwidth = FLASH_CFI_16BIT;
size += flash_info[0].size = flash_get_size(CFG_PROGFLASH_BASE, 0);
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n", 1,
flash_info[0].size, flash_info[0].size<<20);
};
flash_info[1].flash_id = FLASH_UNKNOWN;
flash_info[1].portwidth = FLASH_CFI_8BIT;
flash_info[1].chipwidth = FLASH_CFI_16BIT;
size += flash_info[1].size = flash_get_size(CFG_CONFFLASH_BASE, 1);
if (flash_info[1].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n", 2,
flash_info[1].size, flash_info[1].size<<20);
};
return (size);
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
int rcode = 0;
int prot;
int sect;
if( info->flash_id != FLASH_MAN_CFI) {
printf ("Can't erase unknown flash type - aborted\n");
return 1;
}
if ((s_first < 0) || (s_first > s_last)) {
printf ("- no sectors to erase\n");
return 1;
}
prot = 0;
for (sect=s_first; sect<=s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
} else {
printf ("\n");
}
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
flash_write_cmd(info, sect, 0, FLASH_CMD_CLEAR_STATUS);
flash_write_cmd(info, sect, 0, FLASH_CMD_BLOCK_ERASE);
flash_write_cmd(info, sect, 0, FLASH_CMD_ERASE_CONFIRM);
if(flash_full_status_check(info, sect, info->erase_blk_tout, "erase")) {
rcode = 1;
} else
printf(".");
}
}
printf (" done\n");
return rcode;
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t *info)
{
int i;
if (info->flash_id != FLASH_MAN_CFI) {
printf ("missing or unknown FLASH type\n");
return;
}
printf("CFI conformant FLASH (x%d device in x%d mode)",
(info->chipwidth << 3 ), (info->portwidth << 3 ));
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf(" Erase timeout %ld ms, write timeout %ld ms, buffer write timeout %ld ms, buffer size %d\n",
info->erase_blk_tout, info->write_tout, info->buffer_write_tout, info->buffer_size);
printf (" Sector Start Addresses:");
for (i=0; i<info->sector_count; ++i) {
if ((i % 5) == 0)
printf ("\n");
printf (" %08lX%5s",
info->start[i],
info->protect[i] ? " (RO)" : " "
);
}
printf ("\n");
return;
}
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
ulong wp;
ulong cp;
int aln;
cfiword_t cword;
int i, rc;
/* get lower aligned address */
wp = (addr & ~(info->portwidth - 1));
/* handle unaligned start */
if((aln = addr - wp) != 0) {
cword.l = 0;
cp = wp;
for(i=0;i<aln; ++i, ++cp)
flash_add_byte(info, &cword, (*(uchar *)cp));
for(; (i< info->portwidth) && (cnt > 0) ; i++) {
flash_add_byte(info, &cword, *src++);
cnt--;
cp++;
}
for(; (cnt == 0) && (i < info->portwidth); ++i, ++cp)
flash_add_byte(info, &cword, (*(uchar *)cp));
if((rc = flash_write_cfiword(info, wp, cword)) != 0)
return rc;
wp = cp;
}
#ifdef CFG_FLASH_USE_BUFFER_WRITE
while(cnt >= info->portwidth) {
i = info->buffer_size > cnt? cnt: info->buffer_size;
if((rc = flash_write_cfibuffer(info, wp, src,i)) != ERR_OK)
return rc;
wp += i;
src += i;
cnt -=i;
}
#else
/* handle the aligned part */
while(cnt >= info->portwidth) {
cword.l = 0;
for(i = 0; i < info->portwidth; i++) {
flash_add_byte(info, &cword, *src++);
}
if((rc = flash_write_cfiword(info, wp, cword)) != 0)
return rc;
wp += info->portwidth;
cnt -= info->portwidth;
}
#endif /* CFG_FLASH_USE_BUFFER_WRITE */
if (cnt == 0) {
return (0);
}
/*
* handle unaligned tail bytes
*/
cword.l = 0;
for (i=0, cp=wp; (i<info->portwidth) && (cnt>0); ++i, ++cp) {
flash_add_byte(info, &cword, *src++);
--cnt;
}
for (; i<info->portwidth; ++i, ++cp) {
flash_add_byte(info, & cword, (*(uchar *)cp));
}
return flash_write_cfiword(info, wp, cword);
}
/*-----------------------------------------------------------------------
*/
int flash_real_protect(flash_info_t *info, long sector, int prot)
{
int retcode = 0;
flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT);
if(prot)
flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT_SET);
else
flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT_CLEAR);
if((retcode = flash_full_status_check(info, sector, info->erase_blk_tout,
prot?"protect":"unprotect")) == 0) {
info->protect[sector] = prot;
/* Intel's unprotect unprotects all locking */
if(prot == 0) {
int i;
for(i = 0 ; i<info->sector_count; i++) {
if(info->protect[i])
flash_real_protect(info, i, 1);
}
}
}
return retcode;
}
/*-----------------------------------------------------------------------
* wait for XSR.7 to be set. Time out with an error if it does not.
* This routine does not set the flash to read-array mode.
*/
static int flash_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt)
{
ulong start;
/* Wait for command completion */
start = get_timer (0);
while(!flash_isset(info, sector, 0, FLASH_STATUS_DONE)) {
if (get_timer(start) > info->erase_blk_tout) {
printf("Flash %s timeout at address %lx\n", prompt, info->start[sector]);
flash_write_cmd(info, sector, 0, FLASH_CMD_RESET);
return ERR_TIMOUT;
}
}
return ERR_OK;
}
/*-----------------------------------------------------------------------
* Wait for XSR.7 to be set, if it times out print an error, otherwise do a full status check.
* This routine sets the flash to read-array mode.
*/
static int flash_full_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt)
{
int retcode;
retcode = flash_status_check(info, sector, tout, prompt);
if((retcode == ERR_OK) && !flash_isequal(info,sector, 0, FLASH_STATUS_DONE)) {
retcode = ERR_INVAL;
printf("Flash %s error at address %lx\n", prompt,info->start[sector]);
if(flash_isset(info, sector, 0, FLASH_STATUS_ECLBS | FLASH_STATUS_PSLBS)){
printf("Command Sequence Error.\n");
} else if(flash_isset(info, sector, 0, FLASH_STATUS_ECLBS)){
printf("Block Erase Error.\n");
retcode = ERR_NOT_ERASED;
} else if (flash_isset(info, sector, 0, FLASH_STATUS_PSLBS)) {
printf("Locking Error\n");
}
if(flash_isset(info, sector, 0, FLASH_STATUS_DPS)){
printf("Block locked.\n");
retcode = ERR_PROTECTED;
}
if(flash_isset(info, sector, 0, FLASH_STATUS_VPENS))
printf("Vpp Low Error.\n");
}
flash_write_cmd(info, sector, 0, FLASH_CMD_RESET);
return retcode;
}
/*-----------------------------------------------------------------------
*/
static void flash_add_byte(flash_info_t *info, cfiword_t * cword, uchar c)
{
switch(info->portwidth) {
case FLASH_CFI_8BIT:
cword->c = c;
break;
case FLASH_CFI_16BIT:
cword->w = (cword->w << 8) | c;
break;
case FLASH_CFI_32BIT:
cword->l = (cword->l << 8) | c;
}
}
/*-----------------------------------------------------------------------
* make a proper sized command based on the port and chip widths
*/
static void flash_make_cmd(flash_info_t * info, uchar cmd, void * cmdbuf)
{
//int i;
uchar *cp = (uchar *)cmdbuf;
// for(i=0; i< info->portwidth; i++)
// *cp++ = ((i+1) % info->chipwidth) ? '\0':cmd;
if (info->portwidth == FLASH_CFI_8BIT && info->chipwidth == FLASH_CFI_16BIT) {
cp[0] = cmd;
} else if (info->portwidth == FLASH_CFI_16BIT && info->chipwidth == FLASH_CFI_16BIT) {
cp[0] = '\0';
cp[1] = cmd;
};
}
/*
* Write a proper sized command to the correct address
*/
static void flash_write_cmd(flash_info_t * info, int sect, uchar offset, uchar cmd)
{
volatile cfiptr_t addr;
cfiword_t cword;
addr.cp = flash_make_addr(info, sect, offset);
flash_make_cmd(info, cmd, &cword);
switch(info->portwidth) {
case FLASH_CFI_8BIT:
*addr.cp = cword.c;
break;
case FLASH_CFI_16BIT:
*addr.wp = cword.w;
break;
case FLASH_CFI_32BIT:
*addr.lp = cword.l;
break;
}
}
/*-----------------------------------------------------------------------
*/
static int flash_isequal(flash_info_t * info, int sect, uchar offset, uchar cmd)
{
cfiptr_t cptr;
cfiword_t cword;
int retval;
cptr.cp = flash_make_addr(info, sect, offset);
flash_make_cmd(info, cmd, &cword);
switch(info->portwidth) {
case FLASH_CFI_8BIT:
retval = (cptr.cp[0] == cword.c);
break;
case FLASH_CFI_16BIT:
retval = (cptr.wp[0] == cword.w);
break;
case FLASH_CFI_32BIT:
retval = (cptr.lp[0] == cword.l);
break;
default:
retval = 0;
break;
}
return retval;
}
/*-----------------------------------------------------------------------
*/
static int flash_isset(flash_info_t * info, int sect, uchar offset, uchar cmd)
{
cfiptr_t cptr;
cfiword_t cword;
int retval;
cptr.cp = flash_make_addr(info, sect, offset);
flash_make_cmd(info, cmd, &cword);
switch(info->portwidth) {
case FLASH_CFI_8BIT:
retval = ((cptr.cp[0] & cword.c) == cword.c);
break;
case FLASH_CFI_16BIT:
retval = ((cptr.wp[0] & cword.w) == cword.w);
break;
case FLASH_CFI_32BIT:
retval = ((cptr.lp[0] & cword.l) == cword.l);
break;
default:
retval = 0;
break;
}
return retval;
}
/*-----------------------------------------------------------------------
* detect if flash is compatible with the Common Flash Interface (CFI)
* http://www.jedec.org/download/search/jesd68.pdf
*
*/
static int flash_detect_cfi(flash_info_t * info)
{
#if 0
for(info->portwidth=FLASH_CFI_8BIT; info->portwidth <= FLASH_CFI_32BIT;
info->portwidth <<= 1) {
for(info->chipwidth =FLASH_CFI_BY8;
info->chipwidth <= info->portwidth;
info->chipwidth <<= 1) {
flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
flash_write_cmd(info, 0, FLASH_OFFSET_CFI, FLASH_CMD_CFI);
if(flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP,'Q') &&
flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R') &&
flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y'))
return 1;
}
}
#endif
flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
flash_write_cmd(info, 0, FLASH_OFFSET_CFI, FLASH_CMD_CFI);
if(flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP,'Q') &&
flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R') &&
flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y')) {
return 1;
} else {
return 0;
};
}
/*
* The following code cannot be run from FLASH!
*
*/
static ulong flash_get_size (ulong base, int banknum)
{
flash_info_t * info = &flash_info[banknum];
int i, j;
int sect_cnt;
unsigned long sector;
unsigned long tmp;
int size_ratio;
uchar num_erase_regions;
int erase_region_size;
int erase_region_count;
info->start[0] = base;
if(flash_detect_cfi(info)){
#ifdef DEBUG_FLASH
printf("portwidth=%d chipwidth=%d\n", info->portwidth, info->chipwidth); /* test-only */
#endif
size_ratio = 1; // info->portwidth / info->chipwidth;
num_erase_regions = flash_read_uchar(info, FLASH_OFFSET_NUM_ERASE_REGIONS);
#ifdef DEBUG_FLASH
printf("found %d erase regions\n", num_erase_regions);
#endif
sect_cnt = 0;
sector = base;
for(i = 0 ; i < num_erase_regions; i++) {
if(i > NUM_ERASE_REGIONS) {
printf("%d erase regions found, only %d used\n",
num_erase_regions, NUM_ERASE_REGIONS);
break;
}
tmp = flash_read_long(info, 0, FLASH_OFFSET_ERASE_REGIONS);
erase_region_count = (tmp & 0xffff) +1;
tmp >>= 16;
erase_region_size = (tmp & 0xffff)? ((tmp & 0xffff) * 256): 128;
for(j = 0; j< erase_region_count; j++) {
info->start[sect_cnt] = sector;
sector += (erase_region_size * size_ratio);
info->protect[sect_cnt] = flash_isset(info, sect_cnt, FLASH_OFFSET_PROTECT, FLASH_STATUS_PROTECT);
sect_cnt++;
}
}
info->sector_count = sect_cnt;
/* multiply the size by the number of chips */
info->size = (1 << flash_read_uchar(info, FLASH_OFFSET_SIZE)) * size_ratio;
info->buffer_size = (1 << flash_read_ushort(info, 0, FLASH_OFFSET_BUFFER_SIZE));
tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_ETOUT);
info->erase_blk_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_EMAX_TOUT)));
tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_WBTOUT);
info->buffer_write_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_WBMAX_TOUT)));
tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_WTOUT);
info->write_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_WMAX_TOUT)))/ 1000;
info->flash_id = FLASH_MAN_CFI;
}
flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
return(info->size);
}
/*-----------------------------------------------------------------------
*/
static int flash_write_cfiword (flash_info_t *info, ulong dest, cfiword_t cword)
{
cfiptr_t ctladdr;
cfiptr_t cptr;
int flag;
ctladdr.cp = flash_make_addr(info, 0, 0);
cptr.cp = (uchar *)dest;
/* Check if Flash is (sufficiently) erased */
switch(info->portwidth) {
case FLASH_CFI_8BIT:
flag = ((cptr.cp[0] & cword.c) == cword.c);
break;
case FLASH_CFI_16BIT:
flag = ((cptr.wp[0] & cword.w) == cword.w);
break;
case FLASH_CFI_32BIT:
flag = ((cptr.lp[0] & cword.l) == cword.l);
break;
default:
return 2;
}
if(!flag)
return 2;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
flash_write_cmd(info, 0, 0, FLASH_CMD_CLEAR_STATUS);
flash_write_cmd(info, 0, 0, FLASH_CMD_WRITE);
switch(info->portwidth) {
case FLASH_CFI_8BIT:
cptr.cp[0] = cword.c;
break;
case FLASH_CFI_16BIT:
cptr.wp[0] = cword.w;
break;
case FLASH_CFI_32BIT:
cptr.lp[0] = cword.l;
break;
}
/* re-enable interrupts if necessary */
if(flag)
enable_interrupts();
return flash_full_status_check(info, 0, info->write_tout, "write");
}
#ifdef CFG_FLASH_USE_BUFFER_WRITE
/* loop through the sectors from the highest address
* when the passed address is greater or equal to the sector address
* we have a match
*/
static int find_sector(flash_info_t *info, ulong addr)
{
int sector;
for(sector = info->sector_count - 1; sector >= 0; sector--) {
if(addr >= info->start[sector])
break;
}
return sector;
}
static int flash_write_cfibuffer(flash_info_t * info, ulong dest, uchar * cp, int len)
{
int sector;
int cnt;
int retcode;
volatile cfiptr_t src;
volatile cfiptr_t dst;
src.cp = cp;
dst.cp = (uchar *)dest;
sector = find_sector(info, dest);
flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
flash_write_cmd(info, sector, 0, FLASH_CMD_WRITE_TO_BUFFER);
if((retcode = flash_status_check(info, sector, info->buffer_write_tout,
"write to buffer")) == ERR_OK) {
switch(info->portwidth) {
case FLASH_CFI_8BIT:
cnt = len;
break;
case FLASH_CFI_16BIT:
cnt = len >> 1;
break;
case FLASH_CFI_32BIT:
cnt = len >> 2;
break;
default:
return ERR_INVAL;
break;
}
flash_write_cmd(info, sector, 0, (uchar)cnt-1);
while(cnt-- > 0) {
switch(info->portwidth) {
case FLASH_CFI_8BIT:
*dst.cp++ = *src.cp++;
break;
case FLASH_CFI_16BIT:
*dst.wp++ = *src.wp++;
break;
case FLASH_CFI_32BIT:
*dst.lp++ = *src.lp++;
break;
default:
return ERR_INVAL;
break;
}
}
flash_write_cmd(info, sector, 0, FLASH_CMD_WRITE_BUFFER_CONFIRM);
retcode = flash_full_status_check(info, sector, info->buffer_write_tout,
"buffer write");
}
flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
return retcode;
}
#endif /* CFG_USE_FLASH_BUFFER_WRITE */

@ -0,0 +1,34 @@
/*
* init.S: Stubs for ppcboot initialization
*
* Copyright 2002 Mind NV
*
* http://www.mind.be/
*
* Author : Peter De Schrijver (p2@mind.be)
*
* This software may be used and distributed according to the terms of
* the GNU General Public License (GPL) version 2, incorporated herein by
* reference. Drivers based on or derived from this code fall under the GPL
* and must retain the authorship, copyright and this license notice. This
* file is not a complete program and may only be used when the entire
* program is licensed under the GPL.
*
*/
#include <ppc4xx.h>
#include <ppc_asm.tmpl>
#include <ppc_defs.h>
#include <asm/cache.h>
#include <asm/mmu.h>
.globl ext_bus_cntlr_init
ext_bus_cntlr_init:
blr
.globl sdram_init
sdram_init:
blr

@ -0,0 +1,346 @@
/*
* (C) Copyright 2003
* AMIRIX Systems Inc.
*
* 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 <ppc4xx.h>
#include <asm/processor.h>
#include <pci.h>
#define PCI_MEM_82559ER_CSR_BASE 0x30200000
#define PCI_IO_82559ER_CSR_BASE 0x40000200
/** AP1100 specific values */
#define PSII_BASE 0x30000000 /**< PowerSpan II dual bridge local bus register address */
#define PSII_CONFIG_ADDR 0x30000290 /**< PowerSpan II Configuration Cycle Address configuration register */
#define PSII_CONFIG_DATA 0x30000294 /**< PowerSpan II Configuration Cycle Data register. */
#define PSII_CONFIG_DEST_PCI2 0x01000000 /**< PowerSpan II configuration cycle destination selection, set for PCI2 bus */
#define PSII_PCI_MEM_BASE 0x30200000 /**< Local Bus address for start of PCI memory space on PCI2 bus. */
#define PSII_PCI_MEM_SIZE 0x1BE00000 /**< PCI Memory space about 510 Meg. */
#define AP1000_SYS_MEM_START 0x00000000 /**< System memory starts at 0. */
#define AP1000_SYS_MEM_SIZE 0x08000000 /**< System memory is 128 Meg. */
/* static int G_verbosity_level = 1; */
#define G_verbosity_level 1
void write1(unsigned long addr, unsigned char val) {
volatile unsigned char* p = (volatile unsigned char*)addr;
if(G_verbosity_level > 1)
printf("write1: addr=%08x val=%02x\n", (unsigned int)addr, val);
*p = val;
asm("eieio");
}
unsigned char read1(unsigned long addr) {
unsigned char val;
volatile unsigned char* p = (volatile unsigned char*)addr;
if(G_verbosity_level > 1)
printf("read1: addr=%08x ", (unsigned int)addr);
val = *p;
asm("eieio");
if(G_verbosity_level > 1)
printf("val=%08x\n", val);
return val;
}
void write2(unsigned long addr, unsigned short val) {
volatile unsigned short* p = (volatile unsigned short*)addr;
if(G_verbosity_level > 1)
printf("write2: addr=%08x val=%04x -> *p=%04x\n", (unsigned int)addr, val,
((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8));
*p = ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8);
asm("eieio");
}
unsigned short read2(unsigned long addr) {
unsigned short val;
volatile unsigned short* p = (volatile unsigned short*)addr;
if(G_verbosity_level > 1)
printf("read2: addr=%08x ", (unsigned int)addr);
val = *p;
val = ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8);
asm("eieio");
if(G_verbosity_level > 1)
printf("*p=%04x -> val=%04x\n",
((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8), val);
return val;
}
void write4(unsigned long addr, unsigned long val) {
volatile unsigned long* p = (volatile unsigned long*)addr;
if(G_verbosity_level > 1)
printf("write4: addr=%08x val=%08x -> *p=%08x\n", (unsigned int)addr, (unsigned int)val,
(unsigned int)(((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8)));
*p = ((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8);
asm("eieio");
}
unsigned long read4(unsigned long addr) {
unsigned long val;
volatile unsigned long* p = (volatile unsigned long*)addr;
if(G_verbosity_level > 1)
printf("read4: addr=%08x", (unsigned int)addr);
val = *p;
val = ((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8);
asm("eieio");
if(G_verbosity_level > 1)
printf("*p=%04x -> val=%04x\n",
(unsigned int)(((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8)), (unsigned int)val);
return val;
}
void write4be(unsigned long addr, unsigned long val) {
volatile unsigned long* p = (volatile unsigned long*)addr;
if(G_verbosity_level > 1)
printf("write4: addr=%08x val=%08x\n", (unsigned int)addr, (unsigned int)val);
*p = val;
asm("eieio");
}
/** One byte configuration write on PSII.
* Currently fixes destination PCI bus to PCI2, onboard
* pci.
* @param hose PCI Host controller information. Ignored.
* @param dev Encoded PCI device/Bus and Function value.
* @param reg PCI Configuration register number.
* @param val Address of location for received byte.
* @return Always Zero.
*/
static int psII_read_config_byte(
struct pci_controller *hose,
pci_dev_t dev,
int reg,
u8 *val)
{
write4be(PSII_CONFIG_ADDR,
PSII_CONFIG_DEST_PCI2 | /* Operate on PCI2 bus interface . */
(PCI_BUS(dev) << 16) |
(PCI_DEV(dev) << 11) |
(PCI_FUNC(dev) << 8) |
((reg & 0xFF) & ~3)); /* Configuation cycle type 0 */
*val = read1(PSII_CONFIG_DATA+(reg&0x03));
return(0);
}
/** One byte configuration write on PSII.
* Currently fixes destination bus to PCI2, onboard
* pci.
* @param hose PCI Host controller information. Ignored.
* @param dev Encoded PCI device/Bus and Function value.
* @param reg PCI Configuration register number.
* @param val Output byte.
* @return Always Zero.
*/
static int psII_write_config_byte(
struct pci_controller *hose,
pci_dev_t dev,
int reg,
u8 val)
{
write4be(PSII_CONFIG_ADDR,
PSII_CONFIG_DEST_PCI2 | /* Operate on PCI2 bus interface . */
(PCI_BUS(dev) << 16) |
(PCI_DEV(dev) << 11) |
(PCI_FUNC(dev) << 8) |
((reg & 0xFF) & ~3)); /* Configuation cycle type 0 */
write1(PSII_CONFIG_DATA+(reg&0x03),(unsigned char )val);
return(0);
}
/** One word (16 bit) configuration read on PSII.
* Currently fixes destination PCI bus to PCI2, onboard
* pci.
* @param hose PCI Host controller information. Ignored.
* @param dev Encoded PCI device/Bus and Function value.
* @param reg PCI Configuration register number.
* @param val Address of location for received word.
* @return Always Zero.
*/
static int psII_read_config_word(
struct pci_controller *hose,
pci_dev_t dev,
int reg,
u16 *val)
{
write4be(PSII_CONFIG_ADDR,
PSII_CONFIG_DEST_PCI2 | /* Operate on PCI2 bus interface . */
(PCI_BUS(dev) << 16) |
(PCI_DEV(dev) << 11) |
(PCI_FUNC(dev) << 8) |
((reg & 0xFF) & ~3)); /* Configuation cycle type 0 */
*val = read2(PSII_CONFIG_DATA+(reg&0x03));
return(0);
}
/** One word (16 bit) configuration write on PSII.
* Currently fixes destination bus to PCI2, onboard
* pci.
* @param hose PCI Host controller information. Ignored.
* @param dev Encoded PCI device/Bus and Function value.
* @param reg PCI Configuration register number.
* @param val Output word.
* @return Always Zero.
*/
static int psII_write_config_word(
struct pci_controller *hose,
pci_dev_t dev,
int reg,
u16 val)
{
write4be(PSII_CONFIG_ADDR,
PSII_CONFIG_DEST_PCI2 | /* Operate on PCI2 bus interface . */
(PCI_BUS(dev) << 16) |
(PCI_DEV(dev) << 11) |
(PCI_FUNC(dev) << 8) |
((reg & 0xFF) & ~3)); /* Configuation cycle type 0 */
write2(PSII_CONFIG_DATA+(reg&0x03),(unsigned short )val);
return(0);
}
/** One DWord (32 bit) configuration read on PSII.
* Currently fixes destination PCI bus to PCI2, onboard
* pci.
* @param hose PCI Host controller information. Ignored.
* @param dev Encoded PCI device/Bus and Function value.
* @param reg PCI Configuration register number.
* @param val Address of location for received byte.
* @return Always Zero.
*/
static int psII_read_config_dword(
struct pci_controller *hose,
pci_dev_t dev,
int reg,
u32 *val)
{
write4be(PSII_CONFIG_ADDR,
PSII_CONFIG_DEST_PCI2 | /* Operate on PCI2 bus interface . */
(PCI_BUS(dev) << 16) |
(PCI_DEV(dev) << 11) |
(PCI_FUNC(dev) << 8) |
((reg & 0xFF) & ~3)); /* Configuation cycle type 0 */
*val = read4(PSII_CONFIG_DATA);
return(0);
}
/** One DWord (32 bit) configuration write on PSII.
* Currently fixes destination bus to PCI2, onboard
* pci.
* @param hose PCI Host controller information. Ignored.
* @param dev Encoded PCI device/Bus and Function value.
* @param reg PCI Configuration register number.
* @param val Output Dword.
* @return Always Zero.
*/
static int psII_write_config_dword(
struct pci_controller *hose,
pci_dev_t dev,
int reg,
u32 val)
{
write4be(PSII_CONFIG_ADDR,
PSII_CONFIG_DEST_PCI2 | /* Operate on PCI2 bus interface . */
(PCI_BUS(dev) << 16) |
(PCI_DEV(dev) << 11) |
(PCI_FUNC(dev) << 8) |
((reg & 0xFF) & ~3)); /* Configuation cycle type 0 */
write4(PSII_CONFIG_DATA,(unsigned long)val);
return(0);
}
static struct pci_config_table ap1000_config_table[] = {
#ifdef CONFIG_AP1000
{PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_BUS(CFG_ETH_DEV_FN), PCI_DEV(CFG_ETH_DEV_FN), PCI_FUNC(CFG_ETH_DEV_FN),
pci_cfgfunc_config_device,
{CFG_ETH_IOBASE, CFG_ETH_MEMBASE, PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
#endif
{ }
};
static struct pci_controller psII_hose = {
config_table: ap1000_config_table,
};
void pci_init_board(void)
{
struct pci_controller *hose = &psII_hose;
/*
* Register the hose
*/
hose->first_busno = 0;
hose->last_busno = 0xff;
/* System memory space */
pci_set_region(hose->regions + 0,
AP1000_SYS_MEM_START, AP1000_SYS_MEM_START, AP1000_SYS_MEM_SIZE,
PCI_REGION_MEM | PCI_REGION_MEMORY);
/* PCI Memory space */
pci_set_region(hose->regions + 1,
PSII_PCI_MEM_BASE, PSII_PCI_MEM_BASE, PSII_PCI_MEM_SIZE,
PCI_REGION_MEM);
/* No IO Memory space - for now */
pci_set_ops(hose,
psII_read_config_byte,
psII_read_config_word,
psII_read_config_dword,
psII_write_config_byte,
psII_write_config_word,
psII_write_config_dword);
hose->region_count = 2;
pci_register_hose(hose);
hose->last_busno = pci_hose_scan(hose);
}

@ -0,0 +1,712 @@
/**
* @file powerspan.c Source file for PowerSpan II code.
*/
/*
* (C) Copyright 2005
* AMIRIX Systems Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <command.h>
#include <asm/processor.h>
#include "powerspan.h"
#define tolower(x) x
#include "ap1000.h"
#ifdef INCLUDE_PCI
/** Write one byte with byte swapping.
* @param addr [IN] the address to write to
* @param val [IN] the value to write
*/
void write1(unsigned long addr, unsigned char val) {
volatile unsigned char* p = (volatile unsigned char*)addr;
#ifdef VERBOSITY
if(gVerbosityLevel > 1){
printf("write1: addr=%08x val=%02x\n", addr, val);
}
#endif
*p = val;
PSII_SYNC();
}
/** Read one byte with byte swapping.
* @param addr [IN] the address to read from
* @return the value at addr
*/
unsigned char read1(unsigned long addr) {
unsigned char val;
volatile unsigned char* p = (volatile unsigned char*)addr;
val = *p;
PSII_SYNC();
#ifdef VERBOSITY
if(gVerbosityLevel > 1){
printf("read1: addr=%08x val=%02x\n", addr, val);
}
#endif
return val;
}
/** Write one 2-byte word with byte swapping.
* @param addr [IN] the address to write to
* @param val [IN] the value to write
*/
void write2(unsigned long addr, unsigned short val) {
volatile unsigned short* p = (volatile unsigned short*)addr;
#ifdef VERBOSITY
if(gVerbosityLevel > 1){
printf("write2: addr=%08x val=%04x -> *p=%04x\n", addr, val,
((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8));
}
#endif
*p = ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8);
PSII_SYNC();
}
/** Read one 2-byte word with byte swapping.
* @param addr [IN] the address to read from
* @return the value at addr
*/
unsigned short read2(unsigned long addr) {
unsigned short val;
volatile unsigned short* p = (volatile unsigned short*)addr;
val = *p;
val = ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8);
PSII_SYNC();
#ifdef VERBOSITY
if(gVerbosityLevel > 1){
printf("read2: addr=%08x *p=%04x -> val=%04x\n", addr, *p, val);
}
#endif
return val;
}
/** Write one 4-byte word with byte swapping.
* @param addr [IN] the address to write to
* @param val [IN] the value to write
*/
void write4(unsigned long addr, unsigned long val) {
volatile unsigned long* p = (volatile unsigned long*)addr;
#ifdef VERBOSITY
if(gVerbosityLevel > 1){
printf("write4: addr=%08x val=%08x -> *p=%08x\n", addr, val,
((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8));
}
#endif
*p = ((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8);
PSII_SYNC();
}
/** Read one 4-byte word with byte swapping.
* @param addr [IN] the address to read from
* @return the value at addr
*/
unsigned long read4(unsigned long addr) {
unsigned long val;
volatile unsigned long* p = (volatile unsigned long*)addr;
val = *p;
val = ((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8);
PSII_SYNC();
#ifdef VERBOSITY
if(gVerbosityLevel > 1){
printf("read4: addr=%08x *p=%08x -> val=%08x\n", addr, *p, val);
}
#endif
return val;
}
int PCIReadConfig(int bus, int dev, int fn, int reg, int width, unsigned long* val){
unsigned int conAdrVal;
unsigned int conDataReg = REG_CONFIG_DATA;
unsigned int status;
int ret_val = 0;
/* DEST bit hardcoded to 1: local pci is PCI-2 */
/* TYPE bit is hardcoded to 1: all config cycles are local */
conAdrVal = (1 << 24)
| ((bus & 0xFF) << 16)
| ((dev & 0xFF) << 11)
| ((fn & 0x07) << 8)
| (reg & 0xFC);
/* clear any pending master aborts */
write4(REG_P1_CSR, CLEAR_MASTER_ABORT);
/* Load the conAdrVal value first, then read from pb_conf_data */
write4(REG_CONFIG_ADDRESS, conAdrVal);
PSII_SYNC();
/* Note: documentation does not match the pspan library code */
/* Note: *pData comes back as -1 if device is not present */
switch (width){
case 4:{
*(unsigned int*)val = read4(conDataReg);
break;
}
case 2:{
*(unsigned short*)val = read2(conDataReg);
break;
}
case 1:{
*(unsigned char*)val = read1(conDataReg);
break;
}
default:{
ret_val = ILLEGAL_REG_OFFSET;
break;
}
}
PSII_SYNC();
/* clear any pending master aborts */
status = read4(REG_P1_CSR);
if(status & CLEAR_MASTER_ABORT){
ret_val = NO_DEVICE_FOUND;
write4(REG_P1_CSR, CLEAR_MASTER_ABORT);
}
return ret_val;
}
int PCIWriteConfig(int bus, int dev, int fn, int reg, int width, unsigned long val){
unsigned int conAdrVal;
unsigned int conDataReg = REG_CONFIG_DATA;
unsigned int status;
int ret_val = 0;
/* DEST bit hardcoded to 1: local pci is PCI-2 */
/* TYPE bit is hardcoded to 1: all config cycles are local */
conAdrVal = (1 << 24)
| ((bus & 0xFF) << 16)
| ((dev & 0xFF) << 11)
| ((fn & 0x07) << 8)
| (reg & 0xFC);
/* clear any pending master aborts */
write4(REG_P1_CSR, CLEAR_MASTER_ABORT);
/* Load the conAdrVal value first, then read from pb_conf_data */
write4(REG_CONFIG_ADDRESS, conAdrVal);
PSII_SYNC();
/* Note: documentation does not match the pspan library code */
/* Note: *pData comes back as -1 if device is not present */
switch (width){
case 4:{
write4(conDataReg, val);
break;
}
case 2:{
write2(conDataReg, val);
break;
}
case 1:{
write1(conDataReg, val);
break;
}
default:{
ret_val = ILLEGAL_REG_OFFSET;
break;
}
}
PSII_SYNC();
/* clear any pending master aborts */
status = read4(REG_P1_CSR);
if(status & CLEAR_MASTER_ABORT){
ret_val = NO_DEVICE_FOUND;
write4(REG_P1_CSR, CLEAR_MASTER_ABORT);
}
return ret_val;
}
int pci_read_config_byte(int bus, int dev, int fn, int reg, unsigned char* val){
unsigned long read_val;
int ret_val;
ret_val = PCIReadConfig(bus, dev, fn, reg, 1, &read_val);
*val = read_val & 0xFF;
return ret_val;
}
int pci_write_config_byte(int bus, int dev, int fn, int reg, unsigned char val){
return PCIWriteConfig(bus, dev, fn, reg, 1, val);
}
int pci_read_config_word(int bus, int dev, int fn, int reg, unsigned short* val){
unsigned long read_val;
int ret_val;
ret_val = PCIReadConfig(bus, dev, fn, reg, 2, &read_val);
*val = read_val & 0xFFFF;
return ret_val;
}
int pci_write_config_word(int bus, int dev, int fn, int reg, unsigned short val){
return PCIWriteConfig(bus, dev, fn, reg, 2, val);
}
int pci_read_config_dword(int bus, int dev, int fn, int reg, unsigned long* val){
return PCIReadConfig(bus, dev, fn, reg, 4, val);
}
int pci_write_config_dword(int bus, int dev, int fn, int reg, unsigned long val){
return PCIWriteConfig(bus, dev, fn, reg, 4, val);
}
#endif /* INCLUDE_PCI */
int I2CAccess(unsigned char theI2CAddress, unsigned char theDevCode, unsigned char theChipSel, unsigned char* theValue, int RWFlag){
int ret_val = 0;
unsigned int reg_value;
reg_value = PowerSpanRead(REG_I2C_CSR);
if(reg_value & I2C_CSR_ACT){
printf("Error: I2C busy\n");
ret_val = I2C_BUSY;
}
else{
reg_value = ((theI2CAddress & 0xFF) << 24)
| ((theDevCode & 0x0F) << 12)
| ((theChipSel & 0x07) << 9)
| I2C_CSR_ERR;
if(RWFlag == I2C_WRITE){
reg_value |= I2C_CSR_RW | ((*theValue & 0xFF) << 16);
}
PowerSpanWrite(REG_I2C_CSR, reg_value);
udelay(1);
do{
reg_value = PowerSpanRead(REG_I2C_CSR);
if((reg_value & I2C_CSR_ACT) == 0){
if(reg_value & I2C_CSR_ERR){
ret_val = I2C_ERR;
}
else{
*theValue = (reg_value & I2C_CSR_DATA) >> 16;
}
}
} while(reg_value & I2C_CSR_ACT);
}
return ret_val;
}
int EEPROMRead(unsigned char theI2CAddress, unsigned char* theValue){
return I2CAccess(theI2CAddress, I2C_EEPROM_DEV, I2C_EEPROM_CHIP_SEL, theValue, I2C_READ);
}
int EEPROMWrite(unsigned char theI2CAddress, unsigned char theValue){
return I2CAccess(theI2CAddress, I2C_EEPROM_DEV, I2C_EEPROM_CHIP_SEL, &theValue, I2C_WRITE);
}
int do_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
char cmd;
int ret_val = 0;
unsigned int address = 0;
unsigned char value = 1;
unsigned char read_value;
int ii;
int error = 0;
unsigned char* mem_ptr;
unsigned char default_eeprom[] = EEPROM_DEFAULT;
if(argc < 2){
goto usage;
}
cmd = argv[1][0];
if(argc > 2){
address = simple_strtoul(argv[2], NULL, 16);
if(argc > 3){
value = simple_strtoul(argv[3], NULL, 16) & 0xFF;
}
}
switch (cmd){
case 'r':{
if(address > 256){
printf("Illegal Address\n");
goto usage;
}
printf("@0x%x: ", address);
for(ii = 0;ii < value;ii++){
if(EEPROMRead(address + ii, &read_value) != 0){
printf("Read Error\n");
}
else{
printf("0x%02x ", read_value);
}
if(((ii + 1) % 16) == 0){
printf("\n");
}
}
printf("\n");
break;
}
case 'w':{
if(address > 256){
printf("Illegal Address\n");
goto usage;
}
if(argc < 4){
goto usage;
}
if(EEPROMWrite(address, value) != 0){
printf("Write Error\n");
}
break;
}
case 'g':{
if(argc != 3){
goto usage;
}
mem_ptr = (unsigned char*)address;
for(ii = 0;((ii < EEPROM_LENGTH) && (error == 0));ii++){
if(EEPROMRead(ii, &read_value) != 0){
printf("Read Error\n");
error = 1;
}
else{
*mem_ptr = read_value;
mem_ptr++;
}
}
break;
}
case 'p':{
if(argc != 3){
goto usage;
}
mem_ptr = (unsigned char*)address;
for(ii = 0;((ii < EEPROM_LENGTH) && (error == 0));ii++){
if(EEPROMWrite(ii, *mem_ptr) != 0){
printf("Write Error\n");
error = 1;
}
mem_ptr++;
}
break;
}
case 'd':{
if(argc != 2){
goto usage;
}
for(ii = 0;((ii < EEPROM_LENGTH) && (error == 0));ii++){
if(EEPROMWrite(ii, default_eeprom[ii]) != 0){
printf("Write Error\n");
error = 1;
}
}
break;
}
default:{
goto usage;
}
}
goto done;
usage:
printf ("Usage:\n%s\n", cmdtp->help);
done:
return ret_val;
}
U_BOOT_CMD(
eeprom, 4, 0, do_eeprom,
"eeprom - read/write/copy to/from the PowerSpan II eeprom\n",
"eeprom r OFF [NUM]\n"
" - read NUM words starting at OFF\n"
"eeprom w OFF VAL\n"
" - write word VAL at offset OFF\n"
"eeprom g ADD\n"
" - store contents of eeprom at address ADD\n"
"eeprom p ADD\n"
" - put data stored at address ADD into the eeprom\n"
"eeprom d\n"
" - return eeprom to default contents\n"
);
unsigned int PowerSpanRead(unsigned int theOffset){
volatile unsigned int* ptr = (volatile unsigned int*)(PSPAN_BASEADDR + theOffset);
unsigned int ret_val;
#ifdef VERBOSITY
if(gVerbosityLevel > 1){
printf("PowerSpanRead: offset=%08x ", theOffset);
}
#endif
ret_val = *ptr;
PSII_SYNC();
#ifdef VERBOSITY
if(gVerbosityLevel > 1){
printf("value=%08x\n", ret_val);
}
#endif
return ret_val;
}
void PowerSpanWrite(unsigned int theOffset, unsigned int theValue){
volatile unsigned int* ptr = (volatile unsigned int*)(PSPAN_BASEADDR + theOffset);
#ifdef VERBOSITY
if(gVerbosityLevel > 1){
printf("PowerSpanWrite: offset=%08x val=%02x\n", theOffset, theValue);
}
#endif
*ptr = theValue;
PSII_SYNC();
}
/**
* Sets the indicated bits in the indicated register.
* @param theOffset [IN] the register to access.
* @param theMask [IN] bits set in theMask will be set in the register.
*/
void PowerSpanSetBits(unsigned int theOffset, unsigned int theMask){
volatile unsigned int* ptr = (volatile unsigned int*)(PSPAN_BASEADDR + theOffset);
unsigned int register_value;
#ifdef VERBOSITY
if(gVerbosityLevel > 1){
printf("PowerSpanSetBits: offset=%08x mask=%02x\n", theOffset, theMask);
}
#endif
register_value = *ptr;
PSII_SYNC();
register_value |= theMask;
*ptr = register_value;
PSII_SYNC();
}
/**
* Clears the indicated bits in the indicated register.
* @param theOffset [IN] the register to access.
* @param theMask [IN] bits set in theMask will be cleared in the register.
*/
void PowerSpanClearBits(unsigned int theOffset, unsigned int theMask){
volatile unsigned int* ptr = (volatile unsigned int*)(PSPAN_BASEADDR + theOffset);
unsigned int register_value;
#ifdef VERBOSITY
if(gVerbosityLevel > 1){
printf("PowerSpanClearBits: offset=%08x mask=%02x\n", theOffset, theMask);
}
#endif
register_value = *ptr;
PSII_SYNC();
register_value &= ~theMask;
*ptr = register_value;
PSII_SYNC();
}
/**
* Configures a slave image on the local bus, based on the parameters and some hardcoded system values.
* Slave Images are images that cause the PowerSpan II to be a master on the PCI bus. Thus, they
* are outgoing from the standpoint of the local bus.
* @param theImageIndex [IN] the PowerSpan II image to set (assumed to be 0-7).
* @param theBlockSize [IN] the block size of the image (as used by PowerSpan II: PB_SIx_CTL[BS]).
* @param theMemIOFlag [IN] if PX_TGT_USE_MEM_IO, this image will have the MEM_IO bit set.
* @param theEndianness [IN] the endian bits for the image (already shifted, use defines).
* @param theLocalBaseAddr [IN] the Local address for the image (assumed to be valid with provided block size).
* @param thePCIBaseAddr [IN] the PCI address for the image (assumed to be valid with provided block size).
*/
int SetSlaveImage(int theImageIndex, unsigned int theBlockSize, int theMemIOFlag, int theEndianness, unsigned int theLocalBaseAddr, unsigned int thePCIBaseAddr){
unsigned int reg_offset = theImageIndex * PB_SLAVE_IMAGE_OFF;
unsigned int reg_value = 0;
/* Make sure that the Slave Image is disabled */
PowerSpanClearBits((REGS_PB_SLAVE_CSR + reg_offset), PB_SLAVE_CSR_IMG_EN);
/* Setup the mask required for requested PB Slave Image configuration */
reg_value = PB_SLAVE_CSR_TA_EN | theEndianness | (theBlockSize << 24);
if(theMemIOFlag == PB_SLAVE_USE_MEM_IO){
reg_value |= PB_SLAVE_CSR_MEM_IO;
}
/* hardcoding the following:
TA_EN = 1
MD_EN = 0
MODE = 0
PRKEEP = 0
RD_AMT = 0
*/
PowerSpanWrite((REGS_PB_SLAVE_CSR + reg_offset), reg_value);
/* these values are not checked by software */
PowerSpanWrite((REGS_PB_SLAVE_BADDR + reg_offset), theLocalBaseAddr);
PowerSpanWrite((REGS_PB_SLAVE_TADDR + reg_offset), thePCIBaseAddr);
/* Enable the Slave Image */
PowerSpanSetBits((REGS_PB_SLAVE_CSR + reg_offset), PB_SLAVE_CSR_IMG_EN);
return 0;
}
/**
* Configures a target image on the local bus, based on the parameters and some hardcoded system values.
* Target Images are used when the PowerSpan II is acting as a target for an access. Thus, they
* are incoming from the standpoint of the local bus.
* In order to behave better on the host PCI bus, if thePCIBaseAddr is NULL (0x00000000), then the PCI
* base address will not be updated; makes sense given that the hosts own memory should be mapped to
* PCI address 0x00000000.
* @param theImageIndex [IN] the PowerSpan II image to set.
* @param theBlockSize [IN] the block size of the image (as used by PowerSpan II: Px_TIx_CTL[BS]).
* @param theMemIOFlag [IN] if PX_TGT_USE_MEM_IO, this image will have the MEM_IO bit set.
* @param theEndianness [IN] the endian bits for the image (already shifted, use defines).
* @param theLocalBaseAddr [IN] the Local address for the image (assumed to be valid with provided block size).
* @param thePCIBaseAddr [IN] the PCI address for the image (assumed to be valid with provided block size).
*/
int SetTargetImage(int theImageIndex, unsigned int theBlockSize, int theMemIOFlag, int theEndianness, unsigned int theLocalBaseAddr, unsigned int thePCIBaseAddr){
unsigned int csr_reg_offset = theImageIndex * P1_TGT_IMAGE_OFF;
unsigned int pci_reg_offset = theImageIndex * P1_BST_OFF;
unsigned int reg_value = 0;
/* Make sure that the Slave Image is disabled */
PowerSpanClearBits((REGS_P1_TGT_CSR + csr_reg_offset), PB_SLAVE_CSR_IMG_EN);
/* Setup the mask required for requested PB Slave Image configuration */
reg_value = PX_TGT_CSR_TA_EN | PX_TGT_CSR_BAR_EN | (theBlockSize << 24) | PX_TGT_CSR_RTT_READ | PX_TGT_CSR_WTT_WFLUSH | theEndianness;
if(theMemIOFlag == PX_TGT_USE_MEM_IO){
reg_value |= PX_TGT_MEM_IO;
}
/* hardcoding the following:
TA_EN = 1
BAR_EN = 1
MD_EN = 0
MODE = 0
DEST = 0
RTT = 01010
GBL = 0
CI = 0
WTT = 00010
PRKEEP = 0
MRA = 0
RD_AMT = 0
*/
PowerSpanWrite((REGS_P1_TGT_CSR + csr_reg_offset), reg_value);
PowerSpanWrite((REGS_P1_TGT_TADDR + csr_reg_offset), theLocalBaseAddr);
if(thePCIBaseAddr != (unsigned int)NULL){
PowerSpanWrite((REGS_P1_BST + pci_reg_offset), thePCIBaseAddr);
}
/* Enable the Slave Image */
PowerSpanSetBits((REGS_P1_TGT_CSR + csr_reg_offset), PB_SLAVE_CSR_IMG_EN);
return 0;
}
int do_bridge(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
char cmd;
int ret_val = 1;
unsigned int image_index;
unsigned int block_size;
unsigned int mem_io;
unsigned int local_addr;
unsigned int pci_addr;
int endianness;
if(argc != 8){
goto usage;
}
cmd = argv[1][0];
image_index = simple_strtoul(argv[2], NULL, 16);
block_size = simple_strtoul(argv[3], NULL, 16);
mem_io = simple_strtoul(argv[4], NULL, 16);
endianness = argv[5][0];
local_addr = simple_strtoul(argv[6], NULL, 16);
pci_addr = simple_strtoul(argv[7], NULL, 16);
switch (cmd){
case 'i':{
if(tolower(endianness) == 'b'){
endianness = PX_TGT_CSR_BIG_END;
}
else if(tolower(endianness) == 'l'){
endianness = PX_TGT_CSR_TRUE_LEND;
}
else{
goto usage;
}
SetTargetImage(image_index, block_size, mem_io, endianness, local_addr, pci_addr);
break;
}
case 'o':{
if(tolower(endianness) == 'b'){
endianness = PB_SLAVE_CSR_BIG_END;
}
else if(tolower(endianness) == 'l'){
endianness = PB_SLAVE_CSR_TRUE_LEND;
}
else{
goto usage;
}
SetSlaveImage(image_index, block_size, mem_io, endianness, local_addr, pci_addr);
break;
}
default:{
goto usage;
}
}
goto done;
usage:
printf ("Usage:\n%s\n", cmdtp->help);
done:
return ret_val;
}

@ -0,0 +1,170 @@
/**
* @file powerspan.h Header file for PowerSpan II code.
*/
/*
* (C) Copyright 2005
* AMIRIX Systems Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef POWERSPAN_H
#define POWERSPAN_H
#define CLEAR_MASTER_ABORT 0xdeadbeef
#define NO_DEVICE_FOUND -1
#define ILLEGAL_REG_OFFSET -2
#define I2C_BUSY -3
#define I2C_ERR -4
#define REG_P1_CSR 0x004
#define REGS_P1_BST 0x018
#define REG_P1_ERR_CSR 0x150
#define REG_P1_MISC_CSR 0x160
#define REGS_P1_TGT_CSR 0x100
#define REGS_P1_TGT_TADDR 0x104
#define REGS_PB_SLAVE_CSR 0x200
#define REGS_PB_SLAVE_TADDR 0x204
#define REGS_PB_SLAVE_BADDR 0x208
#define REG_CONFIG_ADDRESS 0x290
#define REG_CONFIG_DATA 0x294
#define REG_PB_ERR_CSR 0x2B0
#define REG_PB_MISC_CSR 0x2C0
#define REG_MISC_CSR 0x400
#define REG_I2C_CSR 0x408
#define REG_RESET_CSR 0x40C
#define REG_ISR0 0x410
#define REG_ISR1 0x414
#define REG_IER0 0x418
#define REG_MBOX_MAP 0x420
#define REG_HW_MAP 0x42C
#define REG_IDR 0x444
#define CSR_MEMORY_SPACE_ENABLE 0x00000002
#define CSR_PCI_MASTER_ENABLE 0x00000004
#define P1_BST_OFF 0x04
#define PX_ERR_ERR_STATUS 0x01000000
#define PX_MISC_CSR_MAX_RETRY_MASK 0x00000F00
#define PX_MISC_CSR_MAX_RETRY 0x00000F00
#define PX_MISC_REG_BAR_ENABLE 0x00008000
#define PB_MISC_TEA_ENABLE 0x00000010
#define PB_MISC_MAC_TEA 0x00000040
#define P1_TGT_IMAGE_OFF 0x010
#define PX_TGT_CSR_IMG_EN 0x80000000
#define PX_TGT_CSR_TA_EN 0x40000000
#define PX_TGT_CSR_BAR_EN 0x20000000
#define PX_TGT_CSR_MD_EN 0x10000000
#define PX_TGT_CSR_MODE 0x00800000
#define PX_TGT_CSR_DEST 0x00400000
#define PX_TGT_CSR_MEM_IO 0x00200000
#define PX_TGT_CSR_GBL 0x00080000
#define PX_TGT_CSR_CL 0x00040000
#define PX_TGT_CSR_PRKEEP 0x00000080
#define PX_TGT_CSR_BS_MASK 0x0F000000
#define PX_TGT_MEM_IO 0x00200000
#define PX_TGT_CSR_RTT_MASK 0x001F0000
#define PX_TGT_CSR_RTT_READ 0x000A0000
#define PX_TGT_CSR_WTT_MASK 0x00001F00
#define PX_TGT_CSR_WTT_WFLUSH 0x00000200
#define PX_TGT_CSR_END_MASK 0x00000060
#define PX_TGT_CSR_BIG_END 0x00000040
#define PX_TGT_CSR_TRUE_LEND 0x00000060
#define PX_TGT_CSR_RDAMT_MASK 0x00000007
#define PX_TGT_CSR_BS_64MB 0xa
#define PX_TGT_CSR_BS_16MB 0x8
#define PX_TGT_USE_MEM_IO 1
#define PX_TGT_NOT_MEM_IO 0
#define PB_SLAVE_IMAGE_OFF 0x010
#define PB_SLAVE_CSR_IMG_EN 0x80000000
#define PB_SLAVE_CSR_TA_EN 0x40000000
#define PB_SLAVE_CSR_MD_EN 0x20000000
#define PB_SLAVE_CSR_MODE 0x00800000
#define PB_SLAVE_CSR_DEST 0x00400000
#define PB_SLAVE_CSR_MEM_IO 0x00200000
#define PB_SLAVE_CSR_PRKEEP 0x00000080
#define PB_SLAVE_CSR_BS_MASK 0x1F000000
#define PB_SLAVE_CSR_END_MASK 0x00000060
#define PB_SLAVE_CSR_BIG_END 0x00000040
#define PB_SLAVE_CSR_TRUE_LEND 0x00000060
#define PB_SLAVE_CSR_RDAMT_MASK 0x00000007
#define PB_SLAVE_USE_MEM_IO 1
#define PB_SLAVE_NOT_MEM_IO 0
#define MISC_CSR_PCI1_LOCK 0x00000080
#define I2C_CSR_ADDR 0xFF000000 /* Specifies I2C Device Address to be Accessed */
#define I2C_CSR_DATA 0x00FF0000 /* Specifies the Required Data for a Write */
#define I2C_CSR_DEV_CODE 0x0000F000 /* Device Select. I2C 4-bit Device Code */
#define I2C_CSR_CS 0x00000E00 /* Chip Select */
#define I2C_CSR_RW 0x00000100 /* Read/Write */
#define I2C_CSR_ACT 0x00000080 /* I2C Interface Active */
#define I2C_CSR_ERR 0x00000040 /* Error */
#define I2C_EEPROM_DEV 0xa
#define I2C_EEPROM_CHIP_SEL 0
#define I2C_READ 0
#define I2C_WRITE 1
#define RESET_CSR_EEPROM_LOAD 0x00000010
#define ISR_CLEAR_ALL 0xFFFFFFFF
#define IER0_DMA_INTS_EN 0x0F000000
#define IER0_PCI_1_EN 0x00400000
#define IER0_HW_INTS_EN 0x003F0000
#define IER0_MB_INTS_EN 0x000000FF
#define IER0_DEFAULT (IER0_DMA_INTS_EN | IER0_PCI_1_EN | IER0_HW_INTS_EN | IER0_MB_INTS_EN)
#define MBOX_MAP_TO_INT4 0xCCCCCCCC
#define HW_MAP_HW4_TO_INT4 0x000C0000
#define IDR_PCI_A_OUT 0x40000000
#define IDR_MBOX_OUT 0x10000000
int pci_read_config_byte(int bus, int dev, int fn, int reg, unsigned char* val);
int pci_write_config_byte(int bus, int dev, int fn, int reg, unsigned char val);
int pci_read_config_word(int bus, int dev, int fn, int reg, unsigned short* val);
int pci_write_config_word(int bus, int dev, int fn, int reg, unsigned short val);
int pci_read_config_dword(int bus, int dev, int fn, int reg, unsigned long* val);
int pci_write_config_dword(int bus, int dev, int fn, int reg, unsigned long val);
unsigned int PowerSpanRead(unsigned int theOffset);
void PowerSpanWrite(unsigned int theOffset, unsigned int theValue);
int I2CAccess(unsigned char theI2CAddress, unsigned char theDevCode, unsigned char theChipSel, unsigned char* theValue, int RWFlag);
int PCIWriteConfig(int bus, int dev, int fn, int reg, int width, unsigned long val);
int PCIReadConfig(int bus, int dev, int fn, int reg, int width, unsigned long* val);
int SetSlaveImage(int theImageIndex, unsigned int theBlockSize, int theMemIOFlag, int theEndianness, unsigned int theLocalBaseAddr, unsigned int thePCIBaseAddr);
int SetTargetImage(int theImageIndex, unsigned int theBlockSize, int theMemIOFlag, int theEndianness, unsigned int theLocalBaseAddr, unsigned int thePCIBaseAddr);
#endif

@ -0,0 +1,128 @@
/*
* (C) Copyright 2002
* Peter De Schrijver (p2@mind.be), Mind Linux Solutions, NV.
*
* 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 <asm/u-boot.h>
#include <asm/processor.h>
#include <common.h>
#include <command.h>
#include <config.h>
#include <ns16550.h>
#if 0
#include "serial.h"
#endif
const NS16550_t COM_PORTS[] = { (NS16550_t) CFG_NS16550_COM1, (NS16550_t) CFG_NS16550_COM2 };
#undef CFG_DUART_CHAN
#define CFG_DUART_CHAN gComPort
static int gComPort = 0;
int
serial_init (void)
{
DECLARE_GLOBAL_DATA_PTR;
int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate;
(void)NS16550_init(COM_PORTS[0], clock_divisor);
gComPort = 0;
return 0;
}
void
serial_putc(const char c)
{
if (c == '\n'){
NS16550_putc(COM_PORTS[CFG_DUART_CHAN], '\r');
}
NS16550_putc(COM_PORTS[CFG_DUART_CHAN], c);
}
int
serial_getc(void)
{
return NS16550_getc(COM_PORTS[CFG_DUART_CHAN]);
}
int
serial_tstc(void)
{
return NS16550_tstc(COM_PORTS[CFG_DUART_CHAN]);
}
void
serial_setbrg (void)
{
DECLARE_GLOBAL_DATA_PTR;
int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate;
#ifdef CFG_INIT_CHAN1
NS16550_reinit(COM_PORTS[0], clock_divisor);
#endif
#ifdef CFG_INIT_CHAN2
NS16550_reinit(COM_PORTS[1], clock_divisor);
#endif
}
void
serial_puts (const char *s)
{
while (*s) {
serial_putc (*s++);
}
}
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
void
kgdb_serial_init(void)
{
}
void
putDebugChar (int c)
{
serial_putc (c);
}
void
putDebugStr (const char *str)
{
serial_puts (str);
}
int
getDebugChar (void)
{
return serial_getc();
}
void
kgdb_interruptible (int yes)
{
return;
}
#endif /* CFG_CMD_KGDB */

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

@ -381,6 +381,13 @@ ulong get_OPB_freq (void)
extern void get_sys_info (sys_info_t * sysInfo);
extern ulong get_PCI_freq (void);
#elif defined(CONFIG_AP1000)
void get_sys_info (sys_info_t * sysInfo) {
sysInfo->freqProcessor = 240 * 1000 * 1000;
sysInfo->freqPLB = 80 * 1000 * 1000;
sysInfo->freqPCI = 33 * 1000 * 1000;
}
#elif defined(CONFIG_405)
void get_sys_info (sys_info_t * sysInfo) {

@ -112,6 +112,7 @@ static int e1000_detect_gig_phy(struct e1000_hw *hw);
readl((a)->hw_addr + E1000_##reg + ((offset) << 2)))
#define E1000_WRITE_FLUSH(a) {uint32_t x; x = E1000_READ_REG(a, STATUS);}
#ifndef CONFIG_AP1000 /* remove for warnings */
/******************************************************************************
* Raises the EEPROM's clock input.
*
@ -478,6 +479,7 @@ e1000_validate_eeprom_checksum(struct eth_device *nic)
return -E1000_ERR_EEPROM;
}
}
#endif /* #ifndef CONFIG_AP1000 */
/******************************************************************************
* Reads the adapter's MAC address from the EEPROM and inverts the LSB for the
@ -488,6 +490,7 @@ e1000_validate_eeprom_checksum(struct eth_device *nic)
static int
e1000_read_mac_addr(struct eth_device *nic)
{
#ifndef CONFIG_AP1000
struct e1000_hw *hw = nic->priv;
uint16_t offset;
uint16_t eeprom_data;
@ -509,6 +512,32 @@ e1000_read_mac_addr(struct eth_device *nic)
/* Invert the last bit if this is the second device */
nic->enetaddr[5] += 1;
}
#else
/*
* The AP1000's e1000 has no eeprom; the MAC address is stored in the
* environment variables. Currently this does not support the addition
* of a PMC e1000 card, which is certainly a possibility, so this should
* be updated to properly use the env variable only for the onboard e1000
*/
int ii;
char *s, *e;
DEBUGFUNC();
s = getenv ("ethaddr");
if (s == NULL){
return -E1000_ERR_EEPROM;
}
else{
for(ii = 0; ii < 6; ii++) {
nic->enetaddr[ii] = s ? simple_strtoul (s, &e, 16) : 0;
if (s){
s = (*e) ? e + 1 : e;
}
}
}
#endif
return 0;
}
@ -876,6 +905,7 @@ e1000_setup_link(struct eth_device *nic)
DEBUGFUNC();
#ifndef CONFIG_AP1000
/* Read and store word 0x0F of the EEPROM. This word contains bits
* that determine the hardware's default PAUSE (flow control) mode,
* a bit that determines whether the HW defaults to enabling or
@ -888,6 +918,11 @@ e1000_setup_link(struct eth_device *nic)
DEBUGOUT("EEPROM Read Error\n");
return -E1000_ERR_EEPROM;
}
#else
/* we have to hardcode the proper value for our hardware. */
/* this value is for the 82540EM pci card used for prototyping, and it works. */
eeprom_data = 0xb220;
#endif
if (hw->fc == e1000_fc_default) {
if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
@ -2950,12 +2985,14 @@ e1000_initialize(bd_t * bis)
free(nic);
return 0;
}
#ifndef CONFIG_AP1000
if (e1000_validate_eeprom_checksum(nic) < 0) {
printf("The EEPROM Checksum Is Not Valid\n");
free(hw);
free(nic);
return 0;
}
#endif
e1000_read_mac_addr(nic);
E1000_WRITE_REG(hw, PBA, E1000_DEFAULT_PBA);

@ -0,0 +1,255 @@
/*
* AMIRIX.h: AMIRIX specific config options
*
* Author : Frank Smith (smith at amirix dot com)
*
* Derived from : other configuration header files in this tree
*
* This software may be used and distributed according to the terms of
* the GNU General Public License (GPL) version 2, incorporated herein by
* reference. Drivers based on or derived from this code fall under the GPL
* and must retain the authorship, copyright and this license notice. This
* file is not a complete program and may only be used when the entire
* program is licensed under the GPL.
*
*/
#ifndef __CONFIG_H
#define __CONFIG_H
/*
* High Level Configuration Options
* (easy to change)
*/
#undef DEBUG
#define CONFIG_405 1 /* This is a PPC405 CPU */
#define CONFIG_4xx 1 /* ...member of PPC4xx family */
#define CONFIG_AP1000 1 /* ...on an AP1000 board */
#define CONFIG_PCI 1
#define CFG_HUSH_PARSER 1 /* use "hush" command parser */
#define CFG_PROMPT "0> "
#define CFG_PROMPT_HUSH_PS2 "> "
#define CONFIG_COMMAND_EDIT 1
#define CONFIG_COMMAND_HISTORY 1
#define CONFIG_COMPLETE_ADDRESSES 1
#define CFG_ENV_IS_IN_FLASH 1
#define CFG_FLASH_USE_BUFFER_WRITE
#ifdef CFG_ENV_IS_IN_NVRAM
#undef CFG_ENV_IS_IN_FLASH
#else
#ifdef CFG_ENV_IS_IN_FLASH
#undef CFG_ENV_IS_IN_NVRAM
#endif
#endif
#define CONFIG_BAUDRATE 57600
#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
#define CONFIG_BOOTCOMMAND "" /* autoboot command */
/* Size (bytes) of interrupt driven serial port buffer.
* Set to 0 to use polling instead of interrupts.
* Setting to 0 will also disable RTS/CTS handshaking.
*/
#undef CONFIG_SERIAL_SOFTWARE_FIFO
#define CONFIG_BOOTARGS "console=ttyS0,57600"
#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */
#define CONFIG_COMMANDS ( (CONFIG_CMD_DFL & \
(~CFG_CMD_RTC) & ~(CFG_CMD_I2C)) | \
CFG_CMD_IRQ | \
CFG_CMD_PCI | \
CFG_CMD_DHCP | \
CFG_CMD_ASKENV | \
CFG_CMD_ELF | \
CFG_CMD_PING | \
CFG_CMD_MVENV \
)
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
#undef CONFIG_WATCHDOG /* watchdog disabled */
#define CONFIG_SYS_CLK_FREQ 30000000
#define CONFIG_SPD_EEPROM 1 /* use SPD EEPROM for setup */
/*
* Miscellaneous configurable options
*/
#define CFG_LONGHELP /* undef to save memory */
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
#else
#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
#endif
/* usually: (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) */
#define CFG_PBSIZE (CFG_CBSIZE+4+16) /* Print Buffer Size */
#define CFG_MAXARGS 16 /* max number of command args */
#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
#define CFG_ALT_MEMTEST 1
#define CFG_MEMTEST_START 0x00400000 /* memtest works on */
#define CFG_MEMTEST_END 0x01000000 /* 4 ... 16 MB in DRAM */
/*
* If CFG_EXT_SERIAL_CLOCK, then the UART divisor is 1.
* If CFG_405_UART_ERRATA_59, then UART divisor is 31.
* Otherwise, UART divisor is determined by CPU Clock and CFG_BASE_BAUD value.
* The Linux BASE_BAUD define should match this configuration.
* baseBaud = cpuClock/(uartDivisor*16)
* If CFG_405_UART_ERRATA_59 and 200MHz CPU clock,
* set Linux BASE_BAUD to 403200.
*/
#undef CFG_EXT_SERIAL_CLOCK /* external serial clock */
#undef CFG_405_UART_ERRATA_59 /* 405GP/CR Rev. D silicon */
#define CFG_NS16550_CLK 40000000
#define CFG_DUART_CHAN 0
#define CFG_NS16550_COM1 (0x4C000000 + 0x1000)
#define CFG_NS16550_COM2 (0x4C800000 + 0x1000)
#define CFG_NS16550_REG_SIZE 4
#define CFG_NS16550 1
#define CFG_INIT_CHAN1 1
#define CFG_INIT_CHAN2 0
/* The following table includes the supported baudrates */
#define CFG_BAUDRATE_TABLE \
{300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400}
#define CFG_LOAD_ADDR 0x00100000 /* default load address */
#define CFG_EXTBDINFO 1 /* To use extended board_into (bd_t) */
#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
/*-----------------------------------------------------------------------
* Start addresses for the final memory configuration
* (Set up by the startup code)
* Please note that CFG_SDRAM_BASE _must_ start at 0
*/
#define CFG_SDRAM_BASE 0x00000000
#define CFG_FLASH_BASE 0x20000000
#define CFG_MONITOR_BASE TEXT_BASE
#define CFG_MONITOR_LEN (192 * 1024) /* Reserve 196 kB for Monitor */
#define CFG_MALLOC_LEN (128 * 1024) /* Reserve 128 kB for malloc() */
/*
* For booting Linux, the board info and command line data
* have to be in the first 8 MB of memory, since this is
* the maximum mapped by the Linux kernel during initialization.
*/
#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
/*-----------------------------------------------------------------------
* FLASH organization
*/
#define CFG_FLASH_CFI 1
#define CFG_PROGFLASH_BASE CFG_FLASH_BASE
#define CFG_CONFFLASH_BASE 0x24000000
#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */
#define CFG_MAX_FLASH_SECT 256 /* max number of sectors on one chip */
#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
#define CFG_FLASH_PROTECTION 1 /* use hardware protection */
/* BEG ENVIRONNEMENT FLASH */
#ifdef CFG_ENV_IS_IN_FLASH
#define CFG_ENV_OFFSET 0x00040000 /* Offset of Environment Sector */
#define CFG_ENV_SIZE 0x1000 /* Total Size of Environment Sector */
#define CFG_ENV_SECT_SIZE 0x20000 /* see README - env sector total size */
#endif
/* END ENVIRONNEMENT FLASH */
/*-----------------------------------------------------------------------
* NVRAM organization
*/
#define CFG_NVRAM_BASE_ADDR 0xf0000000 /* NVRAM base address */
#define CFG_NVRAM_SIZE 0x1ff8 /* NVRAM size */
#ifdef CFG_ENV_IS_IN_NVRAM
#define CFG_ENV_SIZE 0x1000 /* Size of Environment vars */
#define CFG_ENV_ADDR \
(CFG_NVRAM_BASE_ADDR+CFG_NVRAM_SIZE-CFG_ENV_SIZE) /* Env */
#endif
/*-----------------------------------------------------------------------
* Cache Configuration
*/
#define CFG_DCACHE_SIZE 16384
#define CFG_CACHELINE_SIZE 32
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
#endif
/*
* Init Memory Controller:
*
* BR0/1 and OR0/1 (FLASH)
*/
#define FLASH_BASE0_PRELIM CFG_FLASH_BASE /* FLASH bank #0 */
#define FLASH_BASE1_PRELIM 0 /* FLASH bank #1 */
/* Configuration Port location */
#define CONFIG_PORT_ADDR 0xF0000500
/*-----------------------------------------------------------------------
* Definitions for initial stack pointer and data area (in DPRAM)
*/
#define CFG_INIT_RAM_ADDR 0x400000 /* inside of SDRAM */
#define CFG_INIT_RAM_END 0x2000 /* End of used area in RAM */
#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
/*-----------------------------------------------------------------------
* Definitions for Serial Presence Detect EEPROM address
* (to get SDRAM settings)
*/
#define SPD_EEPROM_ADDRESS 0x50
/*
* Internal Definitions
*
* Boot Flags
*/
#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
#define BOOTFLAG_WARM 0x02 /* Software reboot */
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#define CONFIG_KGDB_BAUDRATE 230400 /* speed to run kgdb serial port */
#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */
#endif
/* JFFS2 stuff */
#define CFG_JFFS2_FIRST_BANK 0
#define CFG_JFFS2_NUM_BANKS 1
#define CFG_JFFS2_FIRST_SECTOR 1
#define CONFIG_NET_MULTI
#define CONFIG_E1000
#define CFG_ETH_DEV_FN 0x0800
#define CFG_ETH_IOBASE 0x31000000
#define CFG_ETH_MEMBASE 0x32000000
#endif /* __CONFIG_H */

@ -125,7 +125,7 @@ int eth_initialize(bd_t *bis)
#ifdef CONFIG_DB64460
mv6446x_eth_initialize(bis);
#endif
#if defined(CONFIG_4xx) && !defined(CONFIG_IOP480)
#if defined(CONFIG_4xx) && !defined(CONFIG_IOP480) && !defined(CONFIG_AP1000)
ppc_4xx_eth_initialize(bis);
#endif
#ifdef CONFIG_INCA_IP_SWITCH

Loading…
Cancel
Save