parent
95f9dda216
commit
7521af1c7d
@ -0,0 +1,47 @@ |
||||
#
|
||||
# (C) Copyright 2000
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk |
||||
|
||||
LIB = lib$(BOARD).a
|
||||
|
||||
OBJS = $(BOARD).o flash.o serial.o pci.o powerspan.o
|
||||
SOBJS = init.o
|
||||
|
||||
$(LIB): $(OBJS) $(SOBJS) |
||||
$(AR) crv $@ $^
|
||||
|
||||
clean: |
||||
rm -f $(SOBJS) $(OBJS)
|
||||
|
||||
distclean: clean |
||||
rm -f $(LIB) core *.bak .depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) |
||||
$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
|
||||
|
||||
sinclude .depend |
||||
|
||||
#########################################################################
|
@ -0,0 +1,672 @@ |
||||
/*
|
||||
* amirix.c: ppcboot platform support for AMIRIX board |
||||
* |
||||
* Copyright 2002 Mind NV |
||||
* Copyright 2003 AMIRIX Systems Inc. |
||||
* |
||||
* http://www.mind.be/
|
||||
* http://www.amirix.com/
|
||||
* |
||||
* Author : Peter De Schrijver (p2@mind.be) |
||||
* Frank Smith (smith@amirix.com) |
||||
* |
||||
* Derived from : Other platform support files in this tree, ml2 |
||||
* |
||||
* This software may be used and distributed according to the terms of |
||||
* the GNU General Public License (GPL) version 2, incorporated herein by |
||||
* reference. Drivers based on or derived from this code fall under the GPL |
||||
* and must retain the authorship, copyright and this license notice. This |
||||
* file is not a complete program and may only be used when the entire |
||||
* program is licensed under the GPL. |
||||
* |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <command.h> |
||||
#include <asm/processor.h> |
||||
|
||||
#include "powerspan.h" |
||||
#include "ap1000.h" |
||||
|
||||
int board_pre_init (void) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
/** serial number and platform display at startup */ |
||||
int checkboard (void) |
||||
{ |
||||
unsigned char *s = getenv ("serial#"); |
||||
unsigned char *e; |
||||
|
||||
/* After a loadace command, the SystemAce control register is left in a wonky state. */ |
||||
/* this code did not work in board_pre_init */ |
||||
unsigned char* p = (unsigned char*)AP1000_SYSACE_REGBASE; |
||||
p[SYSACE_CTRLREG0] = 0x0; |
||||
|
||||
/* add platform and device to banner */ |
||||
switch(get_device()){ |
||||
case AP1xx_AP107_TARGET:{ |
||||
puts(AP1xx_AP107_TARGET_STR); |
||||
break; |
||||
} |
||||
case AP1xx_AP120_TARGET:{ |
||||
puts(AP1xx_AP120_TARGET_STR); |
||||
break; |
||||
} |
||||
case AP1xx_AP130_TARGET:{ |
||||
puts(AP1xx_AP130_TARGET_STR); |
||||
break; |
||||
} |
||||
case AP1xx_AP1070_TARGET:{ |
||||
puts(AP1xx_AP1070_TARGET_STR); |
||||
break; |
||||
} |
||||
case AP1xx_AP1100_TARGET:{ |
||||
puts(AP1xx_AP1100_TARGET_STR); |
||||
break; |
||||
} |
||||
default:{ |
||||
puts(AP1xx_UNKNOWN_STR); |
||||
break; |
||||
} |
||||
} |
||||
puts(AP1xx_TARGET_STR); |
||||
puts(" with "); |
||||
|
||||
switch(get_platform()){ |
||||
case AP100_BASELINE_PLATFORM: |
||||
case AP1000_BASELINE_PLATFORM:{ |
||||
puts(AP1xx_BASELINE_PLATFORM_STR); |
||||
break; |
||||
} |
||||
case AP1xx_QUADGE_PLATFORM:{ |
||||
puts(AP1xx_QUADGE_PLATFORM_STR); |
||||
break; |
||||
} |
||||
case AP1xx_MGT_REF_PLATFORM:{ |
||||
puts(AP1xx_MGT_REF_PLATFORM_STR); |
||||
break; |
||||
} |
||||
case AP1xx_STANDARD_PLATFORM:{ |
||||
puts(AP1xx_STANDARD_PLATFORM_STR); |
||||
break; |
||||
} |
||||
case AP1xx_DUAL_PLATFORM:{ |
||||
puts(AP1xx_DUAL_PLATFORM_STR); |
||||
break; |
||||
} |
||||
case AP1xx_BASE_SRAM_PLATFORM:{ |
||||
puts(AP1xx_BASE_SRAM_PLATFORM_STR); |
||||
break; |
||||
} |
||||
case AP1xx_PCI_PCB_TESTPLATFORM: |
||||
case AP1000_PCI_PCB_TESTPLATFORM:{ |
||||
puts(AP1xx_PCI_PCB_TESTPLATFORM_STR); |
||||
break; |
||||
} |
||||
case AP1xx_DUAL_GE_MEZZ_TESTPLATFORM:{ |
||||
puts(AP1xx_DUAL_GE_MEZZ_TESTPLATFORM_STR); |
||||
break; |
||||
} |
||||
case AP1xx_SFP_MEZZ_TESTPLATFORM:{ |
||||
puts(AP1xx_SFP_MEZZ_TESTPLATFORM_STR); |
||||
break; |
||||
} |
||||
default:{ |
||||
puts(AP1xx_UNKNOWN_STR); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if((get_platform() & AP1xx_TESTPLATFORM_MASK) != 0){ |
||||
puts(AP1xx_TESTPLATFORM_STR); |
||||
} |
||||
else{ |
||||
puts(AP1xx_PLATFORM_STR); |
||||
} |
||||
|
||||
putc('\n'); |
||||
|
||||
puts ("Serial#: "); |
||||
|
||||
if (!s) { |
||||
printf ("### No HW ID - assuming AMIRIX"); |
||||
} else { |
||||
for (e = s; *e; ++e) { |
||||
if (*e == ' ') |
||||
break; |
||||
} |
||||
|
||||
for (; s < e; ++s) { |
||||
putc (*s); |
||||
} |
||||
} |
||||
|
||||
putc ('\n'); |
||||
|
||||
return (0); |
||||
} |
||||
|
||||
|
||||
long int initdram (int board_type) |
||||
{ |
||||
unsigned char *s = getenv ("dramsize"); |
||||
|
||||
if(s != NULL){ |
||||
if((s[0] == '0') && ((s[1] == 'x') || (s[1] == 'X'))){ |
||||
s += 2; |
||||
} |
||||
return simple_strtoul(s, NULL, 16); |
||||
} |
||||
else{ |
||||
/* give all 64 MB */ |
||||
return 64 * 1024 * 1024; |
||||
} |
||||
} |
||||
|
||||
unsigned int get_platform(void){ |
||||
unsigned int *revision_reg_ptr = (unsigned int *)AP1xx_FPGA_REV_ADDR; |
||||
return (*revision_reg_ptr & AP1xx_PLATFORM_MASK); |
||||
} |
||||
|
||||
unsigned int get_device(void){ |
||||
unsigned int *revision_reg_ptr = (unsigned int *)AP1xx_FPGA_REV_ADDR; |
||||
|
||||
return (*revision_reg_ptr & AP1xx_TARGET_MASK); |
||||
} |
||||
|
||||
#if 0 // loadace is not working; it appears to be a hardware issue with the system ace.
|
||||
/*
|
||||
This function loads FPGA configurations from the SystemACE CompactFlash |
||||
*/ |
||||
int do_loadace (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
||||
{ |
||||
unsigned char *p = (unsigned char *)AP1000_SYSACE_REGBASE; |
||||
int cfg; |
||||
|
||||
if((p[SYSACE_STATREG0] & 0x10) == 0) { |
||||
p[SYSACE_CTRLREG0] = 0x80; |
||||
printf ("\nNo CompactFlash Detected\n\n"); |
||||
p[SYSACE_CTRLREG0] = 0x00; |
||||
return 1; |
||||
} |
||||
|
||||
// reset configuration controller: | 0x80
|
||||
// select cpflash & ~0x40
|
||||
// cfg start | 0x20
|
||||
// wait for cfgstart & ~0x10
|
||||
// force cfgmode: | 0x08
|
||||
// do no force cfgaddr: & ~0x04
|
||||
// clear mpulock: & ~0x02
|
||||
// do not force lock request & ~0x01
|
||||
|
||||
p[SYSACE_CTRLREG0] = 0x80 | 0x20 | 0x08; |
||||
p[SYSACE_CTRLREG1] = 0x00; |
||||
|
||||
// force config address if arg2 exists
|
||||
if (argc == 2) { |
||||
cfg = simple_strtoul(argv[1], NULL, 10); |
||||
|
||||
if(cfg > 7) { |
||||
printf ("\nInvalid Configuration\n\n"); |
||||
p[SYSACE_CTRLREG0] = 0x00; |
||||
return 1; |
||||
} |
||||
// Set config address
|
||||
p[SYSACE_CTRLREG1] = (cfg << 5); |
||||
// force cfgaddr
|
||||
p[SYSACE_CTRLREG0] |= 0x04; |
||||
|
||||
} else { |
||||
cfg = (p[SYSACE_STATREG1] & 0xE0) >> 5; |
||||
} |
||||
|
||||
/* release configuration controller */ |
||||
printf("\nLoading V2PRO with config %d...\n", cfg); |
||||
p[SYSACE_CTRLREG0] &= ~0x80; |
||||
|
||||
|
||||
while((p[SYSACE_STATREG1] & 0x01) == 0) { |
||||
|
||||
if(p[SYSACE_ERRREG0] & 0x80) { |
||||
// attempting to load an invalid configuration makes the cpflash
|
||||
// appear to be removed. Reset here to avoid that problem
|
||||
p[SYSACE_CTRLREG0] = 0x80; |
||||
printf("\nConfiguration %d Read Error\n\n", cfg); |
||||
p[SYSACE_CTRLREG0] = 0x00; |
||||
return 1; |
||||
} |
||||
} |
||||
|
||||
p[SYSACE_CTRLREG0] |= 0x20; |
||||
|
||||
return 0; |
||||
} |
||||
#endif |
||||
|
||||
/** Console command to display and set the software reconfigure byte
|
||||
* <pre> |
||||
* swconfig - display the current value of the software reconfigure byte |
||||
* swconfig [#] - change the software reconfigure byte to # |
||||
* </pre> |
||||
* @param *cmdtp [IN] as passed by run_command (ignored) |
||||
* @param flag [IN] as passed by run_command (ignored) |
||||
* @param argc [IN] as passed by run_command if 1, display, if 2 change |
||||
* @param *argv[] [IN] contains the parameters to use |
||||
* @return |
||||
* <pre> |
||||
* 0 if passed |
||||
* -1 if failed |
||||
* </pre> |
||||
*/ |
||||
int do_swconfigbyte(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ |
||||
unsigned char *sector_buffer = NULL; |
||||
unsigned char input_char; |
||||
int write_result; |
||||
unsigned int input_uint; |
||||
|
||||
/* display value if no argument */ |
||||
if(argc < 2){ |
||||
printf("Software configuration byte is currently: 0x%02x\n", |
||||
*((unsigned char *) (SW_BYTE_SECTOR_ADDR + SW_BYTE_SECTOR_OFFSET))); |
||||
return 0; |
||||
} |
||||
else if(argc > 3){ |
||||
printf("Too many arguments\n"); |
||||
return -1; |
||||
} |
||||
|
||||
/* if 3 arguments, 3rd argument is the address to use */ |
||||
if(argc == 3){ |
||||
input_uint = simple_strtoul(argv[1], NULL, 16); |
||||
sector_buffer = (unsigned char *)input_uint; |
||||
} |
||||
else{ |
||||
sector_buffer = (unsigned char *)DEFAULT_TEMP_ADDR; |
||||
} |
||||
|
||||
input_char = simple_strtoul(argv[1], NULL, 0); |
||||
if((input_char & ~SW_BYTE_MASK) != 0){ |
||||
printf("Input of 0x%02x will be masked to 0x%02x\n", |
||||
input_char, (input_char & SW_BYTE_MASK)); |
||||
input_char = input_char & SW_BYTE_MASK; |
||||
} |
||||
|
||||
memcpy(sector_buffer, (void *)SW_BYTE_SECTOR_ADDR, SW_BYTE_SECTOR_SIZE); |
||||
sector_buffer[SW_BYTE_SECTOR_OFFSET] = input_char; |
||||
|
||||
|
||||
printf("Erasing Flash..."); |
||||
if (flash_sect_erase (SW_BYTE_SECTOR_ADDR, (SW_BYTE_SECTOR_ADDR + SW_BYTE_SECTOR_OFFSET))){ |
||||
return -1; |
||||
} |
||||
|
||||
printf("Writing to Flash... "); |
||||
write_result = flash_write(sector_buffer, SW_BYTE_SECTOR_ADDR, SW_BYTE_SECTOR_SIZE); |
||||
if (write_result != 0) { |
||||
flash_perror (write_result); |
||||
return -1; |
||||
} |
||||
else{ |
||||
printf("done\n"); |
||||
printf("Software configuration byte is now: 0x%02x\n", |
||||
*((unsigned char *) (SW_BYTE_SECTOR_ADDR + SW_BYTE_SECTOR_OFFSET))); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
#define ONE_SECOND 1000000 |
||||
|
||||
int do_pause(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ |
||||
int pause_time; |
||||
unsigned int delay_time; |
||||
int break_loop = 0; |
||||
|
||||
/* display value if no argument */ |
||||
if(argc < 2){ |
||||
pause_time = 1; |
||||
} |
||||
|
||||
else if(argc > 2){ |
||||
printf("Too many arguments\n"); |
||||
return -1; |
||||
} |
||||
else{ |
||||
pause_time = simple_strtoul(argv[1], NULL, 0); |
||||
} |
||||
|
||||
printf("Pausing with a poll time of %d, press any key to reactivate\n", pause_time); |
||||
delay_time = pause_time * ONE_SECOND; |
||||
while(break_loop == 0){ |
||||
udelay(delay_time); |
||||
if(serial_tstc() != 0){ |
||||
break_loop = 1; |
||||
/* eat user key presses */ |
||||
while(serial_tstc() != 0){ |
||||
serial_getc(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int do_swreconfig(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ |
||||
printf("Triggering software reconfigure (software config byte is 0x%02x)...\n", |
||||
*((unsigned char *) (SW_BYTE_SECTOR_ADDR + SW_BYTE_SECTOR_OFFSET))); |
||||
udelay (1000); |
||||
*((unsigned char*)AP1000_CPLD_BASE) = 1; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
#define GET_DECIMAL(low_byte) ((low_byte >> 5) * 125) |
||||
#define TEMP_BUSY_BIT 0x80 |
||||
#define TEMP_LHIGH_BIT 0x40 |
||||
#define TEMP_LLOW_BIT 0x20 |
||||
#define TEMP_EHIGH_BIT 0x10 |
||||
#define TEMP_ELOW_BIT 0x08 |
||||
#define TEMP_OPEN_BIT 0x04 |
||||
#define TEMP_ETHERM_BIT 0x02 |
||||
#define TEMP_LTHERM_BIT 0x01 |
||||
|
||||
int do_temp_sensor(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ |
||||
char cmd; |
||||
int ret_val = 0; |
||||
unsigned char temp_byte; |
||||
int temp; |
||||
int temp_low; |
||||
int low; |
||||
int low_low; |
||||
int high; |
||||
int high_low; |
||||
int therm; |
||||
unsigned char user_data[4] = { 0 }; |
||||
int user_data_count = 0; |
||||
int ii; |
||||
|
||||
if(argc > 1){ |
||||
cmd = argv[1][0]; |
||||
} |
||||
else{ |
||||
cmd = 's'; /* default to status */ |
||||
} |
||||
|
||||
user_data_count = argc - 2; |
||||
for(ii = 0;ii < user_data_count;ii++){ |
||||
user_data[ii] = simple_strtoul(argv[2 + ii], NULL, 0); |
||||
} |
||||
switch (cmd){ |
||||
case 's':{ |
||||
|
||||
if(I2CAccess(0x2, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){ |
||||
goto fail; |
||||
} |
||||
printf("Status : 0x%02x ", temp_byte); |
||||
if(temp_byte & TEMP_BUSY_BIT){ |
||||
printf("BUSY "); |
||||
} |
||||
|
||||
if(temp_byte & TEMP_LHIGH_BIT){ |
||||
printf("LHIGH "); |
||||
} |
||||
|
||||
if(temp_byte & TEMP_LLOW_BIT){ |
||||
printf("LLOW "); |
||||
} |
||||
|
||||
if(temp_byte & TEMP_EHIGH_BIT){ |
||||
printf("EHIGH "); |
||||
} |
||||
|
||||
if(temp_byte & TEMP_ELOW_BIT){ |
||||
printf("ELOW "); |
||||
} |
||||
|
||||
if(temp_byte & TEMP_OPEN_BIT){ |
||||
printf("OPEN "); |
||||
} |
||||
|
||||
if(temp_byte & TEMP_ETHERM_BIT){ |
||||
printf("ETHERM "); |
||||
} |
||||
|
||||
if(temp_byte & TEMP_LTHERM_BIT){ |
||||
printf("LTHERM"); |
||||
} |
||||
printf("\n"); |
||||
|
||||
if(I2CAccess(0x3, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){ |
||||
goto fail; |
||||
} |
||||
printf("Config : 0x%02x ", temp_byte); |
||||
|
||||
if(I2CAccess(0x4, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){ |
||||
printf("\n"); |
||||
goto fail; |
||||
} |
||||
printf("Conversion: 0x%02x\n", temp_byte); |
||||
if(I2CAccess(0x22, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){ |
||||
goto fail; |
||||
} |
||||
printf("Cons Alert: 0x%02x ", temp_byte); |
||||
|
||||
if(I2CAccess(0x21, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){ |
||||
printf("\n"); |
||||
goto fail; |
||||
} |
||||
printf("Therm Hyst: %d\n", temp_byte); |
||||
|
||||
if(I2CAccess(0x0, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){ |
||||
goto fail; |
||||
} |
||||
temp = temp_byte; |
||||
if(I2CAccess(0x6, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){ |
||||
goto fail; |
||||
} |
||||
low = temp_byte; |
||||
if(I2CAccess(0x5, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){ |
||||
goto fail; |
||||
} |
||||
high = temp_byte; |
||||
if(I2CAccess(0x20, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){ |
||||
goto fail; |
||||
} |
||||
therm = temp_byte; |
||||
printf("Local Temp: %2d Low: %2d High: %2d THERM: %2d\n", temp, low, high, therm); |
||||
|
||||
if(I2CAccess(0x1, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){ |
||||
goto fail; |
||||
} |
||||
temp = temp_byte; |
||||
if(I2CAccess(0x10, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){ |
||||
goto fail; |
||||
} |
||||
temp_low = temp_byte; |
||||
if(I2CAccess(0x8, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){ |
||||
goto fail; |
||||
} |
||||
low = temp_byte; |
||||
if(I2CAccess(0x14, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){ |
||||
goto fail; |
||||
} |
||||
low_low = temp_byte; |
||||
if(I2CAccess(0x7, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){ |
||||
goto fail; |
||||
} |
||||
high = temp_byte; |
||||
if(I2CAccess(0x13, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){ |
||||
goto fail; |
||||
} |
||||
high_low = temp_byte; |
||||
if(I2CAccess(0x19, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){ |
||||
goto fail; |
||||
} |
||||
therm = temp_byte; |
||||
if(I2CAccess(0x11, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){ |
||||
goto fail; |
||||
} |
||||
printf("Ext Temp : %2d.%03d Low: %2d.%03d High: %2d.%03d THERM: %2d Offset: %2d\n", temp, GET_DECIMAL(temp_low), low, GET_DECIMAL(low_low), high, GET_DECIMAL(high_low), therm, temp_byte); |
||||
break; |
||||
} |
||||
case 'l':{ /* alter local limits : low, high, therm */ |
||||
if(argc < 3){ |
||||
goto usage; |
||||
} |
||||
|
||||
/* low */ |
||||
if(I2CAccess(0xC, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[0], I2C_WRITE) != 0){ |
||||
goto fail; |
||||
} |
||||
|
||||
if(user_data_count > 1){ |
||||
/* high */ |
||||
if(I2CAccess(0xB, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[1], I2C_WRITE) != 0){ |
||||
goto fail; |
||||
} |
||||
} |
||||
|
||||
if(user_data_count > 2){ |
||||
/* therm */ |
||||
if(I2CAccess(0x20, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[2], I2C_WRITE) != 0){ |
||||
goto fail; |
||||
} |
||||
} |
||||
break; |
||||
} |
||||
case 'e':{ /* alter external limits: low, high, therm, offset */ |
||||
if(argc < 3){ |
||||
goto usage; |
||||
} |
||||
|
||||
/* low */ |
||||
if(I2CAccess(0xE, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[0], I2C_WRITE) != 0){ |
||||
goto fail; |
||||
} |
||||
|
||||
if(user_data_count > 1){ |
||||
/* high */ |
||||
if(I2CAccess(0xD, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[1], I2C_WRITE) != 0){ |
||||
goto fail; |
||||
} |
||||
} |
||||
|
||||
if(user_data_count > 2){ |
||||
/* therm */ |
||||
if(I2CAccess(0x19, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[2], I2C_WRITE) != 0){ |
||||
goto fail; |
||||
} |
||||
} |
||||
|
||||
if(user_data_count > 3){ |
||||
/* offset */ |
||||
if(I2CAccess(0x11, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[3], I2C_WRITE) != 0){ |
||||
goto fail; |
||||
} |
||||
} |
||||
break; |
||||
} |
||||
case 'c':{ /* alter config settings: config, conv, cons alert, therm hyst */ |
||||
if(argc < 3){ |
||||
goto usage; |
||||
} |
||||
|
||||
/* config */ |
||||
if(I2CAccess(0x9, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[0], I2C_WRITE) != 0){ |
||||
goto fail; |
||||
} |
||||
|
||||
if(user_data_count > 1){ |
||||
/* conversion */ |
||||
if(I2CAccess(0xA, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[1], I2C_WRITE) != 0){ |
||||
goto fail; |
||||
} |
||||
} |
||||
|
||||
if(user_data_count > 2){ |
||||
/* cons alert */ |
||||
if(I2CAccess(0x22, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[2], I2C_WRITE) != 0){ |
||||
goto fail; |
||||
} |
||||
} |
||||
|
||||
if(user_data_count > 3){ |
||||
/* therm hyst */ |
||||
if(I2CAccess(0x21, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[3], I2C_WRITE) != 0){ |
||||
goto fail; |
||||
} |
||||
} |
||||
break; |
||||
} |
||||
default:{ |
||||
goto usage; |
||||
} |
||||
} |
||||
|
||||
goto done; |
||||
fail: |
||||
printf("Access to sensor failed\n"); |
||||
ret_val = -1; |
||||
goto done; |
||||
usage: |
||||
printf ("Usage:\n%s\n", cmdtp->help); |
||||
|
||||
done: |
||||
return ret_val; |
||||
} |
||||
|
||||
U_BOOT_CMD( |
||||
temp, 6, 0, do_temp_sensor, |
||||
"temp - interact with the temperature sensor\n", |
||||
"temp [s]\n" |
||||
" - Show status.\n" |
||||
"temp l LOW [HIGH] [THERM]\n" |
||||
" - Set local limits.\n" |
||||
"temp e LOW [HIGH] [THERM] [OFFSET]\n" |
||||
" - Set external limits.\n" |
||||
"temp c CONFIG [CONVERSION] [CONS. ALERT] [THERM HYST]\n" |
||||
" - Set config options.\n" |
||||
"\n" |
||||
"All values can be decimal or hex (hex preceded with 0x).\n" |
||||
"Only whole numbers are supported for external limits.\n" |
||||
); |
||||
|
||||
#if 0 |
||||
U_BOOT_CMD( |
||||
loadace, 2, 0, do_loadace, |
||||
"loadace - load fpga configuration from System ACE compact flash\n", |
||||
"N\n" |
||||
" - Load configuration N (0-7) from System ACE compact flash\n" |
||||
"loadace\n" |
||||
" - loads default configuration\n" |
||||
); |
||||
#endif |
||||
|
||||
U_BOOT_CMD( |
||||
swconfig, 2, 0, do_swconfigbyte, |
||||
"swconfig- display or modify the software configuration byte\n", |
||||
"N [ADDRESS]\n" |
||||
" - set software configuration byte to N, optionally use ADDRESS as\n" |
||||
" location of buffer for flash copy\n" |
||||
"swconfig\n" |
||||
" - display software configuration byte\n" |
||||
); |
||||
|
||||
U_BOOT_CMD( |
||||
pause, 2, 0, do_pause, |
||||
"pause - sleep processor until any key is pressed with poll time of N seconds\n", |
||||
"N\n" |
||||
" - sleep processor until any key is pressed with poll time of N seconds\n" |
||||
"pause\n" |
||||
" - sleep processor until any key is pressed with poll time of 1 second\n" |
||||
); |
||||
|
||||
U_BOOT_CMD( |
||||
swrecon, 1, 0, do_swreconfig, |
||||
"swrecon - trigger a board reconfigure to the software selected configuration\n", |
||||
"\n" |
||||
" - trigger a board reconfigure to the software selected configuration\n" |
||||
); |
||||
|
@ -0,0 +1,173 @@ |
||||
/*
|
||||
* ap1000.h: AP1000 (e.g. AP1070, AP1100) board specific definitions and functions that are needed globally |
||||
* |
||||
* Author : James MacAulay |
||||
* |
||||
* This software may be used and distributed according to the terms of |
||||
* the GNU General Public License (GPL) version 2, incorporated herein by |
||||
* reference. Drivers based on or derived from this code fall under the GPL |
||||
* and must retain the authorship, copyright and this license notice. This |
||||
* file is not a complete program and may only be used when the entire |
||||
* program is licensed under the GPL. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef __AP1000_H |
||||
#define __AP1000_H |
||||
|
||||
/*
|
||||
* Revision Register stuff |
||||
*/ |
||||
#define AP1xx_FPGA_REV_ADDR 0x29000000 |
||||
|
||||
#define AP1xx_PLATFORM_MASK 0xFF000000 |
||||
#define AP100_BASELINE_PLATFORM 0x01000000 |
||||
#define AP1xx_QUADGE_PLATFORM 0x02000000 |
||||
#define AP1xx_MGT_REF_PLATFORM 0x03000000 |
||||
#define AP1xx_STANDARD_PLATFORM 0x04000000 |
||||
#define AP1xx_DUAL_PLATFORM 0x05000000 |
||||
#define AP1xx_BASE_SRAM_PLATFORM 0x06000000 |
||||
|
||||
#define AP1000_BASELINE_PLATFORM 0x21000000 |
||||
|
||||
#define AP1xx_TESTPLATFORM_MASK 0xC0000000 |
||||
#define AP1xx_PCI_PCB_TESTPLATFORM 0xC0000000 |
||||
#define AP1xx_DUAL_GE_MEZZ_TESTPLATFORM 0xC1000000 |
||||
#define AP1xx_SFP_MEZZ_TESTPLATFORM 0xC2000000 |
||||
|
||||
#define AP1000_PCI_PCB_TESTPLATFORM 0xC3000000 |
||||
|
||||
#define AP1xx_TARGET_MASK 0x00FF0000 |
||||
#define AP1xx_AP107_TARGET 0x00010000 |
||||
#define AP1xx_AP120_TARGET 0x00020000 |
||||
#define AP1xx_AP130_TARGET 0x00030000 |
||||
#define AP1xx_AP1070_TARGET 0x00040000 |
||||
#define AP1xx_AP1100_TARGET 0x00050000 |
||||
|
||||
#define AP1xx_UNKNOWN_STR "Unknown" |
||||
|
||||
#define AP1xx_PLATFORM_STR " Platform" |
||||
#define AP1xx_BASELINE_PLATFORM_STR "Baseline" |
||||
#define AP1xx_QUADGE_PLATFORM_STR "Quad GE" |
||||
#define AP1xx_MGT_REF_PLATFORM_STR "MGT Reference" |
||||
#define AP1xx_STANDARD_PLATFORM_STR "Standard" |
||||
#define AP1xx_DUAL_PLATFORM_STR "Dual" |
||||
#define AP1xx_BASE_SRAM_PLATFORM_STR "Baseline with SRAM" |
||||
|
||||
#define AP1xx_TESTPLATFORM_STR " Test Platform" |
||||
#define AP1xx_PCI_PCB_TESTPLATFORM_STR "Base" |
||||
#define AP1xx_DUAL_GE_MEZZ_TESTPLATFORM_STR "Dual GE Mezzanine" |
||||
#define AP1xx_SFP_MEZZ_TESTPLATFORM_STR "SFP Mezzanine" |
||||
|
||||
#define AP1xx_TARGET_STR " Board" |
||||
#define AP1xx_AP107_TARGET_STR "AP107" |
||||
#define AP1xx_AP120_TARGET_STR "AP120" |
||||
#define AP1xx_AP130_TARGET_STR "AP130" |
||||
|
||||
#define AP1xx_AP1070_TARGET_STR "AP1070" |
||||
#define AP1xx_AP1100_TARGET_STR "AP1100" |
||||
|
||||
/*
|
||||
* Flash Stuff |
||||
*/ |
||||
#define AP1xx_PROGRAM_FLASH_INDEX 0 |
||||
#define AP1xx_CONFIG_FLASH_INDEX 1 |
||||
|
||||
/*
|
||||
* System Ace Stuff |
||||
*/ |
||||
#define AP1000_SYSACE_REGBASE 0x28000000 |
||||
|
||||
#define SYSACE_STATREG0 0x04 // 7:0
|
||||
#define SYSACE_STATREG1 0x05 // 15:8
|
||||
#define SYSACE_STATREG2 0x06 // 23:16
|
||||
#define SYSACE_STATREG3 0x07 // 31:24
|
||||
|
||||
#define SYSACE_ERRREG0 0x08 // 7:0
|
||||
#define SYSACE_ERRREG1 0x09 // 15:8
|
||||
#define SYSACE_ERRREG2 0x0a // 23:16
|
||||
#define SYSACE_ERRREG3 0x0b // 31:24
|
||||
|
||||
#define SYSACE_CTRLREG0 0x18 // 7:0
|
||||
#define SYSACE_CTRLREG1 0x19 // 15:8
|
||||
#define SYSACE_CTRLREG2 0x1A // 23:16
|
||||
#define SYSACE_CTRLREG3 0x1B // 31:24
|
||||
|
||||
/*
|
||||
* Software reconfig thing |
||||
*/ |
||||
#define SW_BYTE_SECTOR_ADDR 0x24FE0000 |
||||
#define SW_BYTE_SECTOR_OFFSET 0x0001FFFF |
||||
#define SW_BYTE_SECTOR_SIZE 0x00020000 |
||||
#define SW_BYTE_MASK 0x00000003 |
||||
|
||||
#define DEFAULT_TEMP_ADDR 0x00100000 |
||||
|
||||
#define AP1000_CPLD_BASE 0x26000000 |
||||
|
||||
/* PowerSpan II Stuff */ |
||||
#define PSII_SYNC() asm("eieio") |
||||
#define PSPAN_BASEADDR 0x30000000 |
||||
#define EEPROM_DEFAULT { 0x01, /* Byte 0 - Long Load = 0x02, short = 01, use 0xff for try no load */ \ |
||||
0x0,0x0,0x0, /* Bytes 1 - 3 Power span reserved */ \
|
||||
0x0, /* Byte 4 - Powerspan reserved - start of short load */ \
|
||||
0x0F, /* Byte 5 - Enable PCI 1 & 2 as Bus masters and Memory targets. */ \
|
||||
0x0E, /* Byte 6 - PCI 1 Target image prefetch - on for image 0,1,2, off for i20 & 3. */ \
|
||||
0x00, 0x00, /* Byte 7,8 - PCI-1 Subsystem ID - */ \
|
||||
0x00, 0x00, /* Byte 9,10 - PCI-1 Subsystem Vendor Id - */ \
|
||||
0x00, /* Byte 11 - No PCI interrupt generation on PCI-1 PCI-2 int A */ \
|
||||
0x1F, /* Byte 12 - PCI-1 enable bridge registers, all target images */ \
|
||||
0xBA, /* Byte 13 - Target 0 image 128 Meg(Ram), Target 1 image 64 Meg. (config Flash/CPLD )*/ \
|
||||
0xA0, /* Byte 14 - Target 2 image 64 Meg(program Flash), target 3 64k. */ \
|
||||
0x00, /* Byte 15 - Vital Product Data Disabled. */ \
|
||||
0x88, /* Byte 16 - PCI arbiter config complete, all requests routed through PCI-1, Unlock PCI-1 */ \
|
||||
0x40, /* Byte 17 - Interrupt direction control - PCI-1 Int A out, everything else in. */ \
|
||||
0x00, /* Byte 18 - I2O disabled */ \
|
||||
0x00, /* Byte 19 - PCI-2 Target image prefetch - off for all images. */ \
|
||||
0x00,0x00, /* Bytes 20,21 - PCI 2 Subsystem Id */ \
|
||||
0x00,0x00, /* Bytes 22,23 - PCI 2 Subsystem Vendor id */ \
|
||||
0x0C, /* Byte 24 - PCI-2 BAR enables, target image 0, & 1 */ \
|
||||
0xBB, /* Byte 25 - PCI-2 target 0 - 128 Meg(Ram), target 1 - 128 Meg (program/config flash) */ \
|
||||
0x00, /* Byte 26 - PCI-2 target 2 & 3 unused. */ \
|
||||
0x00,0x00,0x00,0x00,0x00, /* Bytes 27,28,29,30, 31 - Reserved */ \
|
||||
/* Long Load Information */ \
|
||||
0x82,0x60, /* Bytes 32,33 - PCI-1 Device ID - Powerspan II */ \
|
||||
0x10,0xE3, /* Bytes 24,35 - PCI-1 Vendor ID - Tundra */ \
|
||||
0x06, /* Byte 36 - PCI-1 Class Base - Bridge device. */ \
|
||||
0x80, /* Byte 37 - PCI-1 Class sub class - Other bridge. */ \
|
||||
0x00, /* Byte 38 - PCI-1 Class programing interface - Other bridge */ \
|
||||
0x01, /* Byte 39 - Power span revision 1. */ \
|
||||
0x6E, /* Byte 40 - PB SI0 enabled, translation enabled, decode enabled, 64 Meg */ \
|
||||
0x40, /* Byte 41 - PB SI0 memory command mode, PCI-1 dest */ \
|
||||
0x22, /* Byte 42 - Prefetch discard after read, PCI-little endian conversion, 32 byte prefetch */ \
|
||||
0x00,0x00, /* Bytes 43, 44 - Translation address for SI0, set to zero for now. */ \
|
||||
0x0E, /* Byte 45 - Translation address (0) and PB bus master enables - all. */ \
|
||||
0x2c,00,00, /* Bytes 46,47,48 - PB SI0 processor base address - 0x2C000000 */ \
|
||||
0x30,00,00, /* Bytes 49,50,51 - PB Address for Powerspan registers - 0x30000000, big Endian */ \
|
||||
0x82,0x60, /* Bytes 52, 53 - PCI-2 Device ID - Powerspan II */ \
|
||||
0x10,0xE3, /* Bytes 54,55 - PCI 2 Vendor Id - Tundra */ \
|
||||
0x06, /* Byte 56 - PCI-2 Class Base - Bridge device */ \
|
||||
0x80, /* Byte 57 - PCI-2 Class sub class - Other Bridge. */ \
|
||||
0x00, /* Byte 58 - PCI-2 class programming interface - Other bridge */ \
|
||||
0x01, /* Byte 59 - PCI-2 class revision 1 */ \
|
||||
0x00,0x00,0x00,0x00 }; /* Bytes 60,61, 62, 63 - Powerspan reserved */ |
||||
|
||||
|
||||
#define EEPROM_LENGTH 64 /* Long Load */ |
||||
|
||||
#define I2C_SENSOR_DEV 0x9 |
||||
#define I2C_SENSOR_CHIP_SEL 0x4 |
||||
|
||||
/*
|
||||
* Board Functions |
||||
*/ |
||||
void set_eat_machine_checks(int a_flag); |
||||
int get_eat_machine_checks(void); |
||||
unsigned int get_platform(void); |
||||
unsigned int get_device(void); |
||||
void* memcpyb(void * dest,const void *src,size_t count); |
||||
int process_bootflag(ulong bootflag); |
||||
void user_led_on(void); |
||||
void user_led_off(void); |
||||
|
||||
#endif /* __COMMON_H_ */ |
@ -0,0 +1,27 @@ |
||||
#
|
||||
# (C) Copyright 2000
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
# Start at bottom of RAM, but at an aliased address so that it looks
|
||||
# like it's not in RAM. This is a bit of voodoo to allow it to be
|
||||
# run from RAM instead of Flash.
|
||||
TEXT_BASE = 0x08000000
|
@ -0,0 +1,853 @@ |
||||
/**
|
||||
* @file flash.c |
||||
*/ |
||||
|
||||
/*
|
||||
* (C) Copyright 2003 |
||||
* AMIRIX Systems Inc. |
||||
* |
||||
* Originated from ppcboot-2.0.0/board/esd/cpci440/strataflash.c |
||||
* |
||||
* (C) Copyright 2002 |
||||
* Brad Kemp, Seranoa Networks, Brad.Kemp@seranoa.com |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/processor.h> |
||||
|
||||
#undef DEBUG_FLASH |
||||
/*
|
||||
* This file implements a Common Flash Interface (CFI) driver for ppcboot. |
||||
* The width of the port and the width of the chips are determined at initialization. |
||||
* These widths are used to calculate the address for access CFI data structures. |
||||
* It has been tested on an Intel Strataflash implementation. |
||||
* |
||||
* References |
||||
* JEDEC Standard JESD68 - Common Flash Interface (CFI) |
||||
* JEDEC Standard JEP137-A Common Flash Interface (CFI) ID Codes |
||||
* Intel Application Note 646 Common Flash Interface (CFI) and Command Sets |
||||
* Intel 290667-008 3 Volt Intel StrataFlash Memory datasheet |
||||
* |
||||
* TODO |
||||
* Use Primary Extended Query table (PRI) and Alternate Algorithm Query Table (ALT) to determine if protection is available |
||||
* Add support for other command sets Use the PRI and ALT to determine command set |
||||
* Verify erase and program timeouts. |
||||
*/ |
||||
|
||||
#define FLASH_CMD_CFI 0x98 |
||||
#define FLASH_CMD_READ_ID 0x90 |
||||
#define FLASH_CMD_RESET 0xff |
||||
#define FLASH_CMD_BLOCK_ERASE 0x20 |
||||
#define FLASH_CMD_ERASE_CONFIRM 0xD0 |
||||
#define FLASH_CMD_WRITE 0x40 |
||||
#define FLASH_CMD_PROTECT 0x60 |
||||
#define FLASH_CMD_PROTECT_SET 0x01 |
||||
#define FLASH_CMD_PROTECT_CLEAR 0xD0 |
||||
#define FLASH_CMD_CLEAR_STATUS 0x50 |
||||
#define FLASH_CMD_WRITE_TO_BUFFER 0xE8 |
||||
#define FLASH_CMD_WRITE_BUFFER_CONFIRM 0xD0 |
||||
|
||||
#define FLASH_STATUS_DONE 0x80 |
||||
#define FLASH_STATUS_ESS 0x40 |
||||
#define FLASH_STATUS_ECLBS 0x20 |
||||
#define FLASH_STATUS_PSLBS 0x10 |
||||
#define FLASH_STATUS_VPENS 0x08 |
||||
#define FLASH_STATUS_PSS 0x04 |
||||
#define FLASH_STATUS_DPS 0x02 |
||||
#define FLASH_STATUS_R 0x01 |
||||
#define FLASH_STATUS_PROTECT 0x01 |
||||
|
||||
#define FLASH_OFFSET_CFI 0x55 |
||||
#define FLASH_OFFSET_CFI_RESP 0x10 |
||||
#define FLASH_OFFSET_WTOUT 0x1F |
||||
#define FLASH_OFFSET_WBTOUT 0x20 |
||||
#define FLASH_OFFSET_ETOUT 0x21 |
||||
#define FLASH_OFFSET_CETOUT 0x22 |
||||
#define FLASH_OFFSET_WMAX_TOUT 0x23 |
||||
#define FLASH_OFFSET_WBMAX_TOUT 0x24 |
||||
#define FLASH_OFFSET_EMAX_TOUT 0x25 |
||||
#define FLASH_OFFSET_CEMAX_TOUT 0x26 |
||||
#define FLASH_OFFSET_SIZE 0x27 |
||||
#define FLASH_OFFSET_INTERFACE 0x28 |
||||
#define FLASH_OFFSET_BUFFER_SIZE 0x2A |
||||
#define FLASH_OFFSET_NUM_ERASE_REGIONS 0x2C |
||||
#define FLASH_OFFSET_ERASE_REGIONS 0x2D |
||||
#define FLASH_OFFSET_PROTECT 0x02 |
||||
#define FLASH_OFFSET_USER_PROTECTION 0x85 |
||||
#define FLASH_OFFSET_INTEL_PROTECTION 0x81 |
||||
|
||||
|
||||
#define FLASH_MAN_CFI 0x01000000 |
||||
|
||||
|
||||
|
||||
|
||||
typedef union { |
||||
unsigned char c; |
||||
unsigned short w; |
||||
unsigned long l; |
||||
} cfiword_t; |
||||
|
||||
typedef union { |
||||
unsigned char * cp; |
||||
unsigned short *wp; |
||||
unsigned long *lp; |
||||
} cfiptr_t; |
||||
|
||||
#define NUM_ERASE_REGIONS 4 |
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ |
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions |
||||
*/ |
||||
|
||||
|
||||
|
||||
static void flash_add_byte(flash_info_t *info, cfiword_t * cword, uchar c); |
||||
static void flash_make_cmd(flash_info_t * info, uchar cmd, void * cmdbuf); |
||||
static void flash_write_cmd(flash_info_t * info, int sect, uchar offset, uchar cmd); |
||||
static int flash_isequal(flash_info_t * info, int sect, uchar offset, uchar cmd); |
||||
static int flash_isset(flash_info_t * info, int sect, uchar offset, uchar cmd); |
||||
static int flash_detect_cfi(flash_info_t * info); |
||||
static ulong flash_get_size (ulong base, int banknum); |
||||
static int flash_write_cfiword (flash_info_t *info, ulong dest, cfiword_t cword); |
||||
static int flash_full_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt); |
||||
#ifdef CFG_FLASH_USE_BUFFER_WRITE |
||||
static int flash_write_cfibuffer(flash_info_t * info, ulong dest, uchar * cp, int len); |
||||
#endif |
||||
/*-----------------------------------------------------------------------
|
||||
* create an address based on the offset and the port width |
||||
*/ |
||||
uchar * flash_make_addr(flash_info_t * info, int sect, int offset) |
||||
{ |
||||
return ((uchar *)(info->start[sect] + (offset * info->chipwidth))); |
||||
} |
||||
/*-----------------------------------------------------------------------
|
||||
* read a character at a port width address |
||||
*/ |
||||
uchar flash_read_uchar(flash_info_t * info, uchar offset) |
||||
{ |
||||
if (info->portwidth == FLASH_CFI_8BIT) { |
||||
volatile uchar *cp; |
||||
uchar c; |
||||
cp = flash_make_addr(info, 0, offset); |
||||
c = *cp; |
||||
#ifdef DEBUG_FLASH |
||||
printf("flash_read_uchar offset=%04x ptr=%08x c=%02x\n", |
||||
offset, (unsigned int)cp, c); |
||||
#endif |
||||
return (c); |
||||
|
||||
} else if (info->portwidth == FLASH_CFI_16BIT) { |
||||
volatile ushort *sp; |
||||
ushort s; |
||||
uchar c; |
||||
sp = (ushort*)flash_make_addr(info, 0, offset); |
||||
s = *sp; |
||||
c = (uchar)s; |
||||
#ifdef DEBUG_FLASH |
||||
printf("flash_read_uchar offset=%04x ptr=%08x s=%04x c=%02x\n", |
||||
offset, (unsigned int)sp, s, c); |
||||
#endif |
||||
return (c); |
||||
|
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* read a short word by swapping for ppc format. |
||||
*/ |
||||
ushort flash_read_ushort(flash_info_t * info, int sect, uchar offset) |
||||
{ |
||||
if (info->portwidth == FLASH_CFI_8BIT) { |
||||
volatile uchar *cp; |
||||
uchar c0, c1; |
||||
ushort s; |
||||
cp = flash_make_addr(info, 0, offset); |
||||
c1 = cp[2]; |
||||
c0 = cp[0]; |
||||
s = c1<<8 | c0; |
||||
#ifdef DEBUG_FLASH |
||||
printf("flash_read_ushort offset=%04x ptr=%08x c1=%02x c0=%02x s=%04x\n", |
||||
offset, (unsigned int)cp, c1, c0, s); |
||||
#endif |
||||
return (s); |
||||
|
||||
} else if (info->portwidth == FLASH_CFI_16BIT) { |
||||
volatile ushort *sp; |
||||
ushort s; |
||||
uchar c0, c1; |
||||
sp = (ushort*)flash_make_addr(info, 0, offset); |
||||
s = *sp; |
||||
c1 = (uchar)sp[1]; |
||||
c0 = (uchar)sp[0]; |
||||
s = c1<<8 | c0; |
||||
#ifdef DEBUG_FLASH |
||||
printf("flash_read_ushort offset=%04x ptr=%08x c1=%02x c0=%02x s=%04x\n", |
||||
offset, (unsigned int)sp, c1, c0, s); |
||||
#endif |
||||
return (s); |
||||
|
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* read a long word by picking the least significant byte of each maiximum |
||||
* port size word. Swap for ppc format. |
||||
*/ |
||||
ulong flash_read_long(flash_info_t * info, int sect, uchar offset) |
||||
{ |
||||
if (info->portwidth == FLASH_CFI_8BIT) { |
||||
volatile uchar *cp; |
||||
uchar c0, c1, c2, c3; |
||||
ulong l; |
||||
cp = flash_make_addr(info, 0, offset); |
||||
c3 = cp[6]; |
||||
c2 = cp[4]; |
||||
c1 = cp[2]; |
||||
c0 = cp[0]; |
||||
l = c3<<24 | c2<<16 | c1<<8 | c0; |
||||
#ifdef DEBUG_FLASH |
||||
printf("flash_read_long offset=%04x ptr=%08x c3=%02x c2=%02x c1=%02x c0=%02x l=%08x\n", |
||||
offset, (unsigned int)cp, c3, c2, c1, c0, l); |
||||
#endif |
||||
return (l); |
||||
|
||||
} else if (info->portwidth == FLASH_CFI_16BIT) { |
||||
volatile ushort *sp; |
||||
uchar c0, c1, c2, c3; |
||||
ulong l; |
||||
sp = (ushort*)flash_make_addr(info, 0, offset); |
||||
c3 = (uchar)sp[3]; |
||||
c2 = (uchar)sp[2]; |
||||
c1 = (uchar)sp[1]; |
||||
c0 = (uchar)sp[0]; |
||||
l = c3<<24 | c2<<16 | c1<<8 | c0; |
||||
#ifdef DEBUG_FLASH |
||||
printf("flash_read_long offset=%04x ptr=%08x c3=%02x c2=%02x c1=%02x c0=%02x l=%08x\n", |
||||
offset, (unsigned int)sp, c3, c2, c1, c0, l); |
||||
#endif |
||||
return (l); |
||||
|
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/ |
||||
unsigned long flash_init (void) |
||||
{ |
||||
unsigned long size; |
||||
|
||||
size = 0; |
||||
|
||||
flash_info[0].flash_id = FLASH_UNKNOWN; |
||||
flash_info[0].portwidth = FLASH_CFI_16BIT; |
||||
flash_info[0].chipwidth = FLASH_CFI_16BIT; |
||||
size += flash_info[0].size = flash_get_size(CFG_PROGFLASH_BASE, 0); |
||||
if (flash_info[0].flash_id == FLASH_UNKNOWN) { |
||||
printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n", 1, |
||||
flash_info[0].size, flash_info[0].size<<20); |
||||
}; |
||||
|
||||
flash_info[1].flash_id = FLASH_UNKNOWN; |
||||
flash_info[1].portwidth = FLASH_CFI_8BIT; |
||||
flash_info[1].chipwidth = FLASH_CFI_16BIT; |
||||
size += flash_info[1].size = flash_get_size(CFG_CONFFLASH_BASE, 1); |
||||
if (flash_info[1].flash_id == FLASH_UNKNOWN) { |
||||
printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n", 2, |
||||
flash_info[1].size, flash_info[1].size<<20); |
||||
}; |
||||
|
||||
return (size); |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/ |
||||
int flash_erase (flash_info_t *info, int s_first, int s_last) |
||||
{ |
||||
int rcode = 0; |
||||
int prot; |
||||
int sect; |
||||
|
||||
if( info->flash_id != FLASH_MAN_CFI) { |
||||
printf ("Can't erase unknown flash type - aborted\n"); |
||||
return 1; |
||||
} |
||||
if ((s_first < 0) || (s_first > s_last)) { |
||||
printf ("- no sectors to erase\n"); |
||||
return 1; |
||||
} |
||||
|
||||
prot = 0; |
||||
for (sect=s_first; sect<=s_last; ++sect) { |
||||
if (info->protect[sect]) { |
||||
prot++; |
||||
} |
||||
} |
||||
if (prot) { |
||||
printf ("- Warning: %d protected sectors will not be erased!\n", |
||||
prot); |
||||
} else { |
||||
printf ("\n"); |
||||
} |
||||
|
||||
|
||||
for (sect = s_first; sect<=s_last; sect++) { |
||||
if (info->protect[sect] == 0) { /* not protected */ |
||||
flash_write_cmd(info, sect, 0, FLASH_CMD_CLEAR_STATUS); |
||||
flash_write_cmd(info, sect, 0, FLASH_CMD_BLOCK_ERASE); |
||||
flash_write_cmd(info, sect, 0, FLASH_CMD_ERASE_CONFIRM); |
||||
|
||||
if(flash_full_status_check(info, sect, info->erase_blk_tout, "erase")) { |
||||
rcode = 1; |
||||
} else |
||||
printf("."); |
||||
} |
||||
} |
||||
printf (" done\n"); |
||||
return rcode; |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/ |
||||
void flash_print_info (flash_info_t *info) |
||||
{ |
||||
int i; |
||||
|
||||
if (info->flash_id != FLASH_MAN_CFI) { |
||||
printf ("missing or unknown FLASH type\n"); |
||||
return; |
||||
} |
||||
|
||||
printf("CFI conformant FLASH (x%d device in x%d mode)", |
||||
(info->chipwidth << 3 ), (info->portwidth << 3 )); |
||||
printf (" Size: %ld MB in %d Sectors\n", |
||||
info->size >> 20, info->sector_count); |
||||
printf(" Erase timeout %ld ms, write timeout %ld ms, buffer write timeout %ld ms, buffer size %d\n", |
||||
info->erase_blk_tout, info->write_tout, info->buffer_write_tout, info->buffer_size); |
||||
|
||||
printf (" Sector Start Addresses:"); |
||||
for (i=0; i<info->sector_count; ++i) { |
||||
if ((i % 5) == 0) |
||||
printf ("\n"); |
||||
printf (" %08lX%5s", |
||||
info->start[i], |
||||
info->protect[i] ? " (RO)" : " " |
||||
); |
||||
} |
||||
printf ("\n"); |
||||
return; |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash, returns: |
||||
* 0 - OK |
||||
* 1 - write timeout |
||||
* 2 - Flash not erased |
||||
*/ |
||||
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) |
||||
{ |
||||
ulong wp; |
||||
ulong cp; |
||||
int aln; |
||||
cfiword_t cword; |
||||
int i, rc; |
||||
|
||||
/* get lower aligned address */ |
||||
wp = (addr & ~(info->portwidth - 1)); |
||||
|
||||
/* handle unaligned start */ |
||||
if((aln = addr - wp) != 0) { |
||||
cword.l = 0; |
||||
cp = wp; |
||||
for(i=0;i<aln; ++i, ++cp) |
||||
flash_add_byte(info, &cword, (*(uchar *)cp)); |
||||
|
||||
for(; (i< info->portwidth) && (cnt > 0) ; i++) { |
||||
flash_add_byte(info, &cword, *src++); |
||||
cnt--; |
||||
cp++; |
||||
} |
||||
for(; (cnt == 0) && (i < info->portwidth); ++i, ++cp) |
||||
flash_add_byte(info, &cword, (*(uchar *)cp)); |
||||
if((rc = flash_write_cfiword(info, wp, cword)) != 0) |
||||
return rc; |
||||
wp = cp; |
||||
} |
||||
|
||||
#ifdef CFG_FLASH_USE_BUFFER_WRITE |
||||
while(cnt >= info->portwidth) { |
||||
i = info->buffer_size > cnt? cnt: info->buffer_size; |
||||
if((rc = flash_write_cfibuffer(info, wp, src,i)) != ERR_OK) |
||||
return rc; |
||||
wp += i; |
||||
src += i; |
||||
cnt -=i; |
||||
} |
||||
#else |
||||
/* handle the aligned part */ |
||||
while(cnt >= info->portwidth) { |
||||
cword.l = 0; |
||||
for(i = 0; i < info->portwidth; i++) { |
||||
flash_add_byte(info, &cword, *src++); |
||||
} |
||||
if((rc = flash_write_cfiword(info, wp, cword)) != 0) |
||||
return rc; |
||||
wp += info->portwidth; |
||||
cnt -= info->portwidth; |
||||
} |
||||
#endif /* CFG_FLASH_USE_BUFFER_WRITE */ |
||||
if (cnt == 0) { |
||||
return (0); |
||||
} |
||||
|
||||
/*
|
||||
* handle unaligned tail bytes |
||||
*/ |
||||
cword.l = 0; |
||||
for (i=0, cp=wp; (i<info->portwidth) && (cnt>0); ++i, ++cp) { |
||||
flash_add_byte(info, &cword, *src++); |
||||
--cnt; |
||||
} |
||||
for (; i<info->portwidth; ++i, ++cp) { |
||||
flash_add_byte(info, & cword, (*(uchar *)cp)); |
||||
} |
||||
|
||||
return flash_write_cfiword(info, wp, cword); |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/ |
||||
int flash_real_protect(flash_info_t *info, long sector, int prot) |
||||
{ |
||||
int retcode = 0; |
||||
|
||||
flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS); |
||||
flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT); |
||||
if(prot) |
||||
flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT_SET); |
||||
else |
||||
flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT_CLEAR); |
||||
|
||||
if((retcode = flash_full_status_check(info, sector, info->erase_blk_tout, |
||||
prot?"protect":"unprotect")) == 0) { |
||||
|
||||
info->protect[sector] = prot; |
||||
/* Intel's unprotect unprotects all locking */ |
||||
if(prot == 0) { |
||||
int i; |
||||
for(i = 0 ; i<info->sector_count; i++) { |
||||
if(info->protect[i]) |
||||
flash_real_protect(info, i, 1); |
||||
} |
||||
} |
||||
} |
||||
|
||||
return retcode; |
||||
} |
||||
/*-----------------------------------------------------------------------
|
||||
* wait for XSR.7 to be set. Time out with an error if it does not. |
||||
* This routine does not set the flash to read-array mode. |
||||
*/ |
||||
static int flash_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt) |
||||
{ |
||||
ulong start; |
||||
|
||||
/* Wait for command completion */ |
||||
start = get_timer (0); |
||||
while(!flash_isset(info, sector, 0, FLASH_STATUS_DONE)) { |
||||
if (get_timer(start) > info->erase_blk_tout) { |
||||
printf("Flash %s timeout at address %lx\n", prompt, info->start[sector]); |
||||
flash_write_cmd(info, sector, 0, FLASH_CMD_RESET); |
||||
return ERR_TIMOUT; |
||||
} |
||||
} |
||||
return ERR_OK; |
||||
} |
||||
/*-----------------------------------------------------------------------
|
||||
* Wait for XSR.7 to be set, if it times out print an error, otherwise do a full status check. |
||||
* This routine sets the flash to read-array mode. |
||||
*/ |
||||
static int flash_full_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt) |
||||
{ |
||||
int retcode; |
||||
retcode = flash_status_check(info, sector, tout, prompt); |
||||
if((retcode == ERR_OK) && !flash_isequal(info,sector, 0, FLASH_STATUS_DONE)) { |
||||
retcode = ERR_INVAL; |
||||
printf("Flash %s error at address %lx\n", prompt,info->start[sector]); |
||||
if(flash_isset(info, sector, 0, FLASH_STATUS_ECLBS | FLASH_STATUS_PSLBS)){ |
||||
printf("Command Sequence Error.\n"); |
||||
} else if(flash_isset(info, sector, 0, FLASH_STATUS_ECLBS)){ |
||||
printf("Block Erase Error.\n"); |
||||
retcode = ERR_NOT_ERASED; |
||||
} else if (flash_isset(info, sector, 0, FLASH_STATUS_PSLBS)) { |
||||
printf("Locking Error\n"); |
||||
} |
||||
if(flash_isset(info, sector, 0, FLASH_STATUS_DPS)){ |
||||
printf("Block locked.\n"); |
||||
retcode = ERR_PROTECTED; |
||||
} |
||||
if(flash_isset(info, sector, 0, FLASH_STATUS_VPENS)) |
||||
printf("Vpp Low Error.\n"); |
||||
} |
||||
flash_write_cmd(info, sector, 0, FLASH_CMD_RESET); |
||||
return retcode; |
||||
} |
||||
/*-----------------------------------------------------------------------
|
||||
*/ |
||||
static void flash_add_byte(flash_info_t *info, cfiword_t * cword, uchar c) |
||||
{ |
||||
switch(info->portwidth) { |
||||
case FLASH_CFI_8BIT: |
||||
cword->c = c; |
||||
break; |
||||
case FLASH_CFI_16BIT: |
||||
cword->w = (cword->w << 8) | c; |
||||
break; |
||||
case FLASH_CFI_32BIT: |
||||
cword->l = (cword->l << 8) | c; |
||||
} |
||||
} |
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* make a proper sized command based on the port and chip widths |
||||
*/ |
||||
static void flash_make_cmd(flash_info_t * info, uchar cmd, void * cmdbuf) |
||||
{ |
||||
//int i;
|
||||
uchar *cp = (uchar *)cmdbuf; |
||||
// for(i=0; i< info->portwidth; i++)
|
||||
// *cp++ = ((i+1) % info->chipwidth) ? '\0':cmd;
|
||||
if (info->portwidth == FLASH_CFI_8BIT && info->chipwidth == FLASH_CFI_16BIT) { |
||||
cp[0] = cmd; |
||||
} else if (info->portwidth == FLASH_CFI_16BIT && info->chipwidth == FLASH_CFI_16BIT) { |
||||
cp[0] = '\0'; |
||||
cp[1] = cmd; |
||||
}; |
||||
} |
||||
|
||||
/*
|
||||
* Write a proper sized command to the correct address |
||||
*/ |
||||
static void flash_write_cmd(flash_info_t * info, int sect, uchar offset, uchar cmd) |
||||
{ |
||||
|
||||
volatile cfiptr_t addr; |
||||
cfiword_t cword; |
||||
addr.cp = flash_make_addr(info, sect, offset); |
||||
flash_make_cmd(info, cmd, &cword); |
||||
switch(info->portwidth) { |
||||
case FLASH_CFI_8BIT: |
||||
*addr.cp = cword.c; |
||||
break; |
||||
case FLASH_CFI_16BIT: |
||||
*addr.wp = cword.w; |
||||
break; |
||||
case FLASH_CFI_32BIT: |
||||
*addr.lp = cword.l; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/ |
||||
static int flash_isequal(flash_info_t * info, int sect, uchar offset, uchar cmd) |
||||
{ |
||||
cfiptr_t cptr; |
||||
cfiword_t cword; |
||||
int retval; |
||||
cptr.cp = flash_make_addr(info, sect, offset); |
||||
flash_make_cmd(info, cmd, &cword); |
||||
switch(info->portwidth) { |
||||
case FLASH_CFI_8BIT: |
||||
retval = (cptr.cp[0] == cword.c); |
||||
break; |
||||
case FLASH_CFI_16BIT: |
||||
retval = (cptr.wp[0] == cword.w); |
||||
break; |
||||
case FLASH_CFI_32BIT: |
||||
retval = (cptr.lp[0] == cword.l); |
||||
break; |
||||
default: |
||||
retval = 0; |
||||
break; |
||||
} |
||||
return retval; |
||||
} |
||||
/*-----------------------------------------------------------------------
|
||||
*/ |
||||
static int flash_isset(flash_info_t * info, int sect, uchar offset, uchar cmd) |
||||
{ |
||||
cfiptr_t cptr; |
||||
cfiword_t cword; |
||||
int retval; |
||||
cptr.cp = flash_make_addr(info, sect, offset); |
||||
flash_make_cmd(info, cmd, &cword); |
||||
switch(info->portwidth) { |
||||
case FLASH_CFI_8BIT: |
||||
retval = ((cptr.cp[0] & cword.c) == cword.c); |
||||
break; |
||||
case FLASH_CFI_16BIT: |
||||
retval = ((cptr.wp[0] & cword.w) == cword.w); |
||||
break; |
||||
case FLASH_CFI_32BIT: |
||||
retval = ((cptr.lp[0] & cword.l) == cword.l); |
||||
break; |
||||
default: |
||||
retval = 0; |
||||
break; |
||||
} |
||||
return retval; |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* detect if flash is compatible with the Common Flash Interface (CFI) |
||||
* http://www.jedec.org/download/search/jesd68.pdf
|
||||
* |
||||
*/ |
||||
static int flash_detect_cfi(flash_info_t * info) |
||||
{ |
||||
|
||||
#if 0 |
||||
for(info->portwidth=FLASH_CFI_8BIT; info->portwidth <= FLASH_CFI_32BIT; |
||||
info->portwidth <<= 1) { |
||||
for(info->chipwidth =FLASH_CFI_BY8; |
||||
info->chipwidth <= info->portwidth; |
||||
info->chipwidth <<= 1) { |
||||
flash_write_cmd(info, 0, 0, FLASH_CMD_RESET); |
||||
flash_write_cmd(info, 0, FLASH_OFFSET_CFI, FLASH_CMD_CFI); |
||||
if(flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP,'Q') && |
||||
flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R') && |
||||
flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y')) |
||||
return 1; |
||||
} |
||||
} |
||||
#endif |
||||
flash_write_cmd(info, 0, 0, FLASH_CMD_RESET); |
||||
flash_write_cmd(info, 0, FLASH_OFFSET_CFI, FLASH_CMD_CFI); |
||||
if(flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP,'Q') && |
||||
flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R') && |
||||
flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y')) { |
||||
return 1; |
||||
} else { |
||||
return 0; |
||||
}; |
||||
} |
||||
/*
|
||||
* The following code cannot be run from FLASH! |
||||
* |
||||
*/ |
||||
static ulong flash_get_size (ulong base, int banknum) |
||||
{ |
||||
flash_info_t * info = &flash_info[banknum]; |
||||
int i, j; |
||||
int sect_cnt; |
||||
unsigned long sector; |
||||
unsigned long tmp; |
||||
int size_ratio; |
||||
uchar num_erase_regions; |
||||
int erase_region_size; |
||||
int erase_region_count; |
||||
|
||||
info->start[0] = base; |
||||
|
||||
if(flash_detect_cfi(info)){ |
||||
#ifdef DEBUG_FLASH |
||||
printf("portwidth=%d chipwidth=%d\n", info->portwidth, info->chipwidth); /* test-only */ |
||||
#endif |
||||
size_ratio = 1; // info->portwidth / info->chipwidth;
|
||||
num_erase_regions = flash_read_uchar(info, FLASH_OFFSET_NUM_ERASE_REGIONS); |
||||
#ifdef DEBUG_FLASH |
||||
printf("found %d erase regions\n", num_erase_regions); |
||||
#endif |
||||
sect_cnt = 0; |
||||
sector = base; |
||||
for(i = 0 ; i < num_erase_regions; i++) { |
||||
if(i > NUM_ERASE_REGIONS) { |
||||
printf("%d erase regions found, only %d used\n", |
||||
num_erase_regions, NUM_ERASE_REGIONS); |
||||
break; |
||||
} |
||||
tmp = flash_read_long(info, 0, FLASH_OFFSET_ERASE_REGIONS); |
||||
erase_region_count = (tmp & 0xffff) +1; |
||||
tmp >>= 16; |
||||
erase_region_size = (tmp & 0xffff)? ((tmp & 0xffff) * 256): 128; |
||||
for(j = 0; j< erase_region_count; j++) { |
||||
info->start[sect_cnt] = sector; |
||||
sector += (erase_region_size * size_ratio); |
||||
info->protect[sect_cnt] = flash_isset(info, sect_cnt, FLASH_OFFSET_PROTECT, FLASH_STATUS_PROTECT); |
||||
sect_cnt++; |
||||
} |
||||
} |
||||
|
||||
info->sector_count = sect_cnt; |
||||
/* multiply the size by the number of chips */ |
||||
info->size = (1 << flash_read_uchar(info, FLASH_OFFSET_SIZE)) * size_ratio; |
||||
info->buffer_size = (1 << flash_read_ushort(info, 0, FLASH_OFFSET_BUFFER_SIZE)); |
||||
tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_ETOUT); |
||||
info->erase_blk_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_EMAX_TOUT))); |
||||
tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_WBTOUT); |
||||
info->buffer_write_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_WBMAX_TOUT))); |
||||
tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_WTOUT); |
||||
info->write_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_WMAX_TOUT)))/ 1000; |
||||
info->flash_id = FLASH_MAN_CFI; |
||||
} |
||||
|
||||
flash_write_cmd(info, 0, 0, FLASH_CMD_RESET); |
||||
return(info->size); |
||||
} |
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/ |
||||
static int flash_write_cfiword (flash_info_t *info, ulong dest, cfiword_t cword) |
||||
{ |
||||
|
||||
cfiptr_t ctladdr; |
||||
cfiptr_t cptr; |
||||
int flag; |
||||
|
||||
ctladdr.cp = flash_make_addr(info, 0, 0); |
||||
cptr.cp = (uchar *)dest; |
||||
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */ |
||||
switch(info->portwidth) { |
||||
case FLASH_CFI_8BIT: |
||||
flag = ((cptr.cp[0] & cword.c) == cword.c); |
||||
break; |
||||
case FLASH_CFI_16BIT: |
||||
flag = ((cptr.wp[0] & cword.w) == cword.w); |
||||
break; |
||||
case FLASH_CFI_32BIT: |
||||
flag = ((cptr.lp[0] & cword.l) == cword.l); |
||||
break; |
||||
default: |
||||
return 2; |
||||
} |
||||
if(!flag) |
||||
return 2; |
||||
|
||||
/* Disable interrupts which might cause a timeout here */ |
||||
flag = disable_interrupts(); |
||||
|
||||
flash_write_cmd(info, 0, 0, FLASH_CMD_CLEAR_STATUS); |
||||
flash_write_cmd(info, 0, 0, FLASH_CMD_WRITE); |
||||
|
||||
switch(info->portwidth) { |
||||
case FLASH_CFI_8BIT: |
||||
cptr.cp[0] = cword.c; |
||||
break; |
||||
case FLASH_CFI_16BIT: |
||||
cptr.wp[0] = cword.w; |
||||
break; |
||||
case FLASH_CFI_32BIT: |
||||
cptr.lp[0] = cword.l; |
||||
break; |
||||
} |
||||
|
||||
/* re-enable interrupts if necessary */ |
||||
if(flag) |
||||
enable_interrupts(); |
||||
|
||||
return flash_full_status_check(info, 0, info->write_tout, "write"); |
||||
} |
||||
|
||||
#ifdef CFG_FLASH_USE_BUFFER_WRITE |
||||
|
||||
/* loop through the sectors from the highest address
|
||||
* when the passed address is greater or equal to the sector address |
||||
* we have a match |
||||
*/ |
||||
static int find_sector(flash_info_t *info, ulong addr) |
||||
{ |
||||
int sector; |
||||
for(sector = info->sector_count - 1; sector >= 0; sector--) { |
||||
if(addr >= info->start[sector]) |
||||
break; |
||||
} |
||||
return sector; |
||||
} |
||||
|
||||
static int flash_write_cfibuffer(flash_info_t * info, ulong dest, uchar * cp, int len) |
||||
{ |
||||
|
||||
int sector; |
||||
int cnt; |
||||
int retcode; |
||||
volatile cfiptr_t src; |
||||
volatile cfiptr_t dst; |
||||
|
||||
src.cp = cp; |
||||
dst.cp = (uchar *)dest; |
||||
sector = find_sector(info, dest); |
||||
flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS); |
||||
flash_write_cmd(info, sector, 0, FLASH_CMD_WRITE_TO_BUFFER); |
||||
if((retcode = flash_status_check(info, sector, info->buffer_write_tout, |
||||
"write to buffer")) == ERR_OK) { |
||||
switch(info->portwidth) { |
||||
case FLASH_CFI_8BIT: |
||||
cnt = len; |
||||
break; |
||||
case FLASH_CFI_16BIT: |
||||
cnt = len >> 1; |
||||
break; |
||||
case FLASH_CFI_32BIT: |
||||
cnt = len >> 2; |
||||
break; |
||||
default: |
||||
return ERR_INVAL; |
||||
break; |
||||
} |
||||
flash_write_cmd(info, sector, 0, (uchar)cnt-1); |
||||
while(cnt-- > 0) { |
||||
switch(info->portwidth) { |
||||
case FLASH_CFI_8BIT: |
||||
*dst.cp++ = *src.cp++; |
||||
break; |
||||
case FLASH_CFI_16BIT: |
||||
*dst.wp++ = *src.wp++; |
||||
break; |
||||
case FLASH_CFI_32BIT: |
||||
*dst.lp++ = *src.lp++; |
||||
break; |
||||
default: |
||||
return ERR_INVAL; |
||||
break; |
||||
} |
||||
} |
||||
flash_write_cmd(info, sector, 0, FLASH_CMD_WRITE_BUFFER_CONFIRM); |
||||
retcode = flash_full_status_check(info, sector, info->buffer_write_tout, |
||||
"buffer write"); |
||||
} |
||||
flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS); |
||||
return retcode; |
||||
} |
||||
#endif /* CFG_USE_FLASH_BUFFER_WRITE */ |
@ -0,0 +1,34 @@ |
||||
/* |
||||
* init.S: Stubs for ppcboot initialization |
||||
* |
||||
* Copyright 2002 Mind NV |
||||
* |
||||
* http://www.mind.be/ |
||||
* |
||||
* Author : Peter De Schrijver (p2@mind.be)
|
||||
* |
||||
* This software may be used and distributed according to the terms of |
||||
* the GNU General Public License (GPL) version 2, incorporated herein by |
||||
* reference. Drivers based on or derived from this code fall under the GPL |
||||
* and must retain the authorship, copyright and this license notice. This |
||||
* file is not a complete program and may only be used when the entire |
||||
* program is licensed under the GPL. |
||||
* |
||||
*/ |
||||
|
||||
#include <ppc4xx.h> |
||||
|
||||
#include <ppc_asm.tmpl> |
||||
#include <ppc_defs.h> |
||||
|
||||
#include <asm/cache.h> |
||||
#include <asm/mmu.h> |
||||
|
||||
|
||||
.globl ext_bus_cntlr_init
|
||||
ext_bus_cntlr_init: |
||||
blr |
||||
|
||||
.globl sdram_init
|
||||
sdram_init: |
||||
blr |
@ -0,0 +1,346 @@ |
||||
/*
|
||||
* (C) Copyright 2003 |
||||
* AMIRIX Systems Inc. |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <ppc4xx.h> |
||||
#include <asm/processor.h> |
||||
#include <pci.h> |
||||
|
||||
#define PCI_MEM_82559ER_CSR_BASE 0x30200000 |
||||
#define PCI_IO_82559ER_CSR_BASE 0x40000200 |
||||
|
||||
/** AP1100 specific values */ |
||||
#define PSII_BASE 0x30000000 /**< PowerSpan II dual bridge local bus register address */ |
||||
#define PSII_CONFIG_ADDR 0x30000290 /**< PowerSpan II Configuration Cycle Address configuration register */ |
||||
#define PSII_CONFIG_DATA 0x30000294 /**< PowerSpan II Configuration Cycle Data register. */ |
||||
#define PSII_CONFIG_DEST_PCI2 0x01000000 /**< PowerSpan II configuration cycle destination selection, set for PCI2 bus */ |
||||
#define PSII_PCI_MEM_BASE 0x30200000 /**< Local Bus address for start of PCI memory space on PCI2 bus. */ |
||||
#define PSII_PCI_MEM_SIZE 0x1BE00000 /**< PCI Memory space about 510 Meg. */ |
||||
#define AP1000_SYS_MEM_START 0x00000000 /**< System memory starts at 0. */ |
||||
#define AP1000_SYS_MEM_SIZE 0x08000000 /**< System memory is 128 Meg. */ |
||||
|
||||
/* static int G_verbosity_level = 1; */ |
||||
#define G_verbosity_level 1 |
||||
|
||||
void write1(unsigned long addr, unsigned char val) { |
||||
volatile unsigned char* p = (volatile unsigned char*)addr; |
||||
|
||||
if(G_verbosity_level > 1) |
||||
printf("write1: addr=%08x val=%02x\n", (unsigned int)addr, val); |
||||
*p = val; |
||||
asm("eieio"); |
||||
} |
||||
|
||||
unsigned char read1(unsigned long addr) { |
||||
unsigned char val; |
||||
volatile unsigned char* p = (volatile unsigned char*)addr; |
||||
|
||||
if(G_verbosity_level > 1) |
||||
printf("read1: addr=%08x ", (unsigned int)addr); |
||||
val = *p; |
||||
asm("eieio"); |
||||
if(G_verbosity_level > 1) |
||||
printf("val=%08x\n", val); |
||||
return val; |
||||
} |
||||
|
||||
void write2(unsigned long addr, unsigned short val) { |
||||
volatile unsigned short* p = (volatile unsigned short*)addr; |
||||
|
||||
if(G_verbosity_level > 1) |
||||
printf("write2: addr=%08x val=%04x -> *p=%04x\n", (unsigned int)addr, val, |
||||
((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8)); |
||||
|
||||
*p = ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8); |
||||
asm("eieio"); |
||||
} |
||||
|
||||
unsigned short read2(unsigned long addr) { |
||||
unsigned short val; |
||||
volatile unsigned short* p = (volatile unsigned short*)addr; |
||||
|
||||
if(G_verbosity_level > 1) |
||||
printf("read2: addr=%08x ", (unsigned int)addr); |
||||
val = *p; |
||||
val = ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8); |
||||
asm("eieio"); |
||||
if(G_verbosity_level > 1) |
||||
printf("*p=%04x -> val=%04x\n", |
||||
((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8), val); |
||||
return val; |
||||
} |
||||
|
||||
void write4(unsigned long addr, unsigned long val) { |
||||
volatile unsigned long* p = (volatile unsigned long*)addr; |
||||
|
||||
if(G_verbosity_level > 1) |
||||
printf("write4: addr=%08x val=%08x -> *p=%08x\n", (unsigned int)addr, (unsigned int)val, |
||||
(unsigned int)(((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) | |
||||
((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8))); |
||||
|
||||
*p = ((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) | |
||||
((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8); |
||||
asm("eieio"); |
||||
} |
||||
|
||||
unsigned long read4(unsigned long addr) { |
||||
unsigned long val; |
||||
volatile unsigned long* p = (volatile unsigned long*)addr; |
||||
|
||||
if(G_verbosity_level > 1) |
||||
printf("read4: addr=%08x", (unsigned int)addr); |
||||
|
||||
val = *p; |
||||
val = ((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) | |
||||
((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8); |
||||
asm("eieio"); |
||||
|
||||
if(G_verbosity_level > 1) |
||||
printf("*p=%04x -> val=%04x\n", |
||||
(unsigned int)(((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) | |
||||
((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8)), (unsigned int)val); |
||||
return val; |
||||
} |
||||
|
||||
void write4be(unsigned long addr, unsigned long val) { |
||||
volatile unsigned long* p = (volatile unsigned long*)addr; |
||||
|
||||
if(G_verbosity_level > 1) |
||||
printf("write4: addr=%08x val=%08x\n", (unsigned int)addr, (unsigned int)val); |
||||
*p = val; |
||||
asm("eieio"); |
||||
} |
||||
|
||||
/** One byte configuration write on PSII.
|
||||
* Currently fixes destination PCI bus to PCI2, onboard |
||||
* pci. |
||||
* @param hose PCI Host controller information. Ignored. |
||||
* @param dev Encoded PCI device/Bus and Function value. |
||||
* @param reg PCI Configuration register number. |
||||
* @param val Address of location for received byte. |
||||
* @return Always Zero. |
||||
*/ |
||||
static int psII_read_config_byte( |
||||
struct pci_controller *hose, |
||||
pci_dev_t dev, |
||||
int reg, |
||||
u8 *val) |
||||
{ |
||||
write4be(PSII_CONFIG_ADDR, |
||||
PSII_CONFIG_DEST_PCI2 | /* Operate on PCI2 bus interface . */ |
||||
(PCI_BUS(dev) << 16) | |
||||
(PCI_DEV(dev) << 11) | |
||||
(PCI_FUNC(dev) << 8) | |
||||
((reg & 0xFF) & ~3)); /* Configuation cycle type 0 */ |
||||
|
||||
*val = read1(PSII_CONFIG_DATA+(reg&0x03)); |
||||
return(0); |
||||
} |
||||
|
||||
/** One byte configuration write on PSII.
|
||||
* Currently fixes destination bus to PCI2, onboard |
||||
* pci. |
||||
* @param hose PCI Host controller information. Ignored. |
||||
* @param dev Encoded PCI device/Bus and Function value. |
||||
* @param reg PCI Configuration register number. |
||||
* @param val Output byte. |
||||
* @return Always Zero. |
||||
*/ |
||||
static int psII_write_config_byte( |
||||
struct pci_controller *hose, |
||||
pci_dev_t dev, |
||||
int reg, |
||||
u8 val) |
||||
{ |
||||
write4be(PSII_CONFIG_ADDR, |
||||
PSII_CONFIG_DEST_PCI2 | /* Operate on PCI2 bus interface . */ |
||||
(PCI_BUS(dev) << 16) | |
||||
(PCI_DEV(dev) << 11) | |
||||
(PCI_FUNC(dev) << 8) | |
||||
((reg & 0xFF) & ~3)); /* Configuation cycle type 0 */ |
||||
|
||||
write1(PSII_CONFIG_DATA+(reg&0x03),(unsigned char )val); |
||||
|
||||
return(0); |
||||
} |
||||
|
||||
/** One word (16 bit) configuration read on PSII.
|
||||
* Currently fixes destination PCI bus to PCI2, onboard |
||||
* pci. |
||||
* @param hose PCI Host controller information. Ignored. |
||||
* @param dev Encoded PCI device/Bus and Function value. |
||||
* @param reg PCI Configuration register number. |
||||
* @param val Address of location for received word. |
||||
* @return Always Zero. |
||||
*/ |
||||
static int psII_read_config_word( |
||||
struct pci_controller *hose, |
||||
pci_dev_t dev, |
||||
int reg, |
||||
u16 *val) |
||||
{ |
||||
write4be(PSII_CONFIG_ADDR, |
||||
PSII_CONFIG_DEST_PCI2 | /* Operate on PCI2 bus interface . */ |
||||
(PCI_BUS(dev) << 16) | |
||||
(PCI_DEV(dev) << 11) | |
||||
(PCI_FUNC(dev) << 8) | |
||||
((reg & 0xFF) & ~3)); /* Configuation cycle type 0 */ |
||||
|
||||
*val = read2(PSII_CONFIG_DATA+(reg&0x03)); |
||||
return(0); |
||||
} |
||||
|
||||
/** One word (16 bit) configuration write on PSII.
|
||||
* Currently fixes destination bus to PCI2, onboard |
||||
* pci. |
||||
* @param hose PCI Host controller information. Ignored. |
||||
* @param dev Encoded PCI device/Bus and Function value. |
||||
* @param reg PCI Configuration register number. |
||||
* @param val Output word. |
||||
* @return Always Zero. |
||||
*/ |
||||
static int psII_write_config_word( |
||||
struct pci_controller *hose, |
||||
pci_dev_t dev, |
||||
int reg, |
||||
u16 val) |
||||
{ |
||||
write4be(PSII_CONFIG_ADDR, |
||||
PSII_CONFIG_DEST_PCI2 | /* Operate on PCI2 bus interface . */ |
||||
(PCI_BUS(dev) << 16) | |
||||
(PCI_DEV(dev) << 11) | |
||||
(PCI_FUNC(dev) << 8) | |
||||
((reg & 0xFF) & ~3)); /* Configuation cycle type 0 */ |
||||
|
||||
write2(PSII_CONFIG_DATA+(reg&0x03),(unsigned short )val); |
||||
|
||||
return(0); |
||||
} |
||||
|
||||
/** One DWord (32 bit) configuration read on PSII.
|
||||
* Currently fixes destination PCI bus to PCI2, onboard |
||||
* pci. |
||||
* @param hose PCI Host controller information. Ignored. |
||||
* @param dev Encoded PCI device/Bus and Function value. |
||||
* @param reg PCI Configuration register number. |
||||
* @param val Address of location for received byte. |
||||
* @return Always Zero. |
||||
*/ |
||||
static int psII_read_config_dword( |
||||
struct pci_controller *hose, |
||||
pci_dev_t dev, |
||||
int reg, |
||||
u32 *val) |
||||
{ |
||||
write4be(PSII_CONFIG_ADDR, |
||||
PSII_CONFIG_DEST_PCI2 | /* Operate on PCI2 bus interface . */ |
||||
(PCI_BUS(dev) << 16) | |
||||
(PCI_DEV(dev) << 11) | |
||||
(PCI_FUNC(dev) << 8) | |
||||
((reg & 0xFF) & ~3)); /* Configuation cycle type 0 */ |
||||
|
||||
*val = read4(PSII_CONFIG_DATA); |
||||
return(0); |
||||
} |
||||
|
||||
/** One DWord (32 bit) configuration write on PSII.
|
||||
* Currently fixes destination bus to PCI2, onboard |
||||
* pci. |
||||
* @param hose PCI Host controller information. Ignored. |
||||
* @param dev Encoded PCI device/Bus and Function value. |
||||
* @param reg PCI Configuration register number. |
||||
* @param val Output Dword. |
||||
* @return Always Zero. |
||||
*/ |
||||
static int psII_write_config_dword( |
||||
struct pci_controller *hose, |
||||
pci_dev_t dev, |
||||
int reg, |
||||
u32 val) |
||||
{ |
||||
write4be(PSII_CONFIG_ADDR, |
||||
PSII_CONFIG_DEST_PCI2 | /* Operate on PCI2 bus interface . */ |
||||
(PCI_BUS(dev) << 16) | |
||||
(PCI_DEV(dev) << 11) | |
||||
(PCI_FUNC(dev) << 8) | |
||||
((reg & 0xFF) & ~3)); /* Configuation cycle type 0 */ |
||||
|
||||
write4(PSII_CONFIG_DATA,(unsigned long)val); |
||||
|
||||
return(0); |
||||
} |
||||
|
||||
|
||||
|
||||
static struct pci_config_table ap1000_config_table[] = { |
||||
#ifdef CONFIG_AP1000 |
||||
{PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
||||
PCI_BUS(CFG_ETH_DEV_FN), PCI_DEV(CFG_ETH_DEV_FN), PCI_FUNC(CFG_ETH_DEV_FN), |
||||
pci_cfgfunc_config_device,
|
||||
{CFG_ETH_IOBASE, CFG_ETH_MEMBASE, PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }}, |
||||
#endif |
||||
{ } |
||||
}; |
||||
|
||||
|
||||
static struct pci_controller psII_hose = { |
||||
config_table: ap1000_config_table, |
||||
}; |
||||
|
||||
void pci_init_board(void) |
||||
{ |
||||
struct pci_controller *hose = &psII_hose; |
||||
|
||||
/*
|
||||
* Register the hose |
||||
*/ |
||||
hose->first_busno = 0; |
||||
hose->last_busno = 0xff; |
||||
|
||||
|
||||
/* System memory space */ |
||||
pci_set_region(hose->regions + 0, |
||||
AP1000_SYS_MEM_START, AP1000_SYS_MEM_START, AP1000_SYS_MEM_SIZE, |
||||
PCI_REGION_MEM | PCI_REGION_MEMORY); |
||||
|
||||
/* PCI Memory space */ |
||||
pci_set_region(hose->regions + 1, |
||||
PSII_PCI_MEM_BASE, PSII_PCI_MEM_BASE, PSII_PCI_MEM_SIZE, |
||||
PCI_REGION_MEM); |
||||
|
||||
/* No IO Memory space - for now */ |
||||
|
||||
pci_set_ops(hose, |
||||
psII_read_config_byte, |
||||
psII_read_config_word, |
||||
psII_read_config_dword, |
||||
psII_write_config_byte, |
||||
psII_write_config_word, |
||||
psII_write_config_dword); |
||||
|
||||
hose->region_count = 2; |
||||
|
||||
pci_register_hose(hose); |
||||
|
||||
hose->last_busno = pci_hose_scan(hose); |
||||
} |
@ -0,0 +1,712 @@ |
||||
/**
|
||||
* @file powerspan.c Source file for PowerSpan II code. |
||||
*/ |
||||
|
||||
/*
|
||||
* (C) Copyright 2005 |
||||
* AMIRIX Systems Inc. |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <command.h> |
||||
#include <asm/processor.h> |
||||
#include "powerspan.h" |
||||
#define tolower(x) x |
||||
#include "ap1000.h" |
||||
|
||||
#ifdef INCLUDE_PCI |
||||
|
||||
/** Write one byte with byte swapping.
|
||||
* @param addr [IN] the address to write to |
||||
* @param val [IN] the value to write |
||||
*/ |
||||
void write1(unsigned long addr, unsigned char val) { |
||||
volatile unsigned char* p = (volatile unsigned char*)addr; |
||||
#ifdef VERBOSITY |
||||
if(gVerbosityLevel > 1){ |
||||
printf("write1: addr=%08x val=%02x\n", addr, val); |
||||
} |
||||
#endif |
||||
*p = val; |
||||
PSII_SYNC(); |
||||
} |
||||
|
||||
/** Read one byte with byte swapping.
|
||||
* @param addr [IN] the address to read from |
||||
* @return the value at addr |
||||
*/ |
||||
unsigned char read1(unsigned long addr) { |
||||
unsigned char val; |
||||
volatile unsigned char* p = (volatile unsigned char*)addr; |
||||
|
||||
val = *p; |
||||
PSII_SYNC(); |
||||
#ifdef VERBOSITY |
||||
if(gVerbosityLevel > 1){ |
||||
printf("read1: addr=%08x val=%02x\n", addr, val); |
||||
} |
||||
#endif |
||||
return val; |
||||
} |
||||
|
||||
/** Write one 2-byte word with byte swapping.
|
||||
* @param addr [IN] the address to write to |
||||
* @param val [IN] the value to write |
||||
*/ |
||||
void write2(unsigned long addr, unsigned short val) { |
||||
volatile unsigned short* p = (volatile unsigned short*)addr; |
||||
|
||||
#ifdef VERBOSITY |
||||
if(gVerbosityLevel > 1){ |
||||
printf("write2: addr=%08x val=%04x -> *p=%04x\n", addr, val, |
||||
((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8)); |
||||
} |
||||
#endif |
||||
*p = ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8); |
||||
PSII_SYNC(); |
||||
} |
||||
|
||||
/** Read one 2-byte word with byte swapping.
|
||||
* @param addr [IN] the address to read from |
||||
* @return the value at addr |
||||
*/ |
||||
unsigned short read2(unsigned long addr) { |
||||
unsigned short val; |
||||
volatile unsigned short* p = (volatile unsigned short*)addr; |
||||
|
||||
val = *p; |
||||
val = ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8); |
||||
PSII_SYNC(); |
||||
#ifdef VERBOSITY |
||||
if(gVerbosityLevel > 1){ |
||||
printf("read2: addr=%08x *p=%04x -> val=%04x\n", addr, *p, val); |
||||
} |
||||
#endif |
||||
return val; |
||||
} |
||||
|
||||
/** Write one 4-byte word with byte swapping.
|
||||
* @param addr [IN] the address to write to |
||||
* @param val [IN] the value to write |
||||
*/ |
||||
void write4(unsigned long addr, unsigned long val) { |
||||
volatile unsigned long* p = (volatile unsigned long*)addr; |
||||
#ifdef VERBOSITY |
||||
if(gVerbosityLevel > 1){ |
||||
printf("write4: addr=%08x val=%08x -> *p=%08x\n", addr, val, |
||||
((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) | |
||||
((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8)); |
||||
} |
||||
#endif |
||||
*p = ((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) | |
||||
((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8); |
||||
PSII_SYNC(); |
||||
} |
||||
|
||||
/** Read one 4-byte word with byte swapping.
|
||||
* @param addr [IN] the address to read from |
||||
* @return the value at addr |
||||
*/ |
||||
unsigned long read4(unsigned long addr) { |
||||
unsigned long val; |
||||
volatile unsigned long* p = (volatile unsigned long*)addr; |
||||
|
||||
val = *p; |
||||
val = ((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) | |
||||
((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8); |
||||
PSII_SYNC(); |
||||
#ifdef VERBOSITY |
||||
if(gVerbosityLevel > 1){ |
||||
printf("read4: addr=%08x *p=%08x -> val=%08x\n", addr, *p, val); |
||||
} |
||||
#endif |
||||
return val; |
||||
} |
||||
|
||||
int PCIReadConfig(int bus, int dev, int fn, int reg, int width, unsigned long* val){ |
||||
unsigned int conAdrVal; |
||||
unsigned int conDataReg = REG_CONFIG_DATA; |
||||
unsigned int status; |
||||
int ret_val = 0; |
||||
|
||||
|
||||
/* DEST bit hardcoded to 1: local pci is PCI-2 */ |
||||
/* TYPE bit is hardcoded to 1: all config cycles are local */ |
||||
conAdrVal = (1 << 24) |
||||
| ((bus & 0xFF) << 16) |
||||
| ((dev & 0xFF) << 11) |
||||
| ((fn & 0x07) << 8) |
||||
| (reg & 0xFC); |
||||
|
||||
/* clear any pending master aborts */ |
||||
write4(REG_P1_CSR, CLEAR_MASTER_ABORT); |
||||
|
||||
/* Load the conAdrVal value first, then read from pb_conf_data */ |
||||
write4(REG_CONFIG_ADDRESS, conAdrVal); |
||||
PSII_SYNC(); |
||||
|
||||
|
||||
/* Note: documentation does not match the pspan library code */ |
||||
/* Note: *pData comes back as -1 if device is not present */ |
||||
switch (width){ |
||||
case 4:{ |
||||
*(unsigned int*)val = read4(conDataReg); |
||||
break; |
||||
} |
||||
case 2:{ |
||||
*(unsigned short*)val = read2(conDataReg); |
||||
break; |
||||
} |
||||
case 1:{ |
||||
*(unsigned char*)val = read1(conDataReg); |
||||
break; |
||||
} |
||||
default:{ |
||||
ret_val = ILLEGAL_REG_OFFSET; |
||||
break; |
||||
} |
||||
} |
||||
PSII_SYNC(); |
||||
|
||||
/* clear any pending master aborts */ |
||||
status = read4(REG_P1_CSR); |
||||
if(status & CLEAR_MASTER_ABORT){ |
||||
ret_val = NO_DEVICE_FOUND; |
||||
write4(REG_P1_CSR, CLEAR_MASTER_ABORT); |
||||
} |
||||
|
||||
return ret_val; |
||||
} |
||||
|
||||
|
||||
int PCIWriteConfig(int bus, int dev, int fn, int reg, int width, unsigned long val){ |
||||
unsigned int conAdrVal; |
||||
unsigned int conDataReg = REG_CONFIG_DATA; |
||||
unsigned int status; |
||||
int ret_val = 0; |
||||
|
||||
|
||||
/* DEST bit hardcoded to 1: local pci is PCI-2 */ |
||||
/* TYPE bit is hardcoded to 1: all config cycles are local */ |
||||
conAdrVal = (1 << 24) |
||||
| ((bus & 0xFF) << 16) |
||||
| ((dev & 0xFF) << 11) |
||||
| ((fn & 0x07) << 8) |
||||
| (reg & 0xFC); |
||||
|
||||
/* clear any pending master aborts */ |
||||
write4(REG_P1_CSR, CLEAR_MASTER_ABORT); |
||||
|
||||
/* Load the conAdrVal value first, then read from pb_conf_data */ |
||||
write4(REG_CONFIG_ADDRESS, conAdrVal); |
||||
PSII_SYNC(); |
||||
|
||||
|
||||
/* Note: documentation does not match the pspan library code */ |
||||
/* Note: *pData comes back as -1 if device is not present */ |
||||
switch (width){ |
||||
case 4:{ |
||||
write4(conDataReg, val); |
||||
break; |
||||
} |
||||
case 2:{ |
||||
write2(conDataReg, val); |
||||
break; |
||||
} |
||||
case 1:{ |
||||
write1(conDataReg, val); |
||||
break; |
||||
} |
||||
default:{ |
||||
ret_val = ILLEGAL_REG_OFFSET; |
||||
break; |
||||
} |
||||
} |
||||
PSII_SYNC(); |
||||
|
||||
/* clear any pending master aborts */ |
||||
status = read4(REG_P1_CSR); |
||||
if(status & CLEAR_MASTER_ABORT){ |
||||
ret_val = NO_DEVICE_FOUND; |
||||
write4(REG_P1_CSR, CLEAR_MASTER_ABORT); |
||||
} |
||||
|
||||
return ret_val; |
||||
} |
||||
|
||||
|
||||
int pci_read_config_byte(int bus, int dev, int fn, int reg, unsigned char* val){ |
||||
unsigned long read_val; |
||||
int ret_val; |
||||
|
||||
ret_val = PCIReadConfig(bus, dev, fn, reg, 1, &read_val); |
||||
*val = read_val & 0xFF; |
||||
|
||||
return ret_val; |
||||
} |
||||
|
||||
int pci_write_config_byte(int bus, int dev, int fn, int reg, unsigned char val){ |
||||
return PCIWriteConfig(bus, dev, fn, reg, 1, val); |
||||
} |
||||
|
||||
int pci_read_config_word(int bus, int dev, int fn, int reg, unsigned short* val){ |
||||
unsigned long read_val; |
||||
int ret_val; |
||||
|
||||
ret_val = PCIReadConfig(bus, dev, fn, reg, 2, &read_val); |
||||
*val = read_val & 0xFFFF; |
||||
|
||||
return ret_val; |
||||
} |
||||
|
||||
int pci_write_config_word(int bus, int dev, int fn, int reg, unsigned short val){ |
||||
return PCIWriteConfig(bus, dev, fn, reg, 2, val); |
||||
} |
||||
|
||||
int pci_read_config_dword(int bus, int dev, int fn, int reg, unsigned long* val){ |
||||
return PCIReadConfig(bus, dev, fn, reg, 4, val); |
||||
} |
||||
|
||||
int pci_write_config_dword(int bus, int dev, int fn, int reg, unsigned long val){ |
||||
return PCIWriteConfig(bus, dev, fn, reg, 4, val); |
||||
} |
||||
|
||||
#endif /* INCLUDE_PCI */ |
||||
|
||||
int I2CAccess(unsigned char theI2CAddress, unsigned char theDevCode, unsigned char theChipSel, unsigned char* theValue, int RWFlag){ |
||||
int ret_val = 0; |
||||
unsigned int reg_value; |
||||
|
||||
reg_value = PowerSpanRead(REG_I2C_CSR); |
||||
|
||||
if(reg_value & I2C_CSR_ACT){ |
||||
printf("Error: I2C busy\n"); |
||||
ret_val = I2C_BUSY; |
||||
} |
||||
else{ |
||||
reg_value = ((theI2CAddress & 0xFF) << 24) |
||||
| ((theDevCode & 0x0F) << 12) |
||||
| ((theChipSel & 0x07) << 9) |
||||
| I2C_CSR_ERR; |
||||
if(RWFlag == I2C_WRITE){ |
||||
reg_value |= I2C_CSR_RW | ((*theValue & 0xFF) << 16); |
||||
} |
||||
|
||||
PowerSpanWrite(REG_I2C_CSR, reg_value); |
||||
udelay(1); |
||||
|
||||
do{ |
||||
reg_value = PowerSpanRead(REG_I2C_CSR); |
||||
|
||||
if((reg_value & I2C_CSR_ACT) == 0){ |
||||
if(reg_value & I2C_CSR_ERR){ |
||||
ret_val = I2C_ERR; |
||||
} |
||||
else{ |
||||
*theValue = (reg_value & I2C_CSR_DATA) >> 16; |
||||
} |
||||
} |
||||
} while(reg_value & I2C_CSR_ACT); |
||||
} |
||||
|
||||
return ret_val; |
||||
} |
||||
|
||||
int EEPROMRead(unsigned char theI2CAddress, unsigned char* theValue){ |
||||
return I2CAccess(theI2CAddress, I2C_EEPROM_DEV, I2C_EEPROM_CHIP_SEL, theValue, I2C_READ); |
||||
} |
||||
|
||||
int EEPROMWrite(unsigned char theI2CAddress, unsigned char theValue){ |
||||
return I2CAccess(theI2CAddress, I2C_EEPROM_DEV, I2C_EEPROM_CHIP_SEL, &theValue, I2C_WRITE); |
||||
} |
||||
|
||||
int do_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ |
||||
char cmd; |
||||
int ret_val = 0; |
||||
unsigned int address = 0; |
||||
unsigned char value = 1; |
||||
unsigned char read_value; |
||||
int ii; |
||||
int error = 0; |
||||
unsigned char* mem_ptr; |
||||
unsigned char default_eeprom[] = EEPROM_DEFAULT; |
||||
|
||||
if(argc < 2){ |
||||
goto usage; |
||||
} |
||||
|
||||
cmd = argv[1][0]; |
||||
if(argc > 2){ |
||||
address = simple_strtoul(argv[2], NULL, 16); |
||||
if(argc > 3){ |
||||
value = simple_strtoul(argv[3], NULL, 16) & 0xFF; |
||||
} |
||||
} |
||||
|
||||
switch (cmd){ |
||||
case 'r':{ |
||||
if(address > 256){ |
||||
printf("Illegal Address\n"); |
||||
goto usage; |
||||
} |
||||
printf("@0x%x: ", address); |
||||
for(ii = 0;ii < value;ii++){ |
||||
if(EEPROMRead(address + ii, &read_value) != 0){ |
||||
printf("Read Error\n"); |
||||
} |
||||
else{ |
||||
printf("0x%02x ", read_value); |
||||
} |
||||
|
||||
if(((ii + 1) % 16) == 0){ |
||||
printf("\n"); |
||||
} |
||||
} |
||||
printf("\n"); |
||||
break; |
||||
} |
||||
case 'w':{ |
||||
if(address > 256){ |
||||
printf("Illegal Address\n"); |
||||
goto usage; |
||||
} |
||||
if(argc < 4){ |
||||
goto usage; |
||||
} |
||||
if(EEPROMWrite(address, value) != 0){ |
||||
printf("Write Error\n"); |
||||
} |
||||
break; |
||||
} |
||||
case 'g':{ |
||||
if(argc != 3){ |
||||
goto usage; |
||||
} |
||||
mem_ptr = (unsigned char*)address; |
||||
for(ii = 0;((ii < EEPROM_LENGTH) && (error == 0));ii++){ |
||||
if(EEPROMRead(ii, &read_value) != 0){ |
||||
printf("Read Error\n"); |
||||
error = 1; |
||||
} |
||||
else{ |
||||
*mem_ptr = read_value; |
||||
mem_ptr++; |
||||
} |
||||
} |
||||
break; |
||||
} |
||||
case 'p':{ |
||||
if(argc != 3){ |
||||
goto usage; |
||||
} |
||||
mem_ptr = (unsigned char*)address; |
||||
for(ii = 0;((ii < EEPROM_LENGTH) && (error == 0));ii++){ |
||||
if(EEPROMWrite(ii, *mem_ptr) != 0){ |
||||
printf("Write Error\n"); |
||||
error = 1; |
||||
} |
||||
|
||||
mem_ptr++; |
||||
} |
||||
break; |
||||
} |
||||
case 'd':{ |
||||
if(argc != 2){ |
||||
goto usage; |
||||
} |
||||
for(ii = 0;((ii < EEPROM_LENGTH) && (error == 0));ii++){ |
||||
if(EEPROMWrite(ii, default_eeprom[ii]) != 0){ |
||||
printf("Write Error\n"); |
||||
error = 1; |
||||
} |
||||
} |
||||
break; |
||||
} |
||||
default:{ |
||||
goto usage; |
||||
} |
||||
} |
||||
|
||||
goto done; |
||||
usage: |
||||
printf ("Usage:\n%s\n", cmdtp->help); |
||||
|
||||
done: |
||||
return ret_val; |
||||
|
||||
} |
||||
|
||||
U_BOOT_CMD( |
||||
eeprom, 4, 0, do_eeprom, |
||||
"eeprom - read/write/copy to/from the PowerSpan II eeprom\n", |
||||
"eeprom r OFF [NUM]\n" |
||||
" - read NUM words starting at OFF\n" |
||||
"eeprom w OFF VAL\n" |
||||
" - write word VAL at offset OFF\n" |
||||
"eeprom g ADD\n" |
||||
" - store contents of eeprom at address ADD\n" |
||||
"eeprom p ADD\n" |
||||
" - put data stored at address ADD into the eeprom\n" |
||||
"eeprom d\n" |
||||
" - return eeprom to default contents\n" |
||||
); |
||||
|
||||
unsigned int PowerSpanRead(unsigned int theOffset){ |
||||
volatile unsigned int* ptr = (volatile unsigned int*)(PSPAN_BASEADDR + theOffset); |
||||
unsigned int ret_val; |
||||
|
||||
#ifdef VERBOSITY |
||||
if(gVerbosityLevel > 1){ |
||||
printf("PowerSpanRead: offset=%08x ", theOffset); |
||||
} |
||||
#endif |
||||
ret_val = *ptr; |
||||
PSII_SYNC(); |
||||
|
||||
#ifdef VERBOSITY |
||||
if(gVerbosityLevel > 1){ |
||||
printf("value=%08x\n", ret_val); |
||||
} |
||||
#endif |
||||
|
||||
return ret_val; |
||||
} |
||||
|
||||
void PowerSpanWrite(unsigned int theOffset, unsigned int theValue){ |
||||
volatile unsigned int* ptr = (volatile unsigned int*)(PSPAN_BASEADDR + theOffset); |
||||
#ifdef VERBOSITY |
||||
if(gVerbosityLevel > 1){ |
||||
printf("PowerSpanWrite: offset=%08x val=%02x\n", theOffset, theValue); |
||||
} |
||||
#endif |
||||
*ptr = theValue; |
||||
PSII_SYNC(); |
||||
} |
||||
|
||||
/**
|
||||
* Sets the indicated bits in the indicated register. |
||||
* @param theOffset [IN] the register to access. |
||||
* @param theMask [IN] bits set in theMask will be set in the register. |
||||
*/ |
||||
void PowerSpanSetBits(unsigned int theOffset, unsigned int theMask){ |
||||
volatile unsigned int* ptr = (volatile unsigned int*)(PSPAN_BASEADDR + theOffset); |
||||
unsigned int register_value; |
||||
|
||||
#ifdef VERBOSITY |
||||
if(gVerbosityLevel > 1){ |
||||
printf("PowerSpanSetBits: offset=%08x mask=%02x\n", theOffset, theMask); |
||||
} |
||||
#endif |
||||
register_value = *ptr; |
||||
PSII_SYNC(); |
||||
|
||||
register_value |= theMask; |
||||
*ptr = register_value; |
||||
PSII_SYNC(); |
||||
} |
||||
|
||||
/**
|
||||
* Clears the indicated bits in the indicated register. |
||||
* @param theOffset [IN] the register to access. |
||||
* @param theMask [IN] bits set in theMask will be cleared in the register. |
||||
*/ |
||||
void PowerSpanClearBits(unsigned int theOffset, unsigned int theMask){ |
||||
volatile unsigned int* ptr = (volatile unsigned int*)(PSPAN_BASEADDR + theOffset); |
||||
unsigned int register_value; |
||||
|
||||
#ifdef VERBOSITY |
||||
if(gVerbosityLevel > 1){ |
||||
printf("PowerSpanClearBits: offset=%08x mask=%02x\n", theOffset, theMask); |
||||
} |
||||
#endif |
||||
register_value = *ptr; |
||||
PSII_SYNC(); |
||||
|
||||
register_value &= ~theMask; |
||||
*ptr = register_value; |
||||
PSII_SYNC(); |
||||
} |
||||
|
||||
/**
|
||||
* Configures a slave image on the local bus, based on the parameters and some hardcoded system values. |
||||
* Slave Images are images that cause the PowerSpan II to be a master on the PCI bus. Thus, they |
||||
* are outgoing from the standpoint of the local bus. |
||||
* @param theImageIndex [IN] the PowerSpan II image to set (assumed to be 0-7). |
||||
* @param theBlockSize [IN] the block size of the image (as used by PowerSpan II: PB_SIx_CTL[BS]). |
||||
* @param theMemIOFlag [IN] if PX_TGT_USE_MEM_IO, this image will have the MEM_IO bit set. |
||||
* @param theEndianness [IN] the endian bits for the image (already shifted, use defines). |
||||
* @param theLocalBaseAddr [IN] the Local address for the image (assumed to be valid with provided block size). |
||||
* @param thePCIBaseAddr [IN] the PCI address for the image (assumed to be valid with provided block size). |
||||
*/ |
||||
int SetSlaveImage(int theImageIndex, unsigned int theBlockSize, int theMemIOFlag, int theEndianness, unsigned int theLocalBaseAddr, unsigned int thePCIBaseAddr){ |
||||
unsigned int reg_offset = theImageIndex * PB_SLAVE_IMAGE_OFF; |
||||
unsigned int reg_value = 0; |
||||
|
||||
/* Make sure that the Slave Image is disabled */ |
||||
PowerSpanClearBits((REGS_PB_SLAVE_CSR + reg_offset), PB_SLAVE_CSR_IMG_EN); |
||||
|
||||
/* Setup the mask required for requested PB Slave Image configuration */ |
||||
reg_value = PB_SLAVE_CSR_TA_EN | theEndianness | (theBlockSize << 24); |
||||
if(theMemIOFlag == PB_SLAVE_USE_MEM_IO){ |
||||
reg_value |= PB_SLAVE_CSR_MEM_IO; |
||||
} |
||||
|
||||
/* hardcoding the following:
|
||||
TA_EN = 1 |
||||
MD_EN = 0 |
||||
MODE = 0 |
||||
PRKEEP = 0 |
||||
RD_AMT = 0 |
||||
*/ |
||||
PowerSpanWrite((REGS_PB_SLAVE_CSR + reg_offset), reg_value); |
||||
|
||||
/* these values are not checked by software */ |
||||
PowerSpanWrite((REGS_PB_SLAVE_BADDR + reg_offset), theLocalBaseAddr); |
||||
PowerSpanWrite((REGS_PB_SLAVE_TADDR + reg_offset), thePCIBaseAddr); |
||||
|
||||
/* Enable the Slave Image */ |
||||
PowerSpanSetBits((REGS_PB_SLAVE_CSR + reg_offset), PB_SLAVE_CSR_IMG_EN); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/**
|
||||
* Configures a target image on the local bus, based on the parameters and some hardcoded system values. |
||||
* Target Images are used when the PowerSpan II is acting as a target for an access. Thus, they |
||||
* are incoming from the standpoint of the local bus. |
||||
* In order to behave better on the host PCI bus, if thePCIBaseAddr is NULL (0x00000000), then the PCI |
||||
* base address will not be updated; makes sense given that the hosts own memory should be mapped to |
||||
* PCI address 0x00000000. |
||||
* @param theImageIndex [IN] the PowerSpan II image to set. |
||||
* @param theBlockSize [IN] the block size of the image (as used by PowerSpan II: Px_TIx_CTL[BS]). |
||||
* @param theMemIOFlag [IN] if PX_TGT_USE_MEM_IO, this image will have the MEM_IO bit set. |
||||
* @param theEndianness [IN] the endian bits for the image (already shifted, use defines). |
||||
* @param theLocalBaseAddr [IN] the Local address for the image (assumed to be valid with provided block size). |
||||
* @param thePCIBaseAddr [IN] the PCI address for the image (assumed to be valid with provided block size). |
||||
*/ |
||||
int SetTargetImage(int theImageIndex, unsigned int theBlockSize, int theMemIOFlag, int theEndianness, unsigned int theLocalBaseAddr, unsigned int thePCIBaseAddr){ |
||||
unsigned int csr_reg_offset = theImageIndex * P1_TGT_IMAGE_OFF; |
||||
unsigned int pci_reg_offset = theImageIndex * P1_BST_OFF; |
||||
unsigned int reg_value = 0; |
||||
|
||||
/* Make sure that the Slave Image is disabled */ |
||||
PowerSpanClearBits((REGS_P1_TGT_CSR + csr_reg_offset), PB_SLAVE_CSR_IMG_EN); |
||||
|
||||
/* Setup the mask required for requested PB Slave Image configuration */ |
||||
reg_value = PX_TGT_CSR_TA_EN | PX_TGT_CSR_BAR_EN | (theBlockSize << 24) | PX_TGT_CSR_RTT_READ | PX_TGT_CSR_WTT_WFLUSH | theEndianness; |
||||
if(theMemIOFlag == PX_TGT_USE_MEM_IO){ |
||||
reg_value |= PX_TGT_MEM_IO; |
||||
} |
||||
|
||||
/* hardcoding the following:
|
||||
TA_EN = 1 |
||||
BAR_EN = 1 |
||||
MD_EN = 0 |
||||
MODE = 0 |
||||
DEST = 0 |
||||
RTT = 01010 |
||||
GBL = 0 |
||||
CI = 0 |
||||
WTT = 00010 |
||||
PRKEEP = 0 |
||||
MRA = 0 |
||||
RD_AMT = 0 |
||||
*/ |
||||
PowerSpanWrite((REGS_P1_TGT_CSR + csr_reg_offset), reg_value); |
||||
|
||||
PowerSpanWrite((REGS_P1_TGT_TADDR + csr_reg_offset), theLocalBaseAddr); |
||||
|
||||
if(thePCIBaseAddr != (unsigned int)NULL){ |
||||
PowerSpanWrite((REGS_P1_BST + pci_reg_offset), thePCIBaseAddr); |
||||
} |
||||
|
||||
/* Enable the Slave Image */ |
||||
PowerSpanSetBits((REGS_P1_TGT_CSR + csr_reg_offset), PB_SLAVE_CSR_IMG_EN); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int do_bridge(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ |
||||
char cmd; |
||||
int ret_val = 1; |
||||
unsigned int image_index; |
||||
unsigned int block_size; |
||||
unsigned int mem_io; |
||||
unsigned int local_addr; |
||||
unsigned int pci_addr; |
||||
int endianness; |
||||
|
||||
if(argc != 8){ |
||||
goto usage; |
||||
} |
||||
|
||||
cmd = argv[1][0]; |
||||
image_index = simple_strtoul(argv[2], NULL, 16); |
||||
block_size = simple_strtoul(argv[3], NULL, 16); |
||||
mem_io = simple_strtoul(argv[4], NULL, 16); |
||||
endianness = argv[5][0]; |
||||
local_addr = simple_strtoul(argv[6], NULL, 16); |
||||
pci_addr = simple_strtoul(argv[7], NULL, 16); |
||||
|
||||
|
||||
switch (cmd){ |
||||
case 'i':{ |
||||
if(tolower(endianness) == 'b'){ |
||||
endianness = PX_TGT_CSR_BIG_END; |
||||
} |
||||
else if(tolower(endianness) == 'l'){ |
||||
endianness = PX_TGT_CSR_TRUE_LEND; |
||||
} |
||||
else{ |
||||
goto usage; |
||||
} |
||||
SetTargetImage(image_index, block_size, mem_io, endianness, local_addr, pci_addr); |
||||
break; |
||||
} |
||||
case 'o':{ |
||||
if(tolower(endianness) == 'b'){ |
||||
endianness = PB_SLAVE_CSR_BIG_END; |
||||
} |
||||
else if(tolower(endianness) == 'l'){ |
||||
endianness = PB_SLAVE_CSR_TRUE_LEND; |
||||
} |
||||
else{ |
||||
goto usage; |
||||
} |
||||
SetSlaveImage(image_index, block_size, mem_io, endianness, local_addr, pci_addr); |
||||
break; |
||||
} |
||||
default:{ |
||||
goto usage; |
||||
} |
||||
} |
||||
|
||||
goto done; |
||||
usage: |
||||
printf ("Usage:\n%s\n", cmdtp->help); |
||||
|
||||
done: |
||||
return ret_val; |
||||
|
||||
} |
||||
|
||||
|
||||
|
@ -0,0 +1,170 @@ |
||||
/**
|
||||
* @file powerspan.h Header file for PowerSpan II code. |
||||
*/ |
||||
|
||||
/*
|
||||
* (C) Copyright 2005 |
||||
* AMIRIX Systems Inc. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
*/ |
||||
|
||||
#ifndef POWERSPAN_H |
||||
#define POWERSPAN_H |
||||
|
||||
#define CLEAR_MASTER_ABORT 0xdeadbeef |
||||
#define NO_DEVICE_FOUND -1 |
||||
#define ILLEGAL_REG_OFFSET -2 |
||||
#define I2C_BUSY -3 |
||||
#define I2C_ERR -4 |
||||
|
||||
#define REG_P1_CSR 0x004 |
||||
#define REGS_P1_BST 0x018 |
||||
#define REG_P1_ERR_CSR 0x150 |
||||
#define REG_P1_MISC_CSR 0x160 |
||||
#define REGS_P1_TGT_CSR 0x100 |
||||
#define REGS_P1_TGT_TADDR 0x104 |
||||
#define REGS_PB_SLAVE_CSR 0x200 |
||||
#define REGS_PB_SLAVE_TADDR 0x204 |
||||
#define REGS_PB_SLAVE_BADDR 0x208 |
||||
#define REG_CONFIG_ADDRESS 0x290 |
||||
#define REG_CONFIG_DATA 0x294 |
||||
#define REG_PB_ERR_CSR 0x2B0 |
||||
#define REG_PB_MISC_CSR 0x2C0 |
||||
#define REG_MISC_CSR 0x400 |
||||
#define REG_I2C_CSR 0x408 |
||||
#define REG_RESET_CSR 0x40C |
||||
#define REG_ISR0 0x410 |
||||
#define REG_ISR1 0x414 |
||||
#define REG_IER0 0x418 |
||||
#define REG_MBOX_MAP 0x420 |
||||
#define REG_HW_MAP 0x42C |
||||
#define REG_IDR 0x444 |
||||
|
||||
#define CSR_MEMORY_SPACE_ENABLE 0x00000002 |
||||
#define CSR_PCI_MASTER_ENABLE 0x00000004 |
||||
|
||||
#define P1_BST_OFF 0x04 |
||||
|
||||
#define PX_ERR_ERR_STATUS 0x01000000 |
||||
|
||||
#define PX_MISC_CSR_MAX_RETRY_MASK 0x00000F00 |
||||
#define PX_MISC_CSR_MAX_RETRY 0x00000F00 |
||||
#define PX_MISC_REG_BAR_ENABLE 0x00008000 |
||||
#define PB_MISC_TEA_ENABLE 0x00000010 |
||||
#define PB_MISC_MAC_TEA 0x00000040 |
||||
|
||||
#define P1_TGT_IMAGE_OFF 0x010 |
||||
#define PX_TGT_CSR_IMG_EN 0x80000000 |
||||
#define PX_TGT_CSR_TA_EN 0x40000000 |
||||
#define PX_TGT_CSR_BAR_EN 0x20000000 |
||||
#define PX_TGT_CSR_MD_EN 0x10000000 |
||||
#define PX_TGT_CSR_MODE 0x00800000 |
||||
#define PX_TGT_CSR_DEST 0x00400000 |
||||
#define PX_TGT_CSR_MEM_IO 0x00200000 |
||||
#define PX_TGT_CSR_GBL 0x00080000 |
||||
#define PX_TGT_CSR_CL 0x00040000 |
||||
#define PX_TGT_CSR_PRKEEP 0x00000080 |
||||
|
||||
#define PX_TGT_CSR_BS_MASK 0x0F000000 |
||||
#define PX_TGT_MEM_IO 0x00200000 |
||||
#define PX_TGT_CSR_RTT_MASK 0x001F0000 |
||||
#define PX_TGT_CSR_RTT_READ 0x000A0000 |
||||
#define PX_TGT_CSR_WTT_MASK 0x00001F00 |
||||
#define PX_TGT_CSR_WTT_WFLUSH 0x00000200 |
||||
#define PX_TGT_CSR_END_MASK 0x00000060 |
||||
#define PX_TGT_CSR_BIG_END 0x00000040 |
||||
#define PX_TGT_CSR_TRUE_LEND 0x00000060 |
||||
#define PX_TGT_CSR_RDAMT_MASK 0x00000007 |
||||
|
||||
#define PX_TGT_CSR_BS_64MB 0xa |
||||
#define PX_TGT_CSR_BS_16MB 0x8 |
||||
|
||||
#define PX_TGT_USE_MEM_IO 1 |
||||
#define PX_TGT_NOT_MEM_IO 0 |
||||
|
||||
#define PB_SLAVE_IMAGE_OFF 0x010 |
||||
#define PB_SLAVE_CSR_IMG_EN 0x80000000 |
||||
#define PB_SLAVE_CSR_TA_EN 0x40000000 |
||||
#define PB_SLAVE_CSR_MD_EN 0x20000000 |
||||
#define PB_SLAVE_CSR_MODE 0x00800000 |
||||
#define PB_SLAVE_CSR_DEST 0x00400000 |
||||
#define PB_SLAVE_CSR_MEM_IO 0x00200000 |
||||
#define PB_SLAVE_CSR_PRKEEP 0x00000080 |
||||
|
||||
#define PB_SLAVE_CSR_BS_MASK 0x1F000000 |
||||
#define PB_SLAVE_CSR_END_MASK 0x00000060 |
||||
#define PB_SLAVE_CSR_BIG_END 0x00000040 |
||||
#define PB_SLAVE_CSR_TRUE_LEND 0x00000060 |
||||
#define PB_SLAVE_CSR_RDAMT_MASK 0x00000007 |
||||
|
||||
#define PB_SLAVE_USE_MEM_IO 1 |
||||
#define PB_SLAVE_NOT_MEM_IO 0 |
||||
|
||||
|
||||
#define MISC_CSR_PCI1_LOCK 0x00000080 |
||||
|
||||
#define I2C_CSR_ADDR 0xFF000000 /* Specifies I2C Device Address to be Accessed */ |
||||
#define I2C_CSR_DATA 0x00FF0000 /* Specifies the Required Data for a Write */ |
||||
#define I2C_CSR_DEV_CODE 0x0000F000 /* Device Select. I2C 4-bit Device Code */ |
||||
#define I2C_CSR_CS 0x00000E00 /* Chip Select */ |
||||
#define I2C_CSR_RW 0x00000100 /* Read/Write */ |
||||
#define I2C_CSR_ACT 0x00000080 /* I2C Interface Active */ |
||||
#define I2C_CSR_ERR 0x00000040 /* Error */ |
||||
|
||||
#define I2C_EEPROM_DEV 0xa |
||||
#define I2C_EEPROM_CHIP_SEL 0 |
||||
|
||||
#define I2C_READ 0 |
||||
#define I2C_WRITE 1 |
||||
|
||||
#define RESET_CSR_EEPROM_LOAD 0x00000010 |
||||
|
||||
#define ISR_CLEAR_ALL 0xFFFFFFFF |
||||
|
||||
#define IER0_DMA_INTS_EN 0x0F000000 |
||||
#define IER0_PCI_1_EN 0x00400000 |
||||
#define IER0_HW_INTS_EN 0x003F0000 |
||||
#define IER0_MB_INTS_EN 0x000000FF |
||||
#define IER0_DEFAULT (IER0_DMA_INTS_EN | IER0_PCI_1_EN | IER0_HW_INTS_EN | IER0_MB_INTS_EN) |
||||
|
||||
#define MBOX_MAP_TO_INT4 0xCCCCCCCC |
||||
|
||||
#define HW_MAP_HW4_TO_INT4 0x000C0000 |
||||
|
||||
#define IDR_PCI_A_OUT 0x40000000 |
||||
#define IDR_MBOX_OUT 0x10000000 |
||||
|
||||
|
||||
int pci_read_config_byte(int bus, int dev, int fn, int reg, unsigned char* val); |
||||
int pci_write_config_byte(int bus, int dev, int fn, int reg, unsigned char val); |
||||
int pci_read_config_word(int bus, int dev, int fn, int reg, unsigned short* val); |
||||
int pci_write_config_word(int bus, int dev, int fn, int reg, unsigned short val); |
||||
int pci_read_config_dword(int bus, int dev, int fn, int reg, unsigned long* val); |
||||
int pci_write_config_dword(int bus, int dev, int fn, int reg, unsigned long val); |
||||
|
||||
unsigned int PowerSpanRead(unsigned int theOffset); |
||||
void PowerSpanWrite(unsigned int theOffset, unsigned int theValue); |
||||
|
||||
int I2CAccess(unsigned char theI2CAddress, unsigned char theDevCode, unsigned char theChipSel, unsigned char* theValue, int RWFlag); |
||||
|
||||
int PCIWriteConfig(int bus, int dev, int fn, int reg, int width, unsigned long val); |
||||
int PCIReadConfig(int bus, int dev, int fn, int reg, int width, unsigned long* val); |
||||
|
||||
int SetSlaveImage(int theImageIndex, unsigned int theBlockSize, int theMemIOFlag, int theEndianness, unsigned int theLocalBaseAddr, unsigned int thePCIBaseAddr); |
||||
int SetTargetImage(int theImageIndex, unsigned int theBlockSize, int theMemIOFlag, int theEndianness, unsigned int theLocalBaseAddr, unsigned int thePCIBaseAddr); |
||||
|
||||
#endif |
@ -0,0 +1,128 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* Peter De Schrijver (p2@mind.be), Mind Linux Solutions, NV. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
* |
||||
*/ |
||||
|
||||
#include <asm/u-boot.h> |
||||
#include <asm/processor.h> |
||||
#include <common.h> |
||||
#include <command.h> |
||||
#include <config.h> |
||||
|
||||
#include <ns16550.h> |
||||
|
||||
#if 0 |
||||
#include "serial.h" |
||||
#endif |
||||
|
||||
const NS16550_t COM_PORTS[] = { (NS16550_t) CFG_NS16550_COM1, (NS16550_t) CFG_NS16550_COM2 }; |
||||
|
||||
#undef CFG_DUART_CHAN |
||||
#define CFG_DUART_CHAN gComPort |
||||
static int gComPort = 0; |
||||
|
||||
int |
||||
serial_init (void) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate; |
||||
|
||||
(void)NS16550_init(COM_PORTS[0], clock_divisor); |
||||
gComPort = 0; |
||||
|
||||
return 0; |
||||
|
||||
} |
||||
|
||||
void |
||||
serial_putc(const char c) |
||||
{ |
||||
if (c == '\n'){ |
||||
NS16550_putc(COM_PORTS[CFG_DUART_CHAN], '\r'); |
||||
} |
||||
|
||||
NS16550_putc(COM_PORTS[CFG_DUART_CHAN], c); |
||||
} |
||||
|
||||
int |
||||
serial_getc(void) |
||||
{ |
||||
return NS16550_getc(COM_PORTS[CFG_DUART_CHAN]); |
||||
} |
||||
|
||||
int |
||||
serial_tstc(void) |
||||
{ |
||||
return NS16550_tstc(COM_PORTS[CFG_DUART_CHAN]); |
||||
} |
||||
|
||||
void |
||||
serial_setbrg (void) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate; |
||||
|
||||
#ifdef CFG_INIT_CHAN1 |
||||
NS16550_reinit(COM_PORTS[0], clock_divisor); |
||||
#endif |
||||
#ifdef CFG_INIT_CHAN2 |
||||
NS16550_reinit(COM_PORTS[1], clock_divisor); |
||||
#endif |
||||
} |
||||
|
||||
void |
||||
serial_puts (const char *s) |
||||
{ |
||||
while (*s) { |
||||
serial_putc (*s++); |
||||
} |
||||
} |
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB) |
||||
void |
||||
kgdb_serial_init(void) |
||||
{ |
||||
} |
||||
|
||||
void |
||||
putDebugChar (int c) |
||||
{ |
||||
serial_putc (c); |
||||
} |
||||
|
||||
void |
||||
putDebugStr (const char *str) |
||||
{ |
||||
serial_puts (str); |
||||
} |
||||
|
||||
int |
||||
getDebugChar (void) |
||||
{ |
||||
return serial_getc(); |
||||
} |
||||
|
||||
void |
||||
kgdb_interruptible (int yes) |
||||
{ |
||||
return; |
||||
} |
||||
#endif /* CFG_CMD_KGDB */ |
@ -0,0 +1,144 @@ |
||||
/* |
||||
* (C) Copyright 2000 |
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
*/ |
||||
|
||||
OUTPUT_ARCH(powerpc) |
||||
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); |
||||
/* Do we need any of these for elf? |
||||
__DYNAMIC = 0; */ |
||||
SECTIONS |
||||
{ |
||||
/* Read-only sections, merged into text segment: */ |
||||
. = + SIZEOF_HEADERS; |
||||
.interp : { *(.interp) } |
||||
.hash : { *(.hash) } |
||||
.dynsym : { *(.dynsym) } |
||||
.dynstr : { *(.dynstr) } |
||||
.rel.text : { *(.rel.text) } |
||||
.rela.text : { *(.rela.text) } |
||||
.rel.data : { *(.rel.data) } |
||||
.rela.data : { *(.rela.data) } |
||||
.rel.rodata : { *(.rel.rodata) } |
||||
.rela.rodata : { *(.rela.rodata) } |
||||
.rel.got : { *(.rel.got) } |
||||
.rela.got : { *(.rela.got) } |
||||
.rel.ctors : { *(.rel.ctors) } |
||||
.rela.ctors : { *(.rela.ctors) } |
||||
.rel.dtors : { *(.rel.dtors) } |
||||
.rela.dtors : { *(.rela.dtors) } |
||||
.rel.bss : { *(.rel.bss) } |
||||
.rela.bss : { *(.rela.bss) } |
||||
.rel.plt : { *(.rel.plt) } |
||||
.rela.plt : { *(.rela.plt) } |
||||
.init : { *(.init) } |
||||
.plt : { *(.plt) } |
||||
.text : |
||||
{ |
||||
/* WARNING - the following is hand-optimized to fit within */ |
||||
/* the sector layout of our flash chips! XXX FIXME XXX */ |
||||
|
||||
cpu/ppc4xx/start.o (.text) |
||||
board/amirix/ap1000/init.o (.text) |
||||
cpu/ppc4xx/kgdb.o (.text) |
||||
cpu/ppc4xx/traps.o (.text) |
||||
cpu/ppc4xx/interrupts.o (.text) |
||||
cpu/ppc4xx/serial.o (.text) |
||||
cpu/ppc4xx/cpu_init.o (.text) |
||||
cpu/ppc4xx/speed.o (.text) |
||||
common/dlmalloc.o (.text) |
||||
lib_generic/crc32.o (.text) |
||||
lib_ppc/extable.o (.text) |
||||
lib_generic/zlib.o (.text) |
||||
|
||||
/* . = env_offset;*/ |
||||
/* common/environment.o(.text)*/ |
||||
|
||||
*(.text) |
||||
*(.fixup) |
||||
*(.got1) |
||||
} |
||||
_etext = .; |
||||
PROVIDE (etext = .); |
||||
.rodata : |
||||
{ |
||||
*(.rodata) |
||||
*(.rodata1) |
||||
*(.rodata.str1.4) |
||||
} |
||||
.fini : { *(.fini) } =0 |
||||
.ctors : { *(.ctors) } |
||||
.dtors : { *(.dtors) } |
||||
|
||||
/* Read-write section, merged into data segment: */ |
||||
. = (. + 0x00FF) & 0xFFFFFF00; |
||||
_erotext = .; |
||||
PROVIDE (erotext = .); |
||||
.reloc : |
||||
{ |
||||
*(.got) |
||||
_GOT2_TABLE_ = .; |
||||
*(.got2) |
||||
_FIXUP_TABLE_ = .; |
||||
*(.fixup) |
||||
} |
||||
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; |
||||
__fixup_entries = (. - _FIXUP_TABLE_)>>2; |
||||
|
||||
.data : |
||||
{ |
||||
*(.data) |
||||
*(.data1) |
||||
*(.sdata) |
||||
*(.sdata2) |
||||
*(.dynamic) |
||||
CONSTRUCTORS |
||||
} |
||||
_edata = .; |
||||
PROVIDE (edata = .); |
||||
|
||||
__u_boot_cmd_start = .; |
||||
.u_boot_cmd : { *(.u_boot_cmd) } |
||||
__u_boot_cmd_end = .; |
||||
|
||||
|
||||
__start___ex_table = .; |
||||
__ex_table : { *(__ex_table) } |
||||
__stop___ex_table = .; |
||||
|
||||
. = ALIGN(256); |
||||
__init_begin = .; |
||||
.text.init : { *(.text.init) } |
||||
.data.init : { *(.data.init) } |
||||
. = ALIGN(256); |
||||
__init_end = .; |
||||
|
||||
__bss_start = .; |
||||
.bss : |
||||
{ |
||||
*(.sbss) *(.scommon) |
||||
*(.dynbss) |
||||
*(.bss) |
||||
*(COMMON) |
||||
} |
||||
_end = . ; |
||||
PROVIDE (end = .); |
||||
} |
@ -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 */ |
Loading…
Reference in new issue