From 7521af1c7d95ff087a4f7636ed050f4d4be91b59 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 9 Oct 2005 01:04:33 +0200 Subject: Add support for AP1000 board. Patch by James MacAulay, 07 Oct 2005 --- board/amirix/ap1000/ap1000.c | 672 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 672 insertions(+) create mode 100644 board/amirix/ap1000/ap1000.c (limited to 'board/amirix/ap1000/ap1000.c') diff --git a/board/amirix/ap1000/ap1000.c b/board/amirix/ap1000/ap1000.c new file mode 100644 index 0000000..743211f --- /dev/null +++ b/board/amirix/ap1000/ap1000.c @@ -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 +#include +#include + +#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 + *
+  * swconfig        - display the current value of the software reconfigure byte
+  * swconfig [#]    - change the software reconfigure byte to #
+  * 
+ * @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 + *
+  *      0 if passed
+  *     -1 if failed
+  * 
+ */ +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" +); + -- cgit v1.1