Skip to content

Commit ac7f53b

Browse files
ConchuODbjorn-helgaas
authored andcommitted
PCI: microchip: Add support for using either Root Port 1 or 2
The PCI host controller on PolarFire SoC has multiple Root Port instances, each with their own bridge and ctrl address spaces. The original binding has an "apb" register region, and it is expected to be set to the base address of the Root Complex register space. Some defines in the Linux driver were used to compute the addresses of the bridge and ctrl address ranges corresponding to Root Port instance 1. Some customers want to use Root Port instance 2 however, which requires changing the defines in the driver, which is clearly not a portable solution. The binding has been changed from a single register region to a pair, corresponding to the bridge and ctrl regions respectively, so modify the driver to read these regions directly from the devicetree rather than compute them from the base address of the abp region. To maintain backwards compatibility with the existing binding, the driver retains code to handle the "abp" reg and computes the base address of the bridge and ctrl regions using the defines if it is present. reg-names has always been a required property, so this is safe to do. Link: https://lore.kernel.org/r/20241107-surrender-brisket-287d563a5de1@spud Signed-off-by: Conor Dooley <conor.dooley@microchip.com> [bhelgaas: Capitalize PCIe spec terms] Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
1 parent e329b76 commit ac7f53b

File tree

1 file changed

+67
-59
lines changed

1 file changed

+67
-59
lines changed

drivers/pci/controller/plda/pcie-microchip-host.c

Lines changed: 67 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@
2525
#define MC_PCIE1_BRIDGE_ADDR 0x00008000u
2626
#define MC_PCIE1_CTRL_ADDR 0x0000a000u
2727

