]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
PCI: imx6: Simplify switch-case logic by involve core_reset callback
authorFrank Li <Frank.Li@nxp.com>
Mon, 29 Jul 2024 20:18:13 +0000 (16:18 -0400)
committerKrzysztof Wilczyński <kwilczynski@kernel.org>
Mon, 9 Sep 2024 14:08:22 +0000 (14:08 +0000)
Instead of using the switch case statement to assert/dassert the core
reset handled by this driver itself, let's introduce a new callback
core_reset() and define it for platforms that require it.

This simplifies the code.

Link: https://lore.kernel.org/linux-pci/20240729-pci2_upstream-v8-5-b68ee5ef2b4d@nxp.com
Signed-off-by: Frank Li <Frank.Li@nxp.com>
[kwilczynski: commit log]
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
drivers/pci/controller/dwc/pci-imx6.c

index d843ffb7cecb702dbbdf84a0a9b7ab200852581e..a63975bd21ed2289d0956dd6291afb793d843a24 100644 (file)
@@ -102,6 +102,7 @@ struct imx_pcie_drvdata {
        const struct pci_epc_features *epc_features;
        int (*init_phy)(struct imx_pcie *pcie);
        int (*enable_ref_clk)(struct imx_pcie *pcie, bool enable);
+       int (*core_reset)(struct imx_pcie *pcie, bool assert);
 };
 
 struct imx_pcie {
@@ -668,35 +669,75 @@ static void imx_pcie_clk_disable(struct imx_pcie *imx_pcie)
        clk_bulk_disable_unprepare(imx_pcie->drvdata->clks_cnt, imx_pcie->clks);
 }
 
+static int imx6sx_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
+{
+       if (assert)
+               regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
+                               IMX6SX_GPR12_PCIE_TEST_POWERDOWN);
+
+       /* Force PCIe PHY reset */
+       regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR5, IMX6SX_GPR5_PCIE_BTNRST_RESET,
+                          assert ? IMX6SX_GPR5_PCIE_BTNRST_RESET : 0);
+       return 0;
+}
+
+static int imx6qp_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
+{
+       regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_SW_RST,
+                          assert ? IMX6Q_GPR1_PCIE_SW_RST : 0);
+       if (!assert)
+               usleep_range(200, 500);
+
+       return 0;
+}
+
+static int imx6q_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
+{
+       if (!assert)
+               return 0;
+
+       regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_TEST_PD);
+       regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_REF_CLK_EN);
+
+       return 0;
+}
+
+static int imx7d_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
+{
+       struct dw_pcie *pci = imx_pcie->pci;
+       struct device *dev = pci->dev;
+
+       if (assert)
+               return 0;
+
+       /*
+        * Workaround for ERR010728, failure of PCI-e PLL VCO to
+        * oscillate, especially when cold. This turns off "Duty-cycle
+        * Corrector" and other mysterious undocumented things.
+        */
+
+       if (likely(imx_pcie->phy_base)) {
+               /* De-assert DCC_FB_EN */
+               writel(PCIE_PHY_CMN_REG4_DCC_FB_EN, imx_pcie->phy_base + PCIE_PHY_CMN_REG4);
+               /* Assert RX_EQS and RX_EQS_SEL */
+               writel(PCIE_PHY_CMN_REG24_RX_EQ_SEL | PCIE_PHY_CMN_REG24_RX_EQ,
+                      imx_pcie->phy_base + PCIE_PHY_CMN_REG24);
+               /* Assert ATT_MODE */
+               writel(PCIE_PHY_CMN_REG26_ATT_MODE, imx_pcie->phy_base + PCIE_PHY_CMN_REG26);
+       } else {
+               dev_warn(dev, "Unable to apply ERR010728 workaround. DT missing fsl,imx7d-pcie-phy phandle ?\n");
+       }
+       imx7d_pcie_wait_for_phy_pll_lock(imx_pcie);
+       return 0;
+}
+
 static void imx_pcie_assert_core_reset(struct imx_pcie *imx_pcie)
 {
        reset_control_assert(imx_pcie->pciephy_reset);
        reset_control_assert(imx_pcie->apps_reset);
 
-       switch (imx_pcie->drvdata->variant) {
-       case IMX6SX:
-               regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
-                                  IMX6SX_GPR12_PCIE_TEST_POWERDOWN,
-                                  IMX6SX_GPR12_PCIE_TEST_POWERDOWN);
-               /* Force PCIe PHY reset */
-               regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR5,
-                                  IMX6SX_GPR5_PCIE_BTNRST_RESET,
-                                  IMX6SX_GPR5_PCIE_BTNRST_RESET);
-               break;
-       case IMX6QP:
-               regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
-                                  IMX6Q_GPR1_PCIE_SW_RST,
-                                  IMX6Q_GPR1_PCIE_SW_RST);
-               break;
-       case IMX6Q:
-               regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
-                                  IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18);
-               regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
-                                  IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16);
-               break;
-       default:
-               break;
-       }
+       if (imx_pcie->drvdata->core_reset)
+               imx_pcie->drvdata->core_reset(imx_pcie, true);
 
        /* Some boards don't have PCIe reset GPIO. */
        gpiod_set_value_cansleep(imx_pcie->reset_gpiod, 1);
