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 * See file CREDITS for list of people who contributed to this
   9 * project.
  10 *
  11 * This program is free software; you can redistribute it and/or
  12 * modify it under the terms of the GNU General Public License as
  13 * published by the Free Software Foundation; either version 2 of
  14 * the License, or (at your option) any later version.
  15 *
  16 * This program is distributed in the hope that it will be useful,
  17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19 * GNU General Public License for more details.
  20 *
  21 * You should have received a copy of the GNU General Public License
  22 * along with this program; if not, write to the Free Software
  23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24 * MA 02111-1307 USA
  25 */
  26
  27/*
  28 * PCI routines
  29 */
  30
  31#include <common.h>
  32
  33#include <command.h>
  34#include <asm/processor.h>
  35#include <asm/io.h>
  36#include <pci.h>
  37
  38#define PCI_HOSE_OP(rw, size, type)                                     \
  39int pci_hose_##rw##_config_##size(struct pci_controller *hose,          \
  40                                  pci_dev_t dev,                        \
  41                                  int offset, type value)               \
  42{                                                                       \
  43        return hose->rw##_##size(hose, dev, offset, value);             \
  44}
  45
  46PCI_HOSE_OP(read, byte, u8 *)
  47PCI_HOSE_OP(read, word, u16 *)
  48PCI_HOSE_OP(read, dword, u32 *)
  49PCI_HOSE_OP(write, byte, u8)
  50PCI_HOSE_OP(write, word, u16)
  51PCI_HOSE_OP(write, dword, u32)
  52
  53#ifndef CONFIG_IXP425
  54#define PCI_OP(rw, size, type, error_code)                              \
  55int pci_##rw##_config_##size(pci_dev_t dev, int offset, type value)     \
  56{                                                                       \
  57        struct pci_controller *hose = pci_bus_to_hose(PCI_BUS(dev));    \
  58                                                                        \
  59        if (!hose)                                                      \
  60        {                                                               \
  61                error_code;                                             \
  62                return -1;                                              \
  63        }                                                               \
  64                                                                        \
  65        return pci_hose_##rw##_config_##size(hose, dev, offset, value); \
  66}
  67
  68PCI_OP(read, byte, u8 *, *value = 0xff)
  69PCI_OP(read, word, u16 *, *value = 0xffff)
  70PCI_OP(read, dword, u32 *, *value = 0xffffffff)
  71PCI_OP(write, byte, u8, )
  72PCI_OP(write, word, u16, )
  73PCI_OP(write, dword, u32, )
  74#endif  /* CONFIG_IXP425 */
  75
  76#define PCI_READ_VIA_DWORD_OP(size, type, off_mask)                     \
  77int pci_hose_read_config_##size##_via_dword(struct pci_controller *hose,\
  78                                        pci_dev_t dev,                  \
  79                                        int offset, type val)           \
  80{                                                                       \
  81        u32 val32;                                                      \
  82                                                                        \
  83        if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0) { \
  84                *val = -1;                                              \
  85                return -1;                                              \
  86        }                                                               \
  87                                                                        \
  88        *val = (val32 >> ((offset & (int)off_mask) * 8));               \
  89                                                                        \
  90        return 0;                                                       \
  91}
  92
  93#define PCI_WRITE_VIA_DWORD_OP(size, type, off_mask, val_mask)          \
  94int pci_hose_write_config_##size##_via_dword(struct pci_controller *hose,\
  95                                             pci_dev_t dev,             \
  96                                             int offset, type val)      \
  97{                                                                       \
  98        u32 val32, mask, ldata, shift;                                  \
  99                                                                        \
 100        if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0)\
 101                return -1;                                              \
 102                                                                        \
 103        shift = ((offset & (int)off_mask) * 8);                         \
 104        ldata = (((unsigned long)val) & val_mask) << shift;             \
 105        mask = val_mask << shift;                                       \
 106        val32 = (val32 & ~mask) | ldata;                                \
 107                                                                        \
 108        if (pci_hose_write_config_dword(hose, dev, offset & 0xfc, val32) < 0)\
 109                return -1;                                              \
 110                                                                        \
 111        return 0;                                                       \
 112}
 113
 114PCI_READ_VIA_DWORD_OP(byte, u8 *, 0x03)
 115PCI_READ_VIA_DWORD_OP(word, u16 *, 0x02)
 116PCI_WRITE_VIA_DWORD_OP(byte, u8, 0x03, 0x000000ff)
 117PCI_WRITE_VIA_DWORD_OP(word, u16, 0x02, 0x0000ffff)
 118
 119/* Get a virtual address associated with a BAR region */
 120void *pci_map_bar(pci_dev_t pdev, int bar, int flags)
 121{
 122        pci_addr_t pci_bus_addr;
 123        u32 bar_response;
 124
 125        /* read BAR address */
 126        pci_read_config_dword(pdev, bar, &bar_response);
 127        pci_bus_addr = (pci_addr_t)(bar_response & ~0xf);
 128
 129        /*
 130         * Pass "0" as the length argument to pci_bus_to_virt.  The arg
 131         * isn't actualy used on any platform because u-boot assumes a static
 132         * linear mapping.  In the future, this could read the BAR size
 133         * and pass that as the size if needed.
 134         */
 135        return pci_bus_to_virt(pdev, pci_bus_addr, flags, 0, MAP_NOCACHE);
 136}
 137
 138/*
 139 *
 140 */
 141
 142static struct pci_controller* hose_head = NULL;
 143
 144void pci_register_hose(struct pci_controller* hose)
 145{
 146        struct pci_controller **phose = &hose_head;
 147
 148        while(*phose)
 149                phose = &(*phose)->next;
 150
 151        hose->next = NULL;
 152
 153        *phose = hose;
 154}
 155
 156struct pci_controller *pci_bus_to_hose (int bus)
 157{
 158        struct pci_controller *hose;
 159
 160        for (hose = hose_head; hose; hose = hose->next)
 161                if (bus >= hose->first_busno && bus <= hose->last_busno)
 162                        return hose;
 163
 164        printf("pci_bus_to_hose() failed\n");
 165        return NULL;
 166}
 167
 168int pci_last_busno(void)
 169{
 170        struct pci_controller *hose = hose_head;
 171
 172        if (!hose)
 173                return -1;
 174
 175        while (hose->next)
 176                hose = hose->next;
 177
 178        return hose->last_busno;
 179}
 180
 181#ifndef CONFIG_IXP425
 182pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
 183{
 184        struct pci_controller * hose;
 185        u16 vendor, device;
 186        u8 header_type;
 187        pci_dev_t bdf;
 188        int i, bus, found_multi = 0;
 189
 190        for (hose = hose_head; hose; hose = hose->next)
 191        {
 192#ifdef CONFIG_SYS_SCSI_SCAN_BUS_REVERSE
 193                for (bus = hose->last_busno; bus >= hose->first_busno; bus--)
 194#else
 195                for (bus = hose->first_busno; bus <= hose->last_busno; bus++)
 196#endif
 197                        for (bdf = PCI_BDF(bus,0,0);
 198#if defined(CONFIG_ELPPC) || defined(CONFIG_PPMC7XX)
 199                             bdf < PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1);
 200#else
 201                             bdf < PCI_BDF(bus+1,0,0);
 202#endif
 203                             bdf += PCI_BDF(0,0,1))
 204                        {
 205                                if (!PCI_FUNC(bdf)) {
 206                                        pci_read_config_byte(bdf,
 207                                                             PCI_HEADER_TYPE,
 208                                                             &header_type);
 209
 210                                        found_multi = header_type & 0x80;
 211                                } else {
 212                                        if (!found_multi)
 213                                                continue;
 214                                }
 215
 216                                pci_read_config_word(bdf,
 217                                                     PCI_VENDOR_ID,
 218                                                     &vendor);
 219                                pci_read_config_word(bdf,
 220                                                     PCI_DEVICE_ID,
 221                                                     &device);
 222
 223                                for (i=0; ids[i].vendor != 0; i++)
 224                                        if (vendor == ids[i].vendor &&
 225                                            device == ids[i].device)
 226                                        {
 227                                                if (index <= 0)
 228                                                        return bdf;
 229
 230                                                index--;
 231                                        }
 232                        }
 233        }
 234
 235        return (-1);
 236}
 237#endif  /* CONFIG_IXP425 */
 238
 239pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
 240{
 241        static struct pci_device_id ids[2] = {{}, {0, 0}};
 242
 243        ids[0].vendor = vendor;
 244        ids[0].device = device;
 245
 246        return pci_find_devices(ids, index);
 247}
 248
 249/*
 250 *
 251 */
 252
 253int __pci_hose_phys_to_bus (struct pci_controller *hose,
 254                                phys_addr_t phys_addr,
 255                                unsigned long flags,
 256                                unsigned long skip_mask,
 257                                pci_addr_t *ba)
 258{
 259        struct pci_region *res;
 260        pci_addr_t bus_addr;
 261        int i;
 262
 263        for (i = 0; i < hose->region_count; i++) {
 264                res = &hose->regions[i];
 265
 266                if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
 267                        continue;
 268
 269                if (res->flags & skip_mask)
 270                        continue;
 271
 272                bus_addr = phys_addr - res->phys_start + res->bus_start;
 273
 274                if (bus_addr >= res->bus_start &&
 275                        bus_addr < res->bus_start + res->size) {
 276                        *ba = bus_addr;
 277                        return 0;
 278                }
 279        }
 280
 281        return 1;
 282}
 283
 284pci_addr_t pci_hose_phys_to_bus (struct pci_controller *hose,
 285                                    phys_addr_t phys_addr,
 286                                    unsigned long flags)
 287{
 288        pci_addr_t bus_addr = 0;
 289        int ret;
 290
 291        if (!hose) {
 292                puts ("pci_hose_phys_to_bus: invalid hose\n");
 293                return bus_addr;
 294        }
 295
 296        /* if PCI_REGION_MEM is set we do a two pass search with preference
 297         * on matches that don't have PCI_REGION_SYS_MEMORY set */
 298        if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
 299                ret = __pci_hose_phys_to_bus(hose, phys_addr,
 300                                flags, PCI_REGION_SYS_MEMORY, &bus_addr);
 301                if (!ret)
 302                        return bus_addr;
 303        }
 304
 305        ret = __pci_hose_phys_to_bus(hose, phys_addr, flags, 0, &bus_addr);
 306
 307        if (ret)
 308                puts ("pci_hose_phys_to_bus: invalid physical address\n");
 309
 310        return bus_addr;
 311}
 312
 313int __pci_hose_bus_to_phys (struct pci_controller *hose,
 314                                pci_addr_t bus_addr,
 315                                unsigned long flags,
 316                                unsigned long skip_mask,
 317                                phys_addr_t *pa)
 318{
 319        struct pci_region *res;
 320        int i;
 321
 322        for (i = 0; i < hose->region_count; i++) {
 323                res = &hose->regions[i];
 324
 325                if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
 326                        continue;
 327
 328                if (res->flags & skip_mask)
 329                        continue;
 330
 331                if (bus_addr >= res->bus_start &&
 332                        bus_addr < res->bus_start + res->size) {
 333                        *pa = (bus_addr - res->bus_start + res->phys_start);
 334                        return 0;
 335                }
 336        }
 337
 338        return 1;
 339}
 340
 341phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose,
 342                                 pci_addr_t bus_addr,
 343                                 unsigned long flags)
 344{
 345        phys_addr_t phys_addr = 0;
 346        int ret;
 347
 348        if (!hose) {
 349                puts ("pci_hose_bus_to_phys: invalid hose\n");
 350                return phys_addr;
 351        }
 352
 353        /* if PCI_REGION_MEM is set we do a two pass search with preference
 354         * on matches that don't have PCI_REGION_SYS_MEMORY set */
 355        if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
 356                ret = __pci_hose_bus_to_phys(hose, bus_addr,
 357                                flags, PCI_REGION_SYS_MEMORY, &phys_addr);
 358                if (!ret)
 359                        return phys_addr;
 360        }
 361
 362        ret = __pci_hose_bus_to_phys(hose, bus_addr, flags, 0, &phys_addr);
 363
 364        if (ret)
 365                puts ("pci_hose_bus_to_phys: invalid physical address\n");
 366
 367        return phys_addr;
 368}
 369
 370/*
 371 *
 372 */
 373
 374int pci_hose_config_device(struct pci_controller *hose,
 375                           pci_dev_t dev,
 376                           unsigned long io,
 377                           pci_addr_t mem,
 378                           unsigned long command)
 379{
 380        unsigned int bar_response, old_command;
 381        pci_addr_t bar_value;
 382        pci_size_t bar_size;
 383        unsigned char pin;
 384        int bar, found_mem64;
 385
 386        debug ("PCI Config: I/O=0x%lx, Memory=0x%llx, Command=0x%lx\n",
 387                io, (u64)mem, command);
 388
 389        pci_hose_write_config_dword (hose, dev, PCI_COMMAND, 0);
 390
 391        for (bar = PCI_BASE_ADDRESS_0; bar < PCI_BASE_ADDRESS_5; bar += 4) {
 392                pci_hose_write_config_dword (hose, dev, bar, 0xffffffff);
 393                pci_hose_read_config_dword (hose, dev, bar, &bar_response);
 394
 395                if (!bar_response)
 396                        continue;
 397
 398                found_mem64 = 0;
 399
 400                /* Check the BAR type and set our address mask */
 401                if (bar_response & PCI_BASE_ADDRESS_SPACE) {
 402                        bar_size = ~(bar_response & PCI_BASE_ADDRESS_IO_MASK) + 1;
 403                        /* round up region base address to a multiple of size */
 404                        io = ((io - 1) | (bar_size - 1)) + 1;
 405                        bar_value = io;
 406                        /* compute new region base address */
 407                        io = io + bar_size;
 408                } else {
 409                        if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
 410                                PCI_BASE_ADDRESS_MEM_TYPE_64) {
 411                                u32 bar_response_upper;
 412                                u64 bar64;
 413                                pci_hose_write_config_dword(hose, dev, bar+4, 0xffffffff);
 414                                pci_hose_read_config_dword(hose, dev, bar+4, &bar_response_upper);
 415
 416                                bar64 = ((u64)bar_response_upper << 32) | bar_response;
 417
 418                                bar_size = ~(bar64 & PCI_BASE_ADDRESS_MEM_MASK) + 1;
 419                                found_mem64 = 1;
 420                        } else {
 421                                bar_size = (u32)(~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1);
 422                        }
 423
 424                        /* round up region base address to multiple of size */
 425                        mem = ((mem - 1) | (bar_size - 1)) + 1;
 426                        bar_value = mem;
 427                        /* compute new region base address */
 428                        mem = mem + bar_size;
 429                }
 430
 431                /* Write it out and update our limit */
 432                pci_hose_write_config_dword (hose, dev, bar, (u32)bar_value);
 433
 434                if (found_mem64) {
 435                        bar += 4;
 436#ifdef CONFIG_SYS_PCI_64BIT
 437                        pci_hose_write_config_dword(hose, dev, bar, (u32)(bar_value>>32));
 438#else
 439                        pci_hose_write_config_dword (hose, dev, bar, 0x00000000);
 440#endif
 441                }
 442        }
 443
 444        /* Configure Cache Line Size Register */
 445        pci_hose_write_config_byte (hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
 446
 447        /* Configure Latency Timer */
 448        pci_hose_write_config_byte (hose, dev, PCI_LATENCY_TIMER, 0x80);
 449
 450        /* Disable interrupt line, if device says it wants to use interrupts */
 451        pci_hose_read_config_byte (hose, dev, PCI_INTERRUPT_PIN, &pin);
 452        if (pin != 0) {
 453                pci_hose_write_config_byte (hose, dev, PCI_INTERRUPT_LINE, 0xff);
 454        }
 455
 456        pci_hose_read_config_dword (hose, dev, PCI_COMMAND, &old_command);
 457        pci_hose_write_config_dword (hose, dev, PCI_COMMAND,
 458                                     (old_command & 0xffff0000) | command);
 459
 460        return 0;
 461}
 462
 463/*
 464 *
 465 */
 466
 467struct pci_config_table *pci_find_config(struct pci_controller *hose,
 468                                         unsigned short class,
 469                                         unsigned int vendor,
 470                                         unsigned int device,
 471                                         unsigned int bus,
 472                                         unsigned int dev,
 473                                         unsigned int func)
 474{
 475        struct pci_config_table *table;
 476
 477        for (table = hose->config_table; table && table->vendor; table++) {
 478                if ((table->vendor == PCI_ANY_ID || table->vendor == vendor) &&
 479                    (table->device == PCI_ANY_ID || table->device == device) &&
 480                    (table->class  == PCI_ANY_ID || table->class  == class)  &&
 481                    (table->bus    == PCI_ANY_ID || table->bus    == bus)    &&
 482                    (table->dev    == PCI_ANY_ID || table->dev    == dev)    &&
 483                    (table->func   == PCI_ANY_ID || table->func   == func)) {
 484                        return table;
 485                }
 486        }
 487
 488        return NULL;
 489}
 490
 491void pci_cfgfunc_config_device(struct pci_controller *hose,
 492                               pci_dev_t dev,
 493                               struct pci_config_table *entry)
 494{
 495        pci_hose_config_device(hose, dev, entry->priv[0], entry->priv[1], entry->priv[2]);
 496}
 497
 498void pci_cfgfunc_do_nothing(struct pci_controller *hose,
 499                            pci_dev_t dev, struct pci_config_table *entry)
 500{
 501}
 502
 503/*
 504 *
 505 */
 506
 507/* HJF: Changed this to return int. I think this is required
 508 * to get the correct result when scanning bridges
 509 */
 510extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
 511extern void pciauto_config_init(struct pci_controller *hose);
 512
 513int __pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
 514{
 515        /*
 516         * Check if pci device should be skipped in configuration
 517         */
 518        if (dev == PCI_BDF(hose->first_busno, 0, 0)) {
 519#if defined(CONFIG_PCI_CONFIG_HOST_BRIDGE) /* don't skip host bridge */
 520                /*
 521                 * Only skip configuration if "pciconfighost" is not set
 522                 */
 523                if (getenv("pciconfighost") == NULL)
 524                        return 1;
 525#else
 526                return 1;
 527#endif
 528        }
 529
 530        return 0;
 531}
 532int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
 533        __attribute__((weak, alias("__pci_skip_dev")));
 534
 535#ifdef CONFIG_PCI_SCAN_SHOW
 536int __pci_print_dev(struct pci_controller *hose, pci_dev_t dev)
 537{
 538        if (dev == PCI_BDF(hose->first_busno, 0, 0))
 539                return 0;
 540
 541        return 1;
 542}
 543int pci_print_dev(struct pci_controller *hose, pci_dev_t dev)
 544        __attribute__((weak, alias("__pci_print_dev")));
 545#endif /* CONFIG_PCI_SCAN_SHOW */
 546
 547int pci_hose_scan_bus(struct pci_controller *hose, int bus)
 548{
 549        unsigned int sub_bus, found_multi=0;
 550        unsigned short vendor, device, class;
 551        unsigned char header_type;
 552        struct pci_config_table *cfg;
 553        pci_dev_t dev;
 554
 555        sub_bus = bus;
 556
 557        for (dev =  PCI_BDF(bus,0,0);
 558             dev <  PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1);
 559             dev += PCI_BDF(0,0,1)) {
 560
 561                if (pci_skip_dev(hose, dev))
 562                        continue;
 563
 564                if (PCI_FUNC(dev) && !found_multi)
 565                        continue;
 566
 567                pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type);
 568
 569                pci_hose_read_config_word(hose, dev, PCI_VENDOR_ID, &vendor);
 570
 571                if (vendor != 0xffff && vendor != 0x0000) {
 572
 573                        if (!PCI_FUNC(dev))
 574                                found_multi = header_type & 0x80;
 575
 576                        debug ("PCI Scan: Found Bus %d, Device %d, Function %d\n",
 577                                PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev) );
 578
 579                        pci_hose_read_config_word(hose, dev, PCI_DEVICE_ID, &device);
 580                        pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
 581
 582                        cfg = pci_find_config(hose, class, vendor, device,
 583                                              PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev));
 584                        if (cfg) {
 585                                cfg->config_device(hose, dev, cfg);
 586                                sub_bus = max(sub_bus, hose->current_busno);
 587#ifdef CONFIG_PCI_PNP
 588                        } else {
 589                                int n = pciauto_config_device(hose, dev);
 590
 591                                sub_bus = max(sub_bus, n);
 592#endif
 593                        }
 594                        if (hose->fixup_irq)
 595                                hose->fixup_irq(hose, dev);
 596
 597#ifdef CONFIG_PCI_SCAN_SHOW
 598                        if (pci_print_dev(hose, dev)) {
 599                                unsigned char int_line;
 600
 601                                pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_LINE,
 602                                                          &int_line);
 603                                printf("        %02x  %02x  %04x  %04x  %04x  %02x\n",
 604                                       PCI_BUS(dev), PCI_DEV(dev), vendor, device, class,
 605                                       int_line);
 606                        }
 607#endif
 608                }
 609        }
 610
 611        return sub_bus;
 612}
 613
 614int pci_hose_scan(struct pci_controller *hose)
 615{
 616        /* Start scan at current_busno.
 617         * PCIe will start scan at first_busno+1.
 618         */
 619        /* For legacy support, ensure current>=first */
 620        if (hose->first_busno > hose->current_busno)
 621                hose->current_busno = hose->first_busno;
 622#ifdef CONFIG_PCI_PNP
 623        pciauto_config_init(hose);
 624#endif
 625        return pci_hose_scan_bus(hose, hose->current_busno);
 626}
 627
 628void pci_init(void)
 629{
 630#if defined(CONFIG_PCI_BOOTDELAY)
 631        char *s;
 632        int i;
 633
 634        /* wait "pcidelay" ms (if defined)... */
 635        s = getenv ("pcidelay");
 636        if (s) {
 637                int val = simple_strtoul (s, NULL, 10);
 638                for (i=0; i<val; i++)
 639                        udelay (1000);
 640        }
 641#endif /* CONFIG_PCI_BOOTDELAY */
 642
 643        /* now call board specific pci_init()... */
 644        pci_init_board();
 645}
 646