uboot/board/amirix/ap1000/powerspan.c
<<
>>
Prefs
   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  */
  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/** Read one byte with byte swapping.
  55  * @param  addr  [IN] the address to read from
  56  * @return the value at addr
  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/** 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  */
  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/** Read one 2-byte word with byte swapping.
  92  * @param  addr  [IN] the address to read from
  93  * @return the value at addr
  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/** 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  */
 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/** Read one 4-byte word with byte swapping.
 135  * @param  addr  [IN] the address to read from
 136  * @return the value at addr
 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        /* 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
 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        /* 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
 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 /* INCLUDE_PCI */
 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 * 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 */
 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 * 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 */
 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 * 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 */
 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        /* 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 */
 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        /* 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
 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