xref: /linux/drivers/pci/controller/dwc/pcie-artpec6.c (revision 7db28abbea0f7dc1ec4fdfdc149db5fbd9e4c994)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * PCIe host controller driver for Axis ARTPEC-6 SoC
4  *
5  * Author: Niklas Cassel <niklas.cassel@axis.com>
6  *
7  * Based on work done by Phil Edworthy <phil@edworthys.org>
8  */
9 
10 #include <linux/delay.h>
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/of.h>
14 #include <linux/pci.h>
15 #include <linux/platform_device.h>
16 #include <linux/resource.h>
17 #include <linux/signal.h>
18 #include <linux/types.h>
19 #include <linux/interrupt.h>
20 #include <linux/mfd/syscon.h>
21 #include <linux/regmap.h>
22 
23 #include "pcie-designware.h"
24 
25 #define to_artpec6_pcie(x)	dev_get_drvdata((x)->dev)
26 
27 enum artpec_pcie_variants {
28 	ARTPEC6,
29 	ARTPEC7,
30 };
31 
32 struct artpec6_pcie {
33 	struct dw_pcie		*pci;
34 	struct regmap		*regmap;	/* DT axis,syscon-pcie */
35 	void __iomem		*phy_base;	/* DT phy */
36 	enum artpec_pcie_variants variant;
37 };
38 
39 struct artpec_pcie_of_data {
40 	enum artpec_pcie_variants variant;
41 	enum dw_pcie_device_mode mode;
42 };
43 
44 static const struct of_device_id artpec6_pcie_of_match[];
45 
46 /* ARTPEC-6 specific registers */
47 #define PCIECFG				0x18
48 #define  PCIECFG_DBG_OEN		BIT(24)
49 #define  PCIECFG_CORE_RESET_REQ		BIT(21)
50 #define  PCIECFG_LTSSM_ENABLE		BIT(20)
51 #define  PCIECFG_DEVICE_TYPE_MASK	GENMASK(19, 16)
52 #define  PCIECFG_CLKREQ_B		BIT(11)
53 #define  PCIECFG_REFCLK_ENABLE		BIT(10)
54 #define  PCIECFG_PLL_ENABLE		BIT(9)
55 #define  PCIECFG_PCLK_ENABLE		BIT(8)
56 #define  PCIECFG_RISRCREN		BIT(4)
57 #define  PCIECFG_MODE_TX_DRV_EN		BIT(3)
58 #define  PCIECFG_CISRREN		BIT(2)
59 #define  PCIECFG_MACRO_ENABLE		BIT(0)
60 /* ARTPEC-7 specific fields */
61 #define  PCIECFG_REFCLKSEL		BIT(23)
62 #define  PCIECFG_NOC_RESET		BIT(3)
63 
64 #define PCIESTAT			0x1c
65 /* ARTPEC-7 specific fields */
66 #define  PCIESTAT_EXTREFCLK		BIT(3)
67 
68 #define NOCCFG				0x40
69 #define  NOCCFG_ENABLE_CLK_PCIE		BIT(4)
70 #define  NOCCFG_POWER_PCIE_IDLEACK	BIT(3)
71 #define  NOCCFG_POWER_PCIE_IDLE		BIT(2)
72 #define  NOCCFG_POWER_PCIE_IDLEREQ	BIT(1)
73 
74 #define PHY_STATUS			0x118
75 #define  PHY_COSPLLLOCK			BIT(0)
76 
77 #define PHY_TX_ASIC_OUT			0x4040
78 #define  PHY_TX_ASIC_OUT_TX_ACK		BIT(0)
79 
80 #define PHY_RX_ASIC_OUT			0x405c
81 #define  PHY_RX_ASIC_OUT_ACK		BIT(0)
82 
83 static u32 artpec6_pcie_readl(struct artpec6_pcie *artpec6_pcie, u32 offset)
84 {
85 	u32 val;
86 
87 	regmap_read(artpec6_pcie->regmap, offset, &val);
88 	return val;
89 }
90 
91 static void artpec6_pcie_writel(struct artpec6_pcie *artpec6_pcie, u32 offset, u32 val)
92 {
93 	regmap_write(artpec6_pcie->regmap, offset, val);
94 }
95 
96 static u64 artpec6_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 cpu_addr)
97 {
98 	struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
99 	struct dw_pcie_rp *pp = &pci->pp;
100 	struct dw_pcie_ep *ep = &pci->ep;
101 
102 	switch (artpec6_pcie->pci->mode) {
103 	case DW_PCIE_RC_TYPE:
104 		return cpu_addr - pp->cfg0_base;
105 	case DW_PCIE_EP_TYPE:
106 		return cpu_addr - ep->phys_base;
107 	default:
108 		dev_err(pci->dev, "UNKNOWN device type\n");
109 	}
110 	return cpu_addr;
111 }
112 
113 static int artpec6_pcie_establish_link(struct dw_pcie *pci)
114 {
115 	struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
116 	u32 val;
117 
118 	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
119 	val |= PCIECFG_LTSSM_ENABLE;
120 	artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
121 
122 	return 0;
123 }
124 
125 static void artpec6_pcie_stop_link(struct dw_pcie *pci)
126 {
127 	struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
128 	u32 val;
129 
130 	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
131 	val &= ~PCIECFG_LTSSM_ENABLE;
132 	artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
133 }
134 
135 static const struct dw_pcie_ops dw_pcie_ops = {
136 	.cpu_addr_fixup = artpec6_pcie_cpu_addr_fixup,
137 	.start_link = artpec6_pcie_establish_link,
138 	.stop_link = artpec6_pcie_stop_link,
139 };
140 
141 static void artpec6_pcie_wait_for_phy_a6(struct artpec6_pcie *artpec6_pcie)
142 {
143 	struct dw_pcie *pci = artpec6_pcie->pci;
144 	struct device *dev = pci->dev;
145 	u32 val;
146 	unsigned int retries;
147 
148 	retries = 50;
149 	do {
150 		usleep_range(1000, 2000);
151 		val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
152 		retries--;
153 	} while (retries &&
154 		(val & (NOCCFG_POWER_PCIE_IDLEACK | NOCCFG_POWER_PCIE_IDLE)));
155 	if (!retries)
156 		dev_err(dev, "PCIe clock manager did not leave idle state\n");
157 
158 	retries = 50;
159 	do {
160 		usleep_range(1000, 2000);
161 		val = readl(artpec6_pcie->phy_base + PHY_STATUS);
162 		retries--;
163 	} while (retries && !(val & PHY_COSPLLLOCK));
164 	if (!retries)
165 		dev_err(dev, "PHY PLL did not lock\n");
166 }
167 
168 static void artpec6_pcie_wait_for_phy_a7(struct artpec6_pcie *artpec6_pcie)
169 {
170 	struct dw_pcie *pci = artpec6_pcie->pci;
171 	struct device *dev = pci->dev;
172 	u32 val;
173 	u16 phy_status_tx, phy_status_rx;
174 	unsigned int retries;
175 
176 	retries = 50;
177 	do {
178 		usleep_range(1000, 2000);
179 		val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
180 		retries--;
181 	} while (retries &&
182 		(val & (NOCCFG_POWER_PCIE_IDLEACK | NOCCFG_POWER_PCIE_IDLE)));
183 	if (!retries)
184 		dev_err(dev, "PCIe clock manager did not leave idle state\n");
185 
186 	retries = 50;
187 	do {
188 		usleep_range(1000, 2000);
189 		phy_status_tx = readw(artpec6_pcie->phy_base + PHY_TX_ASIC_OUT);
190 		phy_status_rx = readw(artpec6_pcie->phy_base + PHY_RX_ASIC_OUT);
191 		retries--;
192 	} while (retries && ((phy_status_tx & PHY_TX_ASIC_OUT_TX_ACK) ||
193 				(phy_status_rx & PHY_RX_ASIC_OUT_ACK)));
194 	if (!retries)
195 		dev_err(dev, "PHY did not enter Pn state\n");
196 }
197 
198 static void artpec6_pcie_wait_for_phy(struct artpec6_pcie *artpec6_pcie)
199 {
200 	switch (artpec6_pcie->variant) {
201 	case ARTPEC6:
202 		artpec6_pcie_wait_for_phy_a6(artpec6_pcie);
203 		break;
204 	case ARTPEC7:
205 		artpec6_pcie_wait_for_phy_a7(artpec6_pcie);
206 		break;
207 	}
208 }
209 
210 static void artpec6_pcie_init_phy_a6(struct artpec6_pcie *artpec6_pcie)
211 {
212 	u32 val;
213 
214 	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
215 	val |=  PCIECFG_RISRCREN |	/* Receiver term. 50 Ohm */
216 		PCIECFG_MODE_TX_DRV_EN |
217 		PCIECFG_CISRREN |	/* Reference clock term. 100 Ohm */
218 		PCIECFG_MACRO_ENABLE;
219 	val |= PCIECFG_REFCLK_ENABLE;
220 	val &= ~PCIECFG_DBG_OEN;
221 	val &= ~PCIECFG_CLKREQ_B;
222 	artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
223 	usleep_range(5000, 6000);
224 
225 	val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
226 	val |= NOCCFG_ENABLE_CLK_PCIE;
227 	artpec6_pcie_writel(artpec6_pcie, NOCCFG, val);
228 	usleep_range(20, 30);
229 
230 	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
231 	val |= PCIECFG_PCLK_ENABLE | PCIECFG_PLL_ENABLE;
232 	artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
233 	usleep_range(6000, 7000);
234 
235 	val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
236 	val &= ~NOCCFG_POWER_PCIE_IDLEREQ;
237 	artpec6_pcie_writel(artpec6_pcie, NOCCFG, val);
238 }
239 
240 static void artpec6_pcie_init_phy_a7(struct artpec6_pcie *artpec6_pcie)
241 {
242 	struct dw_pcie *pci = artpec6_pcie->pci;
243 	u32 val;
244 	bool extrefclk;
245 
246 	/* Check if external reference clock is connected */
247 	val = artpec6_pcie_readl(artpec6_pcie, PCIESTAT);
248 	extrefclk = !!(val & PCIESTAT_EXTREFCLK);
249 	dev_dbg(pci->dev, "Using reference clock: %s\n",
250 		extrefclk ? "external" : "internal");
251 
252 	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
253 	val |=  PCIECFG_RISRCREN |	/* Receiver term. 50 Ohm */
254 		PCIECFG_PCLK_ENABLE;
255 	if (extrefclk)
256 		val |= PCIECFG_REFCLKSEL;
257 	else
258 		val &= ~PCIECFG_REFCLKSEL;
259 	artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
260 	usleep_range(10, 20);
261 
262 	val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
263 	val |= NOCCFG_ENABLE_CLK_PCIE;
264 	artpec6_pcie_writel(artpec6_pcie, NOCCFG, val);
265 	usleep_range(20, 30);
266 
267 	val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
268 	val &= ~NOCCFG_POWER_PCIE_IDLEREQ;
269 	artpec6_pcie_writel(artpec6_pcie, NOCCFG, val);
270 }
271 
272 static void artpec6_pcie_init_phy(struct artpec6_pcie *artpec6_pcie)
273 {
274 	switch (artpec6_pcie->variant) {
275 	case ARTPEC6:
276 		artpec6_pcie_init_phy_a6(artpec6_pcie);
277 		break;
278 	case ARTPEC7:
279 		artpec6_pcie_init_phy_a7(artpec6_pcie);
280 		break;
281 	}
282 }
283 
284 static void artpec6_pcie_assert_core_reset(struct artpec6_pcie *artpec6_pcie)
285 {
286 	u32 val;
287 
288 	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
289 	switch (artpec6_pcie->variant) {
290 	case ARTPEC6:
291 		val |= PCIECFG_CORE_RESET_REQ;
292 		break;
293 	case ARTPEC7:
294 		val &= ~PCIECFG_NOC_RESET;
295 		break;
296 	}
297 	artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
298 }
299 
300 static void artpec6_pcie_deassert_core_reset(struct artpec6_pcie *artpec6_pcie)
301 {
302 	u32 val;
303 
304 	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
305 	switch (artpec6_pcie->variant) {
306 	case ARTPEC6:
307 		val &= ~PCIECFG_CORE_RESET_REQ;
308 		break;
309 	case ARTPEC7:
310 		val |= PCIECFG_NOC_RESET;
311 		break;
312 	}
313 	artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
314 	usleep_range(100, 200);
315 }
316 
317 static int artpec6_pcie_host_init(struct dw_pcie_rp *pp)
318 {
319 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
320 	struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
321 
322 	if (artpec6_pcie->variant == ARTPEC7) {
323 		pci->n_fts[0] = 180;
324 		pci->n_fts[1] = 180;
325 	}
326 	artpec6_pcie_assert_core_reset(artpec6_pcie);
327 	artpec6_pcie_init_phy(artpec6_pcie);
328 	artpec6_pcie_deassert_core_reset(artpec6_pcie);
329 	artpec6_pcie_wait_for_phy(artpec6_pcie);
330 
331 	return 0;
332 }
333 
334 static const struct dw_pcie_host_ops artpec6_pcie_host_ops = {
335 	.init = artpec6_pcie_host_init,
336 };
337 
338 static int artpec6_pcie_ep_init(struct dw_pcie_ep *ep)
339 {
340 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
341 	struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
342 
343 	artpec6_pcie_assert_core_reset(artpec6_pcie);
344 	artpec6_pcie_init_phy(artpec6_pcie);
345 	artpec6_pcie_deassert_core_reset(artpec6_pcie);
346 	artpec6_pcie_wait_for_phy(artpec6_pcie);
347 
348 	return 0;
349 }
350 
351 static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
352 				  unsigned int type, u16 interrupt_num)
353 {
354 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
355 
356 	switch (type) {
357 	case PCI_IRQ_INTX:
358 		dev_err(pci->dev, "EP cannot trigger INTx IRQs\n");
359 		return -EINVAL;
360 	case PCI_IRQ_MSI:
361 		return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);
362 	default:
363 		dev_err(pci->dev, "UNKNOWN IRQ type\n");
364 	}
365 
366 	return 0;
367 }
368 
369 static const struct pci_epc_features artpec6_pcie_epc_features = {
370 	DWC_EPC_COMMON_FEATURES,
371 	.msi_capable = true,
372 };
373 
374 static const struct pci_epc_features *
375 artpec6_pcie_get_features(struct dw_pcie_ep *ep)
376 {
377 	return &artpec6_pcie_epc_features;
378 }
379 
380 static const struct dw_pcie_ep_ops pcie_ep_ops = {
381 	.init = artpec6_pcie_ep_init,
382 	.raise_irq = artpec6_pcie_raise_irq,
383 	.get_features = artpec6_pcie_get_features,
384 };
385 
386 static int artpec6_pcie_probe(struct platform_device *pdev)
387 {
388 	struct device *dev = &pdev->dev;
389 	struct dw_pcie *pci;
390 	struct artpec6_pcie *artpec6_pcie;
391 	int ret;
392 	const struct artpec_pcie_of_data *data;
393 	enum artpec_pcie_variants variant;
394 	enum dw_pcie_device_mode mode;
395 	u32 val;
396 
397 	data = of_device_get_match_data(dev);
398 	if (!data)
399 		return -EINVAL;
400 
401 	variant = (enum artpec_pcie_variants)data->variant;
402 	mode = (enum dw_pcie_device_mode)data->mode;
403 
404 	artpec6_pcie = devm_kzalloc(dev, sizeof(*artpec6_pcie), GFP_KERNEL);
405 	if (!artpec6_pcie)
406 		return -ENOMEM;
407 
408 	pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
409 	if (!pci)
410 		return -ENOMEM;
411 
412 	pci->dev = dev;
413 	pci->ops = &dw_pcie_ops;
414 
415 	artpec6_pcie->pci = pci;
416 	artpec6_pcie->variant = variant;
417 	artpec6_pcie->pci->mode = mode;
418 
419 	artpec6_pcie->phy_base =
420 		devm_platform_ioremap_resource_byname(pdev, "phy");
421 	if (IS_ERR(artpec6_pcie->phy_base))
422 		return PTR_ERR(artpec6_pcie->phy_base);
423 
424 	artpec6_pcie->regmap =
425 		syscon_regmap_lookup_by_phandle(dev->of_node,
426 						"axis,syscon-pcie");
427 	if (IS_ERR(artpec6_pcie->regmap))
428 		return PTR_ERR(artpec6_pcie->regmap);
429 
430 	platform_set_drvdata(pdev, artpec6_pcie);
431 
432 	switch (artpec6_pcie->pci->mode) {
433 	case DW_PCIE_RC_TYPE:
434 		if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_HOST))
435 			return -ENODEV;
436 
437 		pci->pp.ops = &artpec6_pcie_host_ops;
438 
439 		ret = dw_pcie_host_init(&pci->pp);
440 		if (ret < 0)
441 			return ret;
442 		break;
443 	case DW_PCIE_EP_TYPE:
444 		if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_EP))
445 			return -ENODEV;
446 
447 		val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
448 		val &= ~PCIECFG_DEVICE_TYPE_MASK;
449 		artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
450 
451 		pci->ep.ops = &pcie_ep_ops;
452 
453 		ret = dw_pcie_ep_init(&pci->ep);
454 		if (ret)
455 			return ret;
456 
457 		ret = dw_pcie_ep_init_registers(&pci->ep);
458 		if (ret) {
459 			dev_err(dev, "Failed to initialize DWC endpoint registers\n");
460 			dw_pcie_ep_deinit(&pci->ep);
461 			return ret;
462 		}
463 
464 		pci_epc_init_notify(pci->ep.epc);
465 
466 		break;
467 	default:
468 		dev_err(dev, "INVALID device type %d\n", artpec6_pcie->pci->mode);
469 	}
470 
471 	return 0;
472 }
473 
474 static const struct artpec_pcie_of_data artpec6_pcie_rc_of_data = {
475 	.variant = ARTPEC6,
476 	.mode = DW_PCIE_RC_TYPE,
477 };
478 
479 static const struct artpec_pcie_of_data artpec6_pcie_ep_of_data = {
480 	.variant = ARTPEC6,
481 	.mode = DW_PCIE_EP_TYPE,
482 };
483 
484 static const struct artpec_pcie_of_data artpec7_pcie_rc_of_data = {
485 	.variant = ARTPEC7,
486 	.mode = DW_PCIE_RC_TYPE,
487 };
488 
489 static const struct artpec_pcie_of_data artpec7_pcie_ep_of_data = {
490 	.variant = ARTPEC7,
491 	.mode = DW_PCIE_EP_TYPE,
492 };
493 
494 static const struct of_device_id artpec6_pcie_of_match[] = {
495 	{
496 		.compatible = "axis,artpec6-pcie",
497 		.data = &artpec6_pcie_rc_of_data,
498 	},
499 	{
500 		.compatible = "axis,artpec6-pcie-ep",
501 		.data = &artpec6_pcie_ep_of_data,
502 	},
503 	{
504 		.compatible = "axis,artpec7-pcie",
505 		.data = &artpec7_pcie_rc_of_data,
506 	},
507 	{
508 		.compatible = "axis,artpec7-pcie-ep",
509 		.data = &artpec7_pcie_ep_of_data,
510 	},
511 	{},
512 };
513 
514 static struct platform_driver artpec6_pcie_driver = {
515 	.probe = artpec6_pcie_probe,
516 	.driver = {
517 		.name	= "artpec6-pcie",
518 		.of_match_table = artpec6_pcie_of_match,
519 		.suppress_bind_attrs = true,
520 	},
521 };
522 builtin_platform_driver(artpec6_pcie_driver);
523