9
0
Fork 0

Add support for AP1000 board.

Patch by James MacAulay, 07 Oct 2005
This commit is contained in:
Wolfgang Denk 2005-10-09 01:04:33 +02:00
parent 95f9dda216
commit 7521af1c7d
20 changed files with 3668 additions and 51 deletions

View File

@ -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

View File

@ -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

24
MAKEALL
View File

@ -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 \
"
#########################################################################

View File

@ -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

77
README
View File

@ -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:
-----------------

View File

@ -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
#########################################################################

View File

@ -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"
);

View File

@ -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_ */

View File

@ -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

853
board/amirix/ap1000/flash.c Normal file
View File

@ -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 */

View File

@ -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

346
board/amirix/ap1000/pci.c Normal file
View File

@ -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);
}

View File

@ -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;
}

View File

@ -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

View File

@ -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 */

View File

@ -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 = .);
}

View File

@ -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) {

View File

@ -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);

255
include/configs/AP1000.h Normal file
View File

@ -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 */

View File

@ -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