@@ -102,6 +102,7 @@ struct imx_pcie_drvdata {
102102 const struct pci_epc_features * epc_features ;
103103 int (* init_phy )(struct imx_pcie * pcie );
104104 int (* enable_ref_clk )(struct imx_pcie * pcie , bool enable );
105+ int (* core_reset )(struct imx_pcie * pcie , bool assert );
105106};
106107
107108struct imx_pcie {
@@ -668,83 +669,86 @@ static void imx_pcie_clk_disable(struct imx_pcie *imx_pcie)
668669 clk_bulk_disable_unprepare (imx_pcie -> drvdata -> clks_cnt , imx_pcie -> clks );
669670}
670671
672+ static int imx6sx_pcie_core_reset (struct imx_pcie * imx_pcie , bool assert )
673+ {
674+ if (assert )
675+ regmap_set_bits (imx_pcie -> iomuxc_gpr , IOMUXC_GPR12 ,
676+ IMX6SX_GPR12_PCIE_TEST_POWERDOWN );
677+
678+ /* Force PCIe PHY reset */
679+ regmap_update_bits (imx_pcie -> iomuxc_gpr , IOMUXC_GPR5 , IMX6SX_GPR5_PCIE_BTNRST_RESET ,
680+ assert ? IMX6SX_GPR5_PCIE_BTNRST_RESET : 0 );
681+ return 0 ;
682+ }
683+
684+ static int imx6qp_pcie_core_reset (struct imx_pcie * imx_pcie , bool assert )
685+ {
686+ regmap_update_bits (imx_pcie -> iomuxc_gpr , IOMUXC_GPR1 , IMX6Q_GPR1_PCIE_SW_RST ,
687+ assert ? IMX6Q_GPR1_PCIE_SW_RST : 0 );
688+ if (!assert )
689+ usleep_range (200 , 500 );
690+
691+ return 0 ;
692+ }
693+
694+ static int imx6q_pcie_core_reset (struct imx_pcie * imx_pcie , bool assert )
695+ {
696+ if (!assert )
697+ return 0 ;
698+
699+ regmap_set_bits (imx_pcie -> iomuxc_gpr , IOMUXC_GPR1 , IMX6Q_GPR1_PCIE_TEST_PD );
700+ regmap_set_bits (imx_pcie -> iomuxc_gpr , IOMUXC_GPR1 , IMX6Q_GPR1_PCIE_REF_CLK_EN );
701+
702+ return 0 ;
703+ }
704+
705+ static int imx7d_pcie_core_reset (struct imx_pcie * imx_pcie , bool assert )
706+ {
707+ struct dw_pcie * pci = imx_pcie -> pci ;
708+ struct device * dev = pci -> dev ;
709+
710+ if (assert )
711+ return 0 ;
712+
713+ /*
714+ * Workaround for ERR010728, failure of PCI-e PLL VCO to
715+ * oscillate, especially when cold. This turns off "Duty-cycle
716+ * Corrector" and other mysterious undocumented things.
717+ */
718+
719+ if (likely (imx_pcie -> phy_base )) {
720+ /* De-assert DCC_FB_EN */
721+ writel (PCIE_PHY_CMN_REG4_DCC_FB_EN , imx_pcie -> phy_base + PCIE_PHY_CMN_REG4 );
722+ /* Assert RX_EQS and RX_EQS_SEL */
723+ writel (PCIE_PHY_CMN_REG24_RX_EQ_SEL | PCIE_PHY_CMN_REG24_RX_EQ ,
724+ imx_pcie -> phy_base + PCIE_PHY_CMN_REG24 );
725+ /* Assert ATT_MODE */
726+ writel (PCIE_PHY_CMN_REG26_ATT_MODE , imx_pcie -> phy_base + PCIE_PHY_CMN_REG26 );
727+ } else {
728+ dev_warn (dev , "Unable to apply ERR010728 workaround. DT missing fsl,imx7d-pcie-phy phandle ?\n" );
729+ }
730+ imx7d_pcie_wait_for_phy_pll_lock (imx_pcie );
731+ return 0 ;
732+ }
733+
671734static void imx_pcie_assert_core_reset (struct imx_pcie * imx_pcie )
672735{
673736 reset_control_assert (imx_pcie -> pciephy_reset );
674737 reset_control_assert (imx_pcie -> apps_reset );
675738
676- switch (imx_pcie -> drvdata -> variant ) {
677- case IMX6SX :
678- regmap_update_bits (imx_pcie -> iomuxc_gpr , IOMUXC_GPR12 ,
679- IMX6SX_GPR12_PCIE_TEST_POWERDOWN ,
680- IMX6SX_GPR12_PCIE_TEST_POWERDOWN );
681- /* Force PCIe PHY reset */
682- regmap_update_bits (imx_pcie -> iomuxc_gpr , IOMUXC_GPR5 ,
683- IMX6SX_GPR5_PCIE_BTNRST_RESET ,
684- IMX6SX_GPR5_PCIE_BTNRST_RESET );
685- break ;
686- case IMX6QP :
687- regmap_update_bits (imx_pcie -> iomuxc_gpr , IOMUXC_GPR1 ,
688- IMX6Q_GPR1_PCIE_SW_RST ,
689- IMX6Q_GPR1_PCIE_SW_RST );
690- break ;
691- case IMX6Q :
692- regmap_update_bits (imx_pcie -> iomuxc_gpr , IOMUXC_GPR1 ,
693- IMX6Q_GPR1_PCIE_TEST_PD , 1 << 18 );
694- regmap_update_bits (imx_pcie -> iomuxc_gpr , IOMUXC_GPR1 ,
695- IMX6Q_GPR1_PCIE_REF_CLK_EN , 0 << 16 );
696- break ;
697- default :
698- break ;
699- }
739+ if (imx_pcie -> drvdata -> core_reset )
740+ imx_pcie -> drvdata -> core_reset (imx_pcie , true);
700741
701742 /* Some boards don't have PCIe reset GPIO. */
702743 gpiod_set_value_cansleep (imx_pcie -> reset_gpiod , 1 );
703744}
704745
705746static int imx_pcie_deassert_core_reset (struct imx_pcie * imx_pcie )
706747{
707- struct dw_pcie * pci = imx_pcie -> pci ;
708- struct device * dev = pci -> dev ;
709-
710748 reset_control_deassert (imx_pcie -> pciephy_reset );
711749
712- switch (imx_pcie -> drvdata -> variant ) {
713- case IMX7D :
714- /* Workaround for ERR010728, failure of PCI-e PLL VCO to
715- * oscillate, especially when cold. This turns off "Duty-cycle
716- * Corrector" and other mysterious undocumented things.
717- */
718- if (likely (imx_pcie -> phy_base )) {
719- /* De-assert DCC_FB_EN */
720- writel (PCIE_PHY_CMN_REG4_DCC_FB_EN ,
721- imx_pcie -> phy_base + PCIE_PHY_CMN_REG4 );
722- /* Assert RX_EQS and RX_EQS_SEL */
723- writel (PCIE_PHY_CMN_REG24_RX_EQ_SEL
724- | PCIE_PHY_CMN_REG24_RX_EQ ,
725- imx_pcie -> phy_base + PCIE_PHY_CMN_REG24 );
726- /* Assert ATT_MODE */
727- writel (PCIE_PHY_CMN_REG26_ATT_MODE ,
728- imx_pcie -> phy_base + PCIE_PHY_CMN_REG26 );
729- } else {
730- dev_warn (dev , "Unable to apply ERR010728 workaround. DT missing fsl,imx7d-pcie-phy phandle ?\n" );
731- }
732-
733- imx7d_pcie_wait_for_phy_pll_lock (imx_pcie );
734- break ;
735- case IMX6SX :
736- regmap_update_bits (imx_pcie -> iomuxc_gpr , IOMUXC_GPR5 ,
737- IMX6SX_GPR5_PCIE_BTNRST_RESET , 0 );
738- break ;
739- case IMX6QP :
740- regmap_update_bits (imx_pcie -> iomuxc_gpr , IOMUXC_GPR1 ,
741- IMX6Q_GPR1_PCIE_SW_RST , 0 );
742-
743- usleep_range (200 , 500 );
744- break ;
745- default :
746- break ;
747- }
750+ if (imx_pcie -> drvdata -> core_reset )
751+ imx_pcie -> drvdata -> core_reset (imx_pcie , false);
748752
749753 /* Some boards don't have PCIe reset GPIO. */
750754 if (imx_pcie -> reset_gpiod ) {
@@ -1441,6 +1445,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
14411445 .mode_mask [0 ] = IMX6Q_GPR12_DEVICE_TYPE ,
14421446 .init_phy = imx_pcie_init_phy ,
14431447 .enable_ref_clk = imx6q_pcie_enable_ref_clk ,
1448+ .core_reset = imx6q_pcie_core_reset ,
14441449 },
14451450 [IMX6SX ] = {
14461451 .variant = IMX6SX ,
@@ -1456,6 +1461,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
14561461 .mode_mask [0 ] = IMX6Q_GPR12_DEVICE_TYPE ,
14571462 .init_phy = imx6sx_pcie_init_phy ,
14581463 .enable_ref_clk = imx6sx_pcie_enable_ref_clk ,
1464+ .core_reset = imx6sx_pcie_core_reset ,
14591465 },
14601466 [IMX6QP ] = {
14611467 .variant = IMX6QP ,
@@ -1472,6 +1478,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
14721478 .mode_mask [0 ] = IMX6Q_GPR12_DEVICE_TYPE ,
14731479 .init_phy = imx_pcie_init_phy ,
14741480 .enable_ref_clk = imx6q_pcie_enable_ref_clk ,
1481+ .core_reset = imx6qp_pcie_core_reset ,
14751482 },
14761483 [IMX7D ] = {
14771484 .variant = IMX7D ,
@@ -1485,6 +1492,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
14851492 .mode_mask [0 ] = IMX6Q_GPR12_DEVICE_TYPE ,
14861493 .init_phy = imx7d_pcie_init_phy ,
14871494 .enable_ref_clk = imx7d_pcie_enable_ref_clk ,
1495+ .core_reset = imx7d_pcie_core_reset ,
14881496 },
14891497 [IMX8MQ ] = {
14901498 .variant = IMX8MQ ,
0 commit comments