2 * amirix.c: ppcboot platform support for AMIRIX board
4 * Copyright 2002 Mind NV
5 * Copyright 2003 AMIRIX Systems Inc.
8 * http://www.amirix.com/
10 * Author : Peter De Schrijver (p2@mind.be)
11 * Frank Smith (smith@amirix.com)
13 * Derived from : Other platform support files in this tree, ml2
15 * This software may be used and distributed according to the terms of
16 * the GNU General Public License (GPL) version 2, incorporated herein by
17 * reference. Drivers based on or derived from this code fall under the GPL
18 * and must retain the authorship, copyright and this license notice. This
19 * file is not a complete program and may only be used when the entire
20 * program is licensed under the GPL.
26 #include <asm/processor.h>
28 #include "powerspan.h"
31 int board_pre_init (void)
36 /** serial number and platform display at startup */
39 unsigned char *s
= getenv ("serial#");
42 /* After a loadace command, the SystemAce control register is left in a wonky state. */
43 /* this code did not work in board_pre_init */
44 unsigned char* p
= (unsigned char*)AP1000_SYSACE_REGBASE
;
45 p
[SYSACE_CTRLREG0
] = 0x0;
47 /* add platform and device to banner */
49 case AP1xx_AP107_TARGET
:{
50 puts(AP1xx_AP107_TARGET_STR
);
53 case AP1xx_AP120_TARGET
:{
54 puts(AP1xx_AP120_TARGET_STR
);
57 case AP1xx_AP130_TARGET
:{
58 puts(AP1xx_AP130_TARGET_STR
);
61 case AP1xx_AP1070_TARGET
:{
62 puts(AP1xx_AP1070_TARGET_STR
);
65 case AP1xx_AP1100_TARGET
:{
66 puts(AP1xx_AP1100_TARGET_STR
);
70 puts(AP1xx_UNKNOWN_STR
);
74 puts(AP1xx_TARGET_STR
);
77 switch(get_platform()){
78 case AP100_BASELINE_PLATFORM
:
79 case AP1000_BASELINE_PLATFORM
:{
80 puts(AP1xx_BASELINE_PLATFORM_STR
);
83 case AP1xx_QUADGE_PLATFORM
:{
84 puts(AP1xx_QUADGE_PLATFORM_STR
);
87 case AP1xx_MGT_REF_PLATFORM
:{
88 puts(AP1xx_MGT_REF_PLATFORM_STR
);
91 case AP1xx_STANDARD_PLATFORM
:{
92 puts(AP1xx_STANDARD_PLATFORM_STR
);
95 case AP1xx_DUAL_PLATFORM
:{
96 puts(AP1xx_DUAL_PLATFORM_STR
);
99 case AP1xx_BASE_SRAM_PLATFORM
:{
100 puts(AP1xx_BASE_SRAM_PLATFORM_STR
);
103 case AP1xx_PCI_PCB_TESTPLATFORM
:
104 case AP1000_PCI_PCB_TESTPLATFORM
:{
105 puts(AP1xx_PCI_PCB_TESTPLATFORM_STR
);
108 case AP1xx_DUAL_GE_MEZZ_TESTPLATFORM
:{
109 puts(AP1xx_DUAL_GE_MEZZ_TESTPLATFORM_STR
);
112 case AP1xx_SFP_MEZZ_TESTPLATFORM
:{
113 puts(AP1xx_SFP_MEZZ_TESTPLATFORM_STR
);
117 puts(AP1xx_UNKNOWN_STR
);
122 if((get_platform() & AP1xx_TESTPLATFORM_MASK
) != 0){
123 puts(AP1xx_TESTPLATFORM_STR
);
126 puts(AP1xx_PLATFORM_STR
);
134 printf ("### No HW ID - assuming AMIRIX");
136 for (e
= s
; *e
; ++e
) {
152 long int initdram (int board_type
)
154 unsigned char *s
= getenv ("dramsize");
157 if((s
[0] == '0') && ((s
[1] == 'x') || (s
[1] == 'X'))){
160 return simple_strtoul(s
, NULL
, 16);
164 return 64 * 1024 * 1024;
168 unsigned int get_platform(void){
169 unsigned int *revision_reg_ptr
= (unsigned int *)AP1xx_FPGA_REV_ADDR
;
170 return (*revision_reg_ptr
& AP1xx_PLATFORM_MASK
);
173 unsigned int get_device(void){
174 unsigned int *revision_reg_ptr
= (unsigned int *)AP1xx_FPGA_REV_ADDR
;
176 return (*revision_reg_ptr
& AP1xx_TARGET_MASK
);
179 #if 0 // loadace is not working; it appears to be a hardware issue with the system ace.
181 This function loads FPGA configurations from the SystemACE CompactFlash
183 int do_loadace (cmd_tbl_t
*cmdtp
, int flag
, int argc
, char *argv
[])
185 unsigned char *p
= (unsigned char *)AP1000_SYSACE_REGBASE
;
188 if((p
[SYSACE_STATREG0
] & 0x10) == 0) {
189 p
[SYSACE_CTRLREG0
] = 0x80;
190 printf ("\nNo CompactFlash Detected\n\n");
191 p
[SYSACE_CTRLREG0
] = 0x00;
195 // reset configuration controller: | 0x80
196 // select cpflash & ~0x40
198 // wait for cfgstart & ~0x10
199 // force cfgmode: | 0x08
200 // do no force cfgaddr: & ~0x04
201 // clear mpulock: & ~0x02
202 // do not force lock request & ~0x01
204 p
[SYSACE_CTRLREG0
] = 0x80 | 0x20 | 0x08;
205 p
[SYSACE_CTRLREG1
] = 0x00;
207 // force config address if arg2 exists
209 cfg
= simple_strtoul(argv
[1], NULL
, 10);
212 printf ("\nInvalid Configuration\n\n");
213 p
[SYSACE_CTRLREG0
] = 0x00;
216 // Set config address
217 p
[SYSACE_CTRLREG1
] = (cfg
<< 5);
219 p
[SYSACE_CTRLREG0
] |= 0x04;
222 cfg
= (p
[SYSACE_STATREG1
] & 0xE0) >> 5;
225 /* release configuration controller */
226 printf("\nLoading V2PRO with config %d...\n", cfg
);
227 p
[SYSACE_CTRLREG0
] &= ~0x80;
230 while((p
[SYSACE_STATREG1
] & 0x01) == 0) {
232 if(p
[SYSACE_ERRREG0
] & 0x80) {
233 // attempting to load an invalid configuration makes the cpflash
234 // appear to be removed. Reset here to avoid that problem
235 p
[SYSACE_CTRLREG0
] = 0x80;
236 printf("\nConfiguration %d Read Error\n\n", cfg
);
237 p
[SYSACE_CTRLREG0
] = 0x00;
242 p
[SYSACE_CTRLREG0
] |= 0x20;
248 /** Console command to display and set the software reconfigure byte
250 * swconfig - display the current value of the software reconfigure byte
251 * swconfig [#] - change the software reconfigure byte to #
253 * @param *cmdtp [IN] as passed by run_command (ignored)
254 * @param flag [IN] as passed by run_command (ignored)
255 * @param argc [IN] as passed by run_command if 1, display, if 2 change
256 * @param *argv[] [IN] contains the parameters to use
263 int do_swconfigbyte(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char *argv
[]){
264 unsigned char *sector_buffer
= NULL
;
265 unsigned char input_char
;
267 unsigned int input_uint
;
269 /* display value if no argument */
271 printf("Software configuration byte is currently: 0x%02x\n",
272 *((unsigned char *) (SW_BYTE_SECTOR_ADDR
+ SW_BYTE_SECTOR_OFFSET
)));
276 printf("Too many arguments\n");
280 /* if 3 arguments, 3rd argument is the address to use */
282 input_uint
= simple_strtoul(argv
[1], NULL
, 16);
283 sector_buffer
= (unsigned char *)input_uint
;
286 sector_buffer
= (unsigned char *)DEFAULT_TEMP_ADDR
;
289 input_char
= simple_strtoul(argv
[1], NULL
, 0);
290 if((input_char
& ~SW_BYTE_MASK
) != 0){
291 printf("Input of 0x%02x will be masked to 0x%02x\n",
292 input_char
, (input_char
& SW_BYTE_MASK
));
293 input_char
= input_char
& SW_BYTE_MASK
;
296 memcpy(sector_buffer
, (void *)SW_BYTE_SECTOR_ADDR
, SW_BYTE_SECTOR_SIZE
);
297 sector_buffer
[SW_BYTE_SECTOR_OFFSET
] = input_char
;
300 printf("Erasing Flash...");
301 if (flash_sect_erase (SW_BYTE_SECTOR_ADDR
, (SW_BYTE_SECTOR_ADDR
+ SW_BYTE_SECTOR_OFFSET
))){
305 printf("Writing to Flash... ");
306 write_result
= flash_write(sector_buffer
, SW_BYTE_SECTOR_ADDR
, SW_BYTE_SECTOR_SIZE
);
307 if (write_result
!= 0) {
308 flash_perror (write_result
);
313 printf("Software configuration byte is now: 0x%02x\n",
314 *((unsigned char *) (SW_BYTE_SECTOR_ADDR
+ SW_BYTE_SECTOR_OFFSET
)));
320 #define ONE_SECOND 1000000
322 int do_pause(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char *argv
[]){
324 unsigned int delay_time
;
327 /* display value if no argument */
333 printf("Too many arguments\n");
337 pause_time
= simple_strtoul(argv
[1], NULL
, 0);
340 printf("Pausing with a poll time of %d, press any key to reactivate\n", pause_time
);
341 delay_time
= pause_time
* ONE_SECOND
;
342 while(break_loop
== 0){
344 if(serial_tstc() != 0){
346 /* eat user key presses */
347 while(serial_tstc() != 0){
356 int do_swreconfig(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char *argv
[]){
357 printf("Triggering software reconfigure (software config byte is 0x%02x)...\n",
358 *((unsigned char *) (SW_BYTE_SECTOR_ADDR
+ SW_BYTE_SECTOR_OFFSET
)));
360 *((unsigned char*)AP1000_CPLD_BASE
) = 1;
365 #define GET_DECIMAL(low_byte) ((low_byte >> 5) * 125)
366 #define TEMP_BUSY_BIT 0x80
367 #define TEMP_LHIGH_BIT 0x40
368 #define TEMP_LLOW_BIT 0x20
369 #define TEMP_EHIGH_BIT 0x10
370 #define TEMP_ELOW_BIT 0x08
371 #define TEMP_OPEN_BIT 0x04
372 #define TEMP_ETHERM_BIT 0x02
373 #define TEMP_LTHERM_BIT 0x01
375 int do_temp_sensor(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char *argv
[]){
378 unsigned char temp_byte
;
386 unsigned char user_data
[4] = { 0 };
387 int user_data_count
= 0;
394 cmd
= 's'; /* default to status */
397 user_data_count
= argc
- 2;
398 for(ii
= 0;ii
< user_data_count
;ii
++){
399 user_data
[ii
] = simple_strtoul(argv
[2 + ii
], NULL
, 0);
404 if(I2CAccess(0x2, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &temp_byte
, I2C_READ
) != 0){
407 printf("Status : 0x%02x ", temp_byte
);
408 if(temp_byte
& TEMP_BUSY_BIT
){
412 if(temp_byte
& TEMP_LHIGH_BIT
){
416 if(temp_byte
& TEMP_LLOW_BIT
){
420 if(temp_byte
& TEMP_EHIGH_BIT
){
424 if(temp_byte
& TEMP_ELOW_BIT
){
428 if(temp_byte
& TEMP_OPEN_BIT
){
432 if(temp_byte
& TEMP_ETHERM_BIT
){
436 if(temp_byte
& TEMP_LTHERM_BIT
){
441 if(I2CAccess(0x3, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &temp_byte
, I2C_READ
) != 0){
444 printf("Config : 0x%02x ", temp_byte
);
446 if(I2CAccess(0x4, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &temp_byte
, I2C_READ
) != 0){
450 printf("Conversion: 0x%02x\n", temp_byte
);
451 if(I2CAccess(0x22, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &temp_byte
, I2C_READ
) != 0){
454 printf("Cons Alert: 0x%02x ", temp_byte
);
456 if(I2CAccess(0x21, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &temp_byte
, I2C_READ
) != 0){
460 printf("Therm Hyst: %d\n", temp_byte
);
462 if(I2CAccess(0x0, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &temp_byte
, I2C_READ
) != 0){
466 if(I2CAccess(0x6, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &temp_byte
, I2C_READ
) != 0){
470 if(I2CAccess(0x5, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &temp_byte
, I2C_READ
) != 0){
474 if(I2CAccess(0x20, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &temp_byte
, I2C_READ
) != 0){
478 printf("Local Temp: %2d Low: %2d High: %2d THERM: %2d\n", temp
, low
, high
, therm
);
480 if(I2CAccess(0x1, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &temp_byte
, I2C_READ
) != 0){
484 if(I2CAccess(0x10, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &temp_byte
, I2C_READ
) != 0){
487 temp_low
= temp_byte
;
488 if(I2CAccess(0x8, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &temp_byte
, I2C_READ
) != 0){
492 if(I2CAccess(0x14, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &temp_byte
, I2C_READ
) != 0){
496 if(I2CAccess(0x7, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &temp_byte
, I2C_READ
) != 0){
500 if(I2CAccess(0x13, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &temp_byte
, I2C_READ
) != 0){
503 high_low
= temp_byte
;
504 if(I2CAccess(0x19, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &temp_byte
, I2C_READ
) != 0){
508 if(I2CAccess(0x11, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &temp_byte
, I2C_READ
) != 0){
511 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
);
514 case 'l':{ /* alter local limits : low, high, therm */
520 if(I2CAccess(0xC, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &user_data
[0], I2C_WRITE
) != 0){
524 if(user_data_count
> 1){
526 if(I2CAccess(0xB, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &user_data
[1], I2C_WRITE
) != 0){
531 if(user_data_count
> 2){
533 if(I2CAccess(0x20, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &user_data
[2], I2C_WRITE
) != 0){
539 case 'e':{ /* alter external limits: low, high, therm, offset */
545 if(I2CAccess(0xE, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &user_data
[0], I2C_WRITE
) != 0){
549 if(user_data_count
> 1){
551 if(I2CAccess(0xD, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &user_data
[1], I2C_WRITE
) != 0){
556 if(user_data_count
> 2){
558 if(I2CAccess(0x19, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &user_data
[2], I2C_WRITE
) != 0){
563 if(user_data_count
> 3){
565 if(I2CAccess(0x11, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &user_data
[3], I2C_WRITE
) != 0){
571 case 'c':{ /* alter config settings: config, conv, cons alert, therm hyst */
577 if(I2CAccess(0x9, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &user_data
[0], I2C_WRITE
) != 0){
581 if(user_data_count
> 1){
583 if(I2CAccess(0xA, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &user_data
[1], I2C_WRITE
) != 0){
588 if(user_data_count
> 2){
590 if(I2CAccess(0x22, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &user_data
[2], I2C_WRITE
) != 0){
595 if(user_data_count
> 3){
597 if(I2CAccess(0x21, I2C_SENSOR_DEV
, I2C_SENSOR_CHIP_SEL
, &user_data
[3], I2C_WRITE
) != 0){
610 printf("Access to sensor failed\n");
614 printf ("Usage:\n%s\n", cmdtp
->help
);
621 temp
, 6, 0, do_temp_sensor
,
622 "temp - interact with the temperature sensor\n",
625 "temp l LOW [HIGH] [THERM]\n"
626 " - Set local limits.\n"
627 "temp e LOW [HIGH] [THERM] [OFFSET]\n"
628 " - Set external limits.\n"
629 "temp c CONFIG [CONVERSION] [CONS. ALERT] [THERM HYST]\n"
630 " - Set config options.\n"
632 "All values can be decimal or hex (hex preceded with 0x).\n"
633 "Only whole numbers are supported for external limits.\n"
638 loadace
, 2, 0, do_loadace
,
639 "loadace - load fpga configuration from System ACE compact flash\n",
641 " - Load configuration N (0-7) from System ACE compact flash\n"
643 " - loads default configuration\n"
648 swconfig
, 2, 0, do_swconfigbyte
,
649 "swconfig- display or modify the software configuration byte\n",
651 " - set software configuration byte to N, optionally use ADDRESS as\n"
652 " location of buffer for flash copy\n"
654 " - display software configuration byte\n"
658 pause
, 2, 0, do_pause
,
659 "pause - sleep processor until any key is pressed with poll time of N seconds\n",
661 " - sleep processor until any key is pressed with poll time of N seconds\n"
663 " - sleep processor until any key is pressed with poll time of 1 second\n"
667 swrecon
, 1, 0, do_swreconfig
,
668 "swrecon - trigger a board reconfigure to the software selected configuration\n",
670 " - trigger a board reconfigure to the software selected configuration\n"