PCI: qcom: Use bulk reset APIs for handling resets for IP rev 2.4.0
authorManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Thu, 16 Mar 2023 08:11:10 +0000 (13:41 +0530)
committerLorenzo Pieralisi <lpieralisi@kernel.org>
Tue, 11 Apr 2023 09:31:10 +0000 (11:31 +0200)
All the resets are asserted and deasserted at the same time. So the bulk
reset APIs can be used to handle them together. This simplifies the code
a lot.

It should be noted that there were delays in-between the reset asserts and
deasserts. But going by the config used by other revisions, those delays
are not really necessary. So a single delay after all asserts and one after
deasserts is used.

The total number of resets supported is 12 but only ipq4019 is using all of
them.

Link: https://lore.kernel.org/r/20230316081117.14288-13-manivannan.sadhasivam@linaro.org
Tested-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
drivers/pci/controller/dwc/pcie-qcom.c

index d673cb2..8baeee3 100644 (file)
@@ -176,22 +176,13 @@ struct qcom_pcie_resources_2_3_3 {
        struct reset_control_bulk_data rst[QCOM_PCIE_2_3_3_MAX_RESETS];
 };
 
-#define QCOM_PCIE_2_4_0_MAX_CLOCKS     4
+#define QCOM_PCIE_2_4_0_MAX_CLOCKS             4
+#define QCOM_PCIE_2_4_0_MAX_RESETS             12
 struct qcom_pcie_resources_2_4_0 {
        struct clk_bulk_data clks[QCOM_PCIE_2_4_0_MAX_CLOCKS];
        int num_clks;
-       struct reset_control *axi_m_reset;
-       struct reset_control *axi_s_reset;
-       struct reset_control *pipe_reset;
-       struct reset_control *axi_m_vmid_reset;
-       struct reset_control *axi_s_xpu_reset;
-       struct reset_control *parf_reset;
-       struct reset_control *phy_reset;
-       struct reset_control *axi_m_sticky_reset;
-       struct reset_control *pipe_sticky_reset;
-       struct reset_control *pwr_reset;
-       struct reset_control *ahb_reset;
-       struct reset_control *phy_ahb_reset;
+       struct reset_control_bulk_data resets[QCOM_PCIE_2_4_0_MAX_RESETS];
+       int num_resets;
 };
 
 /* 6 clocks typically, 7 for sm8250 */
@@ -626,65 +617,24 @@ static int qcom_pcie_get_resources_2_4_0(struct qcom_pcie *pcie)
        if (ret < 0)
                return ret;
 