@@ -704,47 +745,10 @@ static void imx_pcie_assert_core_reset(struct imx_pcie *imx_pcie)
 
 static int imx_pcie_deassert_core_reset(struct imx_pcie *imx_pcie)
 {
-       struct dw_pcie *pci = imx_pcie->pci;
-       struct device *dev = pci->dev;
-
        reset_control_deassert(imx_pcie->pciephy_reset);
 
-       switch (imx_pcie->drvdata->variant) {
-       case IMX7D:
-               /* Workaround for ERR010728, failure of PCI-e PLL VCO to
-                * oscillate, especially when cold.  This turns off "Duty-cycle
-                * Corrector" and other mysterious undocumented things.
-                */
-               if (likely(imx_pcie->phy_base)) {
-                       /* De-assert DCC_FB_EN */
-                       writel(PCIE_PHY_CMN_REG4_DCC_FB_EN,
-                              imx_pcie->phy_base + PCIE_PHY_CMN_REG4);
-                       /* Assert RX_EQS and RX_EQS_SEL */
-                       writel(PCIE_PHY_CMN_REG24_RX_EQ_SEL
-                               | PCIE_PHY_CMN_REG24_RX_EQ,
-                              imx_pcie->phy_base + PCIE_PHY_CMN_REG24);
-                       /* Assert ATT_MODE */
-                       writel(PCIE_PHY_CMN_REG26_ATT_MODE,
-                              imx_pcie->phy_base + PCIE_PHY_CMN_REG26);
-               } else {
-                       dev_warn(dev, "Unable to apply ERR010728 workaround. DT missing fsl,imx7d-pcie-phy phandle ?\n");
-               }
-
-               imx7d_pcie_wait_for_phy_pll_lock(imx_pcie);
-               break;
-       case IMX6SX:
-               regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR5,
-                                  IMX6SX_GPR5_PCIE_BTNRST_RESET, 0);
-               break;
-       case IMX6QP:
-               regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
-                                  IMX6Q_GPR1_PCIE_SW_RST, 0);
-
-               usleep_range(200, 500);
-               break;
-       default:
-               break;
-       }
+       if (imx_pcie->drvdata->core_reset)
+               imx_pcie->drvdata->core_reset(imx_pcie, false);
 
        /* Some boards don't have PCIe reset GPIO. */
        if (imx_pcie->reset_gpiod) {
@@ -1441,6 +1445,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
                .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
                .init_phy = imx_pcie_init_phy,
                .enable_ref_clk = imx6q_pcie_enable_ref_clk,
+               .core_reset = imx6q_pcie_core_reset,
        },
        [IMX6SX] = {
                .variant = IMX6SX,
@@ -1456,6 +1461,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
                .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
                .init_phy = imx6sx_pcie_init_phy,
                .enable_ref_clk = imx6sx_pcie_enable_ref_clk,
+               .core_reset = imx6sx_pcie_core_reset,
        },
        [IMX6QP] = {
                .variant = IMX6QP,
@@ -1472,6 +1478,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
                .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
                .init_phy = imx_pcie_init_phy,
                .enable_ref_clk = imx6q_pcie_enable_ref_clk,
+               .core_reset = imx6qp_pcie_core_reset,
        },
        [IMX7D] = {
                .variant = IMX7D,
@@ -1485,6 +1492,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
                .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
                .init_phy = imx7d_pcie_init_phy,
                .enable_ref_clk = imx7d_pcie_enable_ref_clk,
+               .core_reset = imx7d_pcie_core_reset,
        },
        [IMX8MQ] = {
                .variant = IMX8MQ,