1 From 6a114526af4689938863bf34976c83bfd279f517 Mon Sep 17 00:00:00 2001
2 From: Ansuel Smith <ansuelsmth@gmail.com>
3 Date: Mon, 15 Jun 2020 23:06:02 +0200
4 Subject: PCI: qcom: Use bulk clk api and assert on error
6 Rework 2.1.0 revision to use bulk clk api and fix missing assert on
7 reset_control_deassert error.
9 Link: https://lore.kernel.org/r/20200615210608.21469-7-ansuelsmth@gmail.com
10 Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
11 Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
12 Reviewed-by: Rob Herring <robh@kernel.org>
13 Acked-by: Stanimir Varbanov <svarbanov@mm-sol.com>
15 drivers/pci/controller/dwc/pcie-qcom.c | 131 ++++++++++++---------------------
16 1 file changed, 46 insertions(+), 85 deletions(-)
18 --- a/drivers/pci/controller/dwc/pcie-qcom.c
19 +++ b/drivers/pci/controller/dwc/pcie-qcom.c
21 #define SLV_ADDR_SPACE_SZ 0x10000000
23 #define QCOM_PCIE_2_1_0_MAX_SUPPLY 3
24 +#define QCOM_PCIE_2_1_0_MAX_CLOCKS 5
25 struct qcom_pcie_resources_2_1_0 {
26 - struct clk *iface_clk;
27 - struct clk *core_clk;
28 - struct clk *phy_clk;
29 - struct clk *aux_clk;
30 - struct clk *ref_clk;
31 + struct clk_bulk_data clks[QCOM_PCIE_2_1_0_MAX_CLOCKS];
32 struct reset_control *pci_reset;
33 struct reset_control *axi_reset;
34 struct reset_control *ahb_reset;
35 @@ -244,25 +241,21 @@ static int qcom_pcie_get_resources_2_1_0
39 - res->iface_clk = devm_clk_get(dev, "iface");
40 - if (IS_ERR(res->iface_clk))
41 - return PTR_ERR(res->iface_clk);
43 - res->core_clk = devm_clk_get(dev, "core");
44 - if (IS_ERR(res->core_clk))
45 - return PTR_ERR(res->core_clk);
47 - res->phy_clk = devm_clk_get(dev, "phy");
48 - if (IS_ERR(res->phy_clk))
49 - return PTR_ERR(res->phy_clk);
51 - res->aux_clk = devm_clk_get_optional(dev, "aux");
52 - if (IS_ERR(res->aux_clk))
53 - return PTR_ERR(res->aux_clk);
55 - res->ref_clk = devm_clk_get_optional(dev, "ref");
56 - if (IS_ERR(res->ref_clk))
57 - return PTR_ERR(res->ref_clk);
58 + res->clks[0].id = "iface";
59 + res->clks[1].id = "core";
60 + res->clks[2].id = "phy";
61 + res->clks[3].id = "aux";
62 + res->clks[4].id = "ref";
64 + /* iface, core, phy are required */
65 + ret = devm_clk_bulk_get(dev, 3, res->clks);
69 + /* aux, ref are optional */
70 + ret = devm_clk_bulk_get_optional(dev, 2, res->clks + 3);
74 res->pci_reset = devm_reset_control_get_exclusive(dev, "pci");
75 if (IS_ERR(res->pci_reset))
76 @@ -292,17 +285,13 @@ static void qcom_pcie_deinit_2_1_0(struc
78 struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0;
80 - clk_disable_unprepare(res->phy_clk);
81 + clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
82 reset_control_assert(res->pci_reset);
83 reset_control_assert(res->axi_reset);
84 reset_control_assert(res->ahb_reset);
85 reset_control_assert(res->por_reset);
86 reset_control_assert(res->ext_reset);
87 reset_control_assert(res->phy_reset);
88 - clk_disable_unprepare(res->iface_clk);
89 - clk_disable_unprepare(res->core_clk);
90 - clk_disable_unprepare(res->aux_clk);
91 - clk_disable_unprepare(res->ref_clk);
93 writel(1, pcie->parf + PCIE20_PARF_PHY_CTRL);
95 @@ -334,47 +323,45 @@ static int qcom_pcie_init_2_1_0(struct q
99 - ret = reset_control_assert(res->ahb_reset);
100 + ret = reset_control_deassert(res->ahb_reset);
102 - dev_err(dev, "cannot assert ahb reset\n");
103 - goto err_assert_ahb;
104 + dev_err(dev, "cannot deassert ahb reset\n");
105 + goto err_deassert_ahb;
108 - ret = clk_prepare_enable(res->iface_clk);
109 + ret = reset_control_deassert(res->ext_reset);
111 - dev_err(dev, "cannot prepare/enable iface clock\n");
112 - goto err_assert_ahb;
113 + dev_err(dev, "cannot deassert ext reset\n");
114 + goto err_deassert_ext;
117 - ret = clk_prepare_enable(res->core_clk);
118 + ret = reset_control_deassert(res->phy_reset);
120 - dev_err(dev, "cannot prepare/enable core clock\n");
122 + dev_err(dev, "cannot deassert phy reset\n");
123 + goto err_deassert_phy;
126 - ret = clk_prepare_enable(res->aux_clk);
127 + ret = reset_control_deassert(res->pci_reset);
129 - dev_err(dev, "cannot prepare/enable aux clock\n");
131 + dev_err(dev, "cannot deassert pci reset\n");
132 + goto err_deassert_pci;
135 - ret = clk_prepare_enable(res->ref_clk);
136 + ret = reset_control_deassert(res->por_reset);
138 - dev_err(dev, "cannot prepare/enable ref clock\n");
140 + dev_err(dev, "cannot deassert por reset\n");
141 + goto err_deassert_por;
144 - ret = reset_control_deassert(res->ahb_reset);
145 + ret = reset_control_deassert(res->axi_reset);
147 - dev_err(dev, "cannot deassert ahb reset\n");
148 - goto err_deassert_ahb;
149 + dev_err(dev, "cannot deassert axi reset\n");
150 + goto err_deassert_axi;
153 - ret = reset_control_deassert(res->ext_reset);
155 - dev_err(dev, "cannot deassert ext reset\n");
156 - goto err_deassert_ahb;
158 + ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
162 /* enable PCIe clocks and resets */
163 val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
164 @@ -408,36 +395,6 @@ static int qcom_pcie_init_2_1_0(struct q
165 val |= PHY_REFCLK_SSP_EN;
166 writel(val, pcie->parf + PCIE20_PARF_PHY_REFCLK);
168 - ret = reset_control_deassert(res->phy_reset);
170 - dev_err(dev, "cannot deassert phy reset\n");
174 - ret = reset_control_deassert(res->pci_reset);
176 - dev_err(dev, "cannot deassert pci reset\n");
180 - ret = reset_control_deassert(res->por_reset);
182 - dev_err(dev, "cannot deassert por reset\n");
186 - ret = reset_control_deassert(res->axi_reset);
188 - dev_err(dev, "cannot deassert axi reset\n");
192 - ret = clk_prepare_enable(res->phy_clk);
194 - dev_err(dev, "cannot prepare/enable phy clock\n");
195 - goto err_deassert_ahb;
198 /* wait for clock acquisition */
199 usleep_range(1000, 1500);
201 @@ -450,15 +407,19 @@ static int qcom_pcie_init_2_1_0(struct q
206 + reset_control_assert(res->axi_reset);
208 + reset_control_assert(res->por_reset);
210 + reset_control_assert(res->pci_reset);
212 + reset_control_assert(res->phy_reset);
214 + reset_control_assert(res->ext_reset);
216 + reset_control_assert(res->ahb_reset);
218 - clk_disable_unprepare(res->ref_clk);
220 - clk_disable_unprepare(res->aux_clk);
222 - clk_disable_unprepare(res->core_clk);
224 - clk_disable_unprepare(res->iface_clk);
226 regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);