/* * 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) { char *s = getenv ("serial#"); 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) { char *s = getenv ("dramsize"); if (s != NULL) { if ((s[0] == '0') && ((s[1] == 'x') || (s[1] == 'X'))) { s += 2; } return (long int)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 ((char *)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");