Skip to content

Commit dc0352a

Browse files
Russell Kingbjorn-helgaas
authored andcommitted
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 <[email protected]> (Iomega iConnect Kirkwood, MiraBox Armada 370) Tested-by: Andrew Lunn <[email protected]> (D-Link DIR664 Kirkwood) Tested-by: Thomas Petazzoni <[email protected]> (Armada XP GP) Signed-off-by: Russell King <[email protected]> Signed-off-by: Bjorn Helgaas <[email protected]> Reviewed-by: Thomas Petazzoni <[email protected]>
1 parent d609a8d commit dc0352a

File tree

1 file changed

+133
-4
lines changed

1 file changed

+133
-4
lines changed

drivers/pci/host/pci-mvebu.c

Lines changed: 133 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#define PCIE_DEV_REV_OFF 0x0008
3131
#define PCIE_BAR_LO_OFF(n) (0x0010 + ((n) << 3))
3232
#define PCIE_BAR_HI_OFF(n) (0x0014 + ((n) << 3))
33+
#define PCIE_CAP_PCIEXP 0x0060
3334
#define PCIE_HEADER_LOG_4_OFF 0x0128
3435
#define PCIE_BAR_CTRL_OFF(n) (0x1804 + (((n) - 1) * 4))
3536
#define PCIE_WIN04_CTRL_OFF(n) (0x1820 + ((n) << 4))
@@ -57,14 +58,35 @@
5758
#define PCIE_STAT_BUS 0xff00
5859
#define PCIE_STAT_DEV 0x1f0000
5960
#define PCIE_STAT_LINK_DOWN BIT(0)
61+
#define PCIE_RC_RTSTA 0x1a14
6062
#define PCIE_DEBUG_CTRL 0x1a60
6163
#define PCIE_DEBUG_SOFT_RESET BIT(20)
6264

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+
6384
/* PCI configuration space of a PCI-to-PCI bridge */
6485
struct mvebu_sw_pci_bridge {
6586
u16 vendor;
6687
u16 device;
6788
u16 command;
89+
u16 status;
6890
u16 class;
6991
u8 interface;
7092
u8 revision;
@@ -84,13 +106,15 @@ struct mvebu_sw_pci_bridge {
84106
u16 memlimit;
85107
u16 iobaseupper;
86108
u16 iolimitupper;
87-
u8 cappointer;
88-
u8 reserved1;
89-
u16 reserved2;
90109
u32 romaddr;
91110
u8 intline;
92111
u8 intpin;
93112
u16 bridgectrl;
113+
114+
/* PCI express capability */
115+
u32 pcie_sltcap;
116+
u16 pcie_devctl;
117+
u16 pcie_rtctl;
94118
};
95119

96120
struct mvebu_pcie_port;
@@ -451,6 +475,9 @@ static void mvebu_sw_pci_bridge_init(struct mvebu_pcie_port *port)
451475
/* We support 32 bits I/O addressing */
452476
bridge->iobase = PCI_IO_RANGE_TYPE_32;
453477
bridge->iolimit = PCI_IO_RANGE_TYPE_32;
478+
479+
/* Add capabilities */
480+
bridge->status = PCI_STATUS_CAP_LIST;
454481
}
455482

456483
/*
@@ -468,7 +495,7 @@ static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port,
468495
break;
469496

470497
case PCI_COMMAND:
471-
*value = bridge->command;
498+
*value = bridge->command | bridge->status << 16;
472499
break;
473500

474501
case PCI_CLASS_REVISION:
@@ -513,6 +540,10 @@ static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port,
513540
*value = (bridge->iolimitupper << 16 | bridge->iobaseupper);
514541
break;
515542

543+
case PCI_CAPABILITY_LIST:
544+
*value = PCISWCAP;
545+
break;
546+
516547
case PCI_ROM_ADDRESS1:
517548
*value = 0;
518549
break;
@@ -522,6 +553,59 @@ static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port,
522553
*value = 0;
523554
break;
524555

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:
525609
default:
526610
/*
527611
* PCI defines configuration read accesses to reserved or
@@ -614,6 +698,51 @@ static int mvebu_sw_pci_bridge_write(struct mvebu_pcie_port *port,
614698
mvebu_pcie_set_local_bus_nr(port, bridge->secondary_bus);
615699
break;
616700

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+
617746
default:
618747
break;
619748
}

0 commit comments

Comments
 (0)