-       res->axi_m_reset = devm_reset_control_get_exclusive(dev, "axi_m");
-       if (IS_ERR(res->axi_m_reset))
-               return PTR_ERR(res->axi_m_reset);
-
-       res->axi_s_reset = devm_reset_control_get_exclusive(dev, "axi_s");
-       if (IS_ERR(res->axi_s_reset))
-               return PTR_ERR(res->axi_s_reset);
-
-       if (is_ipq) {
-               /*
-                * These resources relates to the PHY or are secure clocks, but
-                * are controlled here for IPQ4019
-                */
-               res->pipe_reset = devm_reset_control_get_exclusive(dev, "pipe");
-               if (IS_ERR(res->pipe_reset))
-                       return PTR_ERR(res->pipe_reset);
-
-               res->axi_m_vmid_reset = devm_reset_control_get_exclusive(dev,
-                                                                        "axi_m_vmid");
-               if (IS_ERR(res->axi_m_vmid_reset))
-                       return PTR_ERR(res->axi_m_vmid_reset);
-
-               res->axi_s_xpu_reset = devm_reset_control_get_exclusive(dev,
-                                                                       "axi_s_xpu");
-               if (IS_ERR(res->axi_s_xpu_reset))
-                       return PTR_ERR(res->axi_s_xpu_reset);
-
-               res->parf_reset = devm_reset_control_get_exclusive(dev, "parf");
-               if (IS_ERR(res->parf_reset))
-                       return PTR_ERR(res->parf_reset);
-
-               res->phy_reset = devm_reset_control_get_exclusive(dev, "phy");
-               if (IS_ERR(res->phy_reset))
-                       return PTR_ERR(res->phy_reset);
-       }
-
-       res->axi_m_sticky_reset = devm_reset_control_get_exclusive(dev,
-                                                                  "axi_m_sticky");
-       if (IS_ERR(res->axi_m_sticky_reset))
-               return PTR_ERR(res->axi_m_sticky_reset);
-
-       res->pipe_sticky_reset = devm_reset_control_get_exclusive(dev,
-                                                                 "pipe_sticky");
-       if (IS_ERR(res->pipe_sticky_reset))
-               return PTR_ERR(res->pipe_sticky_reset);
-
-       res->pwr_reset = devm_reset_control_get_exclusive(dev, "pwr");
-       if (IS_ERR(res->pwr_reset))
-               return PTR_ERR(res->pwr_reset);
-
-       res->ahb_reset = devm_reset_control_get_exclusive(dev, "ahb");
-       if (IS_ERR(res->ahb_reset))
-               return PTR_ERR(res->ahb_reset);
+       res->resets[0].id = "axi_m";
+       res->resets[1].id = "axi_s";
+       res->resets[2].id = "axi_m_sticky";
+       res->resets[3].id = "pipe_sticky";
+       res->resets[4].id = "pwr";
+       res->resets[5].id = "ahb";
+       res->resets[6].id = "pipe";
+       res->resets[7].id = "axi_m_vmid";
+       res->resets[8].id = "axi_s_xpu";
+       res->resets[9].id = "parf";
+       res->resets[10].id = "phy";
+       res->resets[11].id = "phy_ahb";
+
+       res->num_resets = is_ipq ? 12 : 6;
 
-       if (is_ipq) {
-               res->phy_ahb_reset = devm_reset_control_get_exclusive(dev, "phy_ahb");
-               if (IS_ERR(res->phy_ahb_reset))
-                       return PTR_ERR(res->phy_ahb_reset);
-       }
+       ret = devm_reset_control_bulk_get_exclusive(dev, res->num_resets, res->resets);
+       if (ret < 0)
+               return ret;
 
        return 0;
 }
@@ -693,15 +643,7 @@ static void qcom_pcie_deinit_2_4_0(struct qcom_pcie *pcie)
 {
        struct qcom_pcie_resources_2_4_0 *res = &pcie->res.v2_4_0;
 
-       reset_control_assert(res->axi_m_reset);
-       reset_control_assert(res->axi_s_reset);
-       reset_control_assert(res->pipe_reset);
-       reset_control_assert(res->pipe_sticky_reset);
-       reset_control_assert(res->phy_reset);
-       reset_control_assert(res->phy_ahb_reset);
-       reset_control_assert(res->axi_m_sticky_reset);
-       reset_control_assert(res->pwr_reset);
-       reset_control_assert(res->ahb_reset);
+       reset_control_bulk_assert(res->num_resets, res->resets);
        clk_bulk_disable_unprepare(res->num_clks, res->clks);
 }
 
@@ -712,149 +654,29 @@ static int qcom_pcie_init_2_4_0(struct qcom_pcie *pcie)
        struct device *dev = pci->dev;
        int ret;
 
