blob: 743211fa979cf12c4702bb556f4943b052122439 [file] [log] [blame]
Wolfgang Denk56811f62005-10-09 01:04:33 +02001/*
2 * amirix.c: ppcboot platform support for AMIRIX board
3 *
4 * Copyright 2002 Mind NV
5 * Copyright 2003 AMIRIX Systems Inc.
6 *
7 * http://www.mind.be/
8 * http://www.amirix.com/
9 *
10 * Author : Peter De Schrijver (p2@mind.be)
11 * Frank Smith (smith@amirix.com)
12 *
13 * Derived from : Other platform support files in this tree, ml2
14 *
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.
21 *
22 */
23
24#include <common.h>
25#include <command.h>
26#include <asm/processor.h>
27
28#include "powerspan.h"
29#include "ap1000.h"
30
31int board_pre_init (void)
32{
33 return 0;
34}
35
36/** serial number and platform display at startup */
37int checkboard (void)
38{
39 unsigned char *s = getenv ("serial#");
40 unsigned char *e;
41
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;
46
47 /* add platform and device to banner */
48 switch(get_device()){
49 case AP1xx_AP107_TARGET:{
50 puts(AP1xx_AP107_TARGET_STR);
51 break;
52 }
53 case AP1xx_AP120_TARGET:{
54 puts(AP1xx_AP120_TARGET_STR);
55 break;
56 }
57 case AP1xx_AP130_TARGET:{
58 puts(AP1xx_AP130_TARGET_STR);
59 break;
60 }
61 case AP1xx_AP1070_TARGET:{
62 puts(AP1xx_AP1070_TARGET_STR);
63 break;
64 }
65 case AP1xx_AP1100_TARGET:{
66 puts(AP1xx_AP1100_TARGET_STR);
67 break;
68 }
69 default:{
70 puts(AP1xx_UNKNOWN_STR);
71 break;
72 }
73 }
74 puts(AP1xx_TARGET_STR);
75 puts(" with ");
76
77 switch(get_platform()){
78 case AP100_BASELINE_PLATFORM:
79 case AP1000_BASELINE_PLATFORM:{
80 puts(AP1xx_BASELINE_PLATFORM_STR);
81 break;
82 }
83 case AP1xx_QUADGE_PLATFORM:{
84 puts(AP1xx_QUADGE_PLATFORM_STR);
85 break;
86 }
87 case AP1xx_MGT_REF_PLATFORM:{
88 puts(AP1xx_MGT_REF_PLATFORM_STR);
89 break;
90 }
91 case AP1xx_STANDARD_PLATFORM:{
92 puts(AP1xx_STANDARD_PLATFORM_STR);
93 break;
94 }
95 case AP1xx_DUAL_PLATFORM:{
96 puts(AP1xx_DUAL_PLATFORM_STR);
97 break;
98 }
99 case AP1xx_BASE_SRAM_PLATFORM:{
100 puts(AP1xx_BASE_SRAM_PLATFORM_STR);
101 break;
102 }
103 case AP1xx_PCI_PCB_TESTPLATFORM:
104 case AP1000_PCI_PCB_TESTPLATFORM:{
105 puts(AP1xx_PCI_PCB_TESTPLATFORM_STR);
106 break;
107 }
108 case AP1xx_DUAL_GE_MEZZ_TESTPLATFORM:{
109 puts(AP1xx_DUAL_GE_MEZZ_TESTPLATFORM_STR);
110 break;
111 }
112 case AP1xx_SFP_MEZZ_TESTPLATFORM:{
113 puts(AP1xx_SFP_MEZZ_TESTPLATFORM_STR);
114 break;
115 }
116 default:{
117 puts(AP1xx_UNKNOWN_STR);
118 break;
119 }
120 }
121
122 if((get_platform() & AP1xx_TESTPLATFORM_MASK) != 0){
123 puts(AP1xx_TESTPLATFORM_STR);
124 }
125 else{
126 puts(AP1xx_PLATFORM_STR);
127 }
128
129 putc('\n');
130
131 puts ("Serial#: ");
132
133 if (!s) {
134 printf ("### No HW ID - assuming AMIRIX");
135 } else {
136 for (e = s; *e; ++e) {
137 if (*e == ' ')
138 break;
139 }
140
141 for (; s < e; ++s) {
142 putc (*s);
143 }
144 }
145
146 putc ('\n');
147
148 return (0);
149}
150
151
152long int initdram (int board_type)
153{
154 unsigned char *s = getenv ("dramsize");
155
156 if(s != NULL){
157 if((s[0] == '0') && ((s[1] == 'x') || (s[1] == 'X'))){
158 s += 2;
159 }
160 return simple_strtoul(s, NULL, 16);
161 }
162 else{
163 /* give all 64 MB */
164 return 64 * 1024 * 1024;
165 }
166}
167
168unsigned int get_platform(void){
169 unsigned int *revision_reg_ptr = (unsigned int *)AP1xx_FPGA_REV_ADDR;
170 return (*revision_reg_ptr & AP1xx_PLATFORM_MASK);
171}
172
173unsigned int get_device(void){
174 unsigned int *revision_reg_ptr = (unsigned int *)AP1xx_FPGA_REV_ADDR;
175
176 return (*revision_reg_ptr & AP1xx_TARGET_MASK);
177}
178
179#if 0 // loadace is not working; it appears to be a hardware issue with the system ace.
180/*
181 This function loads FPGA configurations from the SystemACE CompactFlash
182*/
183int do_loadace (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
184{
185 unsigned char *p = (unsigned char *)AP1000_SYSACE_REGBASE;
186 int cfg;
187
188 if((p[SYSACE_STATREG0] & 0x10) == 0) {
189 p[SYSACE_CTRLREG0] = 0x80;
190 printf ("\nNo CompactFlash Detected\n\n");
191 p[SYSACE_CTRLREG0] = 0x00;
192 return 1;
193 }
194
195 // reset configuration controller: | 0x80
196 // select cpflash & ~0x40
197 // cfg start | 0x20
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
203
204 p[SYSACE_CTRLREG0] = 0x80 | 0x20 | 0x08;
205 p[SYSACE_CTRLREG1] = 0x00;
206
207 // force config address if arg2 exists
208 if (argc == 2) {
209 cfg = simple_strtoul(argv[1], NULL, 10);
210
211 if(cfg > 7) {
212 printf ("\nInvalid Configuration\n\n");
213 p[SYSACE_CTRLREG0] = 0x00;
214 return 1;
215 }
216 // Set config address
217 p[SYSACE_CTRLREG1] = (cfg << 5);
218 // force cfgaddr
219 p[SYSACE_CTRLREG0] |= 0x04;
220
221 } else {
222 cfg = (p[SYSACE_STATREG1] & 0xE0) >> 5;
223 }
224
225 /* release configuration controller */
226 printf("\nLoading V2PRO with config %d...\n", cfg);
227 p[SYSACE_CTRLREG0] &= ~0x80;
228
229
230 while((p[SYSACE_STATREG1] & 0x01) == 0) {
231
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;
238 return 1;
239 }
240 }
241
242 p[SYSACE_CTRLREG0] |= 0x20;
243
244 return 0;
245}
246#endif
247
248/** Console command to display and set the software reconfigure byte
249 * <pre>
250 * swconfig - display the current value of the software reconfigure byte
251 * swconfig [#] - change the software reconfigure byte to #
252 * </pre>
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
257 * @return
258 * <pre>
259 * 0 if passed
260 * -1 if failed
261 * </pre>
262 */
263int do_swconfigbyte(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
264 unsigned char *sector_buffer = NULL;
265 unsigned char input_char;
266 int write_result;
267 unsigned int input_uint;
268
269 /* display value if no argument */
270 if(argc < 2){
271 printf("Software configuration byte is currently: 0x%02x\n",
272 *((unsigned char *) (SW_BYTE_SECTOR_ADDR + SW_BYTE_SECTOR_OFFSET)));
273 return 0;
274 }
275 else if(argc > 3){
276 printf("Too many arguments\n");
277 return -1;
278 }
279
280 /* if 3 arguments, 3rd argument is the address to use */
281 if(argc == 3){
282 input_uint = simple_strtoul(argv[1], NULL, 16);
283 sector_buffer = (unsigned char *)input_uint;
284 }
285 else{
286 sector_buffer = (unsigned char *)DEFAULT_TEMP_ADDR;
287 }
288
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;
294 }
295
296 memcpy(sector_buffer, (void *)SW_BYTE_SECTOR_ADDR, SW_BYTE_SECTOR_SIZE);
297 sector_buffer[SW_BYTE_SECTOR_OFFSET] = input_char;
298
299
300 printf("Erasing Flash...");
301 if (flash_sect_erase (SW_BYTE_SECTOR_ADDR, (SW_BYTE_SECTOR_ADDR + SW_BYTE_SECTOR_OFFSET))){
302 return -1;
303 }
304
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);
309 return -1;
310 }
311 else{
312 printf("done\n");
313 printf("Software configuration byte is now: 0x%02x\n",
314 *((unsigned char *) (SW_BYTE_SECTOR_ADDR + SW_BYTE_SECTOR_OFFSET)));
315 }
316
317 return 0;
318}
319
320#define ONE_SECOND 1000000
321
322int do_pause(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
323 int pause_time;
324 unsigned int delay_time;
325 int break_loop = 0;
326
327 /* display value if no argument */
328 if(argc < 2){
329 pause_time = 1;
330 }
331
332 else if(argc > 2){
333 printf("Too many arguments\n");
334 return -1;
335 }
336 else{
337 pause_time = simple_strtoul(argv[1], NULL, 0);
338 }
339
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){
343 udelay(delay_time);
344 if(serial_tstc() != 0){
345 break_loop = 1;
346 /* eat user key presses */
347 while(serial_tstc() != 0){
348 serial_getc();
349 }
350 }
351 }
352
353 return 0;
354}
355
356int 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)));
359 udelay (1000);
360 *((unsigned char*)AP1000_CPLD_BASE) = 1;
361
362 return 0;
363}
364
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
374
375int do_temp_sensor(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
376 char cmd;
377 int ret_val = 0;
378 unsigned char temp_byte;
379 int temp;
380 int temp_low;
381 int low;
382 int low_low;
383 int high;
384 int high_low;
385 int therm;
386 unsigned char user_data[4] = { 0 };
387 int user_data_count = 0;
388 int ii;
389
390 if(argc > 1){
391 cmd = argv[1][0];
392 }
393 else{
394 cmd = 's'; /* default to status */
395 }
396
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);
400 }
401 switch (cmd){
402 case 's':{
403
404 if(I2CAccess(0x2, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
405 goto fail;
406 }
407 printf("Status : 0x%02x ", temp_byte);
408 if(temp_byte & TEMP_BUSY_BIT){
409 printf("BUSY ");
410 }
411
412 if(temp_byte & TEMP_LHIGH_BIT){
413 printf("LHIGH ");
414 }
415
416 if(temp_byte & TEMP_LLOW_BIT){
417 printf("LLOW ");
418 }
419
420 if(temp_byte & TEMP_EHIGH_BIT){
421 printf("EHIGH ");
422 }
423
424 if(temp_byte & TEMP_ELOW_BIT){
425 printf("ELOW ");
426 }
427
428 if(temp_byte & TEMP_OPEN_BIT){
429 printf("OPEN ");
430 }
431
432 if(temp_byte & TEMP_ETHERM_BIT){
433 printf("ETHERM ");
434 }
435
436 if(temp_byte & TEMP_LTHERM_BIT){
437 printf("LTHERM");
438 }
439 printf("\n");
440
441 if(I2CAccess(0x3, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
442 goto fail;
443 }
444 printf("Config : 0x%02x ", temp_byte);
445
446 if(I2CAccess(0x4, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
447 printf("\n");
448 goto fail;
449 }
450 printf("Conversion: 0x%02x\n", temp_byte);
451 if(I2CAccess(0x22, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
452 goto fail;
453 }
454 printf("Cons Alert: 0x%02x ", temp_byte);
455
456 if(I2CAccess(0x21, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
457 printf("\n");
458 goto fail;
459 }
460 printf("Therm Hyst: %d\n", temp_byte);
461
462 if(I2CAccess(0x0, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
463 goto fail;
464 }
465 temp = temp_byte;
466 if(I2CAccess(0x6, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
467 goto fail;
468 }
469 low = temp_byte;
470 if(I2CAccess(0x5, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
471 goto fail;
472 }
473 high = temp_byte;
474 if(I2CAccess(0x20, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
475 goto fail;
476 }
477 therm = temp_byte;
478 printf("Local Temp: %2d Low: %2d High: %2d THERM: %2d\n", temp, low, high, therm);
479
480 if(I2CAccess(0x1, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
481 goto fail;
482 }
483 temp = temp_byte;
484 if(I2CAccess(0x10, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
485 goto fail;
486 }
487 temp_low = temp_byte;
488 if(I2CAccess(0x8, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
489 goto fail;
490 }
491 low = temp_byte;
492 if(I2CAccess(0x14, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
493 goto fail;
494 }
495 low_low = temp_byte;
496 if(I2CAccess(0x7, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
497 goto fail;
498 }
499 high = temp_byte;
500 if(I2CAccess(0x13, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
501 goto fail;
502 }
503 high_low = temp_byte;
504 if(I2CAccess(0x19, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
505 goto fail;
506 }
507 therm = temp_byte;
508 if(I2CAccess(0x11, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
509 goto fail;
510 }
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);
512 break;
513 }
514 case 'l':{ /* alter local limits : low, high, therm */
515 if(argc < 3){
516 goto usage;
517 }
518
519 /* low */
520 if(I2CAccess(0xC, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[0], I2C_WRITE) != 0){
521 goto fail;
522 }
523
524 if(user_data_count > 1){
525 /* high */
526 if(I2CAccess(0xB, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[1], I2C_WRITE) != 0){
527 goto fail;
528 }
529 }
530
531 if(user_data_count > 2){
532 /* therm */
533 if(I2CAccess(0x20, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[2], I2C_WRITE) != 0){
534 goto fail;
535 }
536 }
537 break;
538 }
539 case 'e':{ /* alter external limits: low, high, therm, offset */
540 if(argc < 3){
541 goto usage;
542 }
543
544 /* low */
545 if(I2CAccess(0xE, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[0], I2C_WRITE) != 0){
546 goto fail;
547 }
548
549 if(user_data_count > 1){
550 /* high */
551 if(I2CAccess(0xD, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[1], I2C_WRITE) != 0){
552 goto fail;
553 }
554 }
555
556 if(user_data_count > 2){
557 /* therm */
558 if(I2CAccess(0x19, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[2], I2C_WRITE) != 0){
559 goto fail;
560 }
561 }
562
563 if(user_data_count > 3){
564 /* offset */
565 if(I2CAccess(0x11, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[3], I2C_WRITE) != 0){
566 goto fail;
567 }
568 }
569 break;
570 }
571 case 'c':{ /* alter config settings: config, conv, cons alert, therm hyst */
572 if(argc < 3){
573 goto usage;
574 }
575
576 /* config */
577 if(I2CAccess(0x9, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[0], I2C_WRITE) != 0){
578 goto fail;
579 }
580
581 if(user_data_count > 1){
582 /* conversion */
583 if(I2CAccess(0xA, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[1], I2C_WRITE) != 0){
584 goto fail;
585 }
586 }
587
588 if(user_data_count > 2){
589 /* cons alert */
590 if(I2CAccess(0x22, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[2], I2C_WRITE) != 0){
591 goto fail;
592 }
593 }
594
595 if(user_data_count > 3){
596 /* therm hyst */
597 if(I2CAccess(0x21, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[3], I2C_WRITE) != 0){
598 goto fail;
599 }
600 }
601 break;
602 }
603 default:{
604 goto usage;
605 }
606 }
607
608 goto done;
609 fail:
610 printf("Access to sensor failed\n");
611 ret_val = -1;
612 goto done;
613 usage:
614 printf ("Usage:\n%s\n", cmdtp->help);
615
616 done:
617 return ret_val;
618}
619
620U_BOOT_CMD(
621 temp, 6, 0, do_temp_sensor,
622 "temp - interact with the temperature sensor\n",
623 "temp [s]\n"
624 " - Show status.\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"
631 "\n"
632 "All values can be decimal or hex (hex preceded with 0x).\n"
633 "Only whole numbers are supported for external limits.\n"
634);
635
636#if 0
637U_BOOT_CMD(
638 loadace, 2, 0, do_loadace,
639 "loadace - load fpga configuration from System ACE compact flash\n",
640 "N\n"
641 " - Load configuration N (0-7) from System ACE compact flash\n"
642 "loadace\n"
643 " - loads default configuration\n"
644);
645#endif
646
647U_BOOT_CMD(
648 swconfig, 2, 0, do_swconfigbyte,
649 "swconfig- display or modify the software configuration byte\n",
650 "N [ADDRESS]\n"
651 " - set software configuration byte to N, optionally use ADDRESS as\n"
652 " location of buffer for flash copy\n"
653 "swconfig\n"
654 " - display software configuration byte\n"
655);
656
657U_BOOT_CMD(
658 pause, 2, 0, do_pause,
659 "pause - sleep processor until any key is pressed with poll time of N seconds\n",
660 "N\n"
661 " - sleep processor until any key is pressed with poll time of N seconds\n"
662 "pause\n"
663 " - sleep processor until any key is pressed with poll time of 1 second\n"
664);
665
666U_BOOT_CMD(
667 swrecon, 1, 0, do_swreconfig,
668 "swrecon - trigger a board reconfigure to the software selected configuration\n",
669 "\n"
670 " - trigger a board reconfigure to the software selected configuration\n"
671);
672