1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#include <common.h>
29#include <command.h>
30#include <asm/processor.h>
31#include "powerspan.h"
32#define tolower(x) x
33#include "ap1000.h"
34
35#ifdef INCLUDE_PCI
36
37
38
39
40
41void write1 (unsigned long addr, unsigned char val)
42{
43 volatile unsigned char *p = (volatile unsigned char *) addr;
44
45#ifdef VERBOSITY
46 if (gVerbosityLevel > 1) {
47 printf ("write1: addr=%08x val=%02x\n", addr, val);
48 }
49#endif
50 *p = val;
51 PSII_SYNC ();
52}
53
54
55
56
57
58unsigned char read1 (unsigned long addr)
59{
60 unsigned char val;
61 volatile unsigned char *p = (volatile unsigned char *) addr;
62
63 val = *p;
64 PSII_SYNC ();
65#ifdef VERBOSITY
66 if (gVerbosityLevel > 1) {
67 printf ("read1: addr=%08x val=%02x\n", addr, val);
68 }
69#endif
70 return val;
71}
72
73
74
75
76
77void write2 (unsigned long addr, unsigned short val)
78{
79 volatile unsigned short *p = (volatile unsigned short *) addr;
80
81#ifdef VERBOSITY
82 if (gVerbosityLevel > 1) {
83 printf ("write2: addr=%08x val=%04x -> *p=%04x\n", addr, val,
84 ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8));
85 }
86#endif
87 *p = ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8);
88 PSII_SYNC ();
89}
90
91
92
93
94
95unsigned short read2 (unsigned long addr)
96{
97 unsigned short val;
98 volatile unsigned short *p = (volatile unsigned short *) addr;
99
100 val = *p;
101 val = ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8);
102 PSII_SYNC ();
103#ifdef VERBOSITY
104 if (gVerbosityLevel > 1) {
105 printf ("read2: addr=%08x *p=%04x -> val=%04x\n", addr, *p,
106 val);
107 }
108#endif
109 return val;
110}
111
112
113
114
115
116void write4 (unsigned long addr, unsigned long val)
117{
118 volatile unsigned long *p = (volatile unsigned long *) addr;
119
120#ifdef VERBOSITY
121 if (gVerbosityLevel > 1) {
122 printf ("write4: addr=%08x val=%08x -> *p=%08x\n", addr, val,
123 ((val & 0xFF000000) >> 24) |
124 ((val & 0x000000FF) << 24) |
125 ((val & 0x00FF0000) >> 8) |
126 ((val & 0x0000FF00) << 8));
127 }
128#endif
129 *p = ((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
130 ((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8);
131 PSII_SYNC ();
132}
133
134
135
136
137
138unsigned long read4 (unsigned long addr)
139{
140 unsigned long val;
141 volatile unsigned long *p = (volatile unsigned long *) addr;
142
143 val = *p;
144 val = ((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
145 ((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8);
146 PSII_SYNC ();
147#ifdef VERBOSITY
148 if (gVerbosityLevel > 1) {
149 printf ("read4: addr=%08x *p=%08x -> val=%08x\n", addr, *p,
150 val);
151 }
152#endif
153 return val;
154}
155
156int PCIReadConfig (int bus, int dev, int fn, int reg, int width,
157 unsigned long *val)
158{
159 unsigned int conAdrVal;
160 unsigned int conDataReg = REG_CONFIG_DATA;
161 unsigned int status;
162 int ret_val = 0;
163
164
165
166
167 conAdrVal = (1 << 24)
168 | ((bus & 0xFF) << 16)
169 | ((dev & 0xFF) << 11)
170 | ((fn & 0x07) << 8)
171 | (reg & 0xFC);
172
173
174 write4 (REG_P1_CSR, CLEAR_MASTER_ABORT);
175
176
177 write4 (REG_CONFIG_ADDRESS, conAdrVal);
178 PSII_SYNC ();
179
180
181
182
183 switch (width) {
184 case 4:
185 *(unsigned int *) val = read4 (conDataReg);
186 break;
187 case 2:
188 *(unsigned short *) val = read2 (conDataReg);
189 break;
190 case 1:
191 *(unsigned char *) val = read1 (conDataReg);
192 break;
193 default:
194 ret_val = ILLEGAL_REG_OFFSET;
195 break;
196 }
197 PSII_SYNC ();
198
199
200 status = read4 (REG_P1_CSR);
201 if (status & CLEAR_MASTER_ABORT) {
202 ret_val = NO_DEVICE_FOUND;
203 write4 (REG_P1_CSR, CLEAR_MASTER_ABORT);
204 }
205
206 return ret_val;
207}
208
209
210int PCIWriteConfig (int bus, int dev, int fn, int reg, int width,
211 unsigned long val)
212{
213 unsigned int conAdrVal;
214 unsigned int conDataReg = REG_CONFIG_DATA;
215 unsigned int status;
216 int ret_val = 0;
217
218
219
220
221 conAdrVal = (1 << 24)
222 | ((bus & 0xFF) << 16)
223 | ((dev & 0xFF) << 11)
224 | ((fn & 0x07) << 8)
225 | (reg & 0xFC);
226
227
228 write4 (REG_P1_CSR, CLEAR_MASTER_ABORT);
229
230
231 write4 (REG_CONFIG_ADDRESS, conAdrVal);
232 PSII_SYNC ();
233
234
235
236
237 switch (width) {
238 case 4:
239 write4 (conDataReg, val);
240 break;
241 case 2:
242 write2 (conDataReg, val);
243 break;
244 case 1:
245 write1 (conDataReg, val);
246 break;
247 default:
248 ret_val = ILLEGAL_REG_OFFSET;
249 break;
250 }
251 PSII_SYNC ();
252
253
254 status = read4 (REG_P1_CSR);
255 if (status & CLEAR_MASTER_ABORT) {
256 ret_val = NO_DEVICE_FOUND;
257 write4 (REG_P1_CSR, CLEAR_MASTER_ABORT);
258 }
259
260 return ret_val;
261}
262
263
264int pci_read_config_byte (int bus, int dev, int fn, int reg,
265 unsigned char *val)
266{
267 unsigned long read_val;
268 int ret_val;
269
270 ret_val = PCIReadConfig (bus, dev, fn, reg, 1, &read_val);
271 *val = read_val & 0xFF;
272
273 return ret_val;
274}
275
276int pci_write_config_byte (int bus, int dev, int fn, int reg,
277 unsigned char val)
278{
279 return PCIWriteConfig (bus, dev, fn, reg, 1, val);
280}
281
282int pci_read_config_word (int bus, int dev, int fn, int reg,
283 unsigned short *val)
284{
285 unsigned long read_val;
286 int ret_val;
287
288 ret_val = PCIReadConfig (bus, dev, fn, reg, 2, &read_val);
289 *val = read_val & 0xFFFF;
290
291 return ret_val;
292}
293
294int pci_write_config_word (int bus, int dev, int fn, int reg,
295 unsigned short val)
296{
297 return PCIWriteConfig (bus, dev, fn, reg, 2, val);
298}
299
300int pci_read_config_dword (int bus, int dev, int fn, int reg,
301 unsigned long *val)
302{
303 return PCIReadConfig (bus, dev, fn, reg, 4, val);
304}
305
306int pci_write_config_dword (int bus, int dev, int fn, int reg,
307 unsigned long val)
308{
309 return PCIWriteConfig (bus, dev, fn, reg, 4, val);
310}
311
312#endif
313
314int I2CAccess (unsigned char theI2CAddress, unsigned char theDevCode,
315 unsigned char theChipSel, unsigned char *theValue, int RWFlag)
316{
317 int ret_val = 0;
318 unsigned int reg_value;
319
320 reg_value = PowerSpanRead (REG_I2C_CSR);
321
322 if (reg_value & I2C_CSR_ACT) {
323 printf ("Error: I2C busy\n");
324 ret_val = I2C_BUSY;
325 } else {
326 reg_value = ((theI2CAddress & 0xFF) << 24)
327 | ((theDevCode & 0x0F) << 12)
328 | ((theChipSel & 0x07) << 9)
329 | I2C_CSR_ERR;
330 if (RWFlag == I2C_WRITE) {
331 reg_value |= I2C_CSR_RW | ((*theValue & 0xFF) << 16);
332 }
333
334 PowerSpanWrite (REG_I2C_CSR, reg_value);
335 udelay (1);
336
337 do {
338 reg_value = PowerSpanRead (REG_I2C_CSR);
339
340 if ((reg_value & I2C_CSR_ACT) == 0) {
341 if (reg_value & I2C_CSR_ERR) {
342 ret_val = I2C_ERR;
343 } else {
344 *theValue =
345 (reg_value & I2C_CSR_DATA) >>
346 16;
347 }
348 }
349 } while (reg_value & I2C_CSR_ACT);
350 }
351
352 return ret_val;
353}
354
355int EEPROMRead (unsigned char theI2CAddress, unsigned char *theValue)
356{
357 return I2CAccess (theI2CAddress, I2C_EEPROM_DEV, I2C_EEPROM_CHIP_SEL,
358 theValue, I2C_READ);
359}
360
361int EEPROMWrite (unsigned char theI2CAddress, unsigned char theValue)
362{
363 return I2CAccess (theI2CAddress, I2C_EEPROM_DEV, I2C_EEPROM_CHIP_SEL,
364 &theValue, I2C_WRITE);
365}
366
367int do_eeprom (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
368{
369 char cmd;
370 int ret_val = 0;
371 unsigned int address = 0;
372 unsigned char value = 1;
373 unsigned char read_value;
374 int ii;
375 int error = 0;
376 unsigned char *mem_ptr;
377 unsigned char default_eeprom[] = EEPROM_DEFAULT;
378
379 if (argc < 2) {
380 goto usage;
381 }
382
383 cmd = argv[1][0];
384 if (argc > 2) {
385 address = simple_strtoul (argv[2], NULL, 16);
386 if (argc > 3) {
387 value = simple_strtoul (argv[3], NULL, 16) & 0xFF;
388 }
389 }
390
391 switch (cmd) {
392 case 'r':
393 if (address > 256) {
394 printf ("Illegal Address\n");
395 goto usage;
396 }
397 printf ("@0x%x: ", address);
398 for (ii = 0; ii < value; ii++) {
399 if (EEPROMRead (address + ii, &read_value) !=
400 0) {
401 printf ("Read Error\n");
402 } else {
403 printf ("0x%02x ", read_value);
404 }
405
406 if (((ii + 1) % 16) == 0) {
407 printf ("\n");
408 }
409 }
410 printf ("\n");
411 break;
412 case 'w':
413 if (address > 256) {
414 printf ("Illegal Address\n");
415 goto usage;
416 }
417 if (argc < 4) {
418 goto usage;
419 }
420 if (EEPROMWrite (address, value) != 0) {
421 printf ("Write Error\n");
422 }
423 break;
424 case 'g':
425 if (argc != 3) {
426 goto usage;
427 }
428 mem_ptr = (unsigned char *) address;
429 for (ii = 0; ((ii < EEPROM_LENGTH) && (error == 0));
430 ii++) {
431 if (EEPROMRead (ii, &read_value) != 0) {
432 printf ("Read Error\n");
433 error = 1;
434 } else {
435 *mem_ptr = read_value;
436 mem_ptr++;
437 }
438 }
439 break;
440 case 'p':
441 if (argc != 3) {
442 goto usage;
443 }
444 mem_ptr = (unsigned char *) address;
445 for (ii = 0; ((ii < EEPROM_LENGTH) && (error == 0));
446 ii++) {
447 if (EEPROMWrite (ii, *mem_ptr) != 0) {
448 printf ("Write Error\n");
449 error = 1;
450 }
451
452 mem_ptr++;
453 }
454 break;
455 case 'd':
456 if (argc != 2) {
457 goto usage;
458 }
459 for (ii = 0; ((ii < EEPROM_LENGTH) && (error == 0));
460 ii++) {
461 if (EEPROMWrite (ii, default_eeprom[ii]) != 0) {
462 printf ("Write Error\n");
463 error = 1;
464 }
465 }
466 break;
467 default:
468 goto usage;
469 }
470
471 goto done;
472 usage:
473 printf ("Usage:\n%s\n", cmdtp->help);
474
475 done:
476 return ret_val;
477
478}
479
480U_BOOT_CMD (eeprom, 4, 0, do_eeprom,
481 "read/write/copy to/from the PowerSpan II eeprom",
482 "eeprom r OFF [NUM]\n"
483 " - read NUM words starting at OFF\n"
484 "eeprom w OFF VAL\n"
485 " - write word VAL at offset OFF\n"
486 "eeprom g ADD\n"
487 " - store contents of eeprom at address ADD\n"
488 "eeprom p ADD\n"
489 " - put data stored at address ADD into the eeprom\n"
490 "eeprom d\n" " - return eeprom to default contents");
491
492unsigned int PowerSpanRead (unsigned int theOffset)
493{
494 volatile unsigned int *ptr =
495 (volatile unsigned int *) (PSPAN_BASEADDR + theOffset);
496 unsigned int ret_val;
497
498#ifdef VERBOSITY
499 if (gVerbosityLevel > 1) {
500 printf ("PowerSpanRead: offset=%08x ", theOffset);
501 }
502#endif
503 ret_val = *ptr;
504 PSII_SYNC ();
505
506#ifdef VERBOSITY
507 if (gVerbosityLevel > 1) {
508 printf ("value=%08x\n", ret_val);
509 }
510#endif
511
512 return ret_val;
513}
514
515void PowerSpanWrite (unsigned int theOffset, unsigned int theValue)
516{
517 volatile unsigned int *ptr =
518 (volatile unsigned int *) (PSPAN_BASEADDR + theOffset);
519#ifdef VERBOSITY
520 if (gVerbosityLevel > 1) {
521 printf ("PowerSpanWrite: offset=%08x val=%02x\n", theOffset,
522 theValue);
523 }
524#endif
525 *ptr = theValue;
526 PSII_SYNC ();
527}
528
529
530
531
532
533
534void PowerSpanSetBits (unsigned int theOffset, unsigned int theMask)
535{
536 volatile unsigned int *ptr =
537 (volatile unsigned int *) (PSPAN_BASEADDR + theOffset);
538 unsigned int register_value;
539
540#ifdef VERBOSITY
541 if (gVerbosityLevel > 1) {
542 printf ("PowerSpanSetBits: offset=%08x mask=%02x\n",
543 theOffset, theMask);
544 }
545#endif
546 register_value = *ptr;
547 PSII_SYNC ();
548
549 register_value |= theMask;
550 *ptr = register_value;
551 PSII_SYNC ();
552}
553
554
555
556
557
558
559void PowerSpanClearBits (unsigned int theOffset, unsigned int theMask)
560{
561 volatile unsigned int *ptr =
562 (volatile unsigned int *) (PSPAN_BASEADDR + theOffset);
563 unsigned int register_value;
564
565#ifdef VERBOSITY
566 if (gVerbosityLevel > 1) {
567 printf ("PowerSpanClearBits: offset=%08x mask=%02x\n",
568 theOffset, theMask);
569 }
570#endif
571 register_value = *ptr;
572 PSII_SYNC ();
573
574 register_value &= ~theMask;
575 *ptr = register_value;
576 PSII_SYNC ();
577}
578
579
580
581
582
583
584
585
586
587
588
589
590int SetSlaveImage (int theImageIndex, unsigned int theBlockSize,
591 int theMemIOFlag, int theEndianness,
592 unsigned int theLocalBaseAddr, unsigned int thePCIBaseAddr)
593{
594 unsigned int reg_offset = theImageIndex * PB_SLAVE_IMAGE_OFF;
595 unsigned int reg_value = 0;
596
597
598 PowerSpanClearBits ((REGS_PB_SLAVE_CSR + reg_offset),
599 PB_SLAVE_CSR_IMG_EN);
600
601
602 reg_value = PB_SLAVE_CSR_TA_EN | theEndianness | (theBlockSize << 24);
603 if (theMemIOFlag == PB_SLAVE_USE_MEM_IO) {
604 reg_value |= PB_SLAVE_CSR_MEM_IO;
605 }
606
607
608
609
610
611
612
613
614 PowerSpanWrite ((REGS_PB_SLAVE_CSR + reg_offset), reg_value);
615
616
617 PowerSpanWrite ((REGS_PB_SLAVE_BADDR + reg_offset), theLocalBaseAddr);
618 PowerSpanWrite ((REGS_PB_SLAVE_TADDR + reg_offset), thePCIBaseAddr);
619
620
621 PowerSpanSetBits ((REGS_PB_SLAVE_CSR + reg_offset),
622 PB_SLAVE_CSR_IMG_EN);
623
624 return 0;
625}
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641int SetTargetImage (int theImageIndex, unsigned int theBlockSize,
642 int theMemIOFlag, int theEndianness,
643 unsigned int theLocalBaseAddr,
644 unsigned int thePCIBaseAddr)
645{
646 unsigned int csr_reg_offset = theImageIndex * P1_TGT_IMAGE_OFF;
647 unsigned int pci_reg_offset = theImageIndex * P1_BST_OFF;
648 unsigned int reg_value = 0;
649
650
651 PowerSpanClearBits ((REGS_P1_TGT_CSR + csr_reg_offset),
652 PB_SLAVE_CSR_IMG_EN);
653
654
655 reg_value =
656 PX_TGT_CSR_TA_EN | PX_TGT_CSR_BAR_EN | (theBlockSize << 24) |
657 PX_TGT_CSR_RTT_READ | PX_TGT_CSR_WTT_WFLUSH | theEndianness;
658 if (theMemIOFlag == PX_TGT_USE_MEM_IO) {
659 reg_value |= PX_TGT_MEM_IO;
660 }
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676 PowerSpanWrite ((REGS_P1_TGT_CSR + csr_reg_offset), reg_value);
677
678 PowerSpanWrite ((REGS_P1_TGT_TADDR + csr_reg_offset),
679 theLocalBaseAddr);
680
681 if (thePCIBaseAddr != (unsigned int) NULL) {
682 PowerSpanWrite ((REGS_P1_BST + pci_reg_offset),
683 thePCIBaseAddr);
684 }
685
686
687 PowerSpanSetBits ((REGS_P1_TGT_CSR + csr_reg_offset),
688 PB_SLAVE_CSR_IMG_EN);
689
690 return 0;
691}
692
693int do_bridge (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
694{
695 char cmd;
696 int ret_val = 1;
697 unsigned int image_index;
698 unsigned int block_size;
699 unsigned int mem_io;
700 unsigned int local_addr;
701 unsigned int pci_addr;
702 int endianness;
703
704 if (argc != 8) {
705 goto usage;
706 }
707
708 cmd = argv[1][0];
709 image_index = simple_strtoul (argv[2], NULL, 16);
710 block_size = simple_strtoul (argv[3], NULL, 16);
711 mem_io = simple_strtoul (argv[4], NULL, 16);
712 endianness = argv[5][0];
713 local_addr = simple_strtoul (argv[6], NULL, 16);
714 pci_addr = simple_strtoul (argv[7], NULL, 16);
715
716
717 switch (cmd) {
718 case 'i':
719 if (tolower (endianness) == 'b') {
720 endianness = PX_TGT_CSR_BIG_END;
721 } else if (tolower (endianness) == 'l') {
722 endianness = PX_TGT_CSR_TRUE_LEND;
723 } else {
724 goto usage;
725 }
726 SetTargetImage (image_index, block_size, mem_io,
727 endianness, local_addr, pci_addr);
728 break;
729 case 'o':
730 if (tolower (endianness) == 'b') {
731 endianness = PB_SLAVE_CSR_BIG_END;
732 } else if (tolower (endianness) == 'l') {
733 endianness = PB_SLAVE_CSR_TRUE_LEND;
734 } else {
735 goto usage;
736 }
737 SetSlaveImage (image_index, block_size, mem_io,
738 endianness, local_addr, pci_addr);
739 break;
740 default:
741 goto usage;
742 }
743
744 goto done;
745usage:
746 printf ("Usage:\n%s\n", cmdtp->help);
747
748done:
749 return ret_val;
750}
751