-       ret = reset_control_assert(res->axi_m_reset);
-       if (ret) {
-               dev_err(dev, "cannot assert axi master reset\n");
-               return ret;
-       }
-
-       ret = reset_control_assert(res->axi_s_reset);
-       if (ret) {
-               dev_err(dev, "cannot assert axi slave reset\n");
-               return ret;
-       }
-
-       usleep_range(10000, 12000);
-
-       ret = reset_control_assert(res->pipe_reset);
-       if (ret) {
-               dev_err(dev, "cannot assert pipe reset\n");
-               return ret;
-       }
-
-       ret = reset_control_assert(res->pipe_sticky_reset);
-       if (ret) {
-               dev_err(dev, "cannot assert pipe sticky reset\n");
-               return ret;
-       }
-
-       ret = reset_control_assert(res->phy_reset);
-       if (ret) {
-               dev_err(dev, "cannot assert phy reset\n");
-               return ret;
-       }
-
-       ret = reset_control_assert(res->phy_ahb_reset);
-       if (ret) {
-               dev_err(dev, "cannot assert phy ahb reset\n");
+       ret = reset_control_bulk_assert(res->num_resets, res->resets);
+       if (ret < 0) {
+               dev_err(dev, "cannot assert resets\n");
                return ret;
        }
 
        usleep_range(10000, 12000);
 
-       ret = reset_control_assert(res->axi_m_sticky_reset);
-       if (ret) {
-               dev_err(dev, "cannot assert axi master sticky reset\n");
-               return ret;
-       }
-
-       ret = reset_control_assert(res->pwr_reset);
-       if (ret) {
-               dev_err(dev, "cannot assert power reset\n");
-               return ret;
-       }
-
-       ret = reset_control_assert(res->ahb_reset);
-       if (ret) {
-               dev_err(dev, "cannot assert ahb reset\n");
+       ret = reset_control_bulk_deassert(res->num_resets, res->resets);
+       if (ret < 0) {
+               dev_err(dev, "cannot deassert resets\n");
                return ret;
        }
 
        usleep_range(10000, 12000);
 
-       ret = reset_control_deassert(res->phy_ahb_reset);
+       ret = clk_bulk_prepare_enable(res->num_clks, res->clks);
        if (ret) {
-               dev_err(dev, "cannot deassert phy ahb reset\n");
+               reset_control_bulk_assert(res->num_resets, res->resets);
                return ret;
        }
 
-       ret = reset_control_deassert(res->phy_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert phy reset\n");
-               goto err_rst_phy;
-       }
-
-       ret = reset_control_deassert(res->pipe_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert pipe reset\n");
-               goto err_rst_pipe;
-       }
-
-       ret = reset_control_deassert(res->pipe_sticky_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert pipe sticky reset\n");
-               goto err_rst_pipe_sticky;
-       }
-
-       usleep_range(10000, 12000);
-
-       ret = reset_control_deassert(res->axi_m_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert axi master reset\n");
-               goto err_rst_axi_m;
-       }
-
-       ret = reset_control_deassert(res->axi_m_sticky_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert axi master sticky reset\n");
-               goto err_rst_axi_m_sticky;
-       }
-
-       ret = reset_control_deassert(res->axi_s_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert axi slave reset\n");
-               goto err_rst_axi_s;
-       }
-
-       ret = reset_control_deassert(res->pwr_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert power reset\n");
-               goto err_rst_pwr;
-       }
-
-       ret = reset_control_deassert(res->ahb_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert ahb reset\n");
-               goto err_rst_ahb;
-       }
-
-       usleep_range(10000, 12000);
-
-       ret = clk_bulk_prepare_enable(res->num_clks, res->clks);
-       if (ret)
-               goto err_clks;
-
        return 0;
-
-err_clks:
-       reset_control_assert(res->ahb_reset);
-err_rst_ahb:
-       reset_control_assert(res->pwr_reset);
-err_rst_pwr:
-       reset_control_assert(res->axi_s_reset);
-err_rst_axi_s:
-       reset_control_assert(res->axi_m_sticky_reset);
-err_rst_axi_m_sticky:
-       reset_control_assert(res->axi_m_reset);
-err_rst_axi_m:
-       reset_control_assert(res->pipe_sticky_reset);
-err_rst_pipe_sticky:
-       reset_control_assert(res->pipe_reset);
-err_rst_pipe:
-       reset_control_assert(res->phy_reset);
-err_rst_phy:
-       reset_control_assert(res->phy_ahb_reset);
-       return ret;
 }
 
 static int qcom_pcie_post_init_2_4_0(struct qcom_pcie *pcie)