Linux 6.9-rc1
[linux-2.6-microblaze.git] / drivers / pci / controller / dwc / pcie-dw-rockchip.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * PCIe host controller driver for Rockchip SoCs.
4  *
5  * Copyright (C) 2021 Rockchip Electronics Co., Ltd.
6  *              http://www.rock-chips.com
7  *
8  * Author: Simon Xue <xxm@rock-chips.com>
9  */
10
11 #include <linux/clk.h>
12 #include <linux/gpio/consumer.h>
13 #include <linux/irqchip/chained_irq.h>
14 #include <linux/irqdomain.h>
15 #include <linux/mfd/syscon.h>
16 #include <linux/module.h>
17 #include <linux/of.h>
18 #include <linux/of_irq.h>
19 #include <linux/phy/phy.h>
20 #include <linux/platform_device.h>
21 #include <linux/regmap.h>
22 #include <linux/reset.h>
23
24 #include "pcie-designware.h"
25
26 /*
27  * The upper 16 bits of PCIE_CLIENT_CONFIG are a write
28  * mask for the lower 16 bits.
29  */
30 #define HIWORD_UPDATE(mask, val) (((mask) << 16) | (val))
31 #define HIWORD_UPDATE_BIT(val)  HIWORD_UPDATE(val, val)
32 #define HIWORD_DISABLE_BIT(val) HIWORD_UPDATE(val, ~val)
33
34 #define to_rockchip_pcie(x) dev_get_drvdata((x)->dev)
35
36 #define PCIE_CLIENT_RC_MODE             HIWORD_UPDATE_BIT(0x40)
37 #define PCIE_CLIENT_ENABLE_LTSSM        HIWORD_UPDATE_BIT(0xc)
38 #define PCIE_SMLH_LINKUP                BIT(16)
39 #define PCIE_RDLH_LINKUP                BIT(17)
40 #define PCIE_LINKUP                     (PCIE_SMLH_LINKUP | PCIE_RDLH_LINKUP)
41 #define PCIE_L0S_ENTRY                  0x11
42 #define PCIE_CLIENT_GENERAL_CONTROL     0x0
43 #define PCIE_CLIENT_INTR_STATUS_LEGACY  0x8
44 #define PCIE_CLIENT_INTR_MASK_LEGACY    0x1c
45 #define PCIE_CLIENT_GENERAL_DEBUG       0x104
46 #define PCIE_CLIENT_HOT_RESET_CTRL      0x180
47 #define PCIE_CLIENT_LTSSM_STATUS        0x300
48 #define PCIE_LTSSM_ENABLE_ENHANCE       BIT(4)
49 #define PCIE_LTSSM_STATUS_MASK          GENMASK(5, 0)
50
51 struct rockchip_pcie {
52         struct dw_pcie                  pci;
53         void __iomem                    *apb_base;
54         struct phy                      *phy;
55         struct clk_bulk_data            *clks;
56         unsigned int                    clk_cnt;
57         struct reset_control            *rst;
58         struct gpio_desc                *rst_gpio;
59         struct regulator                *vpcie3v3;
60         struct irq_domain               *irq_domain;
61 };
62
63 static int rockchip_pcie_readl_apb(struct rockchip_pcie *rockchip,
64                                              u32 reg)
65 {
66         return readl_relaxed(rockchip->apb_base + reg);
67 }
68
69 static void rockchip_pcie_writel_apb(struct rockchip_pcie *rockchip,
70                                                 u32 val, u32 reg)
71 {
72         writel_relaxed(val, rockchip->apb_base + reg);
73 }
74
75 static void rockchip_pcie_intx_handler(struct irq_desc *desc)
76 {
77         struct irq_chip *chip = irq_desc_get_chip(desc);
78         struct rockchip_pcie *rockchip = irq_desc_get_handler_data(desc);
79         unsigned long reg, hwirq;
80
81         chained_irq_enter(chip, desc);
82
83         reg = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_INTR_STATUS_LEGACY);
84
85         for_each_set_bit(hwirq, &reg, 4)
86                 generic_handle_domain_irq(rockchip->irq_domain, hwirq);
87
88         chained_irq_exit(chip, desc);
89 }
90
91 static void rockchip_intx_mask(struct irq_data *data)
92 {
93         rockchip_pcie_writel_apb(irq_data_get_irq_chip_data(data),
94                                  HIWORD_UPDATE_BIT(BIT(data->hwirq)),
95                                  PCIE_CLIENT_INTR_MASK_LEGACY);
96 };
97
98 static void rockchip_intx_unmask(struct irq_data *data)
99 {
100         rockchip_pcie_writel_apb(irq_data_get_irq_chip_data(data),
101                                  HIWORD_DISABLE_BIT(BIT(data->hwirq)),
102                                  PCIE_CLIENT_INTR_MASK_LEGACY);
103 };
104
105 static struct irq_chip rockchip_intx_irq_chip = {
106         .name                   = "INTx",
107         .irq_mask               = rockchip_intx_mask,
108         .irq_unmask             = rockchip_intx_unmask,
109         .flags                  = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND,
110 };
111
112 static int rockchip_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
113                                   irq_hw_number_t hwirq)
114 {
115         irq_set_chip_and_handler(irq, &rockchip_intx_irq_chip, handle_level_irq);
116         irq_set_chip_data(irq, domain->host_data);
117
118         return 0;
119 }
120
121 static const struct irq_domain_ops intx_domain_ops = {
122         .map = rockchip_pcie_intx_map,
123 };
124
125 static int rockchip_pcie_init_irq_domain(struct rockchip_pcie *rockchip)
126 {
127         struct device *dev = rockchip->pci.dev;
128         struct device_node *intc;
129
130         intc = of_get_child_by_name(dev->of_node, "legacy-interrupt-controller");
131         if (!intc) {
132                 dev_err(dev, "missing child interrupt-controller node\n");
133                 return -EINVAL;
134         }
135
136         rockchip->irq_domain = irq_domain_add_linear(intc, PCI_NUM_INTX,
137                                                     &intx_domain_ops, rockchip);
138         of_node_put(intc);
139         if (!rockchip->irq_domain) {
140                 dev_err(dev, "failed to get a INTx IRQ domain\n");
141                 return -EINVAL;
142         }
143
144         return 0;
145 }
146
147 static void rockchip_pcie_enable_ltssm(struct rockchip_pcie *rockchip)
148 {
149         rockchip_pcie_writel_apb(rockchip, PCIE_CLIENT_ENABLE_LTSSM,
150                                  PCIE_CLIENT_GENERAL_CONTROL);
151 }
152
153 static int rockchip_pcie_link_up(struct dw_pcie *pci)
154 {
155         struct rockchip_pcie *rockchip = to_rockchip_pcie(pci);
156         u32 val = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_LTSSM_STATUS);
157
158         if ((val & PCIE_LINKUP) == PCIE_LINKUP &&
159             (val & PCIE_LTSSM_STATUS_MASK) == PCIE_L0S_ENTRY)
160                 return 1;
161
162         return 0;
163 }
164
165 static int rockchip_pcie_start_link(struct dw_pcie *pci)
166 {
167         struct rockchip_pcie *rockchip = to_rockchip_pcie(pci);
168
169         /* Reset device */
170         gpiod_set_value_cansleep(rockchip->rst_gpio, 0);
171
172         rockchip_pcie_enable_ltssm(rockchip);
173
174         /*
175          * PCIe requires the refclk to be stable for 100µs prior to releasing
176          * PERST. See table 2-4 in section 2.6.2 AC Specifications of the PCI
177          * Express Card Electromechanical Specification, 1.1. However, we don't
178          * know if the refclk is coming from RC's PHY or external OSC. If it's
179          * from RC, so enabling LTSSM is the just right place to release #PERST.
180          * We need more extra time as before, rather than setting just
181          * 100us as we don't know how long should the device need to reset.
182          */
183         msleep(100);
184         gpiod_set_value_cansleep(rockchip->rst_gpio, 1);
185
186         return 0;
187 }
188
189 static int rockchip_pcie_host_init(struct dw_pcie_rp *pp)
190 {
191         struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
192         struct rockchip_pcie *rockchip = to_rockchip_pcie(pci);
193         struct device *dev = rockchip->pci.dev;
194         u32 val = HIWORD_UPDATE_BIT(PCIE_LTSSM_ENABLE_ENHANCE);
195         int irq, ret;
196
197         irq = of_irq_get_byname(dev->of_node, "legacy");
198         if (irq < 0)
199                 return irq;
200
201         ret = rockchip_pcie_init_irq_domain(rockchip);
202         if (ret < 0)
203                 dev_err(dev, "failed to init irq domain\n");
204
205         irq_set_chained_handler_and_data(irq, rockchip_pcie_intx_handler,
206                                          rockchip);
207
208         /* LTSSM enable control mode */
209         rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_HOT_RESET_CTRL);
210
211         rockchip_pcie_writel_apb(rockchip, PCIE_CLIENT_RC_MODE,
212                                  PCIE_CLIENT_GENERAL_CONTROL);
213
214         return 0;
215 }
216
217 static const struct dw_pcie_host_ops rockchip_pcie_host_ops = {
218         .init = rockchip_pcie_host_init,
219 };
220
221 static int rockchip_pcie_clk_init(struct rockchip_pcie *rockchip)
222 {
223         struct device *dev = rockchip->pci.dev;
224         int ret;
225
226         ret = devm_clk_bulk_get_all(dev, &rockchip->clks);
227         if (ret < 0)
228                 return ret;
229
230         rockchip->clk_cnt = ret;
231
232         return clk_bulk_prepare_enable(rockchip->clk_cnt, rockchip->clks);
233 }
234
235 static int rockchip_pcie_resource_get(struct platform_device *pdev,
236                                       struct rockchip_pcie *rockchip)
237 {
238         rockchip->apb_base = devm_platform_ioremap_resource_byname(pdev, "apb");
239         if (IS_ERR(rockchip->apb_base))
240                 return PTR_ERR(rockchip->apb_base);
241
242         rockchip->rst_gpio = devm_gpiod_get_optional(&pdev->dev, "reset",
243                                                      GPIOD_OUT_HIGH);
244         if (IS_ERR(rockchip->rst_gpio))
245                 return PTR_ERR(rockchip->rst_gpio);
246
247         rockchip->rst = devm_reset_control_array_get_exclusive(&pdev->dev);
248         if (IS_ERR(rockchip->rst))
249                 return dev_err_probe(&pdev->dev, PTR_ERR(rockchip->rst),
250                                      "failed to get reset lines\n");
251
252         return 0;
253 }
254
255 static int rockchip_pcie_phy_init(struct rockchip_pcie *rockchip)
256 {
257         struct device *dev = rockchip->pci.dev;
258         int ret;
259
260         rockchip->phy = devm_phy_get(dev, "pcie-phy");
261         if (IS_ERR(rockchip->phy))
262                 return dev_err_probe(dev, PTR_ERR(rockchip->phy),
263                                      "missing PHY\n");
264
265         ret = phy_init(rockchip->phy);
266         if (ret < 0)
267                 return ret;
268
269         ret = phy_power_on(rockchip->phy);
270         if (ret)
271                 phy_exit(rockchip->phy);
272
273         return ret;
274 }
275
276 static void rockchip_pcie_phy_deinit(struct rockchip_pcie *rockchip)
277 {
278         phy_exit(rockchip->phy);
279         phy_power_off(rockchip->phy);
280 }
281
282 static const struct dw_pcie_ops dw_pcie_ops = {
283         .link_up = rockchip_pcie_link_up,
284         .start_link = rockchip_pcie_start_link,
285 };
286
287 static int rockchip_pcie_probe(struct platform_device *pdev)
288 {
289         struct device *dev = &pdev->dev;
290         struct rockchip_pcie *rockchip;
291         struct dw_pcie_rp *pp;
292         int ret;
293
294         rockchip = devm_kzalloc(dev, sizeof(*rockchip), GFP_KERNEL);
295         if (!rockchip)
296                 return -ENOMEM;
297
298         platform_set_drvdata(pdev, rockchip);
299
300         rockchip->pci.dev = dev;
301         rockchip->pci.ops = &dw_pcie_ops;
302
303         pp = &rockchip->pci.pp;
304         pp->ops = &rockchip_pcie_host_ops;
305
306         ret = rockchip_pcie_resource_get(pdev, rockchip);
307         if (ret)
308                 return ret;
309
310         ret = reset_control_assert(rockchip->rst);
311         if (ret)
312                 return ret;
313
314         /* DON'T MOVE ME: must be enable before PHY init */
315         rockchip->vpcie3v3 = devm_regulator_get_optional(dev, "vpcie3v3");
316         if (IS_ERR(rockchip->vpcie3v3)) {
317                 if (PTR_ERR(rockchip->vpcie3v3) != -ENODEV)
318                         return dev_err_probe(dev, PTR_ERR(rockchip->vpcie3v3),
319                                         "failed to get vpcie3v3 regulator\n");
320                 rockchip->vpcie3v3 = NULL;
321         } else {
322                 ret = regulator_enable(rockchip->vpcie3v3);
323                 if (ret) {
324                         dev_err(dev, "failed to enable vpcie3v3 regulator\n");
325                         return ret;
326                 }
327         }
328
329         ret = rockchip_pcie_phy_init(rockchip);
330         if (ret)
331                 goto disable_regulator;
332
333         ret = reset_control_deassert(rockchip->rst);
334         if (ret)
335                 goto deinit_phy;
336
337         ret = rockchip_pcie_clk_init(rockchip);
338         if (ret)
339                 goto deinit_phy;
340
341         ret = dw_pcie_host_init(pp);
342         if (!ret)
343                 return 0;
344
345         clk_bulk_disable_unprepare(rockchip->clk_cnt, rockchip->clks);
346 deinit_phy:
347         rockchip_pcie_phy_deinit(rockchip);
348 disable_regulator:
349         if (rockchip->vpcie3v3)
350                 regulator_disable(rockchip->vpcie3v3);
351
352         return ret;
353 }
354
355 static const struct of_device_id rockchip_pcie_of_match[] = {
356         { .compatible = "rockchip,rk3568-pcie", },
357         {},
358 };
359
360 static struct platform_driver rockchip_pcie_driver = {
361         .driver = {
362                 .name   = "rockchip-dw-pcie",
363                 .of_match_table = rockchip_pcie_of_match,
364                 .suppress_bind_attrs = true,
365         },
366         .probe = rockchip_pcie_probe,
367 };
368 builtin_platform_driver(rockchip_pcie_driver);