@@ -102,6 +102,7 @@ struct imx_pcie_drvdata {
102
102
const struct pci_epc_features * epc_features ;
103
103
int (* init_phy )(struct imx_pcie * pcie );
104
104
int (* enable_ref_clk )(struct imx_pcie * pcie , bool enable );
105
+ int (* core_reset )(struct imx_pcie * pcie , bool assert );
105
106
};
106
107
107
108
struct imx_pcie {
@@ -668,83 +669,86 @@ static void imx_pcie_clk_disable(struct imx_pcie *imx_pcie)
668
669
clk_bulk_disable_unprepare (imx_pcie -> drvdata -> clks_cnt , imx_pcie -> clks );
669
670
}
670
671
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
+
671
734
static void imx_pcie_assert_core_reset (struct imx_pcie * imx_pcie )
672
735
{
673
736
reset_control_assert (imx_pcie -> pciephy_reset );
674
737
reset_control_assert (imx_pcie -> apps_reset );
675
738
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);
700
741
701
742
/* Some boards don't have PCIe reset GPIO. */
702
743
gpiod_set_value_cansleep (imx_pcie -> reset_gpiod , 1 );
703
744
}
704
745
705
746
static int imx_pcie_deassert_core_reset (struct imx_pcie * imx_pcie )
706
747
{
707
- struct dw_pcie * pci = imx_pcie -> pci ;
708
- struct device * dev = pci -> dev ;
709
-
710
748
reset_control_deassert (imx_pcie -> pciephy_reset );
711
749
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);
748
752
749
753
/* Some boards don't have PCIe reset GPIO. */
750
754
if (imx_pcie -> reset_gpiod ) {
@@ -1441,6 +1445,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
1441
1445
.mode_mask [0 ] = IMX6Q_GPR12_DEVICE_TYPE ,
1442
1446
.init_phy = imx_pcie_init_phy ,
1443
1447
.enable_ref_clk = imx6q_pcie_enable_ref_clk ,
1448
+ .core_reset = imx6q_pcie_core_reset ,
1444
1449
},
1445
1450
[IMX6SX ] = {
1446
1451
.variant = IMX6SX ,
@@ -1456,6 +1461,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
1456
1461
.mode_mask [0 ] = IMX6Q_GPR12_DEVICE_TYPE ,
1457
1462
.init_phy = imx6sx_pcie_init_phy ,
1458
1463
.enable_ref_clk = imx6sx_pcie_enable_ref_clk ,
1464
+ .core_reset = imx6sx_pcie_core_reset ,
1459
1465
},
1460
1466
[IMX6QP ] = {
1461
1467
.variant = IMX6QP ,
@@ -1472,6 +1478,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
1472
1478
.mode_mask [0 ] = IMX6Q_GPR12_DEVICE_TYPE ,
1473
1479
.init_phy = imx_pcie_init_phy ,
1474
1480
.enable_ref_clk = imx6q_pcie_enable_ref_clk ,
1481
+ .core_reset = imx6qp_pcie_core_reset ,
1475
1482
},
1476
1483
[IMX7D ] = {
1477
1484
.variant = IMX7D ,
@@ -1485,6 +1492,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
1485
1492
.mode_mask [0 ] = IMX6Q_GPR12_DEVICE_TYPE ,
1486
1493
.init_phy = imx7d_pcie_init_phy ,
1487
1494
.enable_ref_clk = imx7d_pcie_enable_ref_clk ,
1495
+ .core_reset = imx7d_pcie_core_reset ,
1488
1496
},
1489
1497
[IMX8MQ ] = {
1490
1498
.variant = IMX8MQ ,
0 commit comments