Skip to content

Commit 3a4e830

Browse files
Richard Zhubjorn-helgaas
authored andcommitted
PCI: imx6: Keep Root Port MSI capability with iMSI-RX to work around hardware bug
On NXP i.MX7D, i.MX8MM, and i.MX8MQ chipsets, MSIs from the endpoints won't be received by the iMSI-RX MSI controller if the Root Port MSI capability is disabled. Even though the Root Port MSIs won't be received by the iMSI-RX controller due to design, these chipsets have some weird hardware bug that prevents the endpoint MSIs from reaching when the Root Port MSI capability is disabled. Hence, introduce a new flag, 'dw_pcie_rp::keep_rp_msi_en', set it for the above mentioned SoCs, and always keep the Root Port MSI capability when this flag is set. Note that by keeping Root Port MSI capability, Root Port MSIs such as AER, PME and others won't be received by default. So users need to use workarounds such as passing 'pcie_pme=nomsi' cmdline param. Fixes: f5cd8a9 ("PCI: dwc: Remove MSI/MSIX capability for Root Port if iMSI-RX is used as MSI controller") Suggested-by: Manivannan Sadhasivam <mani@kernel.org> Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com> [mani: commit log] Signed-off-by: Manivannan Sadhasivam <mani@kernel.org> [bhelgaas: fix typos] Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Frank Li <Frank.Li@nxp.com> Link: https://patch.msgid.link/20260331085252.1243108-1-hongxing.zhu@nxp.com
1 parent 180ea82 commit 3a4e830

3 files changed

Lines changed: 9 additions & 1 deletion

File tree

drivers/pci/controller/dwc/pci-imx6.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ enum imx_pcie_variants {
117117
#define IMX_PCIE_FLAG_HAS_LUT BIT(10)
118118
#define IMX_PCIE_FLAG_8GT_ECN_ERR051586 BIT(11)
119119
#define IMX_PCIE_FLAG_SKIP_L23_READY BIT(12)
120+
/* Preserve MSI capability for platforms that require it */
121+
#define IMX_PCIE_FLAG_KEEP_MSI_CAP BIT(13)
120122

121123
#define imx_check_flag(pci, val) (pci->drvdata->flags & val)
122124

@@ -1828,6 +1830,8 @@ static int imx_pcie_probe(struct platform_device *pdev)
18281830
} else {
18291831
if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_SKIP_L23_READY))
18301832
pci->pp.skip_l23_ready = true;
1833+
if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_KEEP_MSI_CAP))
1834+
pci->pp.keep_rp_msi_en = true;
18311835
pci->pp.use_atu_msg = true;
18321836
ret = dw_pcie_host_init(&pci->pp);
18331837
if (ret < 0)
@@ -1907,6 +1911,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
19071911
[IMX7D] = {
19081912
.variant = IMX7D,
19091913
.flags = IMX_PCIE_FLAG_SUPPORTS_SUSPEND |
1914+
IMX_PCIE_FLAG_KEEP_MSI_CAP |
19101915
IMX_PCIE_FLAG_HAS_APP_RESET |
19111916
IMX_PCIE_FLAG_SKIP_L23_READY |
19121917
IMX_PCIE_FLAG_HAS_PHY_RESET,
@@ -1919,6 +1924,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
19191924
[IMX8MQ] = {
19201925
.variant = IMX8MQ,
19211926
.flags = IMX_PCIE_FLAG_HAS_APP_RESET |
1927+
IMX_PCIE_FLAG_KEEP_MSI_CAP |
19221928
IMX_PCIE_FLAG_HAS_PHY_RESET |
19231929
IMX_PCIE_FLAG_SUPPORTS_SUSPEND,
19241930
.gpr = "fsl,imx8mq-iomuxc-gpr",
@@ -1933,6 +1939,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
19331939
[IMX8MM] = {
19341940
.variant = IMX8MM,
19351941
.flags = IMX_PCIE_FLAG_SUPPORTS_SUSPEND |
1942+
IMX_PCIE_FLAG_KEEP_MSI_CAP |
19361943
IMX_PCIE_FLAG_HAS_PHYDRV |
19371944
IMX_PCIE_FLAG_HAS_APP_RESET,
19381945
.gpr = "fsl,imx8mm-iomuxc-gpr",

drivers/pci/controller/dwc/pcie-designware-host.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1171,7 +1171,7 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
11711171
* the MSI and MSI-X capabilities of the Root Port to allow the drivers
11721172
* to fall back to INTx instead.
11731173
*/
1174-
if (pp->use_imsi_rx) {
1174+
if (pp->use_imsi_rx && !pp->keep_rp_msi_en) {
11751175
dw_pcie_remove_capability(pci, PCI_CAP_ID_MSI);
11761176
dw_pcie_remove_capability(pci, PCI_CAP_ID_MSIX);
11771177
}

drivers/pci/controller/dwc/pcie-designware.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ struct dw_pcie_host_ops {
421421

422422
struct dw_pcie_rp {
423423
bool use_imsi_rx:1;
424+
bool keep_rp_msi_en:1;
424425
bool cfg0_io_shared:1;
425426
u64 cfg0_base;
426427
void __iomem *va_cfg0_base;

0 commit comments

Comments
 (0)