ecfcd746930a0fff91de5c9ba7c35f84617d03a9
[openwrt/staging/chunkeey.git] /
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
5
6 Rework 2.1.0 revision to use bulk clk api and fix missing assert on
7 reset_control_deassert error.
8
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>
14 ---
15 drivers/pci/controller/dwc/pcie-qcom.c | 131 ++++++++++++---------------------
16 1 file changed, 46 insertions(+), 85 deletions(-)
17
18 --- a/drivers/pci/controller/dwc/pcie-qcom.c
19 +++ b/drivers/pci/controller/dwc/pcie-qcom.c
20 @@ -99,12 +99,9 @@
21 #define SLV_ADDR_SPACE_SZ 0x10000000
22
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
36 if (ret)
37 return ret;
38
39 - res->iface_clk = devm_clk_get(dev, "iface");
40 - if (IS_ERR(res->iface_clk))
41 - return PTR_ERR(res->iface_clk);
42 -
43 - res->core_clk = devm_clk_get(dev, "core");
44 - if (IS_ERR(res->core_clk))
45 - return PTR_ERR(res->core_clk);
46 -
47 - res->phy_clk = devm_clk_get(dev, "phy");
48 - if (IS_ERR(res->phy_clk))
49 - return PTR_ERR(res->phy_clk);
50 -
51 - res->aux_clk = devm_clk_get_optional(dev, "aux");
52 - if (IS_ERR(res->aux_clk))
53 - return PTR_ERR(res->aux_clk);
54 -
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";
63 +
64 + /* iface, core, phy are required */
65 + ret = devm_clk_bulk_get(dev, 3, res->clks);
66 + if (ret < 0)
67 + return ret;
68 +
69 + /* aux, ref are optional */
70 + ret = devm_clk_bulk_get_optional(dev, 2, res->clks + 3);
71 + if (ret < 0)
72 + return ret;
73
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
77 {
78 struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0;
79
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);
92
93 writel(1, pcie->parf + PCIE20_PARF_PHY_CTRL);
94
95 @@ -334,47 +323,45 @@ static int qcom_pcie_init_2_1_0(struct q
96 return ret;
97 }
98
99 - ret = reset_control_assert(res->ahb_reset);
100 + ret = reset_control_deassert(res->ahb_reset);
101 if (ret) {
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;
106 }
107
108 - ret = clk_prepare_enable(res->iface_clk);
109 + ret = reset_control_deassert(res->ext_reset);
110 if (ret) {
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;
115 }
116
117 - ret = clk_prepare_enable(res->core_clk);
118 + ret = reset_control_deassert(res->phy_reset);
119 if (ret) {
120 - dev_err(dev, "cannot prepare/enable core clock\n");
121 - goto err_clk_core;
122 + dev_err(dev, "cannot deassert phy reset\n");
123 + goto err_deassert_phy;
124 }
125
126 - ret = clk_prepare_enable(res->aux_clk);
127 + ret = reset_control_deassert(res->pci_reset);
128 if (ret) {
129 - dev_err(dev, "cannot prepare/enable aux clock\n");
130 - goto err_clk_aux;
131 + dev_err(dev, "cannot deassert pci reset\n");
132 + goto err_deassert_pci;
133 }
134
135 - ret = clk_prepare_enable(res->ref_clk);
136 + ret = reset_control_deassert(res->por_reset);
137 if (ret) {
138 - dev_err(dev, "cannot prepare/enable ref clock\n");
139 - goto err_clk_ref;
140 + dev_err(dev, "cannot deassert por reset\n");
141 + goto err_deassert_por;
142 }
143
144 - ret = reset_control_deassert(res->ahb_reset);
145 + ret = reset_control_deassert(res->axi_reset);
146 if (ret) {
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;
151 }
152
153 - ret = reset_control_deassert(res->ext_reset);
154 - if (ret) {
155 - dev_err(dev, "cannot deassert ext reset\n");
156 - goto err_deassert_ahb;
157 - }
158 + ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
159 + if (ret)
160 + goto err_clks;
161
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);
167
168 - ret = reset_control_deassert(res->phy_reset);
169 - if (ret) {
170 - dev_err(dev, "cannot deassert phy reset\n");
171 - return ret;
172 - }
173 -
174 - ret = reset_control_deassert(res->pci_reset);
175 - if (ret) {
176 - dev_err(dev, "cannot deassert pci reset\n");
177 - return ret;
178 - }
179 -
180 - ret = reset_control_deassert(res->por_reset);
181 - if (ret) {
182 - dev_err(dev, "cannot deassert por reset\n");
183 - return ret;
184 - }
185 -
186 - ret = reset_control_deassert(res->axi_reset);
187 - if (ret) {
188 - dev_err(dev, "cannot deassert axi reset\n");
189 - return ret;
190 - }
191 -
192 - ret = clk_prepare_enable(res->phy_clk);
193 - if (ret) {
194 - dev_err(dev, "cannot prepare/enable phy clock\n");
195 - goto err_deassert_ahb;
196 - }
197 -
198 /* wait for clock acquisition */
199 usleep_range(1000, 1500);
200
201 @@ -450,15 +407,19 @@ static int qcom_pcie_init_2_1_0(struct q
202
203 return 0;
204
205 +err_clks:
206 + reset_control_assert(res->axi_reset);
207 +err_deassert_axi:
208 + reset_control_assert(res->por_reset);
209 +err_deassert_por:
210 + reset_control_assert(res->pci_reset);
211 +err_deassert_pci:
212 + reset_control_assert(res->phy_reset);
213 +err_deassert_phy:
214 + reset_control_assert(res->ext_reset);
215 +err_deassert_ext:
216 + reset_control_assert(res->ahb_reset);
217 err_deassert_ahb:
218 - clk_disable_unprepare(res->ref_clk);
219 -err_clk_ref:
220 - clk_disable_unprepare(res->aux_clk);
221 -err_clk_aux:
222 - clk_disable_unprepare(res->core_clk);
223 -err_clk_core:
224 - clk_disable_unprepare(res->iface_clk);
225 -err_assert_ahb:
226 regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
227
228 return ret;