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 <asm/processor.h> 19 #include <asm/io.h> 20 #include <pci.h> 21 22 #define PCI_HOSE_OP(rw, size, type) \ 23 int pci_hose_##rw##_config_##size(struct pci_controller *hose, \ 24 pci_dev_t dev, \ 25 int offset, type value) \ 26 { \ 27 return hose->rw##_##size(hose, dev, offset, value); \ 28 } 29 30 PCI_HOSE_OP(read, byte, u8 *) 31 PCI_HOSE_OP(read, word, u16 *) 32 PCI_HOSE_OP(read, dword, u32 *) 33 PCI_HOSE_OP(write, byte, u8) 34 PCI_HOSE_OP(write, word, u16) 35 PCI_HOSE_OP(write, dword, u32) 36 37 #define PCI_OP(rw, size, type, error_code) \ 38 int pci_##rw##_config_##size(pci_dev_t dev, int offset, type value) \ 39 { \ 40 struct pci_controller *hose = pci_bus_to_hose(PCI_BUS(dev)); \ 41 \ 42 if (!hose) \ 43 { \ 44 error_code; \ 45 return -1; \ 46 } \ 47 \ 48 return pci_hose_##rw##_config_##size(hose, dev, offset, value); \ 49 } 50 51 PCI_OP(read, byte, u8 *, *value = 0xff) 52 PCI_OP(read, word, u16 *, *value = 0xffff) 53 PCI_OP(read, dword, u32 *, *value = 0xffffffff) 54 PCI_OP(write, byte, u8, ) 55 PCI_OP(write, word, u16, ) 56 PCI_OP(write, dword, u32, ) 57 58 #define PCI_READ_VIA_DWORD_OP(size, type, off_mask) \ 59 int pci_hose_read_config_##size##_via_dword(struct pci_controller *hose,\ 60 pci_dev_t dev, \ 61 int offset, type val) \ 62 { \ 63 u32 val32; \ 64 \ 65 if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0) { \ 66 *val = -1; \ 67 return -1; \ 68 } \ 69 \ 70 *val = (val32 >> ((offset & (int)off_mask) * 8)); \ 71 \ 72 return 0; \ 73 } 74 75 #define PCI_WRITE_VIA_DWORD_OP(size, type, off_mask, val_mask) \ 76 int pci_hose_write_config_##size##_via_dword(struct pci_controller *hose,\ 77 pci_dev_t dev, \ 78 int offset, type val) \ 79 { \ 80 u32 val32, mask, ldata, shift; \ 81 \ 82 if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0)\ 83 return -1; \ 84 \ 85 shift = ((offset & (int)off_mask) * 8); \ 86 ldata = (((unsigned long)val) & val_mask) << shift; \ 87 mask = val_mask << shift; \ 88 val32 = (val32 & ~mask) | ldata; \ 89 \ 90 if (pci_hose_write_config_dword(hose, dev, offset & 0xfc, val32) < 0)\ 91 return -1; \ 92 \ 93 return 0; \ 94 } 95 96 PCI_READ_VIA_DWORD_OP(byte, u8 *, 0x03) 97 PCI_READ_VIA_DWORD_OP(word, u16 *, 0x02) 98 PCI_WRITE_VIA_DWORD_OP(byte, u8, 0x03, 0x000000ff) 99 PCI_WRITE_VIA_DWORD_OP(word, u16, 0x02, 0x0000ffff) 100 101 /* Get a virtual address associated with a BAR region */ 102 void *pci_map_bar(pci_dev_t pdev, int bar, int flags) 103 { 104 pci_addr_t pci_bus_addr; 105 u32 bar_response; 106 107 /* read BAR address */ 108 pci_read_config_dword(pdev, bar, &bar_response); 109 pci_bus_addr = (pci_addr_t)(bar_response & ~0xf); 110 111 /* 112 * Pass "0" as the length argument to pci_bus_to_virt. The arg 113 * isn't actualy used on any platform because u-boot assumes a static 114 * linear mapping. In the future, this could read the BAR size 115 * and pass that as the size if needed. 116 */ 117 return pci_bus_to_virt(pdev, pci_bus_addr, flags, 0, MAP_NOCACHE); 118 } 119 120 /* 121 * 122 */ 123 124 static struct pci_controller* hose_head; 125 126 void pci_register_hose(struct pci_controller* hose) 127 { 128 struct pci_controller **phose = &hose_head; 129 130 while(*phose) 131 phose = &(*phose)->next; 132 133 hose->next = NULL; 134 135 *phose = hose; 136 } 137 138 struct pci_controller *pci_bus_to_hose(int bus) 139 { 140 struct pci_controller *hose; 141 142 for (hose = hose_head; hose; hose = hose->next) { 143 if (bus >= hose->first_busno && bus <= hose->last_busno) 144 return hose; 145 } 146 147 printf("pci_bus_to_hose() failed\n"); 148 return NULL; 149 } 150 151 struct pci_controller *find_hose_by_cfg_addr(void *cfg_addr) 152 { 153 struct pci_controller *hose; 154 155 for (hose = hose_head; hose; hose = hose->next) { 156 if (hose->cfg_addr == cfg_addr) 157 return hose; 158 } 159 160 return NULL; 161 } 162 163 int pci_last_busno(void) 164 { 165 struct pci_controller *hose = hose_head; 166 167 if (!hose) 168 return -1; 169 170 while (hose->next) 171 hose = hose->next; 172 173 return hose->last_busno; 174 } 175 176 pci_dev_t pci_find_devices(struct pci_device_id *ids, int index) 177 { 178 struct pci_controller * hose; 179 u16 vendor, device; 180 u8 header_type; 181 pci_dev_t bdf; 182 int i, bus, found_multi = 0; 183 184 for (hose = hose_head; hose; hose = hose->next) { 185 #ifdef CONFIG_SYS_SCSI_SCAN_BUS_REVERSE 186 for (bus = hose->last_busno; bus >= hose->first_busno; bus--) 187 #else 188 for (bus = hose->first_busno; bus <= hose->last_busno; bus++) 189 #endif 190 for (bdf = PCI_BDF(bus, 0, 0); 191 #if defined(CONFIG_ELPPC) || defined(CONFIG_PPMC7XX) 192 bdf < PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1, 193 PCI_MAX_PCI_FUNCTIONS - 1); 194 #else 195 bdf < PCI_BDF(bus + 1, 0, 0); 196 #endif 197 bdf += PCI_BDF(0, 0, 1)) { 198 if (!PCI_FUNC(bdf)) { 199 pci_read_config_byte(bdf, 200 PCI_HEADER_TYPE, 201 &header_type); 202 203 found_multi = header_type & 0x80; 204 } else { 205 if (!found_multi) 206 continue; 207 } 208 209 pci_read_config_word(bdf, 210 PCI_VENDOR_ID, 211 &vendor); 212 pci_read_config_word(bdf, 213 PCI_DEVICE_ID, 214 &device); 215 216 for (i = 0; ids[i].vendor != 0; i++) { 217 if (vendor == ids[i].vendor && 218 device == ids[i].device) { 219 if (index <= 0) 220 return bdf; 221 222 index--; 223 } 224 } 225 } 226 } 227 228 return -1; 229 } 230 231 pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index) 232 { 233 static struct pci_device_id ids[2] = {{}, {0, 0}}; 234 235 ids[0].vendor = vendor; 236 ids[0].device = device; 237 238 return pci_find_devices(ids, index); 239 } 240 241 /* 242 * 243 */ 244 245 int __pci_hose_phys_to_bus(struct pci_controller *hose, 246 phys_addr_t phys_addr, 247 unsigned long flags, 248 unsigned long skip_mask, 249 pci_addr_t *ba) 250 { 251 struct pci_region *res; 252 pci_addr_t bus_addr; 253 int i; 254 255 for (i = 0; i < hose->region_count; i++) { 256 res = &hose->regions[i]; 257 258 if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0) 259 continue; 260 261 if (res->flags & skip_mask) 262 continue; 263 264 bus_addr = phys_addr - res->phys_start + res->bus_start; 265 266 if (bus_addr >= res->bus_start && 267 bus_addr < res->bus_start + res->size) { 268 *ba = bus_addr; 269 return 0; 270 } 271 } 272 273 return 1; 274 } 275 276 pci_addr_t pci_hose_phys_to_bus (struct pci_controller *hose, 277 phys_addr_t phys_addr, 278 unsigned long flags) 279 { 280 pci_addr_t bus_addr = 0; 281 int ret; 282 283 if (!hose) { 284 puts("pci_hose_phys_to_bus: invalid hose\n"); 285 return bus_addr; 286 } 287 288 /* 289 * if PCI_REGION_MEM is set we do a two pass search with preference 290 * on matches that don't have PCI_REGION_SYS_MEMORY set 291 */ 292 if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) { 293 ret = __pci_hose_phys_to_bus(hose, phys_addr, 294 flags, PCI_REGION_SYS_MEMORY, &bus_addr); 295 if (!ret) 296 return bus_addr; 297 } 298 299 ret = __pci_hose_phys_to_bus(hose, phys_addr, flags, 0, &bus_addr); 300 301 if (ret) 302 puts("pci_hose_phys_to_bus: invalid physical address\n"); 303 304 return bus_addr; 305 } 306 307 int __pci_hose_bus_to_phys(struct pci_controller *hose, 308 pci_addr_t bus_addr, 309 unsigned long flags, 310 unsigned long skip_mask, 311 phys_addr_t *pa) 312 { 313 struct pci_region *res; 314 int i; 315 316 for (i = 0; i < hose->region_count; i++) { 317 res = &hose->regions[i]; 318 319 if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0) 320 continue; 321 322 if (res->flags & skip_mask) 323 continue; 324 325 if (bus_addr >= res->bus_start && 326 bus_addr < res->bus_start + res->size) { 327 *pa = (bus_addr - res->bus_start + res->phys_start); 328 return 0; 329 } 330 } 331 332 return 1; 333 } 334 335 phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose, 336 pci_addr_t bus_addr, 337 unsigned long flags) 338 { 339 phys_addr_t phys_addr = 0; 340 int ret; 341 342 if (!hose) { 343 puts("pci_hose_bus_to_phys: invalid hose\n"); 344 return phys_addr; 345 } 346 347 /* 348 * if PCI_REGION_MEM is set we do a two pass search with preference 349 * on matches that don't have PCI_REGION_SYS_MEMORY set 350 */ 351 if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) { 352 ret = __pci_hose_bus_to_phys(hose, bus_addr, 353 flags, PCI_REGION_SYS_MEMORY, &phys_addr); 354 if (!ret) 355 return phys_addr; 356 } 357 358 ret = __pci_hose_bus_to_phys(hose, bus_addr, flags, 0, &phys_addr); 359 360 if (ret) 361 puts("pci_hose_bus_to_phys: invalid physical address\n"); 362 363 return phys_addr; 364 } 365 366 /* 367 * 368 */ 369 370 int pci_hose_config_device(struct pci_controller *hose, 371 pci_dev_t dev, 372 unsigned long io, 373 pci_addr_t mem, 374 unsigned long command) 375 { 376 u32 bar_response; 377 unsigned int old_command; 378 pci_addr_t bar_value; 379 pci_size_t bar_size; 380 unsigned char pin; 381 int bar, found_mem64; 382 383 debug("PCI Config: I/O=0x%lx, Memory=0x%llx, Command=0x%lx\n", io, 384 (u64)mem, command); 385 386 pci_hose_write_config_dword(hose, dev, PCI_COMMAND, 0); 387 388 for (bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_5; bar += 4) { 389 pci_hose_write_config_dword(hose, dev, bar, 0xffffffff); 390 pci_hose_read_config_dword(hose, dev, bar, &bar_response); 391 392 if (!bar_response) 393 continue; 394 395 found_mem64 = 0; 396 397 /* Check the BAR type and set our address mask */ 398 if (bar_response & PCI_BASE_ADDRESS_SPACE) { 399 bar_size = ~(bar_response & PCI_BASE_ADDRESS_IO_MASK) + 1; 400 /* round up region base address to a multiple of size */ 401 io = ((io - 1) | (bar_size - 1)) + 1; 402 bar_value = io; 403 /* compute new region base address */ 404 io = io + bar_size; 405 } else { 406 if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == 407 PCI_BASE_ADDRESS_MEM_TYPE_64) { 408 u32 bar_response_upper; 409 u64 bar64; 410 pci_hose_write_config_dword(hose, dev, bar + 4, 411 0xffffffff); 412 pci_hose_read_config_dword(hose, dev, bar + 4, 413 &bar_response_upper); 414 415 bar64 = ((u64)bar_response_upper << 32) | bar_response; 416 417 bar_size = ~(bar64 & PCI_BASE_ADDRESS_MEM_MASK) + 1; 418 found_mem64 = 1; 419 } else { 420 bar_size = (u32)(~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1); 421 } 422 423 /* round up region base address to multiple of size */ 424 mem = ((mem - 1) | (bar_size - 1)) + 1; 425 bar_value = mem; 426 /* compute new region base address */ 427 mem = mem + bar_size; 428 } 429 430 /* Write it out and update our limit */ 431 pci_hose_write_config_dword (hose, dev, bar, (u32)bar_value); 432 433 if (found_mem64) { 434 bar += 4; 435 #ifdef CONFIG_SYS_PCI_64BIT 436 pci_hose_write_config_dword(hose, dev, bar, 437 (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 467 struct 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 491 void 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], 496 entry->priv[2]); 497 } 498 499 void pci_cfgfunc_do_nothing(struct pci_controller *hose, 500 pci_dev_t dev, struct pci_config_table *entry) 501 { 502 } 503 504 /* 505 * HJF: Changed this to return int. I think this is required 506 * to get the correct result when scanning bridges 507 */ 508 extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev); 509 510 #if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI_SCAN_SHOW) 511 const char * pci_class_str(u8 class) 512 { 513 switch (class) { 514 case PCI_CLASS_NOT_DEFINED: 515 return "Build before PCI Rev2.0"; 516 break; 517 case PCI_BASE_CLASS_STORAGE: 518 return "Mass storage controller"; 519 break; 520 case PCI_BASE_CLASS_NETWORK: 521 return "Network controller"; 522 break; 523 case PCI_BASE_CLASS_DISPLAY: 524 return "Display controller"; 525 break; 526 case PCI_BASE_CLASS_MULTIMEDIA: 527 return "Multimedia device"; 528 break; 529 case PCI_BASE_CLASS_MEMORY: 530 return "Memory controller"; 531 break; 532 case PCI_BASE_CLASS_BRIDGE: 533 return "Bridge device"; 534 break; 535 case PCI_BASE_CLASS_COMMUNICATION: 536 return "Simple comm. controller"; 537 break; 538 case PCI_BASE_CLASS_SYSTEM: 539 return "Base system peripheral"; 540 break; 541 case PCI_BASE_CLASS_INPUT: 542 return "Input device"; 543 break; 544 case PCI_BASE_CLASS_DOCKING: 545 return "Docking station"; 546 break; 547 case PCI_BASE_CLASS_PROCESSOR: 548 return "Processor"; 549 break; 550 case PCI_BASE_CLASS_SERIAL: 551 return "Serial bus controller"; 552 break; 553 case PCI_BASE_CLASS_INTELLIGENT: 554 return "Intelligent controller"; 555 break; 556 case PCI_BASE_CLASS_SATELLITE: 557 return "Satellite controller"; 558 break; 559 case PCI_BASE_CLASS_CRYPT: 560 return "Cryptographic device"; 561 break; 562 case PCI_BASE_CLASS_SIGNAL_PROCESSING: 563 return "DSP"; 564 break; 565 case PCI_CLASS_OTHERS: 566 return "Does not fit any class"; 567 break; 568 default: 569 return "???"; 570 break; 571 }; 572 } 573 #endif /* CONFIG_CMD_PCI || CONFIG_PCI_SCAN_SHOW */ 574 575 int __pci_skip_dev(struct pci_controller *hose, pci_dev_t dev) 576 { 577 /* 578 * Check if pci device should be skipped in configuration 579 */ 580 if (dev == PCI_BDF(hose->first_busno, 0, 0)) { 581 #if defined(CONFIG_PCI_CONFIG_HOST_BRIDGE) /* don't skip host bridge */ 582 /* 583 * Only skip configuration if "pciconfighost" is not set 584 */ 585 if (getenv("pciconfighost") == NULL) 586 return 1; 587 #else 588 return 1; 589 #endif 590 } 591 592 return 0; 593 } 594 int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev) 595 __attribute__((weak, alias("__pci_skip_dev"))); 596 597 #ifdef CONFIG_PCI_SCAN_SHOW 598 int __pci_print_dev(struct pci_controller *hose, pci_dev_t dev) 599 { 600 if (dev == PCI_BDF(hose->first_busno, 0, 0)) 601 return 0; 602 603 return 1; 604 } 605 int pci_print_dev(struct pci_controller *hose, pci_dev_t dev) 606 __attribute__((weak, alias("__pci_print_dev"))); 607 #endif /* CONFIG_PCI_SCAN_SHOW */ 608 609 int pci_hose_scan_bus(struct pci_controller *hose, int bus) 610 { 611 unsigned int sub_bus, found_multi = 0; 612 unsigned short vendor, device, class; 613 unsigned char header_type; 614 #ifndef CONFIG_PCI_PNP 615 struct pci_config_table *cfg; 616 #endif 617 pci_dev_t dev; 618 #ifdef CONFIG_PCI_SCAN_SHOW 619 static int indent = 0; 620 #endif 621 622 sub_bus = bus; 623 624 for (dev = PCI_BDF(bus,0,0); 625 dev < PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1, 626 PCI_MAX_PCI_FUNCTIONS - 1); 627 dev += PCI_BDF(0, 0, 1)) { 628 629 if (pci_skip_dev(hose, dev)) 630 continue; 631 632 if (PCI_FUNC(dev) && !found_multi) 633 continue; 634 635 pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type); 636 637 pci_hose_read_config_word(hose, dev, PCI_VENDOR_ID, &vendor); 638 639 if (vendor == 0xffff || vendor == 0x0000) 640 continue; 641 642 if (!PCI_FUNC(dev)) 643 found_multi = header_type & 0x80; 644 645 debug("PCI Scan: Found Bus %d, Device %d, Function %d\n", 646 PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev)); 647 648 pci_hose_read_config_word(hose, dev, PCI_DEVICE_ID, &device); 649 pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class); 650 651 #ifdef CONFIG_PCI_SCAN_SHOW 652 indent++; 653 654 /* Print leading space, including bus indentation */ 655 printf("%*c", indent + 1, ' '); 656 657 if (pci_print_dev(hose, dev)) { 658 printf("%02x:%02x.%-*x - %04x:%04x - %s\n", 659 PCI_BUS(dev), PCI_DEV(dev), 6 - indent, PCI_FUNC(dev), 660 vendor, device, pci_class_str(class >> 8)); 661 } 662 #endif 663 664 #ifdef CONFIG_PCI_PNP 665 sub_bus = max(pciauto_config_device(hose, dev), sub_bus); 666 #else 667 cfg = pci_find_config(hose, class, vendor, device, 668 PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev)); 669 if (cfg) { 670 cfg->config_device(hose, dev, cfg); 671 sub_bus = max(sub_bus, hose->current_busno); 672 } 673 #endif 674 675 #ifdef CONFIG_PCI_SCAN_SHOW 676 indent--; 677 #endif 678 679 if (hose->fixup_irq) 680 hose->fixup_irq(hose, dev); 681 } 682 683 return sub_bus; 684 } 685 686 int pci_hose_scan(struct pci_controller *hose) 687 { 688 #if defined(CONFIG_PCI_BOOTDELAY) 689 static int pcidelay_done; 690 char *s; 691 int i; 692 693 if (!pcidelay_done) { 694 /* wait "pcidelay" ms (if defined)... */ 695 s = getenv("pcidelay"); 696 if (s) { 697 int val = simple_strtoul(s, NULL, 10); 698 for (i = 0; i < val; i++) 699 udelay(1000); 700 } 701 pcidelay_done = 1; 702 } 703 #endif /* CONFIG_PCI_BOOTDELAY */ 704 705 /* 706 * Start scan at current_busno. 707 * PCIe will start scan at first_busno+1. 708 */ 709 /* For legacy support, ensure current >= first */ 710 if (hose->first_busno > hose->current_busno) 711 hose->current_busno = hose->first_busno; 712 #ifdef CONFIG_PCI_PNP 713 pciauto_config_init(hose); 714 #endif 715 return pci_hose_scan_bus(hose, hose->current_busno); 716 } 717 718 void pci_init(void) 719 { 720 hose_head = NULL; 721 722 /* now call board specific pci_init()... */ 723 pci_init_board(); 724 } 725 726 /* Returns the address of the requested capability structure within the 727 * device's PCI configuration space or 0 in case the device does not 728 * support it. 729 * */ 730 int pci_hose_find_capability(struct pci_controller *hose, pci_dev_t dev, 731 int cap) 732 { 733 int pos; 734 u8 hdr_type; 735 736 pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &hdr_type); 737 738 pos = pci_hose_find_cap_start(hose, dev, hdr_type & 0x7F); 739 740 if (pos) 741 pos = pci_find_cap(hose, dev, pos, cap); 742 743 return pos; 744 } 745 746 /* Find the header pointer to the Capabilities*/ 747 int pci_hose_find_cap_start(struct pci_controller *hose, pci_dev_t dev, 748 u8 hdr_type) 749 { 750 u16 status; 751 752 pci_hose_read_config_word(hose, dev, PCI_STATUS, &status); 753 754 if (!(status & PCI_STATUS_CAP_LIST)) 755 return 0; 756 757 switch (hdr_type) { 758 case PCI_HEADER_TYPE_NORMAL: 759 case PCI_HEADER_TYPE_BRIDGE: 760 return PCI_CAPABILITY_LIST; 761 case PCI_HEADER_TYPE_CARDBUS: 762 return PCI_CB_CAPABILITY_LIST; 763 default: 764 return 0; 765 } 766 } 767 768 int pci_find_cap(struct pci_controller *hose, pci_dev_t dev, int pos, int cap) 769 { 770 int ttl = PCI_FIND_CAP_TTL; 771 u8 id; 772 u8 next_pos; 773 774 while (ttl--) { 775 pci_hose_read_config_byte(hose, dev, pos, &next_pos); 776 if (next_pos < CAP_START_POS) 777 break; 778 next_pos &= ~3; 779 pos = (int) next_pos; 780 pci_hose_read_config_byte(hose, dev, 781 pos + PCI_CAP_LIST_ID, &id); 782 if (id == 0xff) 783 break; 784 if (id == cap) 785 return pos; 786 pos += PCI_CAP_LIST_NEXT; 787 } 788 return 0; 789 } 790