@@ -585,14 +585,41 @@ static void rockchip_pcie_ep_exit_ob_mem(struct rockchip_pcie_ep *ep)
585585 pci_epc_mem_exit (ep -> epc );
586586}
587587
588+ static void rockchip_pcie_ep_hide_broken_msix_cap (struct rockchip_pcie * rockchip )
589+ {
590+ u32 cfg_msi , cfg_msix_cp ;
591+
592+ /*
593+ * MSI-X is not supported but the controller still advertises the MSI-X
594+ * capability by default, which can lead to the Root Complex side
595+ * allocating MSI-X vectors which cannot be used. Avoid this by skipping
596+ * the MSI-X capability entry in the PCIe capabilities linked-list: get
597+ * the next pointer from the MSI-X entry and set that in the MSI
598+ * capability entry (which is the previous entry). This way the MSI-X
599+ * entry is skipped (left out of the linked-list) and not advertised.
600+ */
601+ cfg_msi = rockchip_pcie_read (rockchip , PCIE_EP_CONFIG_BASE +
602+ ROCKCHIP_PCIE_EP_MSI_CTRL_REG );
603+
604+ cfg_msi &= ~ROCKCHIP_PCIE_EP_MSI_CP1_MASK ;
605+
606+ cfg_msix_cp = rockchip_pcie_read (rockchip , PCIE_EP_CONFIG_BASE +
607+ ROCKCHIP_PCIE_EP_MSIX_CAP_REG ) &
608+ ROCKCHIP_PCIE_EP_MSIX_CAP_CP_MASK ;
609+
610+ cfg_msi |= cfg_msix_cp ;
611+
612+ rockchip_pcie_write (rockchip , cfg_msi ,
613+ PCIE_EP_CONFIG_BASE + ROCKCHIP_PCIE_EP_MSI_CTRL_REG );
614+ }
615+
588616static int rockchip_pcie_ep_probe (struct platform_device * pdev )
589617{
590618 struct device * dev = & pdev -> dev ;
591619 struct rockchip_pcie_ep * ep ;
592620 struct rockchip_pcie * rockchip ;
593621 struct pci_epc * epc ;
594622 int err ;
595- u32 cfg_msi , cfg_msix_cp ;
596623
597624 ep = devm_kzalloc (dev , sizeof (* ep ), GFP_KERNEL );
598625 if (!ep )
@@ -627,36 +654,15 @@ static int rockchip_pcie_ep_probe(struct platform_device *pdev)
627654 if (err )
628655 goto err_disable_clocks ;
629656
657+ rockchip_pcie_ep_hide_broken_msix_cap (rockchip );
658+
630659 /* Establish the link automatically */
631660 rockchip_pcie_write (rockchip , PCIE_CLIENT_LINK_TRAIN_ENABLE ,
632661 PCIE_CLIENT_CONFIG );
633662
634663 /* Only enable function 0 by default */
635664 rockchip_pcie_write (rockchip , BIT (0 ), PCIE_CORE_PHY_FUNC_CFG );
636665
637- /*
638- * MSI-X is not supported but the controller still advertises the MSI-X
639- * capability by default, which can lead to the Root Complex side
640- * allocating MSI-X vectors which cannot be used. Avoid this by skipping
641- * the MSI-X capability entry in the PCIe capabilities linked-list: get
642- * the next pointer from the MSI-X entry and set that in the MSI
643- * capability entry (which is the previous entry). This way the MSI-X
644- * entry is skipped (left out of the linked-list) and not advertised.
645- */
646- cfg_msi = rockchip_pcie_read (rockchip , PCIE_EP_CONFIG_BASE +
647- ROCKCHIP_PCIE_EP_MSI_CTRL_REG );
648-
649- cfg_msi &= ~ROCKCHIP_PCIE_EP_MSI_CP1_MASK ;
650-
651- cfg_msix_cp = rockchip_pcie_read (rockchip , PCIE_EP_CONFIG_BASE +
652- ROCKCHIP_PCIE_EP_MSIX_CAP_REG ) &
653- ROCKCHIP_PCIE_EP_MSIX_CAP_CP_MASK ;
654-
655- cfg_msi |= cfg_msix_cp ;
656-
657- rockchip_pcie_write (rockchip , cfg_msi ,
658- PCIE_EP_CONFIG_BASE + ROCKCHIP_PCIE_EP_MSI_CTRL_REG );
659-
660666 rockchip_pcie_write (rockchip , PCIE_CLIENT_CONF_ENABLE ,
661667 PCIE_CLIENT_CONFIG );
662668
0 commit comments