summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRay Jui <ray.jui@broadcom.com>2018-06-11 20:21:05 -0400
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2018-07-13 06:51:46 -0400
commit1e5748c27ad6669ec4a377f44ef40898c28184e5 (patch)
treeea3a0a1b8a2ae7e08ff950e520bfbdc4e69de442
parent3bc70825e4361eaedffeb4e85e1b2774547e66a0 (diff)
PCI: iproc: Disable MSI parsing in certain PAXC blocks
The internal MSI parsing logic in certain revisions of PAXC root complexes does not work properly and can cause corruptions on the writes transactions so they need to be disabled. Signed-off-by: Ray Jui <ray.jui@broadcom.com> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Reviewed-by: Scott Branden <scott.branden@broadcom.com> Reviewed-by: Oza Pawandeep <poza@codeaurora.org>
-rw-r--r--drivers/pci/controller/pcie-iproc.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/drivers/pci/controller/pcie-iproc.c b/drivers/pci/controller/pcie-iproc.c
index 680f6b170845..0804aa284b87 100644
--- a/drivers/pci/controller/pcie-iproc.c
+++ b/drivers/pci/controller/pcie-iproc.c
@@ -1197,10 +1197,22 @@ static int iproc_pcie_paxb_v2_msi_steer(struct iproc_pcie *pcie, u64 msi_addr)
1197 return ret; 1197 return ret;
1198} 1198}
1199 1199
1200static void iproc_pcie_paxc_v2_msi_steer(struct iproc_pcie *pcie, u64 msi_addr) 1200static void iproc_pcie_paxc_v2_msi_steer(struct iproc_pcie *pcie, u64 msi_addr,
1201 bool enable)
1201{ 1202{
1202 u32 val; 1203 u32 val;
1203 1204
1205 if (!enable) {
1206 /*
1207 * Disable PAXC MSI steering. All write transfers will be
1208 * treated as non-MSI transfers
1209 */
1210 val = iproc_pcie_read_reg(pcie, IPROC_PCIE_MSI_EN_CFG);
1211 val &= ~MSI_ENABLE_CFG;
1212 iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_EN_CFG, val);
1213 return;
1214 }
1215
1204 /* 1216 /*
1205 * Program bits [43:13] of address of GITS_TRANSLATER register into 1217 * Program bits [43:13] of address of GITS_TRANSLATER register into
1206 * bits [30:0] of the MSI base address register. In fact, in all iProc 1218 * bits [30:0] of the MSI base address register. In fact, in all iProc
@@ -1254,7 +1266,7 @@ static int iproc_pcie_msi_steer(struct iproc_pcie *pcie,
1254 return ret; 1266 return ret;
1255 break; 1267 break;
1256 case IPROC_PCIE_PAXC_V2: 1268 case IPROC_PCIE_PAXC_V2:
1257 iproc_pcie_paxc_v2_msi_steer(pcie, msi_addr); 1269 iproc_pcie_paxc_v2_msi_steer(pcie, msi_addr, true);
1258 break; 1270 break;
1259 default: 1271 default:
1260 return -EINVAL; 1272 return -EINVAL;
@@ -1480,6 +1492,24 @@ int iproc_pcie_remove(struct iproc_pcie *pcie)
1480} 1492}
1481EXPORT_SYMBOL(iproc_pcie_remove); 1493EXPORT_SYMBOL(iproc_pcie_remove);
1482 1494
1495/*
1496 * The MSI parsing logic in certain revisions of Broadcom PAXC based root
1497 * complex does not work and needs to be disabled
1498 */
1499static void quirk_paxc_disable_msi_parsing(struct pci_dev *pdev)
1500{
1501 struct iproc_pcie *pcie = iproc_data(pdev->bus);
1502
1503 if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
1504 iproc_pcie_paxc_v2_msi_steer(pcie, 0, false);
1505}
1506DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16f0,
1507 quirk_paxc_disable_msi_parsing);
1508DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd802,
1509 quirk_paxc_disable_msi_parsing);
1510DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd804,
1511 quirk_paxc_disable_msi_parsing);
1512
1483MODULE_AUTHOR("Ray Jui <rjui@broadcom.com>"); 1513MODULE_AUTHOR("Ray Jui <rjui@broadcom.com>");
1484MODULE_DESCRIPTION("Broadcom iPROC PCIe common driver"); 1514MODULE_DESCRIPTION("Broadcom iPROC PCIe common driver");
1485MODULE_LICENSE("GPL v2"); 1515MODULE_LICENSE("GPL v2");