xref: /linux/drivers/pci/controller/dwc/pcie-dw-rockchip.c (revision 8c994eff8fcfe8ecb1f1dbebed25b4d7bb75be12)
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_legacy_int_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_legacy_int_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 	.host_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);
369