| .. | .. |
|---|
| 12 | 12 | #include <linux/gpio.h> |
|---|
| 13 | 13 | #include <linux/init.h> |
|---|
| 14 | 14 | #include <linux/mbus.h> |
|---|
| 15 | | -#include <linux/msi.h> |
|---|
| 16 | 15 | #include <linux/slab.h> |
|---|
| 17 | 16 | #include <linux/platform_device.h> |
|---|
| 18 | 17 | #include <linux/of_address.h> |
|---|
| .. | .. |
|---|
| 22 | 21 | #include <linux/of_platform.h> |
|---|
| 23 | 22 | |
|---|
| 24 | 23 | #include "../pci.h" |
|---|
| 24 | +#include "../pci-bridge-emul.h" |
|---|
| 25 | 25 | |
|---|
| 26 | 26 | /* |
|---|
| 27 | 27 | * PCIe unit register offsets. |
|---|
| .. | .. |
|---|
| 63 | 63 | #define PCIE_DEBUG_CTRL 0x1a60 |
|---|
| 64 | 64 | #define PCIE_DEBUG_SOFT_RESET BIT(20) |
|---|
| 65 | 65 | |
|---|
| 66 | | -enum { |
|---|
| 67 | | - PCISWCAP = PCI_BRIDGE_CONTROL + 2, |
|---|
| 68 | | - PCISWCAP_EXP_LIST_ID = PCISWCAP + PCI_CAP_LIST_ID, |
|---|
| 69 | | - PCISWCAP_EXP_DEVCAP = PCISWCAP + PCI_EXP_DEVCAP, |
|---|
| 70 | | - PCISWCAP_EXP_DEVCTL = PCISWCAP + PCI_EXP_DEVCTL, |
|---|
| 71 | | - PCISWCAP_EXP_LNKCAP = PCISWCAP + PCI_EXP_LNKCAP, |
|---|
| 72 | | - PCISWCAP_EXP_LNKCTL = PCISWCAP + PCI_EXP_LNKCTL, |
|---|
| 73 | | - PCISWCAP_EXP_SLTCAP = PCISWCAP + PCI_EXP_SLTCAP, |
|---|
| 74 | | - PCISWCAP_EXP_SLTCTL = PCISWCAP + PCI_EXP_SLTCTL, |
|---|
| 75 | | - PCISWCAP_EXP_RTCTL = PCISWCAP + PCI_EXP_RTCTL, |
|---|
| 76 | | - PCISWCAP_EXP_RTSTA = PCISWCAP + PCI_EXP_RTSTA, |
|---|
| 77 | | - PCISWCAP_EXP_DEVCAP2 = PCISWCAP + PCI_EXP_DEVCAP2, |
|---|
| 78 | | - PCISWCAP_EXP_DEVCTL2 = PCISWCAP + PCI_EXP_DEVCTL2, |
|---|
| 79 | | - PCISWCAP_EXP_LNKCAP2 = PCISWCAP + PCI_EXP_LNKCAP2, |
|---|
| 80 | | - PCISWCAP_EXP_LNKCTL2 = PCISWCAP + PCI_EXP_LNKCTL2, |
|---|
| 81 | | - PCISWCAP_EXP_SLTCAP2 = PCISWCAP + PCI_EXP_SLTCAP2, |
|---|
| 82 | | - PCISWCAP_EXP_SLTCTL2 = PCISWCAP + PCI_EXP_SLTCTL2, |
|---|
| 83 | | -}; |
|---|
| 84 | | - |
|---|
| 85 | | -/* PCI configuration space of a PCI-to-PCI bridge */ |
|---|
| 86 | | -struct mvebu_sw_pci_bridge { |
|---|
| 87 | | - u16 vendor; |
|---|
| 88 | | - u16 device; |
|---|
| 89 | | - u16 command; |
|---|
| 90 | | - u16 status; |
|---|
| 91 | | - u16 class; |
|---|
| 92 | | - u8 interface; |
|---|
| 93 | | - u8 revision; |
|---|
| 94 | | - u8 bist; |
|---|
| 95 | | - u8 header_type; |
|---|
| 96 | | - u8 latency_timer; |
|---|
| 97 | | - u8 cache_line_size; |
|---|
| 98 | | - u32 bar[2]; |
|---|
| 99 | | - u8 primary_bus; |
|---|
| 100 | | - u8 secondary_bus; |
|---|
| 101 | | - u8 subordinate_bus; |
|---|
| 102 | | - u8 secondary_latency_timer; |
|---|
| 103 | | - u8 iobase; |
|---|
| 104 | | - u8 iolimit; |
|---|
| 105 | | - u16 secondary_status; |
|---|
| 106 | | - u16 membase; |
|---|
| 107 | | - u16 memlimit; |
|---|
| 108 | | - u16 iobaseupper; |
|---|
| 109 | | - u16 iolimitupper; |
|---|
| 110 | | - u32 romaddr; |
|---|
| 111 | | - u8 intline; |
|---|
| 112 | | - u8 intpin; |
|---|
| 113 | | - u16 bridgectrl; |
|---|
| 114 | | - |
|---|
| 115 | | - /* PCI express capability */ |
|---|
| 116 | | - u32 pcie_sltcap; |
|---|
| 117 | | - u16 pcie_devctl; |
|---|
| 118 | | - u16 pcie_rtctl; |
|---|
| 119 | | -}; |
|---|
| 120 | | - |
|---|
| 121 | 66 | struct mvebu_pcie_port; |
|---|
| 122 | 67 | |
|---|
| 123 | 68 | /* Structure representing all PCIe interfaces */ |
|---|
| 124 | 69 | struct mvebu_pcie { |
|---|
| 125 | 70 | struct platform_device *pdev; |
|---|
| 126 | 71 | struct mvebu_pcie_port *ports; |
|---|
| 127 | | - struct msi_controller *msi; |
|---|
| 128 | | - struct list_head resources; |
|---|
| 129 | 72 | struct resource io; |
|---|
| 130 | 73 | struct resource realio; |
|---|
| 131 | 74 | struct resource mem; |
|---|
| .. | .. |
|---|
| 153 | 96 | struct clk *clk; |
|---|
| 154 | 97 | struct gpio_desc *reset_gpio; |
|---|
| 155 | 98 | char *reset_name; |
|---|
| 156 | | - struct mvebu_sw_pci_bridge bridge; |
|---|
| 99 | + struct pci_bridge_emul bridge; |
|---|
| 157 | 100 | struct device_node *dn; |
|---|
| 158 | 101 | struct mvebu_pcie *pcie; |
|---|
| 159 | 102 | struct mvebu_pcie_window memwin; |
|---|
| 160 | 103 | struct mvebu_pcie_window iowin; |
|---|
| 161 | 104 | u32 saved_pcie_stat; |
|---|
| 105 | + struct resource regs; |
|---|
| 162 | 106 | }; |
|---|
| 163 | 107 | |
|---|
| 164 | 108 | static inline void mvebu_writel(struct mvebu_pcie_port *port, u32 val, u32 reg) |
|---|
| .. | .. |
|---|
| 203 | 147 | |
|---|
| 204 | 148 | /* |
|---|
| 205 | 149 | * Setup PCIE BARs and Address Decode Wins: |
|---|
| 206 | | - * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks |
|---|
| 150 | + * BAR[0] -> internal registers (needed for MSI) |
|---|
| 151 | + * BAR[1] -> covers all DRAM banks |
|---|
| 152 | + * BAR[2] -> Disabled |
|---|
| 207 | 153 | * WIN[0-3] -> DRAM bank[0-3] |
|---|
| 208 | 154 | */ |
|---|
| 209 | 155 | static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port) |
|---|
| .. | .. |
|---|
| 257 | 203 | mvebu_writel(port, 0, PCIE_BAR_HI_OFF(1)); |
|---|
| 258 | 204 | mvebu_writel(port, ((size - 1) & 0xffff0000) | 1, |
|---|
| 259 | 205 | PCIE_BAR_CTRL_OFF(1)); |
|---|
| 206 | + |
|---|
| 207 | + /* |
|---|
| 208 | + * Point BAR[0] to the device's internal registers. |
|---|
| 209 | + */ |
|---|
| 210 | + mvebu_writel(port, round_down(port->regs.start, SZ_1M), PCIE_BAR_LO_OFF(0)); |
|---|
| 211 | + mvebu_writel(port, 0, PCIE_BAR_HI_OFF(0)); |
|---|
| 260 | 212 | } |
|---|
| 261 | 213 | |
|---|
| 262 | 214 | static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port) |
|---|
| .. | .. |
|---|
| 415 | 367 | static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port) |
|---|
| 416 | 368 | { |
|---|
| 417 | 369 | struct mvebu_pcie_window desired = {}; |
|---|
| 370 | + struct pci_bridge_emul_conf *conf = &port->bridge.conf; |
|---|
| 418 | 371 | |
|---|
| 419 | 372 | /* Are the new iobase/iolimit values invalid? */ |
|---|
| 420 | | - if (port->bridge.iolimit < port->bridge.iobase || |
|---|
| 421 | | - port->bridge.iolimitupper < port->bridge.iobaseupper || |
|---|
| 422 | | - !(port->bridge.command & PCI_COMMAND_IO)) { |
|---|
| 373 | + if (conf->iolimit < conf->iobase || |
|---|
| 374 | + conf->iolimitupper < conf->iobaseupper || |
|---|
| 375 | + !(conf->command & PCI_COMMAND_IO)) { |
|---|
| 423 | 376 | mvebu_pcie_set_window(port, port->io_target, port->io_attr, |
|---|
| 424 | 377 | &desired, &port->iowin); |
|---|
| 425 | 378 | return; |
|---|
| .. | .. |
|---|
| 438 | 391 | * specifications. iobase is the bus address, port->iowin_base |
|---|
| 439 | 392 | * is the CPU address. |
|---|
| 440 | 393 | */ |
|---|
| 441 | | - desired.remap = ((port->bridge.iobase & 0xF0) << 8) | |
|---|
| 442 | | - (port->bridge.iobaseupper << 16); |
|---|
| 394 | + desired.remap = ((conf->iobase & 0xF0) << 8) | |
|---|
| 395 | + (conf->iobaseupper << 16); |
|---|
| 443 | 396 | desired.base = port->pcie->io.start + desired.remap; |
|---|
| 444 | | - desired.size = ((0xFFF | ((port->bridge.iolimit & 0xF0) << 8) | |
|---|
| 445 | | - (port->bridge.iolimitupper << 16)) - |
|---|
| 397 | + desired.size = ((0xFFF | ((conf->iolimit & 0xF0) << 8) | |
|---|
| 398 | + (conf->iolimitupper << 16)) - |
|---|
| 446 | 399 | desired.remap) + |
|---|
| 447 | 400 | 1; |
|---|
| 448 | 401 | |
|---|
| .. | .. |
|---|
| 453 | 406 | static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port) |
|---|
| 454 | 407 | { |
|---|
| 455 | 408 | struct mvebu_pcie_window desired = {.remap = MVEBU_MBUS_NO_REMAP}; |
|---|
| 409 | + struct pci_bridge_emul_conf *conf = &port->bridge.conf; |
|---|
| 456 | 410 | |
|---|
| 457 | 411 | /* Are the new membase/memlimit values invalid? */ |
|---|
| 458 | | - if (port->bridge.memlimit < port->bridge.membase || |
|---|
| 459 | | - !(port->bridge.command & PCI_COMMAND_MEMORY)) { |
|---|
| 412 | + if (conf->memlimit < conf->membase || |
|---|
| 413 | + !(conf->command & PCI_COMMAND_MEMORY)) { |
|---|
| 460 | 414 | mvebu_pcie_set_window(port, port->mem_target, port->mem_attr, |
|---|
| 461 | 415 | &desired, &port->memwin); |
|---|
| 462 | 416 | return; |
|---|
| .. | .. |
|---|
| 468 | 422 | * window to setup, according to the PCI-to-PCI bridge |
|---|
| 469 | 423 | * specifications. |
|---|
| 470 | 424 | */ |
|---|
| 471 | | - desired.base = ((port->bridge.membase & 0xFFF0) << 16); |
|---|
| 472 | | - desired.size = (((port->bridge.memlimit & 0xFFF0) << 16) | 0xFFFFF) - |
|---|
| 425 | + desired.base = ((conf->membase & 0xFFF0) << 16); |
|---|
| 426 | + desired.size = (((conf->memlimit & 0xFFF0) << 16) | 0xFFFFF) - |
|---|
| 473 | 427 | desired.base + 1; |
|---|
| 474 | 428 | |
|---|
| 475 | 429 | mvebu_pcie_set_window(port, port->mem_target, port->mem_attr, &desired, |
|---|
| 476 | 430 | &port->memwin); |
|---|
| 477 | 431 | } |
|---|
| 478 | 432 | |
|---|
| 479 | | -/* |
|---|
| 480 | | - * Initialize the configuration space of the PCI-to-PCI bridge |
|---|
| 481 | | - * associated with the given PCIe interface. |
|---|
| 482 | | - */ |
|---|
| 483 | | -static void mvebu_sw_pci_bridge_init(struct mvebu_pcie_port *port) |
|---|
| 433 | +static pci_bridge_emul_read_status_t |
|---|
| 434 | +mvebu_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge, |
|---|
| 435 | + int reg, u32 *value) |
|---|
| 484 | 436 | { |
|---|
| 485 | | - struct mvebu_sw_pci_bridge *bridge = &port->bridge; |
|---|
| 437 | + struct mvebu_pcie_port *port = bridge->data; |
|---|
| 486 | 438 | |
|---|
| 487 | | - memset(bridge, 0, sizeof(struct mvebu_sw_pci_bridge)); |
|---|
| 488 | | - |
|---|
| 489 | | - bridge->class = PCI_CLASS_BRIDGE_PCI; |
|---|
| 490 | | - bridge->vendor = PCI_VENDOR_ID_MARVELL; |
|---|
| 491 | | - bridge->device = mvebu_readl(port, PCIE_DEV_ID_OFF) >> 16; |
|---|
| 492 | | - bridge->revision = mvebu_readl(port, PCIE_DEV_REV_OFF) & 0xff; |
|---|
| 493 | | - bridge->header_type = PCI_HEADER_TYPE_BRIDGE; |
|---|
| 494 | | - bridge->cache_line_size = 0x10; |
|---|
| 495 | | - |
|---|
| 496 | | - /* We support 32 bits I/O addressing */ |
|---|
| 497 | | - bridge->iobase = PCI_IO_RANGE_TYPE_32; |
|---|
| 498 | | - bridge->iolimit = PCI_IO_RANGE_TYPE_32; |
|---|
| 499 | | - |
|---|
| 500 | | - /* Add capabilities */ |
|---|
| 501 | | - bridge->status = PCI_STATUS_CAP_LIST; |
|---|
| 502 | | -} |
|---|
| 503 | | - |
|---|
| 504 | | -/* |
|---|
| 505 | | - * Read the configuration space of the PCI-to-PCI bridge associated to |
|---|
| 506 | | - * the given PCIe interface. |
|---|
| 507 | | - */ |
|---|
| 508 | | -static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port, |
|---|
| 509 | | - unsigned int where, int size, u32 *value) |
|---|
| 510 | | -{ |
|---|
| 511 | | - struct mvebu_sw_pci_bridge *bridge = &port->bridge; |
|---|
| 512 | | - |
|---|
| 513 | | - switch (where & ~3) { |
|---|
| 514 | | - case PCI_VENDOR_ID: |
|---|
| 515 | | - *value = bridge->device << 16 | bridge->vendor; |
|---|
| 516 | | - break; |
|---|
| 517 | | - |
|---|
| 518 | | - case PCI_COMMAND: |
|---|
| 519 | | - *value = bridge->command | bridge->status << 16; |
|---|
| 520 | | - break; |
|---|
| 521 | | - |
|---|
| 522 | | - case PCI_CLASS_REVISION: |
|---|
| 523 | | - *value = bridge->class << 16 | bridge->interface << 8 | |
|---|
| 524 | | - bridge->revision; |
|---|
| 525 | | - break; |
|---|
| 526 | | - |
|---|
| 527 | | - case PCI_CACHE_LINE_SIZE: |
|---|
| 528 | | - *value = bridge->bist << 24 | bridge->header_type << 16 | |
|---|
| 529 | | - bridge->latency_timer << 8 | bridge->cache_line_size; |
|---|
| 530 | | - break; |
|---|
| 531 | | - |
|---|
| 532 | | - case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_1: |
|---|
| 533 | | - *value = bridge->bar[((where & ~3) - PCI_BASE_ADDRESS_0) / 4]; |
|---|
| 534 | | - break; |
|---|
| 535 | | - |
|---|
| 536 | | - case PCI_PRIMARY_BUS: |
|---|
| 537 | | - *value = (bridge->secondary_latency_timer << 24 | |
|---|
| 538 | | - bridge->subordinate_bus << 16 | |
|---|
| 539 | | - bridge->secondary_bus << 8 | |
|---|
| 540 | | - bridge->primary_bus); |
|---|
| 541 | | - break; |
|---|
| 542 | | - |
|---|
| 543 | | - case PCI_IO_BASE: |
|---|
| 544 | | - if (!mvebu_has_ioport(port)) |
|---|
| 545 | | - *value = bridge->secondary_status << 16; |
|---|
| 546 | | - else |
|---|
| 547 | | - *value = (bridge->secondary_status << 16 | |
|---|
| 548 | | - bridge->iolimit << 8 | |
|---|
| 549 | | - bridge->iobase); |
|---|
| 550 | | - break; |
|---|
| 551 | | - |
|---|
| 552 | | - case PCI_MEMORY_BASE: |
|---|
| 553 | | - *value = (bridge->memlimit << 16 | bridge->membase); |
|---|
| 554 | | - break; |
|---|
| 555 | | - |
|---|
| 556 | | - case PCI_PREF_MEMORY_BASE: |
|---|
| 557 | | - *value = 0; |
|---|
| 558 | | - break; |
|---|
| 559 | | - |
|---|
| 560 | | - case PCI_IO_BASE_UPPER16: |
|---|
| 561 | | - *value = (bridge->iolimitupper << 16 | bridge->iobaseupper); |
|---|
| 562 | | - break; |
|---|
| 563 | | - |
|---|
| 564 | | - case PCI_CAPABILITY_LIST: |
|---|
| 565 | | - *value = PCISWCAP; |
|---|
| 566 | | - break; |
|---|
| 567 | | - |
|---|
| 568 | | - case PCI_ROM_ADDRESS1: |
|---|
| 569 | | - *value = 0; |
|---|
| 570 | | - break; |
|---|
| 571 | | - |
|---|
| 572 | | - case PCI_INTERRUPT_LINE: |
|---|
| 573 | | - /* LINE PIN MIN_GNT MAX_LAT */ |
|---|
| 574 | | - *value = 0; |
|---|
| 575 | | - break; |
|---|
| 576 | | - |
|---|
| 577 | | - case PCISWCAP_EXP_LIST_ID: |
|---|
| 578 | | - /* Set PCIe v2, root port, slot support */ |
|---|
| 579 | | - *value = (PCI_EXP_TYPE_ROOT_PORT << 4 | 2 | |
|---|
| 580 | | - PCI_EXP_FLAGS_SLOT) << 16 | PCI_CAP_ID_EXP; |
|---|
| 581 | | - break; |
|---|
| 582 | | - |
|---|
| 583 | | - case PCISWCAP_EXP_DEVCAP: |
|---|
| 439 | + switch (reg) { |
|---|
| 440 | + case PCI_EXP_DEVCAP: |
|---|
| 584 | 441 | *value = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_DEVCAP); |
|---|
| 585 | 442 | break; |
|---|
| 586 | 443 | |
|---|
| 587 | | - case PCISWCAP_EXP_DEVCTL: |
|---|
| 444 | + case PCI_EXP_DEVCTL: |
|---|
| 588 | 445 | *value = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_DEVCTL) & |
|---|
| 589 | 446 | ~(PCI_EXP_DEVCTL_URRE | PCI_EXP_DEVCTL_FERE | |
|---|
| 590 | 447 | PCI_EXP_DEVCTL_NFERE | PCI_EXP_DEVCTL_CERE); |
|---|
| 591 | | - *value |= bridge->pcie_devctl; |
|---|
| 592 | 448 | break; |
|---|
| 593 | 449 | |
|---|
| 594 | | - case PCISWCAP_EXP_LNKCAP: |
|---|
| 450 | + case PCI_EXP_LNKCAP: |
|---|
| 595 | 451 | /* |
|---|
| 596 | 452 | * PCIe requires the clock power management capability to be |
|---|
| 597 | 453 | * hard-wired to zero for downstream ports |
|---|
| .. | .. |
|---|
| 600 | 456 | ~PCI_EXP_LNKCAP_CLKPM; |
|---|
| 601 | 457 | break; |
|---|
| 602 | 458 | |
|---|
| 603 | | - case PCISWCAP_EXP_LNKCTL: |
|---|
| 459 | + case PCI_EXP_LNKCTL: |
|---|
| 604 | 460 | *value = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_LNKCTL); |
|---|
| 605 | 461 | break; |
|---|
| 606 | 462 | |
|---|
| 607 | | - case PCISWCAP_EXP_SLTCAP: |
|---|
| 608 | | - *value = bridge->pcie_sltcap; |
|---|
| 609 | | - break; |
|---|
| 610 | | - |
|---|
| 611 | | - case PCISWCAP_EXP_SLTCTL: |
|---|
| 463 | + case PCI_EXP_SLTCTL: |
|---|
| 612 | 464 | *value = PCI_EXP_SLTSTA_PDS << 16; |
|---|
| 613 | 465 | break; |
|---|
| 614 | 466 | |
|---|
| 615 | | - case PCISWCAP_EXP_RTCTL: |
|---|
| 616 | | - *value = bridge->pcie_rtctl; |
|---|
| 617 | | - break; |
|---|
| 618 | | - |
|---|
| 619 | | - case PCISWCAP_EXP_RTSTA: |
|---|
| 467 | + case PCI_EXP_RTSTA: |
|---|
| 620 | 468 | *value = mvebu_readl(port, PCIE_RC_RTSTA); |
|---|
| 621 | 469 | break; |
|---|
| 622 | 470 | |
|---|
| 623 | | - /* PCIe requires the v2 fields to be hard-wired to zero */ |
|---|
| 624 | | - case PCISWCAP_EXP_DEVCAP2: |
|---|
| 625 | | - case PCISWCAP_EXP_DEVCTL2: |
|---|
| 626 | | - case PCISWCAP_EXP_LNKCAP2: |
|---|
| 627 | | - case PCISWCAP_EXP_LNKCTL2: |
|---|
| 628 | | - case PCISWCAP_EXP_SLTCAP2: |
|---|
| 629 | | - case PCISWCAP_EXP_SLTCTL2: |
|---|
| 630 | 471 | default: |
|---|
| 631 | | - /* |
|---|
| 632 | | - * PCI defines configuration read accesses to reserved or |
|---|
| 633 | | - * unimplemented registers to read as zero and complete |
|---|
| 634 | | - * normally. |
|---|
| 635 | | - */ |
|---|
| 636 | | - *value = 0; |
|---|
| 637 | | - return PCIBIOS_SUCCESSFUL; |
|---|
| 472 | + return PCI_BRIDGE_EMUL_NOT_HANDLED; |
|---|
| 638 | 473 | } |
|---|
| 639 | 474 | |
|---|
| 640 | | - if (size == 2) |
|---|
| 641 | | - *value = (*value >> (8 * (where & 3))) & 0xffff; |
|---|
| 642 | | - else if (size == 1) |
|---|
| 643 | | - *value = (*value >> (8 * (where & 3))) & 0xff; |
|---|
| 644 | | - |
|---|
| 645 | | - return PCIBIOS_SUCCESSFUL; |
|---|
| 475 | + return PCI_BRIDGE_EMUL_HANDLED; |
|---|
| 646 | 476 | } |
|---|
| 647 | 477 | |
|---|
| 648 | | -/* Write to the PCI-to-PCI bridge configuration space */ |
|---|
| 649 | | -static int mvebu_sw_pci_bridge_write(struct mvebu_pcie_port *port, |
|---|
| 650 | | - unsigned int where, int size, u32 value) |
|---|
| 478 | +static void |
|---|
| 479 | +mvebu_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge, |
|---|
| 480 | + int reg, u32 old, u32 new, u32 mask) |
|---|
| 651 | 481 | { |
|---|
| 652 | | - struct mvebu_sw_pci_bridge *bridge = &port->bridge; |
|---|
| 653 | | - u32 mask, reg; |
|---|
| 654 | | - int err; |
|---|
| 482 | + struct mvebu_pcie_port *port = bridge->data; |
|---|
| 483 | + struct pci_bridge_emul_conf *conf = &bridge->conf; |
|---|
| 655 | 484 | |
|---|
| 656 | | - if (size == 4) |
|---|
| 657 | | - mask = 0x0; |
|---|
| 658 | | - else if (size == 2) |
|---|
| 659 | | - mask = ~(0xffff << ((where & 3) * 8)); |
|---|
| 660 | | - else if (size == 1) |
|---|
| 661 | | - mask = ~(0xff << ((where & 3) * 8)); |
|---|
| 662 | | - else |
|---|
| 663 | | - return PCIBIOS_BAD_REGISTER_NUMBER; |
|---|
| 664 | | - |
|---|
| 665 | | - err = mvebu_sw_pci_bridge_read(port, where & ~3, 4, ®); |
|---|
| 666 | | - if (err) |
|---|
| 667 | | - return err; |
|---|
| 668 | | - |
|---|
| 669 | | - value = (reg & mask) | value << ((where & 3) * 8); |
|---|
| 670 | | - |
|---|
| 671 | | - switch (where & ~3) { |
|---|
| 485 | + switch (reg) { |
|---|
| 672 | 486 | case PCI_COMMAND: |
|---|
| 673 | 487 | { |
|---|
| 674 | | - u32 old = bridge->command; |
|---|
| 675 | | - |
|---|
| 676 | 488 | if (!mvebu_has_ioport(port)) |
|---|
| 677 | | - value &= ~PCI_COMMAND_IO; |
|---|
| 489 | + conf->command &= ~PCI_COMMAND_IO; |
|---|
| 678 | 490 | |
|---|
| 679 | | - bridge->command = value & 0xffff; |
|---|
| 680 | | - if ((old ^ bridge->command) & PCI_COMMAND_IO) |
|---|
| 491 | + if ((old ^ new) & PCI_COMMAND_IO) |
|---|
| 681 | 492 | mvebu_pcie_handle_iobase_change(port); |
|---|
| 682 | | - if ((old ^ bridge->command) & PCI_COMMAND_MEMORY) |
|---|
| 493 | + if ((old ^ new) & PCI_COMMAND_MEMORY) |
|---|
| 683 | 494 | mvebu_pcie_handle_membase_change(port); |
|---|
| 495 | + |
|---|
| 684 | 496 | break; |
|---|
| 685 | 497 | } |
|---|
| 686 | | - |
|---|
| 687 | | - case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_1: |
|---|
| 688 | | - bridge->bar[((where & ~3) - PCI_BASE_ADDRESS_0) / 4] = value; |
|---|
| 689 | | - break; |
|---|
| 690 | 498 | |
|---|
| 691 | 499 | case PCI_IO_BASE: |
|---|
| 692 | 500 | /* |
|---|
| 693 | | - * We also keep bit 1 set, it is a read-only bit that |
|---|
| 501 | + * We keep bit 1 set, it is a read-only bit that |
|---|
| 694 | 502 | * indicates we support 32 bits addressing for the |
|---|
| 695 | 503 | * I/O |
|---|
| 696 | 504 | */ |
|---|
| 697 | | - bridge->iobase = (value & 0xff) | PCI_IO_RANGE_TYPE_32; |
|---|
| 698 | | - bridge->iolimit = ((value >> 8) & 0xff) | PCI_IO_RANGE_TYPE_32; |
|---|
| 505 | + conf->iobase |= PCI_IO_RANGE_TYPE_32; |
|---|
| 506 | + conf->iolimit |= PCI_IO_RANGE_TYPE_32; |
|---|
| 699 | 507 | mvebu_pcie_handle_iobase_change(port); |
|---|
| 700 | 508 | break; |
|---|
| 701 | 509 | |
|---|
| 702 | 510 | case PCI_MEMORY_BASE: |
|---|
| 703 | | - bridge->membase = value & 0xffff; |
|---|
| 704 | | - bridge->memlimit = value >> 16; |
|---|
| 705 | 511 | mvebu_pcie_handle_membase_change(port); |
|---|
| 706 | 512 | break; |
|---|
| 707 | 513 | |
|---|
| 708 | 514 | case PCI_IO_BASE_UPPER16: |
|---|
| 709 | | - bridge->iobaseupper = value & 0xffff; |
|---|
| 710 | | - bridge->iolimitupper = value >> 16; |
|---|
| 711 | 515 | mvebu_pcie_handle_iobase_change(port); |
|---|
| 712 | 516 | break; |
|---|
| 713 | 517 | |
|---|
| 714 | 518 | case PCI_PRIMARY_BUS: |
|---|
| 715 | | - bridge->primary_bus = value & 0xff; |
|---|
| 716 | | - bridge->secondary_bus = (value >> 8) & 0xff; |
|---|
| 717 | | - bridge->subordinate_bus = (value >> 16) & 0xff; |
|---|
| 718 | | - bridge->secondary_latency_timer = (value >> 24) & 0xff; |
|---|
| 719 | | - mvebu_pcie_set_local_bus_nr(port, bridge->secondary_bus); |
|---|
| 519 | + mvebu_pcie_set_local_bus_nr(port, conf->secondary_bus); |
|---|
| 720 | 520 | break; |
|---|
| 721 | 521 | |
|---|
| 722 | | - case PCISWCAP_EXP_DEVCTL: |
|---|
| 522 | + default: |
|---|
| 523 | + break; |
|---|
| 524 | + } |
|---|
| 525 | +} |
|---|
| 526 | + |
|---|
| 527 | +static void |
|---|
| 528 | +mvebu_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge, |
|---|
| 529 | + int reg, u32 old, u32 new, u32 mask) |
|---|
| 530 | +{ |
|---|
| 531 | + struct mvebu_pcie_port *port = bridge->data; |
|---|
| 532 | + |
|---|
| 533 | + switch (reg) { |
|---|
| 534 | + case PCI_EXP_DEVCTL: |
|---|
| 723 | 535 | /* |
|---|
| 724 | 536 | * Armada370 data says these bits must always |
|---|
| 725 | 537 | * be zero when in root complex mode. |
|---|
| 726 | 538 | */ |
|---|
| 727 | | - value &= ~(PCI_EXP_DEVCTL_URRE | PCI_EXP_DEVCTL_FERE | |
|---|
| 728 | | - PCI_EXP_DEVCTL_NFERE | PCI_EXP_DEVCTL_CERE); |
|---|
| 539 | + new &= ~(PCI_EXP_DEVCTL_URRE | PCI_EXP_DEVCTL_FERE | |
|---|
| 540 | + PCI_EXP_DEVCTL_NFERE | PCI_EXP_DEVCTL_CERE); |
|---|
| 729 | 541 | |
|---|
| 730 | | - /* |
|---|
| 731 | | - * If the mask is 0xffff0000, then we only want to write |
|---|
| 732 | | - * the device control register, rather than clearing the |
|---|
| 733 | | - * RW1C bits in the device status register. Mask out the |
|---|
| 734 | | - * status register bits. |
|---|
| 735 | | - */ |
|---|
| 736 | | - if (mask == 0xffff0000) |
|---|
| 737 | | - value &= 0xffff; |
|---|
| 738 | | - |
|---|
| 739 | | - mvebu_writel(port, value, PCIE_CAP_PCIEXP + PCI_EXP_DEVCTL); |
|---|
| 542 | + mvebu_writel(port, new, PCIE_CAP_PCIEXP + PCI_EXP_DEVCTL); |
|---|
| 740 | 543 | break; |
|---|
| 741 | 544 | |
|---|
| 742 | | - case PCISWCAP_EXP_LNKCTL: |
|---|
| 545 | + case PCI_EXP_LNKCTL: |
|---|
| 743 | 546 | /* |
|---|
| 744 | 547 | * If we don't support CLKREQ, we must ensure that the |
|---|
| 745 | 548 | * CLKREQ enable bit always reads zero. Since we haven't |
|---|
| 746 | 549 | * had this capability, and it's dependent on board wiring, |
|---|
| 747 | 550 | * disable it for the time being. |
|---|
| 748 | 551 | */ |
|---|
| 749 | | - value &= ~PCI_EXP_LNKCTL_CLKREQ_EN; |
|---|
| 552 | + new &= ~PCI_EXP_LNKCTL_CLKREQ_EN; |
|---|
| 750 | 553 | |
|---|
| 751 | | - /* |
|---|
| 752 | | - * If the mask is 0xffff0000, then we only want to write |
|---|
| 753 | | - * the link control register, rather than clearing the |
|---|
| 754 | | - * RW1C bits in the link status register. Mask out the |
|---|
| 755 | | - * RW1C status register bits. |
|---|
| 756 | | - */ |
|---|
| 757 | | - if (mask == 0xffff0000) |
|---|
| 758 | | - value &= ~((PCI_EXP_LNKSTA_LABS | |
|---|
| 759 | | - PCI_EXP_LNKSTA_LBMS) << 16); |
|---|
| 760 | | - |
|---|
| 761 | | - mvebu_writel(port, value, PCIE_CAP_PCIEXP + PCI_EXP_LNKCTL); |
|---|
| 554 | + mvebu_writel(port, new, PCIE_CAP_PCIEXP + PCI_EXP_LNKCTL); |
|---|
| 762 | 555 | break; |
|---|
| 763 | 556 | |
|---|
| 764 | | - case PCISWCAP_EXP_RTSTA: |
|---|
| 765 | | - mvebu_writel(port, value, PCIE_RC_RTSTA); |
|---|
| 766 | | - break; |
|---|
| 767 | | - |
|---|
| 768 | | - default: |
|---|
| 557 | + case PCI_EXP_RTSTA: |
|---|
| 558 | + mvebu_writel(port, new, PCIE_RC_RTSTA); |
|---|
| 769 | 559 | break; |
|---|
| 770 | 560 | } |
|---|
| 561 | +} |
|---|
| 771 | 562 | |
|---|
| 772 | | - return PCIBIOS_SUCCESSFUL; |
|---|
| 563 | +static struct pci_bridge_emul_ops mvebu_pci_bridge_emul_ops = { |
|---|
| 564 | + .write_base = mvebu_pci_bridge_emul_base_conf_write, |
|---|
| 565 | + .read_pcie = mvebu_pci_bridge_emul_pcie_conf_read, |
|---|
| 566 | + .write_pcie = mvebu_pci_bridge_emul_pcie_conf_write, |
|---|
| 567 | +}; |
|---|
| 568 | + |
|---|
| 569 | +/* |
|---|
| 570 | + * Initialize the configuration space of the PCI-to-PCI bridge |
|---|
| 571 | + * associated with the given PCIe interface. |
|---|
| 572 | + */ |
|---|
| 573 | +static void mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port) |
|---|
| 574 | +{ |
|---|
| 575 | + struct pci_bridge_emul *bridge = &port->bridge; |
|---|
| 576 | + u32 pcie_cap = mvebu_readl(port, PCIE_CAP_PCIEXP); |
|---|
| 577 | + u8 pcie_cap_ver = ((pcie_cap >> 16) & PCI_EXP_FLAGS_VERS); |
|---|
| 578 | + |
|---|
| 579 | + bridge->conf.vendor = PCI_VENDOR_ID_MARVELL; |
|---|
| 580 | + bridge->conf.device = mvebu_readl(port, PCIE_DEV_ID_OFF) >> 16; |
|---|
| 581 | + bridge->conf.class_revision = |
|---|
| 582 | + mvebu_readl(port, PCIE_DEV_REV_OFF) & 0xff; |
|---|
| 583 | + |
|---|
| 584 | + if (mvebu_has_ioport(port)) { |
|---|
| 585 | + /* We support 32 bits I/O addressing */ |
|---|
| 586 | + bridge->conf.iobase = PCI_IO_RANGE_TYPE_32; |
|---|
| 587 | + bridge->conf.iolimit = PCI_IO_RANGE_TYPE_32; |
|---|
| 588 | + } |
|---|
| 589 | + |
|---|
| 590 | + /* |
|---|
| 591 | + * Older mvebu hardware provides PCIe Capability structure only in |
|---|
| 592 | + * version 1. New hardware provides it in version 2. |
|---|
| 593 | + */ |
|---|
| 594 | + bridge->pcie_conf.cap = cpu_to_le16(pcie_cap_ver); |
|---|
| 595 | + |
|---|
| 596 | + bridge->has_pcie = true; |
|---|
| 597 | + bridge->data = port; |
|---|
| 598 | + bridge->ops = &mvebu_pci_bridge_emul_ops; |
|---|
| 599 | + |
|---|
| 600 | + pci_bridge_emul_init(bridge, PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR); |
|---|
| 773 | 601 | } |
|---|
| 774 | 602 | |
|---|
| 775 | 603 | static inline struct mvebu_pcie *sys_to_pcie(struct pci_sys_data *sys) |
|---|
| .. | .. |
|---|
| 789 | 617 | if (bus->number == 0 && port->devfn == devfn) |
|---|
| 790 | 618 | return port; |
|---|
| 791 | 619 | if (bus->number != 0 && |
|---|
| 792 | | - bus->number >= port->bridge.secondary_bus && |
|---|
| 793 | | - bus->number <= port->bridge.subordinate_bus) |
|---|
| 620 | + bus->number >= port->bridge.conf.secondary_bus && |
|---|
| 621 | + bus->number <= port->bridge.conf.subordinate_bus) |
|---|
| 794 | 622 | return port; |
|---|
| 795 | 623 | } |
|---|
| 796 | 624 | |
|---|
| .. | .. |
|---|
| 811 | 639 | |
|---|
| 812 | 640 | /* Access the emulated PCI-to-PCI bridge */ |
|---|
| 813 | 641 | if (bus->number == 0) |
|---|
| 814 | | - return mvebu_sw_pci_bridge_write(port, where, size, val); |
|---|
| 642 | + return pci_bridge_emul_conf_write(&port->bridge, where, |
|---|
| 643 | + size, val); |
|---|
| 815 | 644 | |
|---|
| 816 | 645 | if (!mvebu_pcie_link_up(port)) |
|---|
| 817 | 646 | return PCIBIOS_DEVICE_NOT_FOUND; |
|---|
| .. | .. |
|---|
| 839 | 668 | |
|---|
| 840 | 669 | /* Access the emulated PCI-to-PCI bridge */ |
|---|
| 841 | 670 | if (bus->number == 0) |
|---|
| 842 | | - return mvebu_sw_pci_bridge_read(port, where, size, val); |
|---|
| 671 | + return pci_bridge_emul_conf_read(&port->bridge, where, |
|---|
| 672 | + size, val); |
|---|
| 843 | 673 | |
|---|
| 844 | 674 | if (!mvebu_pcie_link_up(port)) { |
|---|
| 845 | 675 | *val = 0xffffffff; |
|---|
| .. | .. |
|---|
| 892 | 722 | struct device_node *np, |
|---|
| 893 | 723 | struct mvebu_pcie_port *port) |
|---|
| 894 | 724 | { |
|---|
| 895 | | - struct resource regs; |
|---|
| 896 | 725 | int ret = 0; |
|---|
| 897 | 726 | |
|---|
| 898 | | - ret = of_address_to_resource(np, 0, ®s); |
|---|
| 727 | + ret = of_address_to_resource(np, 0, &port->regs); |
|---|
| 899 | 728 | if (ret) |
|---|
| 900 | | - return ERR_PTR(ret); |
|---|
| 729 | + return (void __iomem *)ERR_PTR(ret); |
|---|
| 901 | 730 | |
|---|
| 902 | | - return devm_ioremap_resource(&pdev->dev, ®s); |
|---|
| 731 | + return devm_ioremap_resource(&pdev->dev, &port->regs); |
|---|
| 903 | 732 | } |
|---|
| 904 | 733 | |
|---|
| 905 | 734 | #define DT_FLAGS_TO_TYPE(flags) (((flags) >> 24) & 0x03) |
|---|
| .. | .. |
|---|
| 1137 | 966 | } |
|---|
| 1138 | 967 | |
|---|
| 1139 | 968 | /* |
|---|
| 1140 | | - * We can't use devm_of_pci_get_host_bridge_resources() because we |
|---|
| 1141 | | - * need to parse our special DT properties encoding the MEM and IO |
|---|
| 1142 | | - * apertures. |
|---|
| 969 | + * devm_of_pci_get_host_bridge_resources() only sets up translateable resources, |
|---|
| 970 | + * so we need extra resource setup parsing our special DT properties encoding |
|---|
| 971 | + * the MEM and IO apertures. |
|---|
| 1143 | 972 | */ |
|---|
| 1144 | 973 | static int mvebu_pcie_parse_request_resources(struct mvebu_pcie *pcie) |
|---|
| 1145 | 974 | { |
|---|
| 1146 | 975 | struct device *dev = &pcie->pdev->dev; |
|---|
| 1147 | | - struct device_node *np = dev->of_node; |
|---|
| 976 | + struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie); |
|---|
| 1148 | 977 | int ret; |
|---|
| 1149 | | - |
|---|
| 1150 | | - INIT_LIST_HEAD(&pcie->resources); |
|---|
| 1151 | | - |
|---|
| 1152 | | - /* Get the bus range */ |
|---|
| 1153 | | - ret = of_pci_parse_bus_range(np, &pcie->busn); |
|---|
| 1154 | | - if (ret) { |
|---|
| 1155 | | - dev_err(dev, "failed to parse bus-range property: %d\n", ret); |
|---|
| 1156 | | - return ret; |
|---|
| 1157 | | - } |
|---|
| 1158 | | - pci_add_resource(&pcie->resources, &pcie->busn); |
|---|
| 1159 | 978 | |
|---|
| 1160 | 979 | /* Get the PCIe memory aperture */ |
|---|
| 1161 | 980 | mvebu_mbus_get_pcie_mem_aperture(&pcie->mem); |
|---|
| .. | .. |
|---|
| 1165 | 984 | } |
|---|
| 1166 | 985 | |
|---|
| 1167 | 986 | pcie->mem.name = "PCI MEM"; |
|---|
| 1168 | | - pci_add_resource(&pcie->resources, &pcie->mem); |
|---|
| 987 | + pci_add_resource(&bridge->windows, &pcie->mem); |
|---|
| 988 | + ret = devm_request_resource(dev, &iomem_resource, &pcie->mem); |
|---|
| 989 | + if (ret) |
|---|
| 990 | + return ret; |
|---|
| 1169 | 991 | |
|---|
| 1170 | 992 | /* Get the PCIe IO aperture */ |
|---|
| 1171 | 993 | mvebu_mbus_get_pcie_io_aperture(&pcie->io); |
|---|
| .. | .. |
|---|
| 1178 | 1000 | resource_size(&pcie->io) - 1); |
|---|
| 1179 | 1001 | pcie->realio.name = "PCI I/O"; |
|---|
| 1180 | 1002 | |
|---|
| 1181 | | - pci_add_resource(&pcie->resources, &pcie->realio); |
|---|
| 1003 | + pci_add_resource(&bridge->windows, &pcie->realio); |
|---|
| 1004 | + ret = devm_request_resource(dev, &ioport_resource, &pcie->realio); |
|---|
| 1005 | + if (ret) |
|---|
| 1006 | + return ret; |
|---|
| 1182 | 1007 | } |
|---|
| 1183 | 1008 | |
|---|
| 1184 | | - return devm_request_pci_bus_resources(dev, &pcie->resources); |
|---|
| 1009 | + return 0; |
|---|
| 1185 | 1010 | } |
|---|
| 1186 | 1011 | |
|---|
| 1187 | 1012 | /* |
|---|
| .. | .. |
|---|
| 1297 | 1122 | |
|---|
| 1298 | 1123 | mvebu_pcie_setup_hw(port); |
|---|
| 1299 | 1124 | mvebu_pcie_set_local_dev_nr(port, 1); |
|---|
| 1300 | | - mvebu_sw_pci_bridge_init(port); |
|---|
| 1125 | + mvebu_pci_bridge_emul_init(port); |
|---|
| 1301 | 1126 | } |
|---|
| 1302 | 1127 | |
|---|
| 1303 | 1128 | pcie->nports = i; |
|---|
| 1304 | 1129 | |
|---|
| 1305 | | - list_splice_init(&pcie->resources, &bridge->windows); |
|---|
| 1306 | | - bridge->dev.parent = dev; |
|---|
| 1307 | 1130 | bridge->sysdata = pcie; |
|---|
| 1308 | | - bridge->busnr = 0; |
|---|
| 1309 | 1131 | bridge->ops = &mvebu_pcie_ops; |
|---|
| 1310 | | - bridge->map_irq = of_irq_parse_and_map_pci; |
|---|
| 1311 | | - bridge->swizzle_irq = pci_common_swizzle; |
|---|
| 1312 | 1132 | bridge->align_resource = mvebu_pcie_align_resource; |
|---|
| 1313 | | - bridge->msi = pcie->msi; |
|---|
| 1314 | 1133 | |
|---|
| 1315 | 1134 | return mvebu_pci_host_probe(bridge); |
|---|
| 1316 | 1135 | } |
|---|