]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
PCI: imx6: Introduce SoC specific callbacks for controlling REFCLK
authorFrank Li <Frank.Li@nxp.com>
Mon, 29 Jul 2024 20:18:12 +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 enable/disable the
reference clock handled by this driver itself, let's introduce a new
callback enable_ref_clk() 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 2f418508ed9b3871c2e767348d56917265a19dbf..d843ffb7cecb702dbbdf84a0a9b7ab200852581e 100644 (file)
@@ -101,6 +101,7 @@ struct imx_pcie_drvdata {
        const u32 mode_mask[IMX_PCIE_MAX_INSTANCES];
        const struct pci_epc_features *epc_features;
        int (*init_phy)(struct imx_pcie *pcie);
+       int (*enable_ref_clk)(struct imx_pcie *pcie, bool enable);
 };
 
 struct imx_pcie {
@@ -582,21 +583,20 @@ static int imx_pcie_attach_pd(struct device *dev)
        return 0;
 }
 
-static int imx_pcie_enable_ref_clk(struct imx_pcie *imx_pcie)
+static int imx6sx_pcie_enable_ref_clk(struct imx_pcie *imx_pcie, bool enable)
 {
-       unsigned int offset;
-       int ret = 0;
+       if (enable)
+               regmap_clear_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
+                                 IMX6SX_GPR12_PCIE_TEST_POWERDOWN);
 
-       switch (imx_pcie->drvdata->variant) {
-       case IMX6SX:
-               regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
-                                  IMX6SX_GPR12_PCIE_TEST_POWERDOWN, 0);
-               break;
-       case IMX6QP:
-       case IMX6Q:
+       return 0;
+}
+
+static int imx6q_pcie_enable_ref_clk(struct imx_pcie *imx_pcie, bool enable)
+{
+       if (enable) {
                /* power up core phy and enable ref clock */
-               regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
-                                  IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18);
+               regmap_clear_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_TEST_PD);
                /*
                 * the async reset input need ref clock to sync internally,
                 * when the ref clock comes after reset, internal synced
@@ -604,55 +604,33 @@ static int imx_pcie_enable_ref_clk(struct imx_pcie *imx_pcie)
                 * add one ~10us delay here.
                 */
                usleep_range(10, 100);
-               regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
-                                  IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
-               break;
-       case IMX7D:
-       case IMX95:
-       case IMX95_EP:
-               break;
-       case IMX8MM:
-       case IMX8MM_EP:
-       case IMX8MQ:
-       case IMX8MQ_EP:
-       case IMX8MP:
-       case IMX8MP_EP:
-               offset = imx_pcie_grp_offset(imx_pcie);
-               /*
-                * Set the over ride low and enabled
-                * make sure that REF_CLK is turned on.
-                */
-               regmap_update_bits(imx_pcie->iomuxc_gpr, offset,
-                                  IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE,
-                                  0);
-               regmap_update_bits(imx_pcie->iomuxc_gpr, offset,
-                                  IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN,
-                                  IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN);
-               break;
+               regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_REF_CLK_EN);
+       } else {
+               regmap_clear_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_REF_CLK_EN);
+               regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_TEST_PD);
        }
 
-       return ret;
+       return 0;
 }
 
-static void imx_pcie_disable_ref_clk(struct imx_pcie *imx_pcie)
+static int imx8mm_pcie_enable_ref_clk(struct imx_pcie *imx_pcie, bool enable)
 {
-       switch (imx_pcie->drvdata->variant) {
-       case IMX6QP:
-       case IMX6Q:
-               regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
-                               IMX6Q_GPR1_PCIE_REF_CLK_EN, 0);
-               regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
-                               IMX6Q_GPR1_PCIE_TEST_PD,
-                               IMX6Q_GPR1_PCIE_TEST_PD);
-               break;
-       case IMX7D:
-               regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
-                                  IMX7D_GPR12_PCIE_PHY_REFCLK_SEL,
-                                  IMX7D_GPR12_PCIE_PHY_REFCLK_SEL);
-               break;
-       default:
-               break;
+       int offset = imx_pcie_grp_offset(imx_pcie);
+
+       if (enable) {
+               regmap_clear_bits(imx_pcie->iomuxc_gpr, offset, IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE);
+               regmap_set_bits(imx_pcie->iomuxc_gpr, offset, IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN);
        }
+
+       return 0;
+}
+
+static int imx7d_pcie_enable_ref_clk(struct imx_pcie *imx_pcie, bool enable)
+{
+       if (!enable)
+               regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
+                               IMX7D_GPR12_PCIE_PHY_REFCLK_SEL);
+       return 0;
 }
 
 static int imx_pcie_clk_enable(struct imx_pcie *imx_pcie)