28-
#define MC_PCIE_BRIDGE_ADDR (MC_PCIE1_BRIDGE_ADDR)
29-
#define MC_PCIE_CTRL_ADDR (MC_PCIE1_CTRL_ADDR)
30-
3128
/* PCIe Controller Phy Regs */
3229
#define SEC_ERROR_EVENT_CNT 0x20
3330
#define DED_ERROR_EVENT_CNT 0x24
@@ -128,31 +125,27 @@
128125
[EVENT_LOCAL_ ## x] = { __stringify(x), s }
129126

130127
#define PCIE_EVENT(x) \
131-
.base = MC_PCIE_CTRL_ADDR, \
132128
.offset = PCIE_EVENT_INT, \
133129
.mask_offset = PCIE_EVENT_INT, \
134130
.mask_high = 1, \
135131
.mask = PCIE_EVENT_INT_ ## x ## _INT, \
136132
.enb_mask = PCIE_EVENT_INT_ENB_MASK
137133

138134
#define SEC_EVENT(x) \
139-
.base = MC_PCIE_CTRL_ADDR, \
140135
.offset = SEC_ERROR_INT, \
141136
.mask_offset = SEC_ERROR_INT_MASK, \
142137
.mask = SEC_ERROR_INT_ ## x ## _INT, \
143138
.mask_high = 1, \
144139
.enb_mask = 0
145140

146141
#define DED_EVENT(x) \
147-
.base = MC_PCIE_CTRL_ADDR, \
148142
.offset = DED_ERROR_INT, \
149143
.mask_offset = DED_ERROR_INT_MASK, \
150144
.mask_high = 1, \
151145
.mask = DED_ERROR_INT_ ## x ## _INT, \
152146
.enb_mask = 0
153147

154148
#define LOCAL_EVENT(x) \
155-
.base = MC_PCIE_BRIDGE_ADDR, \
156149
.offset = ISTATUS_LOCAL, \
157150
.mask_offset = IMASK_LOCAL, \
158151
.mask_high = 0, \
@@ -179,7 +172,8 @@ struct event_map {
179172

180173
struct mc_pcie {
181174
struct plda_pcie_rp plda;
182-
void __iomem *axi_base_addr;
175+
void __iomem *bridge_base_addr;
176+
void __iomem *ctrl_base_addr;
183177
};
184178

185179
struct cause {
@@ -253,7 +247,6 @@ static struct event_map local_status_to_event[] = {
253247
};
254248

255249
static struct {
256-
u32 base;
257250
u32 offset;
258251
u32 mask;
259252
u32 shift;
@@ -325,8 +318,7 @@ static inline u32 reg_to_event(u32 reg, struct event_map field)
325318

326319
static u32 pcie_events(struct mc_pcie *port)
327320
{
328-
void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
329-
u32 reg = readl_relaxed(ctrl_base_addr + PCIE_EVENT_INT);
321+
u32 reg = readl_relaxed(port->ctrl_base_addr + PCIE_EVENT_INT);
330322
u32 val = 0;
331323
int i;
332324

@@ -338,8 +330,7 @@ static u32 pcie_events(struct mc_pcie *port)
338330

339331
static u32 sec_errors(struct mc_pcie *port)
340332
{
341-
void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
342-
u32 reg = readl_relaxed(ctrl_base_addr + SEC_ERROR_INT);
333+
u32 reg = readl_relaxed(port->ctrl_base_addr + SEC_ERROR_INT);
343334
u32 val = 0;
344335
int i;
345336

@@ -351,8 +342,7 @@ static u32 sec_errors(struct mc_pcie *port)
351342

352343
static u32 ded_errors(struct mc_pcie *port)
353344
{
354-
void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
355-
u32 reg = readl_relaxed(ctrl_base_addr + DED_ERROR_INT);
345+
u32 reg = readl_relaxed(port->ctrl_base_addr + DED_ERROR_INT);
356346
u32 val = 0;
357347
int i;
358348

@@ -364,8 +354,7 @@ static u32 ded_errors(struct mc_pcie *port)
364354

365355
static u32 local_events(struct mc_pcie *port)
366356
{
367-
void __iomem *bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
368-
u32 reg = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
357+
u32 reg = readl_relaxed(port->bridge_base_addr + ISTATUS_LOCAL);
369358
u32 val = 0;
370359
int i;
371360

@@ -412,8 +401,12 @@ static void mc_ack_event_irq(struct irq_data *data)
412401
void __iomem *addr;
413402
u32 mask;
414403

415-
addr = mc_port->axi_base_addr + event_descs[event].base +
416-
event_descs[event].offset;
404+
if (event_descs[event].offset == ISTATUS_LOCAL)
405+
addr = mc_port->bridge_base_addr;
406+
else
407+
addr = mc_port->ctrl_base_addr;
408+
409+
addr += event_descs[event].offset;
417410
mask = event_descs[event].mask;
418411
mask |= event_descs[event].enb_mask;
419412

@@ -429,8 +422,12 @@ static void mc_mask_event_irq(struct irq_data *data)
429422
u32 mask;
430423
u32 val;
431424

432-
addr = mc_port->axi_base_addr + event_descs[event].base +
433-
event_descs[event].mask_offset;
425+
if (event_descs[event].offset == ISTATUS_LOCAL)
426+
addr = mc_port->bridge_base_addr;
427+
else
428+
addr = mc_port->ctrl_base_addr;
429+
430+
addr += event_descs[event].mask_offset;
434431
mask = event_descs[event].mask;
435432
if (event_descs[event].enb_mask) {
436433
mask <<= PCIE_EVENT_INT_ENB_SHIFT;
@@ -460,8 +457,12 @@ static void mc_unmask_event_irq(struct irq_data *data)
460457
u32 mask;
461458
u32 val;
462459

463-
addr = mc_port->axi_base_addr + event_descs[event].base +
464-
event_descs[event].mask_offset;
460+
if (event_descs[event].offset == ISTATUS_LOCAL)
461+
addr = mc_port->bridge_base_addr;
462+
else
463+
addr = mc_port->ctrl_base_addr;
464+
465+
addr += event_descs[event].mask_offset;
465466
mask = event_descs[event].mask;
466467

467468
if (event_descs[event].enb_mask)
@@ -554,49 +555,43 @@ static const struct plda_event mc_event = {
554555

555556
static inline void mc_clear_secs(struct mc_pcie *port)
556557
{
557-
void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
558-
559-
writel_relaxed(SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT, ctrl_base_addr +
560-
SEC_ERROR_INT);
561-
writel_relaxed(0, ctrl_base_addr + SEC_ERROR_EVENT_CNT);
558+
writel_relaxed(SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT,
559+
port->ctrl_base_addr + SEC_ERROR_INT);
560+
writel_relaxed(0, port->ctrl_base_addr + SEC_ERROR_EVENT_CNT);
562561
}
563562

564563
static inline void mc_clear_deds(struct mc_pcie *port)
565564
{
566-
void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
567-
568-
writel_relaxed(DED_ERROR_INT_ALL_RAM_DED_ERR_INT, ctrl_base_addr +
569-
DED_ERROR_INT);
570-
writel_relaxed(0, ctrl_base_addr + DED_ERROR_EVENT_CNT);
565+
writel_relaxed(DED_ERROR_INT_ALL_RAM_DED_ERR_INT,
566+
port->ctrl_base_addr + DED_ERROR_INT);
567+
writel_relaxed(0, port->ctrl_base_addr + DED_ERROR_EVENT_CNT);
571568
}
572569

573570
static void mc_disable_interrupts(struct mc_pcie *port)
574571
{
575-
void __iomem *bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
576-
void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
577572
u32 val;
578573

579574
/* Ensure ECC bypass is enabled */
580575
val = ECC_CONTROL_TX_RAM_ECC_BYPASS |
581576
ECC_CONTROL_RX_RAM_ECC_BYPASS |
582577
ECC_CONTROL_PCIE2AXI_RAM_ECC_BYPASS |
583578
ECC_CONTROL_AXI2PCIE_RAM_ECC_BYPASS;
584-
writel_relaxed(val, ctrl_base_addr + ECC_CONTROL);
579+
writel_relaxed(val, port->ctrl_base_addr + ECC_CONTROL);
585580

586581
/* Disable SEC errors and clear any outstanding */
587-
writel_relaxed(SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT, ctrl_base_addr +
588-
SEC_ERROR_INT_MASK);
582+
writel_relaxed(SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT,
583+
port->ctrl_base_addr + SEC_ERROR_INT_MASK);
589584
mc_clear_secs(port);
590585

591586
/* Disable DED errors and clear any outstanding */
592-
writel_relaxed(DED_ERROR_INT_ALL_RAM_DED_ERR_INT, ctrl_base_addr +
593-
DED_ERROR_INT_MASK);
587+
writel_relaxed(DED_ERROR_INT_ALL_RAM_DED_ERR_INT,
588+
port->ctrl_base_addr + DED_ERROR_INT_MASK);
594589
mc_clear_deds(port);
595590

596591
/* Disable local interrupts and clear any outstanding */
597-
writel_relaxed(0, bridge_base_addr + IMASK_LOCAL);
598-
writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_LOCAL);
599-
writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_MSI);
592+
writel_relaxed(0, port->bridge_base_addr + IMASK_LOCAL);
593+
writel_relaxed(GENMASK(31, 0), port->bridge_base_addr + ISTATUS_LOCAL);
594+
writel_relaxed(GENMASK(31, 0), port->bridge_base_addr + ISTATUS_MSI);
600595

601596
/* Disable PCIe events and clear any outstanding */
602597
val = PCIE_EVENT_INT_L2_EXIT_INT |
@@ -605,24 +600,22 @@ static void mc_disable_interrupts(struct mc_pcie *port)
605600
PCIE_EVENT_INT_L2_EXIT_INT_MASK |
606601
PCIE_EVENT_INT_HOTRST_EXIT_INT_MASK |
607602
PCIE_EVENT_INT_DLUP_EXIT_INT_MASK;
608-
writel_relaxed(val, ctrl_base_addr + PCIE_EVENT_INT);
603+
writel_relaxed(val, port->ctrl_base_addr + PCIE_EVENT_INT);
609604

610605
/* Disable host interrupts and clear any outstanding */
611-
writel_relaxed(0, bridge_base_addr + IMASK_HOST);
612-
writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_HOST);
606+
writel_relaxed(0, port->bridge_base_addr + IMASK_HOST);
607+
writel_relaxed(GENMASK(31, 0), port->bridge_base_addr + ISTATUS_HOST);
613608
}
614609

615610
static int mc_platform_init(struct pci_config_window *cfg)
616611
{
617612
struct device *dev = cfg->parent;
618613
struct platform_device *pdev = to_platform_device(dev);
619614
struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
620-
void __iomem *bridge_base_addr =
621-
port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
622615
int ret;
623616

624617
/* Configure address translation table 0 for PCIe config space */
625-
plda_pcie_setup_window(bridge_base_addr, 0, cfg->res.start,
618+
plda_pcie_setup_window(port->bridge_base_addr, 0, cfg->res.start,
626619
cfg->res.start,
627620
resource_size(&cfg->res));
628621

@@ -649,7 +642,7 @@ static int mc_platform_init(struct pci_config_window *cfg)
649642
static int mc_host_probe(struct platform_device *pdev)
650643
{
651644
struct device *dev = &pdev->dev;
652-
void __iomem *bridge_base_addr;
645+
void __iomem *apb_base_addr;
653646
struct plda_pcie_rp *plda;
654647
int ret;
655648
u32 val;
@@ -661,30 +654,45 @@ static int mc_host_probe(struct platform_device *pdev)
661654
plda = &port->plda;
662655
plda->dev = dev;
663656

664-
port->axi_base_addr = devm_platform_ioremap_resource(pdev, 1);
665-
if (IS_ERR(port->axi_base_addr))
666-
return PTR_ERR(port->axi_base_addr);
657+
port->bridge_base_addr = devm_platform_ioremap_resource_byname(pdev,
658+
"bridge");
659+
port->ctrl_base_addr = devm_platform_ioremap_resource_byname(pdev,
660+
"ctrl");
661+
if (!IS_ERR(port->bridge_base_addr) && !IS_ERR(port->ctrl_base_addr))
662+
goto addrs_set;
663+
664+
/*
665+
* The original, incorrect, binding that lumped the control and
666+
* bridge addresses together still needs to be handled by the driver.
667+
*/
668+
apb_base_addr = devm_platform_ioremap_resource_byname(pdev, "apb");
669+
if (IS_ERR(apb_base_addr))
670+
return dev_err_probe(dev, PTR_ERR(apb_base_addr),
671+
"both legacy apb register and ctrl/bridge regions missing");
672+
673+
port->bridge_base_addr = apb_base_addr + MC_PCIE1_BRIDGE_ADDR;
674+
port->ctrl_base_addr = apb_base_addr + MC_PCIE1_CTRL_ADDR;
667675

676+
addrs_set:
668677
mc_disable_interrupts(port);
669678

670-
bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
671-
plda->bridge_addr = bridge_base_addr;
679+
plda->bridge_addr = port->bridge_base_addr;
672680
plda->num_events = NUM_EVENTS;
673681

674682
/* Allow enabling MSI by disabling MSI-X */
675-
val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
683+
val = readl(port->bridge_base_addr + PCIE_PCI_IRQ_DW0);
676684
val &= ~MSIX_CAP_MASK;
677-
writel(val, bridge_base_addr + PCIE_PCI_IRQ_DW0);
685+
writel(val, port->bridge_base_addr + PCIE_PCI_IRQ_DW0);
678686

679687
/* Pick num vectors from bitfile programmed onto FPGA fabric */
680-
val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
688+
val = readl(port->bridge_base_addr + PCIE_PCI_IRQ_DW0);
681689
val &= NUM_MSI_MSGS_MASK;
682690
val >>= NUM_MSI_MSGS_SHIFT;
683691

684692
plda->msi.num_vectors = 1 << val;
685693

686694
/* Pick vector address from design */
687-
plda->msi.vector_phy = readl_relaxed(bridge_base_addr + IMSI_ADDR);
695+
plda->msi.vector_phy = readl_relaxed(port->bridge_base_addr + IMSI_ADDR);
688696

689697
ret = mc_pcie_init_clks(dev);
690698
if (ret) {

0 commit comments

Comments
 (0)