diff options
author | Thomas Petazzoni <thomas.petazzoni@bootlin.com> | 2018-10-18 11:37:18 -0400 |
---|---|---|
committer | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> | 2018-10-18 12:51:07 -0400 |
commit | 1f08673eef1236f7d02d93fcf596bb8531ef0d12 (patch) | |
tree | fd094f56482d93778827fac6ec26885a8808aeff | |
parent | eae6aaf8488ebbf0fd6e1588f0923db0462e4c5c (diff) |
PCI: mvebu: Convert to PCI emulated bridge config space
Convert the pci-mvebu driver to use the pci-bridge-emul logic, that
helps emulating a root port PCI bridge configuration space.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
[lorenzo.pieralisi@arm.com: updated commit log]
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
-rw-r--r-- | drivers/pci/controller/Kconfig | 1 | ||||
-rw-r--r-- | drivers/pci/controller/pci-mvebu.c | 370 |
2 files changed, 101 insertions, 270 deletions
diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig index 028b287466fb..6d0f9930be7f 100644 --- a/drivers/pci/controller/Kconfig +++ b/drivers/pci/controller/Kconfig | |||
@@ -9,6 +9,7 @@ config PCI_MVEBU | |||
9 | depends on MVEBU_MBUS | 9 | depends on MVEBU_MBUS |
10 | depends on ARM | 10 | depends on ARM |
11 | depends on OF | 11 | depends on OF |
12 | select PCI_BRIDGE_EMUL | ||
12 | 13 | ||
13 | config PCI_AARDVARK | 14 | config PCI_AARDVARK |
14 | bool "Aardvark PCIe controller" | 15 | bool "Aardvark PCIe controller" |
diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c index beaff9325a09..4711ca8fa5d4 100644 --- a/drivers/pci/controller/pci-mvebu.c +++ b/drivers/pci/controller/pci-mvebu.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/of_platform.h> | 22 | #include <linux/of_platform.h> |
23 | 23 | ||
24 | #include "../pci.h" | 24 | #include "../pci.h" |
25 | #include "../pci-bridge-emul.h" | ||
25 | 26 | ||
26 | /* | 27 | /* |
27 | * PCIe unit register offsets. | 28 | * PCIe unit register offsets. |
@@ -63,56 +64,6 @@ | |||
63 | #define PCIE_DEBUG_CTRL 0x1a60 | 64 | #define PCIE_DEBUG_CTRL 0x1a60 |
64 | #define PCIE_DEBUG_SOFT_RESET BIT(20) | 65 | #define PCIE_DEBUG_SOFT_RESET BIT(20) |
65 | 66 | ||
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 | |||
116 | struct mvebu_pcie_port; | 67 | struct mvebu_pcie_port; |
117 | 68 | ||
118 | /* Structure representing all PCIe interfaces */ | 69 | /* Structure representing all PCIe interfaces */ |
@@ -148,7 +99,7 @@ struct mvebu_pcie_port { | |||
148 | struct clk *clk; | 99 | struct clk *clk; |
149 | struct gpio_desc *reset_gpio; | 100 | struct gpio_desc *reset_gpio; |
150 | char *reset_name; | 101 | char *reset_name; |
151 | struct mvebu_sw_pci_bridge bridge; | 102 | struct pci_bridge_emul bridge; |
152 | struct device_node *dn; | 103 | struct device_node *dn; |
153 | struct mvebu_pcie *pcie; | 104 | struct mvebu_pcie *pcie; |
154 | struct mvebu_pcie_window memwin; | 105 | struct mvebu_pcie_window memwin; |
@@ -410,11 +361,12 @@ static void mvebu_pcie_set_window(struct mvebu_pcie_port *port, | |||
410 | static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port) | 361 | static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port) |
411 | { | 362 | { |
412 | struct mvebu_pcie_window desired = {}; | 363 | struct mvebu_pcie_window desired = {}; |
364 | struct pci_bridge_emul_conf *conf = &port->bridge.conf; | ||
413 | 365 | ||
414 | /* Are the new iobase/iolimit values invalid? */ | 366 | /* Are the new iobase/iolimit values invalid? */ |
415 | if (port->bridge.iolimit < port->bridge.iobase || | 367 | if (conf->iolimit < conf->iobase || |
416 | port->bridge.iolimitupper < port->bridge.iobaseupper || | 368 | conf->iolimitupper < conf->iobaseupper || |
417 | !(port->bridge.command & PCI_COMMAND_IO)) { | 369 | !(conf->command & PCI_COMMAND_IO)) { |
418 | mvebu_pcie_set_window(port, port->io_target, port->io_attr, | 370 | mvebu_pcie_set_window(port, port->io_target, port->io_attr, |
419 | &desired, &port->iowin); | 371 | &desired, &port->iowin); |
420 | return; | 372 | return; |
@@ -433,11 +385,11 @@ static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port) | |||
433 | * specifications. iobase is the bus address, port->iowin_base | 385 | * specifications. iobase is the bus address, port->iowin_base |
434 | * is the CPU address. | 386 | * is the CPU address. |
435 | */ | 387 | */ |
436 | desired.remap = ((port->bridge.iobase & 0xF0) << 8) | | 388 | desired.remap = ((conf->iobase & 0xF0) << 8) | |
437 | (port->bridge.iobaseupper << 16); | 389 | (conf->iobaseupper << 16); |
438 | desired.base = port->pcie->io.start + desired.remap; | 390 | desired.base = port->pcie->io.start + desired.remap; |
439 | desired.size = ((0xFFF | ((port->bridge.iolimit & 0xF0) << 8) | | 391 | desired.size = ((0xFFF | ((conf->iolimit & 0xF0) << 8) | |
440 | (port->bridge.iolimitupper << 16)) - | 392 | (conf->iolimitupper << 16)) - |
441 | desired.remap) + | 393 | desired.remap) + |
442 | 1; | 394 | 1; |
443 | 395 | ||
@@ -448,10 +400,11 @@ static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port) | |||
448 | static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port) | 400 | static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port) |
449 | { | 401 | { |
450 | struct mvebu_pcie_window desired = {.remap = MVEBU_MBUS_NO_REMAP}; | 402 | struct mvebu_pcie_window desired = {.remap = MVEBU_MBUS_NO_REMAP}; |
403 | struct pci_bridge_emul_conf *conf = &port->bridge.conf; | ||
451 | 404 | ||
452 | /* Are the new membase/memlimit values invalid? */ | 405 | /* Are the new membase/memlimit values invalid? */ |
453 | if (port->bridge.memlimit < port->bridge.membase || | 406 | if (conf->memlimit < conf->membase || |
454 | !(port->bridge.command & PCI_COMMAND_MEMORY)) { | 407 | !(conf->command & PCI_COMMAND_MEMORY)) { |
455 | mvebu_pcie_set_window(port, port->mem_target, port->mem_attr, | 408 | mvebu_pcie_set_window(port, port->mem_target, port->mem_attr, |
456 | &desired, &port->memwin); | 409 | &desired, &port->memwin); |
457 | return; | 410 | return; |
@@ -463,129 +416,32 @@ static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port) | |||
463 | * window to setup, according to the PCI-to-PCI bridge | 416 | * window to setup, according to the PCI-to-PCI bridge |
464 | * specifications. | 417 | * specifications. |
465 | */ | 418 | */ |
466 | desired.base = ((port->bridge.membase & 0xFFF0) << 16); | 419 | desired.base = ((conf->membase & 0xFFF0) << 16); |
467 | desired.size = (((port->bridge.memlimit & 0xFFF0) << 16) | 0xFFFFF) - | 420 | desired.size = (((conf->memlimit & 0xFFF0) << 16) | 0xFFFFF) - |
468 | desired.base + 1; | 421 | desired.base + 1; |
469 | 422 | ||
470 | mvebu_pcie_set_window(port, port->mem_target, port->mem_attr, &desired, | 423 | mvebu_pcie_set_window(port, port->mem_target, port->mem_attr, &desired, |
471 | &port->memwin); | 424 | &port->memwin); |
472 | } | 425 | } |
473 | 426 | ||
474 | /* | 427 | static pci_bridge_emul_read_status_t |
475 | * Initialize the configuration space of the PCI-to-PCI bridge | 428 | mvebu_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge, |
476 | * associated with the given PCIe interface. | 429 | int reg, u32 *value) |
477 | */ | ||
478 | static void mvebu_sw_pci_bridge_init(struct mvebu_pcie_port *port) | ||
479 | { | 430 | { |
480 | struct mvebu_sw_pci_bridge *bridge = &port->bridge; | 431 | struct mvebu_pcie_port *port = bridge->data; |
481 | |||
482 | memset(bridge, 0, sizeof(struct mvebu_sw_pci_bridge)); | ||
483 | |||
484 | bridge->class = PCI_CLASS_BRIDGE_PCI; | ||
485 | bridge->vendor = PCI_VENDOR_ID_MARVELL; | ||
486 | bridge->device = mvebu_readl(port, PCIE_DEV_ID_OFF) >> 16; | ||
487 | bridge->revision = mvebu_readl(port, PCIE_DEV_REV_OFF) & 0xff; | ||
488 | bridge->header_type = PCI_HEADER_TYPE_BRIDGE; | ||
489 | bridge->cache_line_size = 0x10; | ||
490 | |||
491 | /* We support 32 bits I/O addressing */ | ||
492 | bridge->iobase = PCI_IO_RANGE_TYPE_32; | ||
493 | bridge->iolimit = PCI_IO_RANGE_TYPE_32; | ||
494 | |||
495 | /* Add capabilities */ | ||
496 | bridge->status = PCI_STATUS_CAP_LIST; | ||
497 | } | ||
498 | |||
499 | /* | ||
500 | * Read the configuration space of the PCI-to-PCI bridge associated to | ||
501 | * the given PCIe interface. | ||
502 | */ | ||
503 | static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port, | ||
504 | unsigned int where, int size, u32 *value) | ||
505 | { | ||
506 | struct mvebu_sw_pci_bridge *bridge = &port->bridge; | ||
507 | |||
508 | switch (where & ~3) { | ||
509 | case PCI_VENDOR_ID: | ||
510 | *value = bridge->device << 16 | bridge->vendor; | ||
511 | break; | ||
512 | |||
513 | case PCI_COMMAND: | ||
514 | *value = bridge->command | bridge->status << 16; | ||
515 | break; | ||
516 | |||
517 | case PCI_CLASS_REVISION: | ||
518 | *value = bridge->class << 16 | bridge->interface << 8 | | ||
519 | bridge->revision; | ||
520 | break; | ||
521 | |||
522 | case PCI_CACHE_LINE_SIZE: | ||
523 | *value = bridge->bist << 24 | bridge->header_type << 16 | | ||
524 | bridge->latency_timer << 8 | bridge->cache_line_size; | ||
525 | break; | ||
526 | |||
527 | case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_1: | ||
528 | *value = bridge->bar[((where & ~3) - PCI_BASE_ADDRESS_0) / 4]; | ||
529 | break; | ||
530 | |||
531 | case PCI_PRIMARY_BUS: | ||
532 | *value = (bridge->secondary_latency_timer << 24 | | ||
533 | bridge->subordinate_bus << 16 | | ||
534 | bridge->secondary_bus << 8 | | ||
535 | bridge->primary_bus); | ||
536 | break; | ||
537 | |||
538 | case PCI_IO_BASE: | ||
539 | if (!mvebu_has_ioport(port)) | ||
540 | *value = bridge->secondary_status << 16; | ||
541 | else | ||
542 | *value = (bridge->secondary_status << 16 | | ||
543 | bridge->iolimit << 8 | | ||
544 | bridge->iobase); | ||
545 | break; | ||
546 | |||
547 | case PCI_MEMORY_BASE: | ||
548 | *value = (bridge->memlimit << 16 | bridge->membase); | ||
549 | break; | ||
550 | |||
551 | case PCI_PREF_MEMORY_BASE: | ||
552 | *value = 0; | ||
553 | break; | ||
554 | |||
555 | case PCI_IO_BASE_UPPER16: | ||
556 | *value = (bridge->iolimitupper << 16 | bridge->iobaseupper); | ||
557 | break; | ||
558 | |||
559 | case PCI_CAPABILITY_LIST: | ||
560 | *value = PCISWCAP; | ||
561 | break; | ||
562 | 432 | ||
563 | case PCI_ROM_ADDRESS1: | 433 | switch (reg) { |
564 | *value = 0; | 434 | case PCI_EXP_DEVCAP: |
565 | break; | ||
566 | |||
567 | case PCI_INTERRUPT_LINE: | ||
568 | /* LINE PIN MIN_GNT MAX_LAT */ | ||
569 | *value = 0; | ||
570 | break; | ||
571 | |||
572 | case PCISWCAP_EXP_LIST_ID: | ||
573 | /* Set PCIe v2, root port, slot support */ | ||
574 | *value = (PCI_EXP_TYPE_ROOT_PORT << 4 | 2 | | ||
575 | PCI_EXP_FLAGS_SLOT) << 16 | PCI_CAP_ID_EXP; | ||
576 | break; | ||
577 | |||
578 | case PCISWCAP_EXP_DEVCAP: | ||
579 | *value = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_DEVCAP); | 435 | *value = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_DEVCAP); |
580 | break; | 436 | break; |
581 | 437 | ||
582 | case PCISWCAP_EXP_DEVCTL: | 438 | case PCI_EXP_DEVCTL: |
583 | *value = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_DEVCTL) & | 439 | *value = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_DEVCTL) & |
584 | ~(PCI_EXP_DEVCTL_URRE | PCI_EXP_DEVCTL_FERE | | 440 | ~(PCI_EXP_DEVCTL_URRE | PCI_EXP_DEVCTL_FERE | |
585 | PCI_EXP_DEVCTL_NFERE | PCI_EXP_DEVCTL_CERE); | 441 | PCI_EXP_DEVCTL_NFERE | PCI_EXP_DEVCTL_CERE); |
586 | break; | 442 | break; |
587 | 443 | ||
588 | case PCISWCAP_EXP_LNKCAP: | 444 | case PCI_EXP_LNKCAP: |
589 | /* | 445 | /* |
590 | * PCIe requires the clock power management capability to be | 446 | * PCIe requires the clock power management capability to be |
591 | * hard-wired to zero for downstream ports | 447 | * hard-wired to zero for downstream ports |
@@ -594,168 +450,140 @@ static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port, | |||
594 | ~PCI_EXP_LNKCAP_CLKPM; | 450 | ~PCI_EXP_LNKCAP_CLKPM; |
595 | break; | 451 | break; |
596 | 452 | ||
597 | case PCISWCAP_EXP_LNKCTL: | 453 | case PCI_EXP_LNKCTL: |
598 | *value = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_LNKCTL); | 454 | *value = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_LNKCTL); |
599 | break; | 455 | break; |
600 | 456 | ||
601 | case PCISWCAP_EXP_SLTCTL: | 457 | case PCI_EXP_SLTCTL: |
602 | *value = PCI_EXP_SLTSTA_PDS << 16; | 458 | *value = PCI_EXP_SLTSTA_PDS << 16; |
603 | break; | 459 | break; |
604 | 460 | ||
605 | case PCISWCAP_EXP_RTSTA: | 461 | case PCI_EXP_RTSTA: |
606 | *value = mvebu_readl(port, PCIE_RC_RTSTA); | 462 | *value = mvebu_readl(port, PCIE_RC_RTSTA); |
607 | break; | 463 | break; |
608 | 464 | ||
609 | /* PCIe requires the v2 fields to be hard-wired to zero */ | ||
610 | case PCISWCAP_EXP_DEVCAP2: | ||
611 | case PCISWCAP_EXP_DEVCTL2: | ||
612 | case PCISWCAP_EXP_LNKCAP2: | ||
613 | case PCISWCAP_EXP_LNKCTL2: | ||
614 | case PCISWCAP_EXP_SLTCAP2: | ||
615 | case PCISWCAP_EXP_SLTCTL2: | ||
616 | default: | 465 | default: |
617 | /* | 466 | return PCI_BRIDGE_EMUL_NOT_HANDLED; |
618 | * PCI defines configuration read accesses to reserved or | ||
619 | * unimplemented registers to read as zero and complete | ||
620 | * normally. | ||
621 | */ | ||
622 | *value = 0; | ||
623 | return PCIBIOS_SUCCESSFUL; | ||
624 | } | 467 | } |
625 | 468 | ||
626 | if (size == 2) | 469 | return PCI_BRIDGE_EMUL_HANDLED; |
627 | *value = (*value >> (8 * (where & 3))) & 0xffff; | ||
628 | else if (size == 1) | ||
629 | *value = (*value >> (8 * (where & 3))) & 0xff; | ||
630 | |||
631 | return PCIBIOS_SUCCESSFUL; | ||
632 | } | 470 | } |
633 | 471 | ||
634 | /* Write to the PCI-to-PCI bridge configuration space */ | 472 | static void |
635 | static int mvebu_sw_pci_bridge_write(struct mvebu_pcie_port *port, | 473 | mvebu_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge, |
636 | unsigned int where, int size, u32 value) | 474 | int reg, u32 old, u32 new, u32 mask) |
637 | { | 475 | { |
638 | struct mvebu_sw_pci_bridge *bridge = &port->bridge; | 476 | struct mvebu_pcie_port *port = bridge->data; |
639 | u32 mask, reg; | 477 | struct pci_bridge_emul_conf *conf = &bridge->conf; |
640 | int err; | ||
641 | |||
642 | if (size == 4) | ||
643 | mask = 0x0; | ||
644 | else if (size == 2) | ||
645 | mask = ~(0xffff << ((where & 3) * 8)); | ||
646 | else if (size == 1) | ||
647 | mask = ~(0xff << ((where & 3) * 8)); | ||
648 | else | ||
649 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
650 | 478 | ||
651 | err = mvebu_sw_pci_bridge_read(port, where & ~3, 4, ®); | 479 | switch (reg) { |
652 | if (err) | ||
653 | return err; | ||
654 | |||
655 | value = (reg & mask) | value << ((where & 3) * 8); | ||
656 | |||
657 | switch (where & ~3) { | ||
658 | case PCI_COMMAND: | 480 | case PCI_COMMAND: |
659 | { | 481 | { |
660 | u32 old = bridge->command; | ||
661 | |||
662 | if (!mvebu_has_ioport(port)) | 482 | if (!mvebu_has_ioport(port)) |
663 | value &= ~PCI_COMMAND_IO; | 483 | conf->command &= ~PCI_COMMAND_IO; |
664 | 484 | ||
665 | bridge->command = value & 0xffff; | 485 | if ((old ^ new) & PCI_COMMAND_IO) |
666 | if ((old ^ bridge->command) & PCI_COMMAND_IO) | ||
667 | mvebu_pcie_handle_iobase_change(port); | 486 | mvebu_pcie_handle_iobase_change(port); |
668 | if ((old ^ bridge->command) & PCI_COMMAND_MEMORY) | 487 | if ((old ^ new) & PCI_COMMAND_MEMORY) |
669 | mvebu_pcie_handle_membase_change(port); | 488 | mvebu_pcie_handle_membase_change(port); |
670 | break; | ||
671 | } | ||
672 | 489 | ||
673 | case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_1: | ||
674 | bridge->bar[((where & ~3) - PCI_BASE_ADDRESS_0) / 4] = value; | ||
675 | break; | 490 | break; |
491 | } | ||
676 | 492 | ||
677 | case PCI_IO_BASE: | 493 | case PCI_IO_BASE: |
678 | /* | 494 | /* |
679 | * We also keep bit 1 set, it is a read-only bit that | 495 | * We keep bit 1 set, it is a read-only bit that |
680 | * indicates we support 32 bits addressing for the | 496 | * indicates we support 32 bits addressing for the |
681 | * I/O | 497 | * I/O |
682 | */ | 498 | */ |
683 | bridge->iobase = (value & 0xff) | PCI_IO_RANGE_TYPE_32; | 499 | conf->iobase |= PCI_IO_RANGE_TYPE_32; |
684 | bridge->iolimit = ((value >> 8) & 0xff) | PCI_IO_RANGE_TYPE_32; | 500 | conf->iolimit |= PCI_IO_RANGE_TYPE_32; |
685 | mvebu_pcie_handle_iobase_change(port); | 501 | mvebu_pcie_handle_iobase_change(port); |
686 | break; | 502 | break; |
687 | 503 | ||
688 | case PCI_MEMORY_BASE: | 504 | case PCI_MEMORY_BASE: |
689 | bridge->membase = value & 0xffff; | ||
690 | bridge->memlimit = value >> 16; | ||
691 | mvebu_pcie_handle_membase_change(port); | 505 | mvebu_pcie_handle_membase_change(port); |
692 | break; | 506 | break; |
693 | 507 | ||
694 | case PCI_IO_BASE_UPPER16: | 508 | case PCI_IO_BASE_UPPER16: |
695 | bridge->iobaseupper = value & 0xffff; | ||
696 | bridge->iolimitupper = value >> 16; | ||
697 | mvebu_pcie_handle_iobase_change(port); | 509 | mvebu_pcie_handle_iobase_change(port); |
698 | break; | 510 | break; |
699 | 511 | ||
700 | case PCI_PRIMARY_BUS: | 512 | case PCI_PRIMARY_BUS: |
701 | bridge->primary_bus = value & 0xff; | 513 | mvebu_pcie_set_local_bus_nr(port, conf->secondary_bus); |
702 | bridge->secondary_bus = (value >> 8) & 0xff; | ||
703 | bridge->subordinate_bus = (value >> 16) & 0xff; | ||
704 | bridge->secondary_latency_timer = (value >> 24) & 0xff; | ||
705 | mvebu_pcie_set_local_bus_nr(port, bridge->secondary_bus); | ||
706 | break; | 514 | break; |
707 | 515 | ||
708 | case PCISWCAP_EXP_DEVCTL: | 516 | default: |
517 | break; | ||
518 | } | ||
519 | } | ||
520 | |||
521 | static void | ||
522 | mvebu_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge, | ||
523 | int reg, u32 old, u32 new, u32 mask) | ||
524 | { | ||
525 | struct mvebu_pcie_port *port = bridge->data; | ||
526 | |||
527 | switch (reg) { | ||
528 | case PCI_EXP_DEVCTL: | ||
709 | /* | 529 | /* |
710 | * Armada370 data says these bits must always | 530 | * Armada370 data says these bits must always |
711 | * be zero when in root complex mode. | 531 | * be zero when in root complex mode. |
712 | */ | 532 | */ |
713 | value &= ~(PCI_EXP_DEVCTL_URRE | PCI_EXP_DEVCTL_FERE | | 533 | new &= ~(PCI_EXP_DEVCTL_URRE | PCI_EXP_DEVCTL_FERE | |
714 | PCI_EXP_DEVCTL_NFERE | PCI_EXP_DEVCTL_CERE); | 534 | PCI_EXP_DEVCTL_NFERE | PCI_EXP_DEVCTL_CERE); |
715 | |||
716 | /* | ||
717 | * If the mask is 0xffff0000, then we only want to write | ||
718 | * the device control register, rather than clearing the | ||
719 | * RW1C bits in the device status register. Mask out the | ||
720 | * status register bits. | ||
721 | */ | ||
722 | if (mask == 0xffff0000) | ||
723 | value &= 0xffff; | ||
724 | 535 | ||
725 | mvebu_writel(port, value, PCIE_CAP_PCIEXP + PCI_EXP_DEVCTL); | 536 | mvebu_writel(port, new, PCIE_CAP_PCIEXP + PCI_EXP_DEVCTL); |
726 | break; | 537 | break; |
727 | 538 | ||
728 | case PCISWCAP_EXP_LNKCTL: | 539 | case PCI_EXP_LNKCTL: |
729 | /* | 540 | /* |
730 | * If we don't support CLKREQ, we must ensure that the | 541 | * If we don't support CLKREQ, we must ensure that the |
731 | * CLKREQ enable bit always reads zero. Since we haven't | 542 | * CLKREQ enable bit always reads zero. Since we haven't |
732 | * had this capability, and it's dependent on board wiring, | 543 | * had this capability, and it's dependent on board wiring, |
733 | * disable it for the time being. | 544 | * disable it for the time being. |
734 | */ | 545 | */ |
735 | value &= ~PCI_EXP_LNKCTL_CLKREQ_EN; | 546 | new &= ~PCI_EXP_LNKCTL_CLKREQ_EN; |
736 | |||
737 | /* | ||
738 | * If the mask is 0xffff0000, then we only want to write | ||
739 | * the link control register, rather than clearing the | ||
740 | * RW1C bits in the link status register. Mask out the | ||
741 | * RW1C status register bits. | ||
742 | */ | ||
743 | if (mask == 0xffff0000) | ||
744 | value &= ~((PCI_EXP_LNKSTA_LABS | | ||
745 | PCI_EXP_LNKSTA_LBMS) << 16); | ||
746 | 547 | ||
747 | mvebu_writel(port, value, PCIE_CAP_PCIEXP + PCI_EXP_LNKCTL); | 548 | mvebu_writel(port, new, PCIE_CAP_PCIEXP + PCI_EXP_LNKCTL); |
748 | break; | 549 | break; |
749 | 550 | ||
750 | case PCISWCAP_EXP_RTSTA: | 551 | case PCI_EXP_RTSTA: |
751 | mvebu_writel(port, value, PCIE_RC_RTSTA); | 552 | mvebu_writel(port, new, PCIE_RC_RTSTA); |
752 | break; | 553 | break; |
554 | } | ||
555 | } | ||
753 | 556 | ||
754 | default: | 557 | struct pci_bridge_emul_ops mvebu_pci_bridge_emul_ops = { |
755 | break; | 558 | .write_base = mvebu_pci_bridge_emul_base_conf_write, |
559 | .read_pcie = mvebu_pci_bridge_emul_pcie_conf_read, | ||
560 | .write_pcie = mvebu_pci_bridge_emul_pcie_conf_write, | ||
561 | }; | ||
562 | |||
563 | /* | ||
564 | * Initialize the configuration space of the PCI-to-PCI bridge | ||
565 | * associated with the given PCIe interface. | ||
566 | */ | ||
567 | static void mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port) | ||
568 | { | ||
569 | struct pci_bridge_emul *bridge = &port->bridge; | ||
570 | |||
571 | bridge->conf.vendor = PCI_VENDOR_ID_MARVELL; | ||
572 | bridge->conf.device = mvebu_readl(port, PCIE_DEV_ID_OFF) >> 16; | ||
573 | bridge->conf.class_revision = | ||
574 | mvebu_readl(port, PCIE_DEV_REV_OFF) & 0xff; | ||
575 | |||
576 | if (mvebu_has_ioport(port)) { | ||
577 | /* We support 32 bits I/O addressing */ | ||
578 | bridge->conf.iobase = PCI_IO_RANGE_TYPE_32; | ||
579 | bridge->conf.iolimit = PCI_IO_RANGE_TYPE_32; | ||
756 | } | 580 | } |
757 | 581 | ||
758 | return PCIBIOS_SUCCESSFUL; | 582 | bridge->has_pcie = true; |
583 | bridge->data = port; | ||
584 | bridge->ops = &mvebu_pci_bridge_emul_ops; | ||
585 | |||
586 | pci_bridge_emul_init(bridge); | ||
759 | } | 587 | } |
760 | 588 | ||
761 | static inline struct mvebu_pcie *sys_to_pcie(struct pci_sys_data *sys) | 589 | static inline struct mvebu_pcie *sys_to_pcie(struct pci_sys_data *sys) |
@@ -775,8 +603,8 @@ static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie, | |||
775 | if (bus->number == 0 && port->devfn == devfn) | 603 | if (bus->number == 0 && port->devfn == devfn) |
776 | return port; | 604 | return port; |
777 | if (bus->number != 0 && | 605 | if (bus->number != 0 && |
778 | bus->number >= port->bridge.secondary_bus && | 606 | bus->number >= port->bridge.conf.secondary_bus && |
779 | bus->number <= port->bridge.subordinate_bus) | 607 | bus->number <= port->bridge.conf.subordinate_bus) |
780 | return port; | 608 | return port; |
781 | } | 609 | } |
782 | 610 | ||
@@ -797,7 +625,8 @@ static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn, | |||
797 | 625 | ||
798 | /* Access the emulated PCI-to-PCI bridge */ | 626 | /* Access the emulated PCI-to-PCI bridge */ |
799 | if (bus->number == 0) | 627 | if (bus->number == 0) |
800 | return mvebu_sw_pci_bridge_write(port, where, size, val); | 628 | return pci_bridge_emul_conf_write(&port->bridge, where, |
629 | size, val); | ||
801 | 630 | ||
802 | if (!mvebu_pcie_link_up(port)) | 631 | if (!mvebu_pcie_link_up(port)) |
803 | return PCIBIOS_DEVICE_NOT_FOUND; | 632 | return PCIBIOS_DEVICE_NOT_FOUND; |
@@ -825,7 +654,8 @@ static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, | |||
825 | 654 | ||
826 | /* Access the emulated PCI-to-PCI bridge */ | 655 | /* Access the emulated PCI-to-PCI bridge */ |
827 | if (bus->number == 0) | 656 | if (bus->number == 0) |
828 | return mvebu_sw_pci_bridge_read(port, where, size, val); | 657 | return pci_bridge_emul_conf_read(&port->bridge, where, |
658 | size, val); | ||
829 | 659 | ||
830 | if (!mvebu_pcie_link_up(port)) { | 660 | if (!mvebu_pcie_link_up(port)) { |
831 | *val = 0xffffffff; | 661 | *val = 0xffffffff; |
@@ -1239,7 +1069,7 @@ static int mvebu_pcie_probe(struct platform_device *pdev) | |||
1239 | 1069 | ||
1240 | mvebu_pcie_setup_hw(port); | 1070 | mvebu_pcie_setup_hw(port); |
1241 | mvebu_pcie_set_local_dev_nr(port, 1); | 1071 | mvebu_pcie_set_local_dev_nr(port, 1); |
1242 | mvebu_sw_pci_bridge_init(port); | 1072 | mvebu_pci_bridge_emul_init(port); |
1243 | } | 1073 | } |
1244 | 1074 | ||
1245 | pcie->nports = i; | 1075 | pcie->nports = i; |