uboot/board/esd/cpci750/pci.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2000
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 *
  23 */
  24/* PCI.c - PCI functions */
  25
  26
  27#include <common.h>
  28#ifdef CONFIG_PCI
  29#include <pci.h>
  30
  31#ifdef CONFIG_PCI_PNP
  32void pciauto_config_init(struct pci_controller *hose);
  33int  pciauto_region_allocate(struct pci_region* res, unsigned int size, unsigned int *bar);
  34#endif
  35
  36#include "../../Marvell/include/pci.h"
  37
  38#undef DEBUG
  39#undef IDE_SET_NATIVE_MODE
  40static unsigned int local_buses[] = { 0, 0 };
  41
  42static const unsigned char pci_irq_swizzle[2][PCI_MAX_DEVICES] = {
  43        {0, 0, 0, 0, 0, 0, 0, 27, 27, [9 ... PCI_MAX_DEVICES - 1] = 0 },
  44        {0, 0, 0, 0, 0, 0, 0, 29, 29, [9 ... PCI_MAX_DEVICES - 1] = 0 },
  45};
  46
  47#ifdef CONFIG_USE_CPCIDVI
  48typedef struct {
  49        unsigned int base;
  50        unsigned int init;
  51} GT_CPCIDVI_ROM_T;
  52
  53static GT_CPCIDVI_ROM_T gt_cpcidvi_rom = {0, 0};
  54#endif
  55
  56#ifdef DEBUG
  57static const unsigned int pci_bus_list[] = { PCI_0_MODE, PCI_1_MODE };
  58static void gt_pci_bus_mode_display (PCI_HOST host)
  59{
  60        unsigned int mode;
  61
  62
  63        mode = (GTREGREAD (pci_bus_list[host]) & (BIT4 | BIT5)) >> 4;
  64        switch (mode) {
  65        case 0:
  66                printf ("PCI %d bus mode: Conventional PCI\n", host);
  67                break;
  68        case 1:
  69                printf ("PCI %d bus mode: 66 MHz PCIX\n", host);
  70                break;
  71        case 2:
  72                printf ("PCI %d bus mode: 100 MHz PCIX\n", host);
  73                break;
  74        case 3:
  75                printf ("PCI %d bus mode: 133 MHz PCIX\n", host);
  76                break;
  77        default:
  78                printf ("Unknown BUS %d\n", mode);
  79        }
  80}
  81#endif
  82
  83static const unsigned int pci_p2p_configuration_reg[] = {
  84        PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION
  85};
  86
  87static const unsigned int pci_configuration_address[] = {
  88        PCI_0CONFIGURATION_ADDRESS, PCI_1CONFIGURATION_ADDRESS
  89};
  90
  91static const unsigned int pci_configuration_data[] = {
  92        PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
  93        PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER
  94};
  95
  96static const unsigned int pci_error_cause_reg[] = {
  97        PCI_0ERROR_CAUSE, PCI_1ERROR_CAUSE
  98};
  99
 100static const unsigned int pci_arbiter_control[] = {
 101        PCI_0ARBITER_CONTROL, PCI_1ARBITER_CONTROL
 102};
 103
 104static const unsigned int pci_address_space_en[] = {
 105        PCI_0_BASE_ADDR_REG_ENABLE, PCI_1_BASE_ADDR_REG_ENABLE
 106};
 107
 108static const unsigned int pci_snoop_control_base_0_low[] = {
 109        PCI_0SNOOP_CONTROL_BASE_0_LOW, PCI_1SNOOP_CONTROL_BASE_0_LOW
 110};
 111static const unsigned int pci_snoop_control_top_0[] = {
 112        PCI_0SNOOP_CONTROL_TOP_0, PCI_1SNOOP_CONTROL_TOP_0
 113};
 114
 115static const unsigned int pci_access_control_base_0_low[] = {
 116        PCI_0ACCESS_CONTROL_BASE_0_LOW, PCI_1ACCESS_CONTROL_BASE_0_LOW
 117};
 118static const unsigned int pci_access_control_top_0[] = {
 119        PCI_0ACCESS_CONTROL_TOP_0, PCI_1ACCESS_CONTROL_TOP_0
 120};
 121
 122static const unsigned int pci_scs_bank_size[2][4] = {
 123        {PCI_0SCS_0_BANK_SIZE, PCI_0SCS_1_BANK_SIZE,
 124         PCI_0SCS_2_BANK_SIZE, PCI_0SCS_3_BANK_SIZE},
 125        {PCI_1SCS_0_BANK_SIZE, PCI_1SCS_1_BANK_SIZE,
 126         PCI_1SCS_2_BANK_SIZE, PCI_1SCS_3_BANK_SIZE}
 127};
 128
 129static const unsigned int pci_p2p_configuration[] = {
 130        PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION
 131};
 132
 133
 134/********************************************************************
 135* pciWriteConfigReg - Write to a PCI configuration register
 136*                   - Make sure the GT is configured as a master before writing
 137*                     to another device on the PCI.
 138*                   - The function takes care of Big/Little endian conversion.
 139*
 140*
 141* Inputs:   unsigned int regOffset: The register offset as it apears in the GT spec
 142*                  (or any other PCI device spec)
 143*           pciDevNum: The device number needs to be addressed.
 144*
 145*  Configuration Address 0xCF8:
 146*
 147*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
 148*  |congif|Reserved|  Bus |Device|Function|Register|00|
 149*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
 150*
 151*********************************************************************/
 152void pciWriteConfigReg (PCI_HOST host, unsigned int regOffset,
 153                        unsigned int pciDevNum, unsigned int data)
 154{
 155        volatile unsigned int DataForAddrReg;
 156        unsigned int functionNum;
 157        unsigned int busNum = 0;
 158        unsigned int addr;
 159
 160        if (pciDevNum > 32)     /* illegal device Number */
 161                return;
 162        if (pciDevNum == SELF) {        /* configure our configuration space. */
 163                pciDevNum =
 164                        (GTREGREAD (pci_p2p_configuration_reg[host]) >> 24) &
 165                        0x1f;
 166                busNum = GTREGREAD (pci_p2p_configuration_reg[host]) &
 167                        0xff0000;
 168        }
 169        functionNum = regOffset & 0x00000700;
 170        pciDevNum = pciDevNum << 11;
 171        regOffset = regOffset & 0xfc;
 172        DataForAddrReg =
 173                (regOffset | pciDevNum | functionNum | busNum) | BIT31;
 174        GT_REG_WRITE (pci_configuration_address[host], DataForAddrReg);
 175        GT_REG_READ (pci_configuration_address[host], &addr);
 176        if (addr != DataForAddrReg)
 177                return;
 178        GT_REG_WRITE (pci_configuration_data[host], data);
 179}
 180
 181/********************************************************************
 182* pciReadConfigReg  - Read from a PCI0 configuration register
 183*                   - Make sure the GT is configured as a master before reading
 184*                     from another device on the PCI.
 185*                   - The function takes care of Big/Little endian conversion.
 186* INPUTS:   regOffset: The register offset as it apears in the GT spec (or PCI
 187*                       spec)
 188*           pciDevNum: The device number needs to be addressed.
 189* RETURNS: data , if the data == 0xffffffff check the master abort bit in the
 190*                 cause register to make sure the data is valid
 191*
 192*  Configuration Address 0xCF8:
 193*
 194*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
 195*  |congif|Reserved|  Bus |Device|Function|Register|00|
 196*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
 197*
 198*********************************************************************/
 199unsigned int pciReadConfigReg (PCI_HOST host, unsigned int regOffset,
 200                               unsigned int pciDevNum)
 201{
 202        volatile unsigned int DataForAddrReg;
 203        unsigned int data;
 204        unsigned int functionNum;
 205        unsigned int busNum = 0;
 206
 207        if (pciDevNum > 32)     /* illegal device Number */
 208                return 0xffffffff;
 209        if (pciDevNum == SELF) {        /* configure our configuration space. */
 210                pciDevNum =
 211                        (GTREGREAD (pci_p2p_configuration_reg[host]) >> 24) &
 212                        0x1f;
 213                busNum = GTREGREAD (pci_p2p_configuration_reg[host]) &
 214                        0xff0000;
 215        }
 216        functionNum = regOffset & 0x00000700;
 217        pciDevNum = pciDevNum << 11;
 218        regOffset = regOffset & 0xfc;
 219        DataForAddrReg =
 220                (regOffset | pciDevNum | functionNum | busNum) | BIT31;
 221        GT_REG_WRITE (pci_configuration_address[host], DataForAddrReg);
 222        GT_REG_READ (pci_configuration_address[host], &data);
 223        if (data != DataForAddrReg)
 224                return 0xffffffff;
 225        GT_REG_READ (pci_configuration_data[host], &data);
 226        return data;
 227}
 228
 229/********************************************************************
 230* pciOverBridgeWriteConfigReg - Write to a PCI configuration register where
 231*                               the agent is placed on another Bus. For more
 232*                               information read P2P in the PCI spec.
 233*
 234* Inputs:   unsigned int regOffset - The register offset as it apears in the
 235*           GT spec (or any other PCI device spec).
 236*           unsigned int pciDevNum - The device number needs to be addressed.
 237*           unsigned int busNum - On which bus does the Target agent connect
 238*                                 to.
 239*           unsigned int data - data to be written.
 240*
 241*  Configuration Address 0xCF8:
 242*
 243*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
 244*  |congif|Reserved|  Bus |Device|Function|Register|01|
 245*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
 246*
 247*  The configuration Address is configure as type-I (bits[1:0] = '01') due to
 248*   PCI spec referring to P2P.
 249*
 250*********************************************************************/
 251void pciOverBridgeWriteConfigReg (PCI_HOST host,
 252                                  unsigned int regOffset,
 253                                  unsigned int pciDevNum,
 254                                  unsigned int busNum, unsigned int data)
 255{
 256        unsigned int DataForReg;
 257        unsigned int functionNum;
 258
 259        functionNum = regOffset & 0x00000700;
 260        pciDevNum = pciDevNum << 11;
 261        regOffset = regOffset & 0xff;
 262        busNum = busNum << 16;
 263        if (pciDevNum == SELF) {        /* This board */
 264                DataForReg = (regOffset | pciDevNum | functionNum) | BIT0;
 265        } else {
 266                DataForReg = (regOffset | pciDevNum | functionNum | busNum) |
 267                        BIT31 | BIT0;
 268        }
 269        GT_REG_WRITE (pci_configuration_address[host], DataForReg);
 270        GT_REG_WRITE (pci_configuration_data[host], data);
 271}
 272
 273
 274/********************************************************************
 275* pciOverBridgeReadConfigReg  - Read from a PCIn configuration register where
 276*                               the agent target locate on another PCI bus.
 277*                             - Make sure the GT is configured as a master
 278*                               before reading from another device on the PCI.
 279*                             - The function takes care of Big/Little endian
 280*                               conversion.
 281* INPUTS:   regOffset: The register offset as it apears in the GT spec (or PCI
 282*                        spec). (configuration register offset.)
 283*           pciDevNum: The device number needs to be addressed.
 284*           busNum: the Bus number where the agent is place.
 285* RETURNS: data , if the data == 0xffffffff check the master abort bit in the
 286*                 cause register to make sure the data is valid
 287*
 288*  Configuration Address 0xCF8:
 289*
 290*       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
 291*  |congif|Reserved|  Bus |Device|Function|Register|01|
 292*  |Enable|        |Number|Number| Number | Number |  |    <=field Name
 293*
 294*********************************************************************/
 295unsigned int pciOverBridgeReadConfigReg (PCI_HOST host,
 296                                         unsigned int regOffset,
 297                                         unsigned int pciDevNum,
 298                                         unsigned int busNum)
 299{
 300        unsigned int DataForReg;
 301        unsigned int data;
 302        unsigned int functionNum;
 303
 304        functionNum = regOffset & 0x00000700;
 305        pciDevNum = pciDevNum << 11;
 306        regOffset = regOffset & 0xff;
 307        busNum = busNum << 16;
 308        if (pciDevNum == SELF) {        /* This board */
 309                DataForReg = (regOffset | pciDevNum | functionNum) | BIT31;
 310        } else {                /* agent on another bus */
 311
 312                DataForReg = (regOffset | pciDevNum | functionNum | busNum) |
 313                        BIT0 | BIT31;
 314        }
 315        GT_REG_WRITE (pci_configuration_address[host], DataForReg);
 316        GT_REG_READ (pci_configuration_data[host], &data);
 317        return data;
 318}
 319
 320
 321/********************************************************************
 322* pciGetRegOffset - Gets the register offset for this region config.
 323*
 324* INPUT:   Bus, Region - The bus and region we ask for its base address.
 325* OUTPUT:   N/A
 326* RETURNS: PCI register base address
 327*********************************************************************/
 328static unsigned int pciGetRegOffset (PCI_HOST host, PCI_REGION region)
 329{
 330        switch (host) {
 331        case PCI_HOST0:
 332                switch (region) {
 333                case PCI_IO:
 334                        return PCI_0I_O_LOW_DECODE_ADDRESS;
 335                case PCI_REGION0:
 336                        return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
 337                case PCI_REGION1:
 338                        return PCI_0MEMORY1_LOW_DECODE_ADDRESS;
 339                case PCI_REGION2:
 340                        return PCI_0MEMORY2_LOW_DECODE_ADDRESS;
 341                case PCI_REGION3:
 342                        return PCI_0MEMORY3_LOW_DECODE_ADDRESS;
 343                }
 344        case PCI_HOST1:
 345                switch (region) {
 346                case PCI_IO:
 347                        return PCI_1I_O_LOW_DECODE_ADDRESS;
 348                case PCI_REGION0:
 349                        return PCI_1MEMORY0_LOW_DECODE_ADDRESS;
 350                case PCI_REGION1:
 351                        return PCI_1MEMORY1_LOW_DECODE_ADDRESS;
 352                case PCI_REGION2:
 353                        return PCI_1MEMORY2_LOW_DECODE_ADDRESS;
 354                case PCI_REGION3:
 355                        return PCI_1MEMORY3_LOW_DECODE_ADDRESS;
 356                }
 357        }
 358        return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
 359}
 360
 361static unsigned int pciGetRemapOffset (PCI_HOST host, PCI_REGION region)
 362{
 363        switch (host) {
 364        case PCI_HOST0:
 365                switch (region) {
 366                case PCI_IO:
 367                        return PCI_0I_O_ADDRESS_REMAP;
 368                case PCI_REGION0:
 369                        return PCI_0MEMORY0_ADDRESS_REMAP;
 370                case PCI_REGION1:
 371                        return PCI_0MEMORY1_ADDRESS_REMAP;
 372                case PCI_REGION2:
 373                        return PCI_0MEMORY2_ADDRESS_REMAP;
 374                case PCI_REGION3:
 375                        return PCI_0MEMORY3_ADDRESS_REMAP;
 376                }
 377        case PCI_HOST1:
 378                switch (region) {
 379                case PCI_IO:
 380                        return PCI_1I_O_ADDRESS_REMAP;
 381                case PCI_REGION0:
 382                        return PCI_1MEMORY0_ADDRESS_REMAP;
 383                case PCI_REGION1:
 384                        return PCI_1MEMORY1_ADDRESS_REMAP;
 385                case PCI_REGION2:
 386                        return PCI_1MEMORY2_ADDRESS_REMAP;
 387                case PCI_REGION3:
 388                        return PCI_1MEMORY3_ADDRESS_REMAP;
 389                }
 390        }
 391        return PCI_0MEMORY0_ADDRESS_REMAP;
 392}
 393
 394/********************************************************************
 395* pciGetBaseAddress - Gets the base address of a PCI.
 396*           - If the PCI size is 0 then this base address has no meaning!!!
 397*
 398*
 399* INPUT:   Bus, Region - The bus and region we ask for its base address.
 400* OUTPUT:   N/A
 401* RETURNS: PCI base address.
 402*********************************************************************/
 403unsigned int pciGetBaseAddress (PCI_HOST host, PCI_REGION region)
 404{
 405        unsigned int regBase;
 406        unsigned int regEnd;
 407        unsigned int regOffset = pciGetRegOffset (host, region);
 408
 409        GT_REG_READ (regOffset, &regBase);
 410        GT_REG_READ (regOffset + 8, &regEnd);
 411
 412        if (regEnd <= regBase)
 413                return 0xffffffff;      /* ERROR !!! */
 414
 415        regBase = regBase << 16;
 416        return regBase;
 417}
 418
 419bool pciMapSpace (PCI_HOST host, PCI_REGION region, unsigned int remapBase,
 420                  unsigned int bankBase, unsigned int bankLength)
 421{
 422        unsigned int low = 0xfff;
 423        unsigned int high = 0x0;
 424        unsigned int regOffset = pciGetRegOffset (host, region);
 425        unsigned int remapOffset = pciGetRemapOffset (host, region);
 426
 427        if (bankLength != 0) {
 428                low = (bankBase >> 16) & 0xffff;
 429                high = ((bankBase + bankLength) >> 16) - 1;
 430        }
 431
 432        GT_REG_WRITE (regOffset, low | (1 << 24));      /* no swapping */
 433        GT_REG_WRITE (regOffset + 8, high);
 434
 435        if (bankLength != 0) {  /* must do AFTER writing maps */
 436                GT_REG_WRITE (remapOffset, remapBase >> 16);    /* sorry, 32 bits only.
 437                                                                   dont support upper 32
 438                                                                   in this driver */
 439        }
 440        return true;
 441}
 442
 443unsigned int pciGetSpaceBase (PCI_HOST host, PCI_REGION region)
 444{
 445        unsigned int low;
 446        unsigned int regOffset = pciGetRegOffset (host, region);
 447
 448        GT_REG_READ (regOffset, &low);
 449        return (low & 0xffff) << 16;
 450}
 451
 452unsigned int pciGetSpaceSize (PCI_HOST host, PCI_REGION region)
 453{
 454        unsigned int low, high;
 455        unsigned int regOffset = pciGetRegOffset (host, region);
 456
 457        GT_REG_READ (regOffset, &low);
 458        GT_REG_READ (regOffset + 8, &high);
 459        return ((high & 0xffff) + 1) << 16;
 460}
 461
 462
 463/* ronen - 7/Dec/03*/
 464/********************************************************************
 465* gtPciDisable/EnableInternalBAR - This function enable/disable PCI BARS.
 466* Inputs: one of the PCI BAR
 467*********************************************************************/
 468void gtPciEnableInternalBAR (PCI_HOST host, PCI_INTERNAL_BAR pciBAR)
 469{
 470        RESET_REG_BITS (pci_address_space_en[host], BIT0 << pciBAR);
 471}
 472
 473void gtPciDisableInternalBAR (PCI_HOST host, PCI_INTERNAL_BAR pciBAR)
 474{
 475        SET_REG_BITS (pci_address_space_en[host], BIT0 << pciBAR);
 476}
 477
 478/********************************************************************
 479* pciMapMemoryBank - Maps PCI_host memory bank "bank" for the slave.
 480*
 481* Inputs: base and size of PCI SCS
 482*********************************************************************/
 483void pciMapMemoryBank (PCI_HOST host, MEMORY_BANK bank,
 484                       unsigned int pciDramBase, unsigned int pciDramSize)
 485{
 486        /*ronen different function for 3rd bank. */
 487        unsigned int offset = (bank < 2) ? bank * 8 : 0x100 + (bank - 2) * 8;
 488
 489        pciDramBase = pciDramBase & 0xfffff000;
 490        pciDramBase = pciDramBase | (pciReadConfigReg (host,
 491                                                       PCI_SCS_0_BASE_ADDRESS
 492                                                       + offset,
 493                                                       SELF) & 0x00000fff);
 494        pciWriteConfigReg (host, PCI_SCS_0_BASE_ADDRESS + offset, SELF,
 495                           pciDramBase);
 496        if (pciDramSize == 0)
 497                pciDramSize++;
 498        GT_REG_WRITE (pci_scs_bank_size[host][bank], pciDramSize - 1);
 499        gtPciEnableInternalBAR (host, bank);
 500}
 501
 502/********************************************************************
 503* pciSetRegionFeatures - This function modifys one of the 8 regions with
 504*                         feature bits given as an input.
 505*                       - Be advised to check the spec before modifying them.
 506* Inputs: PCI_PROTECT_REGION region - one of the eight regions.
 507*         unsigned int features - See file: pci.h there are defintion for those
 508*                                 region features.
 509*         unsigned int baseAddress - The region base Address.
 510*         unsigned int topAddress - The region top Address.
 511* Returns: false if one of the parameters is erroneous true otherwise.
 512*********************************************************************/
 513bool pciSetRegionFeatures (PCI_HOST host, PCI_ACCESS_REGIONS region,
 514                           unsigned int features, unsigned int baseAddress,
 515                           unsigned int regionLength)
 516{
 517        unsigned int accessLow;
 518        unsigned int accessHigh;
 519        unsigned int accessTop = baseAddress + regionLength;
 520
 521        if (regionLength == 0) {        /* close the region. */
 522                pciDisableAccessRegion (host, region);
 523                return true;
 524        }
 525        /* base Address is store is bits [11:0] */
 526        accessLow = (baseAddress & 0xfff00000) >> 20;
 527        /* All the features are update according to the defines in pci.h (to be on
 528           the safe side we disable bits: [11:0] */
 529        accessLow = accessLow | (features & 0xfffff000);
 530        /* write to the Low Access Region register */
 531        GT_REG_WRITE (pci_access_control_base_0_low[host] + 0x10 * region,
 532                      accessLow);
 533
 534        accessHigh = (accessTop & 0xfff00000) >> 20;
 535
 536        /* write to the High Access Region register */
 537        GT_REG_WRITE (pci_access_control_top_0[host] + 0x10 * region,
 538                      accessHigh - 1);
 539        return true;
 540}
 541
 542/********************************************************************
 543* pciDisableAccessRegion - Disable The given Region by writing MAX size
 544*                           to its low Address and MIN size to its high Address.
 545*
 546* Inputs:   PCI_ACCESS_REGIONS region - The region we to be Disabled.
 547* Returns:  N/A.
 548*********************************************************************/
 549void pciDisableAccessRegion (PCI_HOST host, PCI_ACCESS_REGIONS region)
 550{
 551        /* writing back the registers default values. */
 552        GT_REG_WRITE (pci_access_control_base_0_low[host] + 0x10 * region,
 553                      0x01001fff);
 554        GT_REG_WRITE (pci_access_control_top_0[host] + 0x10 * region, 0);
 555}
 556
 557/********************************************************************
 558* pciArbiterEnable - Enables PCI-0`s Arbitration mechanism.
 559*
 560* Inputs:   N/A
 561* Returns:  true.
 562*********************************************************************/
 563bool pciArbiterEnable (PCI_HOST host)
 564{
 565        unsigned int regData;
 566
 567        GT_REG_READ (pci_arbiter_control[host], &regData);
 568        GT_REG_WRITE (pci_arbiter_control[host], regData | BIT31);
 569        return true;
 570}
 571
 572/********************************************************************
 573* pciArbiterDisable - Disable PCI-0`s Arbitration mechanism.
 574*
 575* Inputs:   N/A
 576* Returns:  true
 577*********************************************************************/
 578bool pciArbiterDisable (PCI_HOST host)
 579{
 580        unsigned int regData;
 581
 582        GT_REG_READ (pci_arbiter_control[host], &regData);
 583        GT_REG_WRITE (pci_arbiter_control[host], regData & 0x7fffffff);
 584        return true;
 585}
 586
 587/********************************************************************
 588* pciSetArbiterAgentsPriority - Priority setup for the PCI agents (Hi or Low)
 589*
 590* Inputs:   PCI_AGENT_PRIO internalAgent - priotity for internal agent.
 591*           PCI_AGENT_PRIO externalAgent0 - priotity for external#0 agent.
 592*           PCI_AGENT_PRIO externalAgent1 - priotity for external#1 agent.
 593*           PCI_AGENT_PRIO externalAgent2 - priotity for external#2 agent.
 594*           PCI_AGENT_PRIO externalAgent3 - priotity for external#3 agent.
 595*           PCI_AGENT_PRIO externalAgent4 - priotity for external#4 agent.
 596*           PCI_AGENT_PRIO externalAgent5 - priotity for external#5 agent.
 597* Returns:  true
 598*********************************************************************/
 599bool pciSetArbiterAgentsPriority (PCI_HOST host, PCI_AGENT_PRIO internalAgent,
 600                                  PCI_AGENT_PRIO externalAgent0,
 601                                  PCI_AGENT_PRIO externalAgent1,
 602                                  PCI_AGENT_PRIO externalAgent2,
 603                                  PCI_AGENT_PRIO externalAgent3,
 604                                  PCI_AGENT_PRIO externalAgent4,
 605                                  PCI_AGENT_PRIO externalAgent5)
 606{
 607        unsigned int regData;
 608        unsigned int writeData;
 609
 610        GT_REG_READ (pci_arbiter_control[host], &regData);
 611        writeData = (internalAgent << 7) + (externalAgent0 << 8) +
 612                (externalAgent1 << 9) + (externalAgent2 << 10) +
 613                (externalAgent3 << 11) + (externalAgent4 << 12) +
 614                (externalAgent5 << 13);
 615        regData = (regData & 0xffffc07f) | writeData;
 616        GT_REG_WRITE (pci_arbiter_control[host], regData & regData);
 617        return true;
 618}
 619
 620/********************************************************************
 621* pciParkingDisable - Park on last option disable, with this function you can
 622*                      disable the park on last mechanism for each agent.
 623*                      disabling this option for all agents results parking
 624*                      on the internal master.
 625*
 626* Inputs: PCI_AGENT_PARK internalAgent -  parking Disable for internal agent.
 627*         PCI_AGENT_PARK externalAgent0 - parking Disable for external#0 agent.
 628*         PCI_AGENT_PARK externalAgent1 - parking Disable for external#1 agent.
 629*         PCI_AGENT_PARK externalAgent2 - parking Disable for external#2 agent.
 630*         PCI_AGENT_PARK externalAgent3 - parking Disable for external#3 agent.
 631*         PCI_AGENT_PARK externalAgent4 - parking Disable for external#4 agent.
 632*         PCI_AGENT_PARK externalAgent5 - parking Disable for external#5 agent.
 633* Returns:  true
 634*********************************************************************/
 635bool pciParkingDisable (PCI_HOST host, PCI_AGENT_PARK internalAgent,
 636                        PCI_AGENT_PARK externalAgent0,
 637                        PCI_AGENT_PARK externalAgent1,
 638                        PCI_AGENT_PARK externalAgent2,
 639                        PCI_AGENT_PARK externalAgent3,
 640                        PCI_AGENT_PARK externalAgent4,
 641                        PCI_AGENT_PARK externalAgent5)
 642{
 643        unsigned int regData;
 644        unsigned int writeData;
 645
 646        GT_REG_READ (pci_arbiter_control[host], &regData);
 647        writeData = (internalAgent << 14) + (externalAgent0 << 15) +
 648                (externalAgent1 << 16) + (externalAgent2 << 17) +
 649                (externalAgent3 << 18) + (externalAgent4 << 19) +
 650                (externalAgent5 << 20);
 651        regData = (regData & ~(0x7f << 14)) | writeData;
 652        GT_REG_WRITE (pci_arbiter_control[host], regData);
 653        return true;
 654}
 655
 656/********************************************************************
 657* pciEnableBrokenAgentDetection - A master is said to be broken if it fails to
 658*                       respond to grant assertion within a window specified in
 659*                       the input value: 'brokenValue'.
 660*
 661* Inputs: unsigned char brokenValue -  A value which limits the Master to hold the
 662*                       grant without asserting frame.
 663* Returns:  Error for illegal broken value otherwise true.
 664*********************************************************************/
 665bool pciEnableBrokenAgentDetection (PCI_HOST host, unsigned char brokenValue)
 666{
 667        unsigned int data;
 668        unsigned int regData;
 669
 670        if (brokenValue > 0xf)
 671                return false;   /* brokenValue must be 4 bit */
 672        data = brokenValue << 3;
 673        GT_REG_READ (pci_arbiter_control[host], &regData);
 674        regData = (regData & 0xffffff87) | data;
 675        GT_REG_WRITE (pci_arbiter_control[host], regData | BIT1);
 676        return true;
 677}
 678
 679/********************************************************************
 680* pciDisableBrokenAgentDetection - This function disable the Broken agent
 681*                           Detection mechanism.
 682*                           NOTE: This operation may cause a dead lock on the
 683*                           pci0 arbitration.
 684*
 685* Inputs:   N/A
 686* Returns:  true.
 687*********************************************************************/
 688bool pciDisableBrokenAgentDetection (PCI_HOST host)
 689{
 690        unsigned int regData;
 691
 692        GT_REG_READ (pci_arbiter_control[host], &regData);
 693        regData = regData & 0xfffffffd;
 694        GT_REG_WRITE (pci_arbiter_control[host], regData);
 695        return true;
 696}
 697
 698/********************************************************************
 699* pciP2PConfig - This function set the PCI_n P2P configurate.
 700*                 For more information on the P2P read PCI spec.
 701*
 702* Inputs:  unsigned int SecondBusLow - Secondery PCI interface Bus Range Lower
 703*                                      Boundry.
 704*          unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper
 705*                                      Boundry.
 706*          unsigned int busNum - The CPI bus number to which the PCI interface
 707*                                      is connected.
 708*          unsigned int devNum - The PCI interface's device number.
 709*
 710* Returns:  true.
 711*********************************************************************/
 712bool pciP2PConfig (PCI_HOST host, unsigned int SecondBusLow,
 713                   unsigned int SecondBusHigh,
 714                   unsigned int busNum, unsigned int devNum)
 715{
 716        unsigned int regData;
 717
 718        regData = (SecondBusLow & 0xff) | ((SecondBusHigh & 0xff) << 8) |
 719                ((busNum & 0xff) << 16) | ((devNum & 0x1f) << 24);
 720        GT_REG_WRITE (pci_p2p_configuration[host], regData);
 721        return true;
 722}
 723
 724/********************************************************************
 725* pciSetRegionSnoopMode - This function modifys one of the 4 regions which
 726*                          supports Cache Coherency in the PCI_n interface.
 727* Inputs: region - One of the four regions.
 728*         snoopType - There is four optional Types:
 729*                        1. No Snoop.
 730*                        2. Snoop to WT region.
 731*                        3. Snoop to WB region.
 732*                        4. Snoop & Invalidate to WB region.
 733*         baseAddress - Base Address of this region.
 734*         regionLength - Region length.
 735* Returns: false if one of the parameters is wrong otherwise return true.
 736*********************************************************************/
 737bool pciSetRegionSnoopMode (PCI_HOST host, PCI_SNOOP_REGION region,
 738                            PCI_SNOOP_TYPE snoopType,
 739                            unsigned int baseAddress,
 740                            unsigned int regionLength)
 741{
 742        unsigned int snoopXbaseAddress;
 743        unsigned int snoopXtopAddress;
 744        unsigned int data;
 745        unsigned int snoopHigh = baseAddress + regionLength;
 746
 747        if ((region > PCI_SNOOP_REGION3) || (snoopType > PCI_SNOOP_WB))
 748                return false;
 749        snoopXbaseAddress =
 750                pci_snoop_control_base_0_low[host] + 0x10 * region;
 751        snoopXtopAddress = pci_snoop_control_top_0[host] + 0x10 * region;
 752        if (regionLength == 0) {        /* closing the region */
 753                GT_REG_WRITE (snoopXbaseAddress, 0x0000ffff);
 754                GT_REG_WRITE (snoopXtopAddress, 0);
 755                return true;
 756        }
 757        baseAddress = baseAddress & 0xfff00000; /* Granularity of 1MByte */
 758        data = (baseAddress >> 20) | snoopType << 12;
 759        GT_REG_WRITE (snoopXbaseAddress, data);
 760        snoopHigh = (snoopHigh & 0xfff00000) >> 20;
 761        GT_REG_WRITE (snoopXtopAddress, snoopHigh - 1);
 762        return true;
 763}
 764
 765static int gt_read_config_dword (struct pci_controller *hose,
 766                                 pci_dev_t dev, int offset, u32 * value)
 767{
 768        int bus = PCI_BUS (dev);
 769
 770        if ((bus == local_buses[0]) || (bus == local_buses[1])) {
 771                *value = pciReadConfigReg ((PCI_HOST) hose->cfg_addr,
 772                                           offset | (PCI_FUNC(dev) << 8),
 773                                           PCI_DEV (dev));
 774        } else {
 775                *value = pciOverBridgeReadConfigReg ((PCI_HOST) hose->cfg_addr,
 776                                                     offset | (PCI_FUNC(dev) << 8),
 777                                                     PCI_DEV (dev), bus);
 778        }
 779
 780        return 0;
 781}
 782
 783static int gt_write_config_dword (struct pci_controller *hose,
 784                                  pci_dev_t dev, int offset, u32 value)
 785{
 786        int bus = PCI_BUS (dev);
 787
 788        if ((bus == local_buses[0]) || (bus == local_buses[1])) {
 789                pciWriteConfigReg ((PCI_HOST) hose->cfg_addr,
 790                                   offset | (PCI_FUNC(dev) << 8),
 791                                   PCI_DEV (dev), value);
 792        } else {
 793                pciOverBridgeWriteConfigReg ((PCI_HOST) hose->cfg_addr,
 794                                             offset | (PCI_FUNC(dev) << 8),
 795                                             PCI_DEV (dev), bus,
 796                                             value);
 797        }
 798        return 0;
 799}
 800
 801
 802static void gt_setup_ide (struct pci_controller *hose,
 803                          pci_dev_t dev, struct pci_config_table *entry)
 804{
 805        static const int ide_bar[] = { 8, 4, 8, 4, 0, 0 };
 806        u32 bar_response, bar_value;
 807        int bar;
 808
 809        if (CPCI750_SLAVE_TEST != 0)
 810                return;
 811
 812        for (bar = 0; bar < 6; bar++) {
 813                /*ronen different function for 3rd bank. */
 814                unsigned int offset =
 815                        (bar < 2) ? bar * 8 : 0x100 + (bar - 2) * 8;
 816
 817                pci_hose_write_config_dword (hose, dev, PCI_BASE_ADDRESS_0 + offset,
 818                                             0x0);
 819                pci_hose_read_config_dword (hose, dev, PCI_BASE_ADDRESS_0 + offset,
 820                                            &bar_response);
 821
 822                pciauto_region_allocate (bar_response &
 823                                         PCI_BASE_ADDRESS_SPACE_IO ? hose->
 824                                         pci_io : hose->pci_mem, ide_bar[bar],
 825                                         &bar_value);
 826
 827                pci_hose_write_config_dword (hose, dev, PCI_BASE_ADDRESS_0 + bar * 4,
 828                                             bar_value);
 829        }
 830}
 831
 832#ifdef CONFIG_USE_CPCIDVI
 833static void gt_setup_cpcidvi (struct pci_controller *hose,
 834                              pci_dev_t dev, struct pci_config_table *entry)
 835{
 836        u32               bar_value, pci_response;
 837
 838        if (CPCI750_SLAVE_TEST != 0)
 839                return;
 840
 841        pci_hose_read_config_dword (hose, dev, PCI_COMMAND, &pci_response);
 842        pci_hose_write_config_dword (hose, dev, PCI_BASE_ADDRESS_0, 0xffffffff);
 843        pci_hose_read_config_dword (hose, dev, PCI_BASE_ADDRESS_0, &pci_response);
 844        pciauto_region_allocate (hose->pci_mem, 0x01000000, &bar_value);
 845        pci_hose_write_config_dword (hose, dev, PCI_BASE_ADDRESS_0, (bar_value & 0xffffff00));
 846        pci_hose_write_config_dword (hose, dev, PCI_ROM_ADDRESS, 0x0);
 847        pciauto_region_allocate (hose->pci_mem, 0x40000, &bar_value);
 848        pci_hose_write_config_dword (hose, dev, PCI_ROM_ADDRESS, (bar_value & 0xffffff00) | 0x01);
 849        gt_cpcidvi_rom.base = bar_value & 0xffffff00;
 850        gt_cpcidvi_rom.init = 1;
 851}
 852
 853unsigned char gt_cpcidvi_in8(unsigned int offset)
 854{
 855        unsigned char     data;
 856
 857        if (gt_cpcidvi_rom.init == 0) {
 858                return(0);
 859                }
 860        data = in8((offset & 0x04) + 0x3f000 + gt_cpcidvi_rom.base);
 861        return(data);
 862}
 863
 864void gt_cpcidvi_out8(unsigned int offset, unsigned char data)
 865{
 866        unsigned int      off;
 867
 868        if (gt_cpcidvi_rom.init == 0) {
 869                return;
 870        }
 871        off = data;
 872        off = ((off << 3) & 0x7f8) + (offset & 0x4) + 0x3e000 + gt_cpcidvi_rom.base;
 873        in8(off);
 874        return;
 875}
 876#endif
 877
 878/* TODO BJW: Change this for DB64360. This was pulled from the EV64260  */
 879/* and is curently not called *. */
 880#if 0
 881static void gt_fixup_irq (struct pci_controller *hose, pci_dev_t dev)
 882{
 883        unsigned char pin, irq;
 884
 885        pci_read_config_byte (dev, PCI_INTERRUPT_PIN, &pin);
 886
 887        if (pin == 1) {         /* only allow INT A */
 888                irq = pci_irq_swizzle[(PCI_HOST) hose->
 889                                      cfg_addr][PCI_DEV (dev)];
 890                if (irq)
 891                        pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq);
 892        }
 893}
 894#endif
 895
 896struct pci_config_table gt_config_table[] = {
 897#ifdef CONFIG_USE_CPCIDVI
 898        {PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69030, PCI_CLASS_DISPLAY_VGA,
 899         PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, gt_setup_cpcidvi},
 900#endif
 901        {PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE,
 902         PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, gt_setup_ide},
 903        {}
 904};
 905
 906struct pci_controller pci0_hose = {
 907/*    fixup_irq: gt_fixup_irq, */
 908        config_table:gt_config_table,
 909};
 910
 911struct pci_controller pci1_hose = {
 912/*    fixup_irq: gt_fixup_irq, */
 913        config_table:gt_config_table,
 914};
 915
 916void pci_init_board (void)
 917{
 918        unsigned int command;
 919        unsigned int slave;
 920#ifdef CONFIG_PCI_PNP
 921        unsigned int bar;
 922#endif
 923#ifdef DEBUG
 924        gt_pci_bus_mode_display (PCI_HOST0);
 925#endif
 926#ifdef CONFIG_USE_CPCIDVI
 927        gt_cpcidvi_rom.init = 0;
 928        gt_cpcidvi_rom.base = 0;
 929#endif
 930
 931        slave = CPCI750_SLAVE_TEST;
 932
 933        pci0_hose.config_table = gt_config_table;
 934        pci1_hose.config_table = gt_config_table;
 935
 936#ifdef CONFIG_USE_CPCIDVI
 937        gt_config_table[0].config_device =  gt_setup_cpcidvi;
 938#endif
 939        gt_config_table[1].config_device =  gt_setup_ide;
 940
 941        pci0_hose.first_busno = 0;
 942        pci0_hose.last_busno = 0xff;
 943        local_buses[0] = pci0_hose.first_busno;
 944
 945        /* PCI memory space */
 946        pci_set_region (pci0_hose.regions + 0,
 947                        CONFIG_SYS_PCI0_0_MEM_SPACE,
 948                        CONFIG_SYS_PCI0_0_MEM_SPACE,
 949                        CONFIG_SYS_PCI0_MEM_SIZE, PCI_REGION_MEM);
 950
 951        /* PCI I/O space */
 952        pci_set_region (pci0_hose.regions + 1,
 953                        CONFIG_SYS_PCI0_IO_SPACE_PCI,
 954                        CONFIG_SYS_PCI0_IO_SPACE, CONFIG_SYS_PCI0_IO_SIZE, PCI_REGION_IO);
 955
 956        pci_set_ops (&pci0_hose,
 957                     pci_hose_read_config_byte_via_dword,
 958                     pci_hose_read_config_word_via_dword,
 959                     gt_read_config_dword,
 960                     pci_hose_write_config_byte_via_dword,
 961                     pci_hose_write_config_word_via_dword,
 962                     gt_write_config_dword);
 963        pci0_hose.region_count = 2;
 964
 965        pci0_hose.cfg_addr = (unsigned int *) PCI_HOST0;
 966
 967        pci_register_hose (&pci0_hose);
 968        if (slave == 0) {
 969                pciArbiterEnable (PCI_HOST0);
 970                pciParkingDisable (PCI_HOST0, 1, 1, 1, 1, 1, 1, 1);
 971                command = pciReadConfigReg (PCI_HOST0, PCI_COMMAND, SELF);
 972                command |= PCI_COMMAND_MASTER;
 973                pciWriteConfigReg (PCI_HOST0, PCI_COMMAND, SELF, command);
 974                command = pciReadConfigReg (PCI_HOST0, PCI_COMMAND, SELF);
 975                command |= PCI_COMMAND_MEMORY;
 976                pciWriteConfigReg (PCI_HOST0, PCI_COMMAND, SELF, command);
 977
 978#ifdef CONFIG_PCI_PNP
 979                pciauto_config_init(&pci0_hose);
 980                pciauto_region_allocate(pci0_hose.pci_io, 0x400, &bar);
 981#endif
 982#ifdef CONFIG_PCI_SCAN_SHOW
 983                printf("PCI:   Bus Dev VenId DevId Class Int\n");
 984#endif
 985                pci0_hose.last_busno = pci_hose_scan_bus (&pci0_hose,
 986                                                          pci0_hose.first_busno);
 987
 988#ifdef DEBUG
 989                gt_pci_bus_mode_display (PCI_HOST1);
 990#endif
 991        } else {
 992                pciArbiterDisable (PCI_HOST0);
 993                pciParkingDisable (PCI_HOST0, 1, 1, 1, 1, 1, 1, 1);
 994                command = pciReadConfigReg (PCI_HOST0, PCI_COMMAND, SELF);
 995                command |= PCI_COMMAND_MASTER;
 996                pciWriteConfigReg (PCI_HOST0, PCI_COMMAND, SELF, command);
 997                command = pciReadConfigReg (PCI_HOST0, PCI_COMMAND, SELF);
 998                command |= PCI_COMMAND_MEMORY;
 999                pciWriteConfigReg (PCI_HOST0, PCI_COMMAND, SELF, command);
1000                pci0_hose.last_busno = pci0_hose.first_busno;
1001        }
1002        pci1_hose.first_busno = pci0_hose.last_busno + 1;
1003        pci1_hose.last_busno = 0xff;
1004        pci1_hose.current_busno = pci1_hose.first_busno;
1005        local_buses[1] = pci1_hose.first_busno;
1006
1007        /* PCI memory space */
1008        pci_set_region (pci1_hose.regions + 0,
1009                        CONFIG_SYS_PCI1_0_MEM_SPACE,
1010                        CONFIG_SYS_PCI1_0_MEM_SPACE,
1011                        CONFIG_SYS_PCI1_MEM_SIZE, PCI_REGION_MEM);
1012
1013        /* PCI I/O space */
1014        pci_set_region (pci1_hose.regions + 1,
1015                        CONFIG_SYS_PCI1_IO_SPACE_PCI,
1016                        CONFIG_SYS_PCI1_IO_SPACE, CONFIG_SYS_PCI1_IO_SIZE, PCI_REGION_IO);
1017
1018        pci_set_ops (&pci1_hose,
1019                     pci_hose_read_config_byte_via_dword,
1020                     pci_hose_read_config_word_via_dword,
1021                     gt_read_config_dword,
1022                     pci_hose_write_config_byte_via_dword,
1023                     pci_hose_write_config_word_via_dword,
1024                     gt_write_config_dword);
1025
1026        pci1_hose.region_count = 2;
1027
1028        pci1_hose.cfg_addr = (unsigned int *) PCI_HOST1;
1029
1030        pci_register_hose (&pci1_hose);
1031
1032        pciArbiterEnable (PCI_HOST1);
1033        pciParkingDisable (PCI_HOST1, 1, 1, 1, 1, 1, 1, 1);
1034
1035        command = pciReadConfigReg (PCI_HOST1, PCI_COMMAND, SELF);
1036        command |= PCI_COMMAND_MASTER;
1037        pciWriteConfigReg (PCI_HOST1, PCI_COMMAND, SELF, command);
1038
1039#ifdef CONFIG_PCI_PNP
1040        pciauto_config_init(&pci1_hose);
1041        pciauto_region_allocate(pci1_hose.pci_io, 0x400, &bar);
1042#endif
1043        pci1_hose.last_busno = pci_hose_scan_bus (&pci1_hose, pci1_hose.first_busno);
1044
1045        command = pciReadConfigReg (PCI_HOST1, PCI_COMMAND, SELF);
1046        command |= PCI_COMMAND_MEMORY;
1047        pciWriteConfigReg (PCI_HOST1, PCI_COMMAND, SELF, command);
1048
1049}
1050#endif /* of CONFIG_PCI */
1051