@@ -665,10 +643,12 @@ static int imx_pcie_clk_enable(struct imx_pcie *imx_pcie)
        if (ret)
                return ret;
 
-       ret = imx_pcie_enable_ref_clk(imx_pcie);
-       if (ret) {
-               dev_err(dev, "unable to enable pcie ref clock\n");
-               goto err_ref_clk;
+       if (imx_pcie->drvdata->enable_ref_clk) {
+               ret = imx_pcie->drvdata->enable_ref_clk(imx_pcie, true);
+               if (ret) {
+                       dev_err(dev, "Failed to enable PCIe REFCLK\n");
+                       goto err_ref_clk;
+               }
        }
 
        /* allow the clocks to stabilize */
@@ -683,7 +663,8 @@ err_ref_clk:
 
 static void imx_pcie_clk_disable(struct imx_pcie *imx_pcie)
 {
-       imx_pcie_disable_ref_clk(imx_pcie);
+       if (imx_pcie->drvdata->enable_ref_clk)
+               imx_pcie->drvdata->enable_ref_clk(imx_pcie, false);
        clk_bulk_disable_unprepare(imx_pcie->drvdata->clks_cnt, imx_pcie->clks);
 }
 
@@ -1459,6 +1440,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
                .mode_off[0] = IOMUXC_GPR12,
                .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
                .init_phy = imx_pcie_init_phy,
+               .enable_ref_clk = imx6q_pcie_enable_ref_clk,
        },
        [IMX6SX] = {
                .variant = IMX6SX,
@@ -1473,6 +1455,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
                .mode_off[0] = IOMUXC_GPR12,
                .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
                .init_phy = imx6sx_pcie_init_phy,
+               .enable_ref_clk = imx6sx_pcie_enable_ref_clk,
        },
        [IMX6QP] = {
                .variant = IMX6QP,
@@ -1488,6 +1471,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
                .mode_off[0] = IOMUXC_GPR12,
                .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
                .init_phy = imx_pcie_init_phy,
+               .enable_ref_clk = imx6q_pcie_enable_ref_clk,
        },
        [IMX7D] = {
                .variant = IMX7D,
@@ -1500,6 +1484,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
                .mode_off[0] = IOMUXC_GPR12,
                .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
                .init_phy = imx7d_pcie_init_phy,
+               .enable_ref_clk = imx7d_pcie_enable_ref_clk,
        },
        [IMX8MQ] = {
                .variant = IMX8MQ,
@@ -1513,6 +1498,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
                .mode_off[1] = IOMUXC_GPR12,
                .mode_mask[1] = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
                .init_phy = imx8mq_pcie_init_phy,
+               .enable_ref_clk = imx8mm_pcie_enable_ref_clk,
        },
        [IMX8MM] = {
                .variant = IMX8MM,
@@ -1524,6 +1510,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
                .clks_cnt = ARRAY_SIZE(imx8mm_clks),
                .mode_off[0] = IOMUXC_GPR12,
                .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
+               .enable_ref_clk = imx8mm_pcie_enable_ref_clk,
        },
        [IMX8MP] = {
                .variant = IMX8MP,
@@ -1535,6 +1522,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
                .clks_cnt = ARRAY_SIZE(imx8mm_clks),
                .mode_off[0] = IOMUXC_GPR12,
                .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
+               .enable_ref_clk = imx8mm_pcie_enable_ref_clk,
        },
        [IMX95] = {
                .variant = IMX95,
@@ -1561,6 +1549,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
                .mode_mask[1] = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
                .epc_features = &imx8m_pcie_epc_features,
                .init_phy = imx8mq_pcie_init_phy,
+               .enable_ref_clk = imx8mm_pcie_enable_ref_clk,
        },
        [IMX8MM_EP] = {
                .variant = IMX8MM_EP,
@@ -1573,6 +1562,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
                .mode_off[0] = IOMUXC_GPR12,
                .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
                .epc_features = &imx8m_pcie_epc_features,
+               .enable_ref_clk = imx8mm_pcie_enable_ref_clk,
        },
        [IMX8MP_EP] = {
                .variant = IMX8MP_EP,
@@ -1585,6 +1575,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
                .mode_off[0] = IOMUXC_GPR12,
                .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
                .epc_features = &imx8m_pcie_epc_features,
+               .enable_ref_clk = imx8mm_pcie_enable_ref_clk,
        },
        [IMX95_EP] = {
                .variant = IMX95_EP,