diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2015-10-03 14:13:33 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2015-10-09 12:22:18 -0400 |
commit | dc0352ab0b2a0c0c4fd11be89b83f4c693a8f662 (patch) | |
tree | 931200534df0e0151e230b8e79d1cdb4e054a605 | |
parent | d609a8d8e88a4292a0b4c42d1c942f8d088a6ebf (diff) |
PCI: mvebu: Add PCI Express root complex capability block
Add a PCI Express root complex capability block so the PCI layer identifies
the bridge as a PCI Express device.
We expose this as a version 1 PCIe capability block, with slot support. We
disable the clock power management capability as this depends on boards
wiring the CLKREQ# signal.
Tested-by: Willy Tarreau <w@1wt.eu> (Iomega iConnect Kirkwood, MiraBox Armada 370)
Tested-by: Andrew Lunn <andrew@lunn.ch> (D-Link DIR664 Kirkwood)
Tested-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> (Armada XP GP)
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
-rw-r--r-- | drivers/pci/host/pci-mvebu.c | 137 |
1 files changed, 133 insertions, 4 deletions
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 97208233d901..6310f2a84cfd 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #define PCIE_DEV_REV_OFF 0x0008 | 30 | #define PCIE_DEV_REV_OFF 0x0008 |
31 | #define PCIE_BAR_LO_OFF(n) (0x0010 + ((n) << 3)) | 31 | #define PCIE_BAR_LO_OFF(n) (0x0010 + ((n) << 3)) |
32 | #define PCIE_BAR_HI_OFF(n) (0x0014 + ((n) << 3)) | 32 | #define PCIE_BAR_HI_OFF(n) (0x0014 + ((n) << 3)) |
33 | #define PCIE_CAP_PCIEXP 0x0060 | ||
33 | #define PCIE_HEADER_LOG_4_OFF 0x0128 | 34 | #define PCIE_HEADER_LOG_4_OFF 0x0128 |
34 | #define PCIE_BAR_CTRL_OFF(n) (0x1804 + (((n) - 1) * 4)) | 35 | #define PCIE_BAR_CTRL_OFF(n) (0x1804 + (((n) - 1) * 4)) |
35 | #define PCIE_WIN04_CTRL_OFF(n) (0x1820 + ((n) << 4)) | 36 | #define PCIE_WIN04_CTRL_OFF(n) (0x1820 + ((n) << 4)) |
@@ -57,14 +58,35 @@ | |||
57 | #define PCIE_STAT_BUS 0xff00 | 58 | #define PCIE_STAT_BUS 0xff00 |
58 | #define PCIE_STAT_DEV 0x1f0000 | 59 | #define PCIE_STAT_DEV 0x1f0000 |
59 | #define PCIE_STAT_LINK_DOWN BIT(0) | 60 | #define PCIE_STAT_LINK_DOWN BIT(0) |
61 | #define PCIE_RC_RTSTA 0x1a14 | ||
60 | #define PCIE_DEBUG_CTRL 0x1a60 | 62 | #define PCIE_DEBUG_CTRL 0x1a60 |
61 | #define PCIE_DEBUG_SOFT_RESET BIT(20) | 63 | #define PCIE_DEBUG_SOFT_RESET BIT(20) |
62 | 64 | ||
65 | enum { | ||
66 | PCISWCAP = PCI_BRIDGE_CONTROL + 2, | ||
67 | PCISWCAP_EXP_LIST_ID = PCISWCAP + PCI_CAP_LIST_ID, | ||
68 | PCISWCAP_EXP_DEVCAP = PCISWCAP + PCI_EXP_DEVCAP, | ||
69 | PCISWCAP_EXP_DEVCTL = PCISWCAP + PCI_EXP_DEVCTL, | ||
70 | PCISWCAP_EXP_LNKCAP = PCISWCAP + PCI_EXP_LNKCAP, | ||
71 | PCISWCAP_EXP_LNKCTL = PCISWCAP + PCI_EXP_LNKCTL, | ||
72 | PCISWCAP_EXP_SLTCAP = PCISWCAP + PCI_EXP_SLTCAP, | ||
73 | PCISWCAP_EXP_SLTCTL = PCISWCAP + PCI_EXP_SLTCTL, | ||
74 | PCISWCAP_EXP_RTCTL = PCISWCAP + PCI_EXP_RTCTL, | ||
75 | PCISWCAP_EXP_RTSTA = PCISWCAP + PCI_EXP_RTSTA, | ||
76 | PCISWCAP_EXP_DEVCAP2 = PCISWCAP + PCI_EXP_DEVCAP2, | ||
77 | PCISWCAP_EXP_DEVCTL2 = PCISWCAP + PCI_EXP_DEVCTL2, | ||
78 | PCISWCAP_EXP_LNKCAP2 = PCISWCAP + PCI_EXP_LNKCAP2, | ||
79 | PCISWCAP_EXP_LNKCTL2 = PCISWCAP + PCI_EXP_LNKCTL2, | ||
80 | PCISWCAP_EXP_SLTCAP2 = PCISWCAP + PCI_EXP_SLTCAP2, | ||
81 | PCISWCAP_EXP_SLTCTL2 = PCISWCAP + PCI_EXP_SLTCTL2, | ||
82 | }; | ||
83 | |||
63 | /* PCI configuration space of a PCI-to-PCI bridge */ | 84 | /* PCI configuration space of a PCI-to-PCI bridge */ |
64 | struct mvebu_sw_pci_bridge { | 85 | struct mvebu_sw_pci_bridge { |
65 | u16 vendor; | 86 | u16 vendor; |
66 | u16 device; | 87 | u16 device; |
67 | u16 command; | 88 | u16 command; |
89 | u16 status; | ||
68 | u16 class; | 90 | u16 class; |
69 | u8 interface; | 91 | u8 interface; |
70 | u8 revision; | 92 | u8 revision; |
@@ -84,13 +106,15 @@ struct mvebu_sw_pci_bridge { | |||
84 | u16 memlimit; | 106 | u16 memlimit; |
85 | u16 iobaseupper; | 107 | u16 iobaseupper; |
86 | u16 iolimitupper; | 108 | u16 iolimitupper; |
87 | u8 cappointer; | ||
88 | u8 reserved1; | ||
89 | u16 reserved2; | ||
90 | u32 romaddr; | 109 | u32 romaddr; |
91 | u8 intline; | 110 | u8 intline; |
92 | u8 intpin; | 111 | u8 intpin; |
93 | u16 bridgectrl; | 112 | u16 bridgectrl; |
113 | |||
114 | /* PCI express capability */ | ||
115 | u32 pcie_sltcap; | ||
116 | u16 pcie_devctl; | ||
117 | u16 pcie_rtctl; | ||
94 | }; | 118 | }; |
95 | 119 | ||
96 | struct mvebu_pcie_port; | 120 | struct mvebu_pcie_port; |
@@ -451,6 +475,9 @@ static void mvebu_sw_pci_bridge_init(struct mvebu_pcie_port *port) | |||
451 | /* We support 32 bits I/O addressing */ | 475 | /* We support 32 bits I/O addressing */ |
452 | bridge->iobase = PCI_IO_RANGE_TYPE_32; | 476 | bridge->iobase = PCI_IO_RANGE_TYPE_32; |
453 | bridge->iolimit = PCI_IO_RANGE_TYPE_32; | 477 | bridge->iolimit = PCI_IO_RANGE_TYPE_32; |
478 | |||
479 | /* Add capabilities */ | ||
480 | bridge->status = PCI_STATUS_CAP_LIST; | ||
454 | } | 481 | } |
455 | 482 | ||
456 | /* | 483 | /* |
@@ -468,7 +495,7 @@ static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port, | |||
468 | break; | 495 | break; |
469 | 496 | ||
470 | case PCI_COMMAND: | 497 | case PCI_COMMAND: |
471 | *value = bridge->command; | 498 | *value = bridge->command | bridge->status << 16; |
472 | break; | 499 | break; |
473 | 500 | ||
474 | case PCI_CLASS_REVISION: | 501 | case PCI_CLASS_REVISION: |
@@ -513,6 +540,10 @@ static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port, | |||
513 | *value = (bridge->iolimitupper << 16 | bridge->iobaseupper); | 540 | *value = (bridge->iolimitupper << 16 | bridge->iobaseupper); |
514 | break; | 541 | break; |
515 | 542 | ||
543 | case PCI_CAPABILITY_LIST: | ||
544 | *value = PCISWCAP; | ||
545 | break; | ||
546 | |||
516 | case PCI_ROM_ADDRESS1: | 547 | case PCI_ROM_ADDRESS1: |
517 | *value = 0; | 548 | *value = 0; |
518 | break; | 549 | break; |
@@ -522,6 +553,59 @@ static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port, | |||
522 | *value = 0; | 553 | *value = 0; |
523 | break; | 554 | break; |
524 | 555 | ||
556 | case PCISWCAP_EXP_LIST_ID: | ||
557 | /* Set PCIe v2, root port, slot support */ | ||
558 | *value = (PCI_EXP_TYPE_ROOT_PORT << 4 | 2 | | ||
559 | PCI_EXP_FLAGS_SLOT) << 16 | PCI_CAP_ID_EXP; | ||
560 | break; | ||
561 | |||
562 | case PCISWCAP_EXP_DEVCAP: | ||
563 | *value = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_DEVCAP); | ||
564 | break; | ||
565 | |||
566 | case PCISWCAP_EXP_DEVCTL: | ||
567 | *value = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_DEVCTL) & | ||
568 | ~(PCI_EXP_DEVCTL_URRE | PCI_EXP_DEVCTL_FERE | | ||
569 | PCI_EXP_DEVCTL_NFERE | PCI_EXP_DEVCTL_CERE); | ||
570 | *value |= bridge->pcie_devctl; | ||
571 | break; | ||
572 | |||
573 | case PCISWCAP_EXP_LNKCAP: | ||
574 | /* | ||
575 | * PCIe requires the clock power management capability to be | ||
576 | * hard-wired to zero for downstream ports | ||
577 | */ | ||
578 | *value = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_LNKCAP) & | ||
579 | ~PCI_EXP_LNKCAP_CLKPM; | ||
580 | break; | ||
581 | |||
582 | case PCISWCAP_EXP_LNKCTL: | ||
583 | *value = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_LNKCTL); | ||
584 | break; | ||
585 | |||
586 | case PCISWCAP_EXP_SLTCAP: | ||
587 | *value = bridge->pcie_sltcap; | ||
588 | break; | ||
589 | |||
590 | case PCISWCAP_EXP_SLTCTL: | ||
591 | *value = PCI_EXP_SLTSTA_PDS << 16; | ||
592 | break; | ||
593 | |||
594 | case PCISWCAP_EXP_RTCTL: | ||
595 | *value = bridge->pcie_rtctl; | ||
596 | break; | ||
597 | |||
598 | case PCISWCAP_EXP_RTSTA: | ||
599 | *value = mvebu_readl(port, PCIE_RC_RTSTA); | ||
600 | break; | ||
601 | |||
602 | /* PCIe requires the v2 fields to be hard-wired to zero */ | ||
603 | case PCISWCAP_EXP_DEVCAP2: | ||
604 | case PCISWCAP_EXP_DEVCTL2: | ||
605 | case PCISWCAP_EXP_LNKCAP2: | ||
606 | case PCISWCAP_EXP_LNKCTL2: | ||
607 | case PCISWCAP_EXP_SLTCAP2: | ||
608 | case PCISWCAP_EXP_SLTCTL2: | ||
525 | default: | 609 | default: |
526 | /* | 610 | /* |
527 | * PCI defines configuration read accesses to reserved or | 611 | * PCI defines configuration read accesses to reserved or |
@@ -614,6 +698,51 @@ static int mvebu_sw_pci_bridge_write(struct mvebu_pcie_port *port, | |||
614 | mvebu_pcie_set_local_bus_nr(port, bridge->secondary_bus); | 698 | mvebu_pcie_set_local_bus_nr(port, bridge->secondary_bus); |
615 | break; | 699 | break; |
616 | 700 | ||
701 | case PCISWCAP_EXP_DEVCTL: | ||
702 | /* | ||
703 | * Armada370 data says these bits must always | ||
704 | * be zero when in root complex mode. | ||
705 | */ | ||
706 | value &= ~(PCI_EXP_DEVCTL_URRE | PCI_EXP_DEVCTL_FERE | | ||
707 | PCI_EXP_DEVCTL_NFERE | PCI_EXP_DEVCTL_CERE); | ||
708 | |||
709 | /* | ||
710 | * If the mask is 0xffff0000, then we only want to write | ||
711 | * the device control register, rather than clearing the | ||
712 | * RW1C bits in the device status register. Mask out the | ||
713 | * status register bits. | ||
714 | */ | ||
715 | if (mask == 0xffff0000) | ||
716 | value &= 0xffff; | ||
717 | |||
718 | mvebu_writel(port, value, PCIE_CAP_PCIEXP + PCI_EXP_DEVCTL); | ||
719 | break; | ||
720 | |||
721 | case PCISWCAP_EXP_LNKCTL: | ||
722 | /* | ||
723 | * If we don't support CLKREQ, we must ensure that the | ||
724 | * CLKREQ enable bit always reads zero. Since we haven't | ||
725 | * had this capability, and it's dependent on board wiring, | ||
726 | * disable it for the time being. | ||
727 | */ | ||
728 | value &= ~PCI_EXP_LNKCTL_CLKREQ_EN; | ||
729 | |||
730 | /* | ||
731 | * If the mask is 0xffff0000, then we only want to write | ||
732 | * the link control register, rather than clearing the | ||
733 | * RW1C bits in the link 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_LNKCTL); | ||
740 | break; | ||
741 | |||
742 | case PCISWCAP_EXP_RTSTA: | ||
743 | mvebu_writel(port, value, PCIE_RC_RTSTA); | ||
744 | break; | ||
745 | |||
617 | default: | 746 | default: |
618 | break; | 747 | break; |
619 | } | 748 | } |