uboot/drivers/pci/pci.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
   3 * Andreas Heppel <aheppel@sysgo.de>
   4 *
   5 * (C) Copyright 2002, 2003
   6 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   7 *
   8 * SPDX-License-Identifier:     GPL-2.0+
   9 */
  10
  11/*
  12 * PCI routines
  13 */
  14
  15#include <common.h>
  16
  17#include <command.h>
  18#include <errno.h>
  19#include <asm/processor.h>
  20#include <asm/io.h>
  21#include <pci.h>
  22
  23DECLARE_GLOBAL_DATA_PTR;
  24
  25#define PCI_HOSE_OP(rw, size, type)                                     \
  26int pci_hose_##rw##_config_##size(struct pci_controller *hose,          \
  27                                  pci_dev_t dev,                        \
  28                                  int offset, type value)               \
  29{                                                                       \
  30        return hose->rw##_##size(hose, dev, offset, value);             \
  31}
  32
  33PCI_HOSE_OP(read, byte, u8 *)
  34PCI_HOSE_OP(read, word, u16 *)
  35PCI_HOSE_OP(read, dword, u32 *)
  36PCI_HOSE_OP(write, byte, u8)
  37PCI_HOSE_OP(write, word, u16)
  38PCI_HOSE_OP(write, dword, u32)
  39
  40#define PCI_OP(rw, size, type, error_code)                              \
  41int pci_##rw##_config_##size(pci_dev_t dev, int offset, type value)     \
  42{                                                                       \
  43        struct pci_controller *hose = pci_bus_to_hose(PCI_BUS(dev));    \
  44                                                                        \
  45        if (!hose)                                                      \
  46        {                                                               \
  47                error_code;                                             \
  48                return -1;                                              \
  49        }                                                               \
  50                                                                        \
  51        return pci_hose_##rw##_config_##size(hose, dev, offset, value); \
  52}
  53
  54PCI_OP(read, byte, u8 *, *value = 0xff)
  55PCI_OP(read, word, u16 *, *value = 0xffff)
  56PCI_OP(read, dword, u32 *, *value = 0xffffffff)
  57PCI_OP(write, byte, u8, )
  58PCI_OP(write, word, u16, )
  59PCI_OP(write, dword, u32, )
  60
  61#define PCI_READ_VIA_DWORD_OP(size, type, off_mask)                     \
  62int pci_hose_read_config_##size##_via_dword(struct pci_controller *hose,\
  63                                        pci_dev_t dev,                  \
  64                                        int offset, type val)           \
  65{                                                                       \
  66        u32 val32;                                                      \
  67                                                                        \
  68        if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0) { \
  69                *val = -1;                                              \
  70                return -1;                                              \
  71        }                                                               \
  72                                                                        \
  73        *val = (val32 >> ((offset & (int)off_mask) * 8));               \
  74                                                                        \
  75        return 0;                                                       \
  76}
  77
  78#define PCI_WRITE_VIA_DWORD_OP(size, type, off_mask, val_mask)          \
  79int pci_hose_write_config_##size##_via_dword(struct pci_controller *hose,\
  80                                             pci_dev_t dev,             \
  81                                             int offset, type val)      \
  82{                                                                       \
  83        u32 val32, mask, ldata, shift;                                  \
  84                                                                        \
  85        if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0)\
  86                return -1;                                              \
  87                                                                        \
  88        shift = ((offset & (int)off_mask) * 8);                         \
  89        ldata = (((unsigned long)val) & val_mask) << shift;             \
  90        mask = val_mask << shift;                                       \
  91        val32 = (val32 & ~mask) | ldata;                                \
  92                                                                        \
  93        if (pci_hose_write_config_dword(hose, dev, offset & 0xfc, val32) < 0)\
  94                return -1;                                              \
  95                                                                        \
  96        return 0;                                                       \
  97}
  98
  99PCI_READ_VIA_DWORD_OP(byte, u8 *, 0x03)
 100PCI_READ_VIA_DWORD_OP(word, u16 *, 0x02)
 101PCI_WRITE_VIA_DWORD_OP(byte, u8, 0x03, 0x000000ff)
 102PCI_WRITE_VIA_DWORD_OP(word, u16, 0x02, 0x0000ffff)
 103
 104/*
 105 *
 106 */
 107
 108static struct pci_controller* hose_head;
 109
 110struct pci_controller *pci_get_hose_head(void)
 111{
 112        if (gd->hose)
 113                return gd->hose;
 114
 115        return hose_head;
 116}
 117
 118void pci_register_hose(struct pci_controller* hose)
 119{
 120        struct pci_controller **phose = &hose_head;
 121
 122        while(*phose)
 123                phose = &(*phose)->next;
 124
 125        hose->next = NULL;
 126
 127        *phose = hose;
 128}
 129
 130struct pci_controller *pci_bus_to_hose(int bus)
 131{
 132        struct pci_controller *hose;
 133
 134        for (hose = pci_get_hose_head(); hose; hose = hose->next) {
 135                if (bus >= hose->first_busno && bus <= hose->last_busno)
 136                        return hose;
 137        }
 138
 139        printf("pci_bus_to_hose() failed\n");
 140        return NULL;
 141}
 142
 143struct pci_controller *find_hose_by_cfg_addr(void *cfg_addr)
 144{
 145        struct pci_controller *hose;
 146
 147        for (hose = pci_get_hose_head(); hose; hose = hose->next) {
 148                if (hose->cfg_addr == cfg_addr)
 149                        return hose;
 150        }
 151
 152        return NULL;
 153}
 154
 155int pci_last_busno(void)
 156{
 157        struct pci_controller *hose = pci_get_hose_head();
 158
 159        if (!hose)
 160                return -1;
 161
 162        while (hose->next)
 163                hose = hose->next;
 164
 165        return hose->last_busno;
 166}
 167
 168pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
 169{
 170        struct pci_controller * hose;
 171        pci_dev_t bdf;
 172        int bus;
 173
 174        for (hose = pci_get_hose_head(); hose; hose = hose->next) {
 175#ifdef CONFIG_SYS_SCSI_SCAN_BUS_REVERSE
 176                for (bus = hose->last_busno; bus >= hose->first_busno; bus--) {
 177#else
 178                for (bus = hose->first_busno; bus <= hose->last_busno; bus++) {
 179#endif
 180                        bdf = pci_hose_find_devices(hose, bus, ids, &index);
 181                        if (bdf != -1)
 182                                return bdf;
 183                }
 184        }
 185
 186        return -1;
 187}
 188
 189int pci_hose_config_device(struct pci_controller *hose,
 190                           pci_dev_t dev,
 191                           unsigned long io,
 192                           pci_addr_t mem,
 193                           unsigned long command)
 194{
 195        u32 bar_response;
 196        unsigned int old_command;
 197        pci_addr_t bar_value;
 198        pci_size_t bar_size;
 199        unsigned char pin;
 200        int bar, found_mem64;
 201
 202        debug("PCI Config: I/O=0x%lx, Memory=0x%llx, Command=0x%lx\n", io,
 203                (u64)mem, command);
 204
 205        pci_hose_write_config_dword(hose, dev, PCI_COMMAND, 0);
 206
 207        for (bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_5; bar += 4) {
 208                pci_hose_write_config_dword(hose, dev, bar, 0xffffffff);
 209                pci_hose_read_config_dword(hose, dev, bar, &bar_response);
 210
 211                if (!bar_response)
 212                        continue;
 213
 214                found_mem64 = 0;
 215
 216                /* Check the BAR type and set our address mask */
 217                if (bar_response & PCI_BASE_ADDRESS_SPACE) {
 218                        bar_size = ~(bar_response & PCI_BASE_ADDRESS_IO_MASK) + 1;
 219                        /* round up region base address to a multiple of size */
 220                        io = ((io - 1) | (bar_size - 1)) + 1;
 221                        bar_value = io;
 222                        /* compute new region base address */
 223                        io = io + bar_size;
 224                } else {
 225                        if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
 226                                PCI_BASE_ADDRESS_MEM_TYPE_64) {
 227                                u32 bar_response_upper;
 228                                u64 bar64;
 229                                pci_hose_write_config_dword(hose, dev, bar + 4,
 230                                        0xffffffff);
 231                                pci_hose_read_config_dword(hose, dev, bar + 4,
 232                                        &bar_response_upper);
 233
 234                                bar64 = ((u64)bar_response_upper << 32) | bar_response;
 235
 236                                bar_size = ~(bar64 & PCI_BASE_ADDRESS_MEM_MASK) + 1;
 237                                found_mem64 = 1;
 238                        } else {
 239                                bar_size = (u32)(~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1);
 240                        }
 241
 242                        /* round up region base address to multiple of size */
 243                        mem = ((mem - 1) | (bar_size - 1)) + 1;
 244                        bar_value = mem;
 245                        /* compute new region base address */
 246                        mem = mem + bar_size;
 247                }
 248
 249                /* Write it out and update our limit */
 250                pci_hose_write_config_dword (hose, dev, bar, (u32)bar_value);
 251
 252                if (found_mem64) {
 253                        bar += 4;
 254#ifdef CONFIG_SYS_PCI_64BIT
 255                        pci_hose_write_config_dword(hose, dev, bar,
 256                                (u32)(bar_value >> 32));
 257#else
 258                        pci_hose_write_config_dword(hose, dev, bar, 0x00000000);
 259#endif
 260                }
 261        }
 262
 263        /* Configure Cache Line Size Register */
 264        pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
 265
 266        /* Configure Latency Timer */
 267        pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
 268
 269        /* Disable interrupt line, if device says it wants to use interrupts */
 270        pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_PIN, &pin);
 271        if (pin != 0) {
 272                pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE,
 273                                           PCI_INTERRUPT_LINE_DISABLE);
 274        }
 275
 276        pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &old_command);
 277        pci_hose_write_config_dword(hose, dev, PCI_COMMAND,
 278                                     (old_command & 0xffff0000) | command);
 279
 280        return 0;
 281}
 282
 283/*
 284 *
 285 */
 286
 287struct pci_config_table *pci_find_config(struct pci_controller *hose,
 288                                         unsigned short class,
 289                                         unsigned int vendor,
 290                                         unsigned int device,
 291                                         unsigned int bus,
 292                                         unsigned int dev,
 293                                         unsigned int func)
 294{
 295        struct pci_config_table *table;
 296
 297        for (table = hose->config_table; table && table->vendor; table++) {
 298                if ((table->vendor == PCI_ANY_ID || table->vendor == vendor) &&
 299                    (table->device == PCI_ANY_ID || table->device == device) &&
 300                    (table->class  == PCI_ANY_ID || table->class  == class)  &&
 301                    (table->bus    == PCI_ANY_ID || table->bus    == bus)    &&
 302                    (table->dev    == PCI_ANY_ID || table->dev    == dev)    &&
 303                    (table->func   == PCI_ANY_ID || table->func   == func)) {
 304                        return table;
 305                }
 306        }
 307
 308        return NULL;
 309}
 310
 311void pci_cfgfunc_config_device(struct pci_controller *hose,
 312                               pci_dev_t dev,
 313                               struct pci_config_table *entry)
 314{
 315        pci_hose_config_device(hose, dev, entry->priv[0], entry->priv[1],
 316                entry->priv[2]);
 317}
 318
 319void pci_cfgfunc_do_nothing(struct pci_controller *hose,
 320                            pci_dev_t dev, struct pci_config_table *entry)
 321{
 322}
 323
 324/*
 325 * HJF: Changed this to return int. I think this is required
 326 * to get the correct result when scanning bridges
 327 */
 328extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
 329
 330#ifdef CONFIG_PCI_SCAN_SHOW
 331__weak int pci_print_dev(struct pci_controller *hose, pci_dev_t dev)
 332{
 333        if (dev == PCI_BDF(hose->first_busno, 0, 0))
 334                return 0;
 335
 336        return 1;
 337}
 338#endif /* CONFIG_PCI_SCAN_SHOW */
 339
 340int pci_hose_scan_bus(struct pci_controller *hose, int bus)
 341{
 342        unsigned int sub_bus, found_multi = 0;
 343        unsigned short vendor, device, class;
 344        unsigned char header_type;
 345#ifndef CONFIG_PCI_PNP
 346        struct pci_config_table *cfg;
 347#endif
 348        pci_dev_t dev;
 349#ifdef CONFIG_PCI_SCAN_SHOW
 350        static int indent = 0;
 351#endif
 352
 353        sub_bus = bus;
 354
 355        for (dev =  PCI_BDF(bus,0,0);
 356             dev <  PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1,
 357                                PCI_MAX_PCI_FUNCTIONS - 1);
 358             dev += PCI_BDF(0, 0, 1)) {
 359
 360                if (pci_skip_dev(hose, dev))
 361                        continue;
 362
 363                if (PCI_FUNC(dev) && !found_multi)
 364                        continue;
 365
 366                pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type);
 367
 368                pci_hose_read_config_word(hose, dev, PCI_VENDOR_ID, &vendor);
 369
 370                if (vendor == 0xffff || vendor == 0x0000)
 371                        continue;
 372
 373                if (!PCI_FUNC(dev))
 374                        found_multi = header_type & 0x80;
 375
 376                debug("PCI Scan: Found Bus %d, Device %d, Function %d\n",
 377                        PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev));
 378
 379                pci_hose_read_config_word(hose, dev, PCI_DEVICE_ID, &device);
 380                pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
 381
 382#ifdef CONFIG_PCI_FIXUP_DEV
 383                board_pci_fixup_dev(hose, dev, vendor, device, class);
 384#endif
 385
 386#ifdef CONFIG_PCI_SCAN_SHOW
 387                indent++;
 388
 389                /* Print leading space, including bus indentation */
 390                printf("%*c", indent + 1, ' ');
 391
 392                if (pci_print_dev(hose, dev)) {
 393                        printf("%02x:%02x.%-*x - %04x:%04x - %s\n",
 394                               PCI_BUS(dev), PCI_DEV(dev), 6 - indent, PCI_FUNC(dev),
 395                               vendor, device, pci_class_str(class >> 8));
 396                }
 397#endif
 398
 399#ifdef CONFIG_PCI_PNP
 400                sub_bus = max((unsigned int)pciauto_config_device(hose, dev),
 401                              sub_bus);
 402#else
 403                cfg = pci_find_config(hose, class, vendor, device,
 404                                      PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev));
 405                if (cfg) {
 406                        cfg->config_device(hose, dev, cfg);
 407                        sub_bus = max(sub_bus,
 408                                      (unsigned int)hose->current_busno);
 409                }
 410#endif
 411
 412#ifdef CONFIG_PCI_SCAN_SHOW
 413                indent--;
 414#endif
 415
 416                if (hose->fixup_irq)
 417                        hose->fixup_irq(hose, dev);
 418        }
 419
 420        return sub_bus;
 421}
 422
 423int pci_hose_scan(struct pci_controller *hose)
 424{
 425#if defined(CONFIG_PCI_BOOTDELAY)
 426        char *s;
 427        int i;
 428
 429        if (!gd->pcidelay_done) {
 430                /* wait "pcidelay" ms (if defined)... */
 431                s = getenv("pcidelay");
 432                if (s) {
 433                        int val = simple_strtoul(s, NULL, 10);
 434                        for (i = 0; i < val; i++)
 435                                udelay(1000);
 436                }
 437                gd->pcidelay_done = 1;
 438        }
 439#endif /* CONFIG_PCI_BOOTDELAY */
 440
 441#ifdef CONFIG_PCI_SCAN_SHOW
 442        puts("PCI:\n");
 443#endif
 444
 445        /*
 446         * Start scan at current_busno.
 447         * PCIe will start scan at first_busno+1.
 448         */
 449        /* For legacy support, ensure current >= first */
 450        if (hose->first_busno > hose->current_busno)
 451                hose->current_busno = hose->first_busno;
 452#ifdef CONFIG_PCI_PNP
 453        pciauto_config_init(hose);
 454#endif
 455        return pci_hose_scan_bus(hose, hose->current_busno);
 456}
 457
 458void pci_init(void)
 459{
 460        hose_head = NULL;
 461
 462        /* now call board specific pci_init()... */
 463        pci_init_board();
 464}
 465
 466/* Returns the address of the requested capability structure within the
 467 * device's PCI configuration space or 0 in case the device does not
 468 * support it.
 469 * */
 470int pci_hose_find_capability(struct pci_controller *hose, pci_dev_t dev,
 471                             int cap)
 472{
 473        int pos;
 474        u8 hdr_type;
 475
 476        pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &hdr_type);
 477
 478        pos = pci_hose_find_cap_start(hose, dev, hdr_type & 0x7F);
 479
 480        if (pos)
 481                pos = pci_find_cap(hose, dev, pos, cap);
 482
 483        return pos;
 484}
 485
 486/* Find the header pointer to the Capabilities*/
 487int pci_hose_find_cap_start(struct pci_controller *hose, pci_dev_t dev,
 488                            u8 hdr_type)
 489{
 490        u16 status;
 491
 492        pci_hose_read_config_word(hose, dev, PCI_STATUS, &status);
 493
 494        if (!(status & PCI_STATUS_CAP_LIST))
 495                return 0;
 496
 497        switch (hdr_type) {
 498        case PCI_HEADER_TYPE_NORMAL:
 499        case PCI_HEADER_TYPE_BRIDGE:
 500                return PCI_CAPABILITY_LIST;
 501        case PCI_HEADER_TYPE_CARDBUS:
 502                return PCI_CB_CAPABILITY_LIST;
 503        default:
 504                return 0;
 505        }
 506}
 507
 508int pci_find_cap(struct pci_controller *hose, pci_dev_t dev, int pos, int cap)
 509{
 510        int ttl = PCI_FIND_CAP_TTL;
 511        u8 id;
 512        u8 next_pos;
 513
 514        while (ttl--) {
 515                pci_hose_read_config_byte(hose, dev, pos, &next_pos);
 516                if (next_pos < CAP_START_POS)
 517                        break;
 518                next_pos &= ~3;
 519                pos = (int) next_pos;
 520                pci_hose_read_config_byte(hose, dev,
 521                                          pos + PCI_CAP_LIST_ID, &id);
 522                if (id == 0xff)
 523                        break;
 524                if (id == cap)
 525                        return pos;
 526                pos += PCI_CAP_LIST_NEXT;
 527        }
 528        return 0;
 529}
 530
 531/**
 532 * pci_find_next_ext_capability - Find an extended capability
 533 *
 534 * Returns the address of the next matching extended capability structure
 535 * within the device's PCI configuration space or 0 if the device does
 536 * not support it.  Some capabilities can occur several times, e.g., the
 537 * vendor-specific capability, and this provides a way to find them all.
 538 */
 539int pci_find_next_ext_capability(struct pci_controller *hose, pci_dev_t dev,
 540                                 int start, int cap)
 541{
 542        u32 header;
 543        int ttl, pos = PCI_CFG_SPACE_SIZE;
 544
 545        /* minimum 8 bytes per capability */
 546        ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
 547
 548        if (start)
 549                pos = start;
 550
 551        pci_hose_read_config_dword(hose, dev, pos, &header);
 552        if (header == 0xffffffff || header == 0)
 553                return 0;
 554
 555        while (ttl-- > 0) {
 556                if (PCI_EXT_CAP_ID(header) == cap && pos != start)
 557                        return pos;
 558
 559                pos = PCI_EXT_CAP_NEXT(header);
 560                if (pos < PCI_CFG_SPACE_SIZE)
 561                        break;
 562
 563                pci_hose_read_config_dword(hose, dev, pos, &header);
 564                if (header == 0xffffffff || header == 0)
 565                        break;
 566        }
 567
 568        return 0;
 569}
 570
 571/**
 572 * pci_hose_find_ext_capability - Find an extended capability
 573 *
 574 * Returns the address of the requested extended capability structure
 575 * within the device's PCI configuration space or 0 if the device does
 576 * not support it.
 577 */
 578int pci_hose_find_ext_capability(struct pci_controller *hose, pci_dev_t dev,
 579                                 int cap)
 580{
 581        return pci_find_next_ext_capability(hose, dev, 0, cap);
 582}
 583