f727061df7bb25826e13efb6e3d1175fc52aa3b2
[platform/kernel/u-boot.git] / board / amirix / ap1000 / powerspan.c
1 /**
2  * @file powerspan.c Source file for PowerSpan II code.
3  */
4
5 /*
6  * (C) Copyright 2005
7  * AMIRIX Systems Inc.
8  *
9  * See file CREDITS for list of people who contributed to this
10  * project.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License as
14  * published by the Free Software Foundation; either version 2 of
15  * the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25  * MA 02111-1307 USA
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 /** Write one byte with byte swapping.
38   * @param  addr [IN] the address to write to
39   * @param  val  [IN] the value to write
40   */
41 void 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 /** Read one byte with byte swapping.
55   * @param  addr  [IN] the address to read from
56   * @return the value at addr
57   */
58 unsigned 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 /** Write one 2-byte word with byte swapping.
74   * @param  addr  [IN] the address to write to
75   * @param  val   [IN] the value to write
76   */
77 void 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 /** Read one 2-byte word with byte swapping.
92   * @param  addr  [IN] the address to read from
93   * @return the value at addr
94   */
95 unsigned 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 /** Write one 4-byte word with byte swapping.
113   * @param  addr  [IN] the address to write to
114   * @param  val   [IN] the value to write
115   */
116 void 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 /** Read one 4-byte word with byte swapping.
135   * @param  addr  [IN] the address to read from
136   * @return the value at addr
137   */
138 unsigned 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
156 int 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         /* DEST bit hardcoded to 1: local pci is PCI-2 */
166         /* TYPE bit is hardcoded to 1: all config cycles are local */
167         conAdrVal = (1 << 24)
168                 | ((bus & 0xFF) << 16)
169                 | ((dev & 0xFF) << 11)
170                 | ((fn & 0x07) << 8)
171                 | (reg & 0xFC);
172
173         /* clear any pending master aborts */
174         write4 (REG_P1_CSR, CLEAR_MASTER_ABORT);
175
176         /* Load the conAdrVal value first, then read from pb_conf_data */
177         write4 (REG_CONFIG_ADDRESS, conAdrVal);
178         PSII_SYNC ();
179
180
181         /* Note: documentation does not match the pspan library code */
182         /* Note: *pData comes back as -1 if device is not present */
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         /* clear any pending master aborts */
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
210 int 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         /* DEST bit hardcoded to 1: local pci is PCI-2 */
220         /* TYPE bit is hardcoded to 1: all config cycles are local */
221         conAdrVal = (1 << 24)
222                 | ((bus & 0xFF) << 16)
223                 | ((dev & 0xFF) << 11)
224                 | ((fn & 0x07) << 8)
225                 | (reg & 0xFC);
226
227         /* clear any pending master aborts */
228         write4 (REG_P1_CSR, CLEAR_MASTER_ABORT);
229
230         /* Load the conAdrVal value first, then read from pb_conf_data */
231         write4 (REG_CONFIG_ADDRESS, conAdrVal);
232         PSII_SYNC ();
233
234
235         /* Note: documentation does not match the pspan library code */
236         /* Note: *pData comes back as -1 if device is not present */
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         /* clear any pending master aborts */
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
264 int 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
276 int 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
282 int 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
294 int 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
300 int 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
306 int 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 /* INCLUDE_PCI */
313
314 int 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
355 int 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
361 int 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
367 int do_eeprom (cmd_tbl_t * cmdtp, int flag, int argc, char *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
480 U_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\n");
491
492 unsigned 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
515 void 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  * Sets the indicated bits in the indicated register.
531  * @param theOffset [IN] the register to access.
532  * @param theMask   [IN] bits set in theMask will be set in the register.
533  */
534 void 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  * Clears the indicated bits in the indicated register.
556  * @param theOffset [IN] the register to access.
557  * @param theMask   [IN] bits set in theMask will be cleared in the register.
558  */
559 void 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  * Configures a slave image on the local bus, based on the parameters and some hardcoded system values.
581  * Slave Images are images that cause the PowerSpan II to be a master on the PCI bus.  Thus, they
582  *  are outgoing from the standpoint of the local bus.
583  * @param theImageIndex    [IN] the PowerSpan II image to set (assumed to be 0-7).
584  * @param theBlockSize     [IN] the block size of the image (as used by PowerSpan II: PB_SIx_CTL[BS]).
585  * @param theMemIOFlag     [IN] if PX_TGT_USE_MEM_IO, this image will have the MEM_IO bit set.
586  * @param theEndianness    [IN] the endian bits for the image (already shifted, use defines).
587  * @param theLocalBaseAddr [IN] the Local address for the image (assumed to be valid with provided block size).
588  * @param thePCIBaseAddr   [IN] the PCI address for the image (assumed to be valid with provided block size).
589  */
590 int 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         /* Make sure that the Slave Image is disabled */
598         PowerSpanClearBits ((REGS_PB_SLAVE_CSR + reg_offset),
599                             PB_SLAVE_CSR_IMG_EN);
600
601         /* Setup the mask required for requested PB Slave Image configuration */
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         /* hardcoding the following:
608            TA_EN = 1
609            MD_EN = 0
610            MODE  = 0
611            PRKEEP = 0
612            RD_AMT = 0
613          */
614         PowerSpanWrite ((REGS_PB_SLAVE_CSR + reg_offset), reg_value);
615
616         /* these values are not checked by software */
617         PowerSpanWrite ((REGS_PB_SLAVE_BADDR + reg_offset), theLocalBaseAddr);
618         PowerSpanWrite ((REGS_PB_SLAVE_TADDR + reg_offset), thePCIBaseAddr);
619
620         /* Enable the Slave Image */
621         PowerSpanSetBits ((REGS_PB_SLAVE_CSR + reg_offset),
622                           PB_SLAVE_CSR_IMG_EN);
623
624         return 0;
625 }
626
627 /**
628  * Configures a target image on the local bus, based on the parameters and some hardcoded system values.
629  * Target Images are used when the PowerSpan II is acting as a target for an access.  Thus, they
630  *  are incoming from the standpoint of the local bus.
631  * In order to behave better on the host PCI bus, if thePCIBaseAddr is NULL (0x00000000), then the PCI
632  *  base address will not be updated; makes sense given that the hosts own memory should be mapped to
633  *  PCI address 0x00000000.
634  * @param theImageIndex    [IN] the PowerSpan II image to set.
635  * @param theBlockSize     [IN] the block size of the image (as used by PowerSpan II: Px_TIx_CTL[BS]).
636  * @param theMemIOFlag     [IN] if PX_TGT_USE_MEM_IO, this image will have the MEM_IO bit set.
637  * @param theEndianness    [IN] the endian bits for the image (already shifted, use defines).
638  * @param theLocalBaseAddr [IN] the Local address for the image (assumed to be valid with provided block size).
639  * @param thePCIBaseAddr   [IN] the PCI address for the image (assumed to be valid with provided block size).
640  */
641 int 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         /* Make sure that the Slave Image is disabled */
651         PowerSpanClearBits ((REGS_P1_TGT_CSR + csr_reg_offset),
652                             PB_SLAVE_CSR_IMG_EN);
653
654         /* Setup the mask required for requested PB Slave Image configuration */
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         /* hardcoding the following:
663            TA_EN = 1
664            BAR_EN = 1
665            MD_EN = 0
666            MODE  = 0
667            DEST  = 0
668            RTT = 01010
669            GBL = 0
670            CI = 0
671            WTT = 00010
672            PRKEEP = 0
673            MRA = 0
674            RD_AMT = 0
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         /* Enable the Slave Image */
687         PowerSpanSetBits ((REGS_P1_TGT_CSR + csr_reg_offset),
688                           PB_SLAVE_CSR_IMG_EN);
689
690         return 0;
691 }
692
693 int do_bridge (cmd_tbl_t * cmdtp, int flag, int argc, char *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;
745 usage:
746         printf ("Usage:\n%s\n", cmdtp->help);
747
748 done:
749         return ret_val;
750 }