diff --git a/MAINTAINERS b/MAINTAINERS index 4eeca0a76c32..02a167a9a9d9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17439,6 +17439,7 @@ M: Roy Zang L: linuxppc-dev@lists.ozlabs.org L: linux-pci@vger.kernel.org L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +L: imx@lists.linux.dev S: Maintained F: drivers/pci/controller/dwc/*layerscape* @@ -17465,6 +17466,7 @@ M: Richard Zhu M: Lucas Stach L: linux-pci@vger.kernel.org L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +L: imx@lists.linux.dev S: Maintained F: Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml F: Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml @@ -17643,6 +17645,7 @@ F: drivers/pci/controller/pci-xgene-msi.c PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS M: Lorenzo Pieralisi M: Krzysztof WilczyƄski +R: Manivannan Sadhasivam R: Rob Herring L: linux-pci@vger.kernel.org S: Supported diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index 236229f66c80..a9b263f749b6 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -58,6 +58,7 @@ #define PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L2 0xc88 #define PARF_DEVICE_TYPE 0x1000 #define PARF_BDF_TO_SID_CFG 0x2c00 +#define PARF_INT_ALL_5_MASK 0x2dcc /* PARF_INT_ALL_{STATUS/CLEAR/MASK} register fields */ #define PARF_INT_ALL_LINK_DOWN BIT(1) @@ -127,6 +128,9 @@ /* PARF_CFG_BITS register fields */ #define PARF_CFG_BITS_REQ_EXIT_L1SS_MSI_LTR_EN BIT(1) +/* PARF_INT_ALL_5_MASK fields */ +#define PARF_INT_ALL_5_MHI_RAM_DATA_PARITY_ERR BIT(0) + /* ELBI registers */ #define ELBI_SYS_STTS 0x08 #define ELBI_CS2_ENABLE 0xa4 @@ -158,10 +162,12 @@ enum qcom_pcie_ep_link_status { * struct qcom_pcie_ep_cfg - Per SoC config struct * @hdma_support: HDMA support on this SoC * @override_no_snoop: Override NO_SNOOP attribute in TLP to enable cache snooping + * @disable_mhi_ram_parity_check: Disable MHI RAM data parity error check */ struct qcom_pcie_ep_cfg { bool hdma_support; bool override_no_snoop; + bool disable_mhi_ram_parity_check; }; /** @@ -480,6 +486,12 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci) PARF_INT_ALL_LINK_UP | PARF_INT_ALL_EDMA; writel_relaxed(val, pcie_ep->parf + PARF_INT_ALL_MASK); + if (pcie_ep->cfg && pcie_ep->cfg->disable_mhi_ram_parity_check) { + val = readl_relaxed(pcie_ep->parf + PARF_INT_ALL_5_MASK); + val &= ~PARF_INT_ALL_5_MHI_RAM_DATA_PARITY_ERR; + writel_relaxed(val, pcie_ep->parf + PARF_INT_ALL_5_MASK); + } + ret = dw_pcie_ep_init_registers(&pcie_ep->pci.ep); if (ret) { dev_err(dev, "Failed to complete initialization: %d\n", ret); @@ -901,6 +913,7 @@ static void qcom_pcie_ep_remove(struct platform_device *pdev) static const struct qcom_pcie_ep_cfg cfg_1_34_0 = { .hdma_support = true, .override_no_snoop = true, + .disable_mhi_ram_parity_check = true, }; static const struct of_device_id qcom_pcie_ep_match[] = { diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 0180edf3310e..6f953e32d990 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -261,6 +261,7 @@ struct qcom_pcie { const struct qcom_pcie_cfg *cfg; struct dentry *debugfs; bool suspended; + bool use_pm_opp; }; #define to_qcom_pcie(x) dev_get_drvdata((x)->dev) @@ -1433,7 +1434,7 @@ static void qcom_pcie_icc_opp_update(struct qcom_pcie *pcie) dev_err(pci->dev, "Failed to set bandwidth for PCIe-MEM interconnect path: %d\n", ret); } - } else { + } else if (pcie->use_pm_opp) { freq_mbps = pcie_dev_speed_mbps(pcie_link_speed[speed]); if (freq_mbps < 0) return; @@ -1592,6 +1593,8 @@ static int qcom_pcie_probe(struct platform_device *pdev) max_freq); goto err_pm_runtime_put; } + + pcie->use_pm_opp = true; } else { /* Skip ICC init if OPP is supported as it is handled by OPP */ ret = qcom_pcie_icc_init(pcie); @@ -1683,7 +1686,7 @@ static int qcom_pcie_suspend_noirq(struct device *dev) if (ret) dev_err(dev, "Failed to disable CPU-PCIe interconnect path: %d\n", ret); - if (!pcie->icc_mem) + if (pcie->use_pm_opp) dev_pm_opp_set_opp(pcie->pci->dev, NULL); } return ret;