aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/controller/dwc
diff options
context:
space:
mode:
authorJonathan Chocron <jonnyc@amazon.com>2019-09-12 09:02:38 -0400
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2019-09-16 09:17:15 -0400
commit0b24134f7888175c9638e6fd1900e23e44fc172f (patch)
tree085ed446d1c3e5c30d6c58d3df950a8701f4f159 /drivers/pci/controller/dwc
parenta8daea94754989f6c48dafda840482cbc9f882f9 (diff)
PCI: dwc: Add validation that PCIe core is set to correct mode
Some PCIe controllers can be set to either Host or EP according to some early boot FW. To make sure there is no discrepancy (e.g. FW configured the port to EP mode while the DT specifies it as a host bridge or vice versa), a check has been added for each mode. Signed-off-by: Jonathan Chocron <jonnyc@amazon.com> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Reviewed-by: Andrew Murray <andrew.murray@arm.com> Acked-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
Diffstat (limited to 'drivers/pci/controller/dwc')
-rw-r--r--drivers/pci/controller/dwc/pcie-designware-ep.c8
-rw-r--r--drivers/pci/controller/dwc/pcie-designware-host.c16
2 files changed, 24 insertions, 0 deletions
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 2bf5a35c0570..0b9a9b27175c 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -531,6 +531,7 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
531 int ret; 531 int ret;
532 u32 reg; 532 u32 reg;
533 void *addr; 533 void *addr;
534 u8 hdr_type;
534 unsigned int nbars; 535 unsigned int nbars;
535 unsigned int offset; 536 unsigned int offset;
536 struct pci_epc *epc; 537 struct pci_epc *epc;
@@ -595,6 +596,13 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
595 if (ep->ops->ep_init) 596 if (ep->ops->ep_init)
596 ep->ops->ep_init(ep); 597 ep->ops->ep_init(ep);
597 598
599 hdr_type = dw_pcie_readb_dbi(pci, PCI_HEADER_TYPE);
600 if (hdr_type != PCI_HEADER_TYPE_NORMAL) {
601 dev_err(pci->dev, "PCIe controller is not set to EP mode (hdr_type:0x%x)!\n",
602 hdr_type);
603 return -EIO;
604 }
605
598 ret = of_property_read_u8(np, "max-functions", &epc->max_functions); 606 ret = of_property_read_u8(np, "max-functions", &epc->max_functions);
599 if (ret < 0) 607 if (ret < 0)
600 epc->max_functions = 1; 608 epc->max_functions = 1;
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index f93252d0da5b..bb275b5e787a 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -323,6 +323,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
323 struct pci_bus *child; 323 struct pci_bus *child;
324 struct pci_host_bridge *bridge; 324 struct pci_host_bridge *bridge;
325 struct resource *cfg_res; 325 struct resource *cfg_res;
326 u32 hdr_type;
326 int ret; 327 int ret;
327 328
328 raw_spin_lock_init(&pci->pp.lock); 329 raw_spin_lock_init(&pci->pp.lock);
@@ -464,6 +465,21 @@ int dw_pcie_host_init(struct pcie_port *pp)
464 goto err_free_msi; 465 goto err_free_msi;
465 } 466 }
466 467
468 ret = dw_pcie_rd_own_conf(pp, PCI_HEADER_TYPE, 1, &hdr_type);
469 if (ret != PCIBIOS_SUCCESSFUL) {
470 dev_err(pci->dev, "Failed reading PCI_HEADER_TYPE cfg space reg (ret: 0x%x)\n",
471 ret);
472 ret = pcibios_err_to_errno(ret);
473 goto err_free_msi;
474 }
475 if (hdr_type != PCI_HEADER_TYPE_BRIDGE) {
476 dev_err(pci->dev,
477 "PCIe controller is not set to bridge type (hdr_type: 0x%x)!\n",
478 hdr_type);
479 ret = -EIO;
480 goto err_free_msi;
481 }
482
467 pp->root_bus_nr = pp->busn->start; 483 pp->root_bus_nr = pp->busn->start;
468 484
469 bridge->dev.parent = dev; 485 bridge->dev.parent = dev;