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 @@ -226,25 +223,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 @@ -274,17 +267,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);
92 regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
95 @@ -302,36 +291,6 @@ static int qcom_pcie_init_2_1_0(struct q
99 - ret = reset_control_assert(res->ahb_reset);
101 - dev_err(dev, "cannot assert ahb reset\n");
102 - goto err_assert_ahb;
105 - ret = clk_prepare_enable(res->iface_clk);
107 - dev_err(dev, "cannot prepare/enable iface clock\n");
108 - goto err_assert_ahb;
111 - ret = clk_prepare_enable(res->core_clk);
113 - dev_err(dev, "cannot prepare/enable core clock\n");
117 - ret = clk_prepare_enable(res->aux_clk);
119 - dev_err(dev, "cannot prepare/enable aux clock\n");
123 - ret = clk_prepare_enable(res->ref_clk);
125 - dev_err(dev, "cannot prepare/enable ref clock\n");
129 ret = reset_control_deassert(res->ahb_reset);
131 dev_err(dev, "cannot deassert ahb reset\n");
132 @@ -341,48 +300,46 @@ static int qcom_pcie_init_2_1_0(struct q
133 ret = reset_control_deassert(res->ext_reset);
135 dev_err(dev, "cannot deassert ext reset\n");
136 - goto err_deassert_ahb;
137 + goto err_deassert_ext;
140 - /* enable PCIe clocks and resets */
141 - val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
143 - writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
145 - /* enable external reference clock */
146 - val = readl(pcie->parf + PCIE20_PARF_PHY_REFCLK);
148 - writel(val, pcie->parf + PCIE20_PARF_PHY_REFCLK);
150 ret = reset_control_deassert(res->phy_reset);
152 dev_err(dev, "cannot deassert phy reset\n");
154 + goto err_deassert_phy;
157 ret = reset_control_deassert(res->pci_reset);
159 dev_err(dev, "cannot deassert pci reset\n");
161 + goto err_deassert_pci;
164 ret = reset_control_deassert(res->por_reset);
166 dev_err(dev, "cannot deassert por reset\n");
168 + goto err_deassert_por;
171 ret = reset_control_deassert(res->axi_reset);
173 dev_err(dev, "cannot deassert axi reset\n");
175 + goto err_deassert_axi;
178 - ret = clk_prepare_enable(res->phy_clk);
180 - dev_err(dev, "cannot prepare/enable phy clock\n");
181 - goto err_deassert_ahb;
183 + ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
187 + /* enable PCIe clocks and resets */
188 + val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
190 + writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
192 + /* enable external reference clock */
193 + val = readl(pcie->parf + PCIE20_PARF_PHY_REFCLK);
195 + writel(val, pcie->parf + PCIE20_PARF_PHY_REFCLK);
197 /* wait for clock acquisition */
198 usleep_range(1000, 1500);
199 @@ -396,15 +353,19 @@ static int qcom_pcie_init_2_1_0(struct q
204 + reset_control_assert(res->axi_reset);
206 + reset_control_assert(res->por_reset);
208 + reset_control_assert(res->pci_reset);
210 + reset_control_assert(res->phy_reset);
212 + reset_control_assert(res->ext_reset);
214 + reset_control_assert(res->ahb_reset);
216 - clk_disable_unprepare(res->ref_clk);
218 - clk_disable_unprepare(res->aux_clk);
220 - clk_disable_unprepare(res->core_clk);
222 - clk_disable_unprepare(res->iface_clk);
224 regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);