1 // SPDX-License-Identifier: GPL-2.0
3 * PCIe host controller driver for Axis ARTPEC-6 SoC
5 * Author: Niklas Cassel <niklas.cassel@axis.com>
7 * Based on work done by Phil Edworthy <phil@edworthys.org>
10 #include <linux/delay.h>
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/of_device.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>
23 #include "pcie-designware.h"
25 #define to_artpec6_pcie(x) dev_get_drvdata((x)->dev)
27 enum artpec_pcie_variants
{
34 struct regmap
*regmap
; /* DT axis,syscon-pcie */
35 void __iomem
*phy_base
; /* DT phy */
36 enum artpec_pcie_variants variant
;
37 enum dw_pcie_device_mode mode
;
40 struct artpec_pcie_of_data
{
41 enum artpec_pcie_variants variant
;
42 enum dw_pcie_device_mode mode
;
45 static const struct of_device_id artpec6_pcie_of_match
[];
47 /* PCIe Port Logic registers (memory-mapped) */
48 #define PL_OFFSET 0x700
50 #define ACK_F_ASPM_CTRL_OFF (PL_OFFSET + 0xc)
51 #define ACK_N_FTS_MASK GENMASK(15, 8)
52 #define ACK_N_FTS(x) (((x) << 8) & ACK_N_FTS_MASK)
54 #define FAST_TRAINING_SEQ_MASK GENMASK(7, 0)
55 #define FAST_TRAINING_SEQ(x) (((x) << 0) & FAST_TRAINING_SEQ_MASK)
57 /* ARTPEC-6 specific registers */
59 #define PCIECFG_DBG_OEN BIT(24)
60 #define PCIECFG_CORE_RESET_REQ BIT(21)
61 #define PCIECFG_LTSSM_ENABLE BIT(20)
62 #define PCIECFG_DEVICE_TYPE_MASK GENMASK(19, 16)
63 #define PCIECFG_CLKREQ_B BIT(11)
64 #define PCIECFG_REFCLK_ENABLE BIT(10)
65 #define PCIECFG_PLL_ENABLE BIT(9)
66 #define PCIECFG_PCLK_ENABLE BIT(8)
67 #define PCIECFG_RISRCREN BIT(4)
68 #define PCIECFG_MODE_TX_DRV_EN BIT(3)
69 #define PCIECFG_CISRREN BIT(2)
70 #define PCIECFG_MACRO_ENABLE BIT(0)
71 /* ARTPEC-7 specific fields */
72 #define PCIECFG_REFCLKSEL BIT(23)
73 #define PCIECFG_NOC_RESET BIT(3)
76 /* ARTPEC-7 specific fields */
77 #define PCIESTAT_EXTREFCLK BIT(3)
80 #define NOCCFG_ENABLE_CLK_PCIE BIT(4)
81 #define NOCCFG_POWER_PCIE_IDLEACK BIT(3)
82 #define NOCCFG_POWER_PCIE_IDLE BIT(2)
83 #define NOCCFG_POWER_PCIE_IDLEREQ BIT(1)
85 #define PHY_STATUS 0x118
86 #define PHY_COSPLLLOCK BIT(0)
88 #define PHY_TX_ASIC_OUT 0x4040
89 #define PHY_TX_ASIC_OUT_TX_ACK BIT(0)
91 #define PHY_RX_ASIC_OUT 0x405c
92 #define PHY_RX_ASIC_OUT_ACK BIT(0)
94 static u32
artpec6_pcie_readl(struct artpec6_pcie
*artpec6_pcie
, u32 offset
)
98 regmap_read(artpec6_pcie
->regmap
, offset
, &val
);
102 static void artpec6_pcie_writel(struct artpec6_pcie
*artpec6_pcie
, u32 offset
, u32 val
)
104 regmap_write(artpec6_pcie
->regmap
, offset
, val
);
107 static u64
artpec6_pcie_cpu_addr_fixup(struct dw_pcie
*pci
, u64 pci_addr
)
109 struct artpec6_pcie
*artpec6_pcie
= to_artpec6_pcie(pci
);
110 struct pcie_port
*pp
= &pci
->pp
;
111 struct dw_pcie_ep
*ep
= &pci
->ep
;
113 switch (artpec6_pcie
->mode
) {
114 case DW_PCIE_RC_TYPE
:
115 return pci_addr
- pp
->cfg0_base
;
116 case DW_PCIE_EP_TYPE
:
117 return pci_addr
- ep
->phys_base
;
119 dev_err(pci
->dev
, "UNKNOWN device type\n");
124 static int artpec6_pcie_establish_link(struct dw_pcie
*pci
)
126 struct artpec6_pcie
*artpec6_pcie
= to_artpec6_pcie(pci
);
129 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
130 val
|= PCIECFG_LTSSM_ENABLE
;
131 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
136 static void artpec6_pcie_stop_link(struct dw_pcie
*pci
)
138 struct artpec6_pcie
*artpec6_pcie
= to_artpec6_pcie(pci
);
141 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
142 val
&= ~PCIECFG_LTSSM_ENABLE
;
143 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
146 static const struct dw_pcie_ops dw_pcie_ops
= {
147 .cpu_addr_fixup
= artpec6_pcie_cpu_addr_fixup
,
148 .start_link
= artpec6_pcie_establish_link
,
149 .stop_link
= artpec6_pcie_stop_link
,
152 static void artpec6_pcie_wait_for_phy_a6(struct artpec6_pcie
*artpec6_pcie
)
154 struct dw_pcie
*pci
= artpec6_pcie
->pci
;
155 struct device
*dev
= pci
->dev
;
157 unsigned int retries
;
161 usleep_range(1000, 2000);
162 val
= artpec6_pcie_readl(artpec6_pcie
, NOCCFG
);
165 (val
& (NOCCFG_POWER_PCIE_IDLEACK
| NOCCFG_POWER_PCIE_IDLE
)));
167 dev_err(dev
, "PCIe clock manager did not leave idle state\n");
171 usleep_range(1000, 2000);
172 val
= readl(artpec6_pcie
->phy_base
+ PHY_STATUS
);
174 } while (retries
&& !(val
& PHY_COSPLLLOCK
));
176 dev_err(dev
, "PHY PLL did not lock\n");
179 static void artpec6_pcie_wait_for_phy_a7(struct artpec6_pcie
*artpec6_pcie
)
181 struct dw_pcie
*pci
= artpec6_pcie
->pci
;
182 struct device
*dev
= pci
->dev
;
184 u16 phy_status_tx
, phy_status_rx
;
185 unsigned int retries
;
189 usleep_range(1000, 2000);
190 val
= artpec6_pcie_readl(artpec6_pcie
, NOCCFG
);
193 (val
& (NOCCFG_POWER_PCIE_IDLEACK
| NOCCFG_POWER_PCIE_IDLE
)));
195 dev_err(dev
, "PCIe clock manager did not leave idle state\n");
199 usleep_range(1000, 2000);
200 phy_status_tx
= readw(artpec6_pcie
->phy_base
+ PHY_TX_ASIC_OUT
);
201 phy_status_rx
= readw(artpec6_pcie
->phy_base
+ PHY_RX_ASIC_OUT
);
203 } while (retries
&& ((phy_status_tx
& PHY_TX_ASIC_OUT_TX_ACK
) ||
204 (phy_status_rx
& PHY_RX_ASIC_OUT_ACK
)));
206 dev_err(dev
, "PHY did not enter Pn state\n");
209 static void artpec6_pcie_wait_for_phy(struct artpec6_pcie
*artpec6_pcie
)
211 switch (artpec6_pcie
->variant
) {
213 artpec6_pcie_wait_for_phy_a6(artpec6_pcie
);
216 artpec6_pcie_wait_for_phy_a7(artpec6_pcie
);
221 static void artpec6_pcie_init_phy_a6(struct artpec6_pcie
*artpec6_pcie
)
225 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
226 val
|= PCIECFG_RISRCREN
| /* Receiver term. 50 Ohm */
227 PCIECFG_MODE_TX_DRV_EN
|
228 PCIECFG_CISRREN
| /* Reference clock term. 100 Ohm */
229 PCIECFG_MACRO_ENABLE
;
230 val
|= PCIECFG_REFCLK_ENABLE
;
231 val
&= ~PCIECFG_DBG_OEN
;
232 val
&= ~PCIECFG_CLKREQ_B
;
233 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
234 usleep_range(5000, 6000);
236 val
= artpec6_pcie_readl(artpec6_pcie
, NOCCFG
);
237 val
|= NOCCFG_ENABLE_CLK_PCIE
;
238 artpec6_pcie_writel(artpec6_pcie
, NOCCFG
, val
);
239 usleep_range(20, 30);
241 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
242 val
|= PCIECFG_PCLK_ENABLE
| PCIECFG_PLL_ENABLE
;
243 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
244 usleep_range(6000, 7000);
246 val
= artpec6_pcie_readl(artpec6_pcie
, NOCCFG
);
247 val
&= ~NOCCFG_POWER_PCIE_IDLEREQ
;
248 artpec6_pcie_writel(artpec6_pcie
, NOCCFG
, val
);
251 static void artpec6_pcie_init_phy_a7(struct artpec6_pcie
*artpec6_pcie
)
253 struct dw_pcie
*pci
= artpec6_pcie
->pci
;
257 /* Check if external reference clock is connected */
258 val
= artpec6_pcie_readl(artpec6_pcie
, PCIESTAT
);
259 extrefclk
= !!(val
& PCIESTAT_EXTREFCLK
);
260 dev_dbg(pci
->dev
, "Using reference clock: %s\n",
261 extrefclk
? "external" : "internal");
263 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
264 val
|= PCIECFG_RISRCREN
| /* Receiver term. 50 Ohm */
267 val
|= PCIECFG_REFCLKSEL
;
269 val
&= ~PCIECFG_REFCLKSEL
;
270 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
271 usleep_range(10, 20);
273 val
= artpec6_pcie_readl(artpec6_pcie
, NOCCFG
);
274 val
|= NOCCFG_ENABLE_CLK_PCIE
;
275 artpec6_pcie_writel(artpec6_pcie
, NOCCFG
, val
);
276 usleep_range(20, 30);
278 val
= artpec6_pcie_readl(artpec6_pcie
, NOCCFG
);
279 val
&= ~NOCCFG_POWER_PCIE_IDLEREQ
;
280 artpec6_pcie_writel(artpec6_pcie
, NOCCFG
, val
);
283 static void artpec6_pcie_init_phy(struct artpec6_pcie
*artpec6_pcie
)
285 switch (artpec6_pcie
->variant
) {
287 artpec6_pcie_init_phy_a6(artpec6_pcie
);
290 artpec6_pcie_init_phy_a7(artpec6_pcie
);
295 static void artpec6_pcie_set_nfts(struct artpec6_pcie
*artpec6_pcie
)
297 struct dw_pcie
*pci
= artpec6_pcie
->pci
;
300 if (artpec6_pcie
->variant
!= ARTPEC7
)
304 * Increase the N_FTS (Number of Fast Training Sequences)
305 * to be transmitted when transitioning from L0s to L0.
307 val
= dw_pcie_readl_dbi(pci
, ACK_F_ASPM_CTRL_OFF
);
308 val
&= ~ACK_N_FTS_MASK
;
309 val
|= ACK_N_FTS(180);
310 dw_pcie_writel_dbi(pci
, ACK_F_ASPM_CTRL_OFF
, val
);
313 * Set the Number of Fast Training Sequences that the core
314 * advertises as its N_FTS during Gen2 or Gen3 link training.
316 val
= dw_pcie_readl_dbi(pci
, PCIE_LINK_WIDTH_SPEED_CONTROL
);
317 val
&= ~FAST_TRAINING_SEQ_MASK
;
318 val
|= FAST_TRAINING_SEQ(180);
319 dw_pcie_writel_dbi(pci
, PCIE_LINK_WIDTH_SPEED_CONTROL
, val
);
322 static void artpec6_pcie_assert_core_reset(struct artpec6_pcie
*artpec6_pcie
)
326 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
327 switch (artpec6_pcie
->variant
) {
329 val
|= PCIECFG_CORE_RESET_REQ
;
332 val
&= ~PCIECFG_NOC_RESET
;
335 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
338 static void artpec6_pcie_deassert_core_reset(struct artpec6_pcie
*artpec6_pcie
)
342 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
343 switch (artpec6_pcie
->variant
) {
345 val
&= ~PCIECFG_CORE_RESET_REQ
;
348 val
|= PCIECFG_NOC_RESET
;
351 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
352 usleep_range(100, 200);
355 static void artpec6_pcie_enable_interrupts(struct artpec6_pcie
*artpec6_pcie
)
357 struct dw_pcie
*pci
= artpec6_pcie
->pci
;
358 struct pcie_port
*pp
= &pci
->pp
;
360 if (IS_ENABLED(CONFIG_PCI_MSI
))
361 dw_pcie_msi_init(pp
);
364 static int artpec6_pcie_host_init(struct pcie_port
*pp
)
366 struct dw_pcie
*pci
= to_dw_pcie_from_pp(pp
);
367 struct artpec6_pcie
*artpec6_pcie
= to_artpec6_pcie(pci
);
369 artpec6_pcie_assert_core_reset(artpec6_pcie
);
370 artpec6_pcie_init_phy(artpec6_pcie
);
371 artpec6_pcie_deassert_core_reset(artpec6_pcie
);
372 artpec6_pcie_wait_for_phy(artpec6_pcie
);
373 artpec6_pcie_set_nfts(artpec6_pcie
);
374 dw_pcie_setup_rc(pp
);
375 artpec6_pcie_establish_link(pci
);
376 dw_pcie_wait_for_link(pci
);
377 artpec6_pcie_enable_interrupts(artpec6_pcie
);
382 static const struct dw_pcie_host_ops artpec6_pcie_host_ops
= {
383 .host_init
= artpec6_pcie_host_init
,
386 static int artpec6_add_pcie_port(struct artpec6_pcie
*artpec6_pcie
,
387 struct platform_device
*pdev
)
389 struct dw_pcie
*pci
= artpec6_pcie
->pci
;
390 struct pcie_port
*pp
= &pci
->pp
;
391 struct device
*dev
= pci
->dev
;
394 if (IS_ENABLED(CONFIG_PCI_MSI
)) {
395 pp
->msi_irq
= platform_get_irq_byname(pdev
, "msi");
396 if (pp
->msi_irq
< 0) {
397 dev_err(dev
, "failed to get MSI irq\n");
402 pp
->ops
= &artpec6_pcie_host_ops
;
404 ret
= dw_pcie_host_init(pp
);
406 dev_err(dev
, "failed to initialize host\n");
413 static void artpec6_pcie_ep_init(struct dw_pcie_ep
*ep
)
415 struct dw_pcie
*pci
= to_dw_pcie_from_ep(ep
);
416 struct artpec6_pcie
*artpec6_pcie
= to_artpec6_pcie(pci
);
419 artpec6_pcie_assert_core_reset(artpec6_pcie
);
420 artpec6_pcie_init_phy(artpec6_pcie
);
421 artpec6_pcie_deassert_core_reset(artpec6_pcie
);
422 artpec6_pcie_wait_for_phy(artpec6_pcie
);
423 artpec6_pcie_set_nfts(artpec6_pcie
);
425 for (bar
= BAR_0
; bar
<= BAR_5
; bar
++)
426 dw_pcie_ep_reset_bar(pci
, bar
);
429 static int artpec6_pcie_raise_irq(struct dw_pcie_ep
*ep
, u8 func_no
,
430 enum pci_epc_irq_type type
, u16 interrupt_num
)
432 struct dw_pcie
*pci
= to_dw_pcie_from_ep(ep
);
435 case PCI_EPC_IRQ_LEGACY
:
436 dev_err(pci
->dev
, "EP cannot trigger legacy IRQs\n");
438 case PCI_EPC_IRQ_MSI
:
439 return dw_pcie_ep_raise_msi_irq(ep
, func_no
, interrupt_num
);
441 dev_err(pci
->dev
, "UNKNOWN IRQ type\n");
447 static struct dw_pcie_ep_ops pcie_ep_ops
= {
448 .ep_init
= artpec6_pcie_ep_init
,
449 .raise_irq
= artpec6_pcie_raise_irq
,
452 static int artpec6_add_pcie_ep(struct artpec6_pcie
*artpec6_pcie
,
453 struct platform_device
*pdev
)
456 struct dw_pcie_ep
*ep
;
457 struct resource
*res
;
458 struct device
*dev
= &pdev
->dev
;
459 struct dw_pcie
*pci
= artpec6_pcie
->pci
;
462 ep
->ops
= &pcie_ep_ops
;
464 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "dbi2");
465 pci
->dbi_base2
= devm_ioremap_resource(dev
, res
);
466 if (IS_ERR(pci
->dbi_base2
))
467 return PTR_ERR(pci
->dbi_base2
);
469 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "addr_space");
473 ep
->phys_base
= res
->start
;
474 ep
->addr_size
= resource_size(res
);
476 ret
= dw_pcie_ep_init(ep
);
478 dev_err(dev
, "failed to initialize endpoint\n");
485 static int artpec6_pcie_probe(struct platform_device
*pdev
)
487 struct device
*dev
= &pdev
->dev
;
489 struct artpec6_pcie
*artpec6_pcie
;
490 struct resource
*dbi_base
;
491 struct resource
*phy_base
;
493 const struct of_device_id
*match
;
494 const struct artpec_pcie_of_data
*data
;
495 enum artpec_pcie_variants variant
;
496 enum dw_pcie_device_mode mode
;
498 match
= of_match_device(artpec6_pcie_of_match
, dev
);
502 data
= (struct artpec_pcie_of_data
*)match
->data
;
503 variant
= (enum artpec_pcie_variants
)data
->variant
;
504 mode
= (enum dw_pcie_device_mode
)data
->mode
;
506 artpec6_pcie
= devm_kzalloc(dev
, sizeof(*artpec6_pcie
), GFP_KERNEL
);
510 pci
= devm_kzalloc(dev
, sizeof(*pci
), GFP_KERNEL
);
515 pci
->ops
= &dw_pcie_ops
;
517 artpec6_pcie
->pci
= pci
;
518 artpec6_pcie
->variant
= variant
;
519 artpec6_pcie
->mode
= mode
;
521 dbi_base
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "dbi");
522 pci
->dbi_base
= devm_ioremap_resource(dev
, dbi_base
);
523 if (IS_ERR(pci
->dbi_base
))
524 return PTR_ERR(pci
->dbi_base
);
526 phy_base
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "phy");
527 artpec6_pcie
->phy_base
= devm_ioremap_resource(dev
, phy_base
);
528 if (IS_ERR(artpec6_pcie
->phy_base
))
529 return PTR_ERR(artpec6_pcie
->phy_base
);
531 artpec6_pcie
->regmap
=
532 syscon_regmap_lookup_by_phandle(dev
->of_node
,
534 if (IS_ERR(artpec6_pcie
->regmap
))
535 return PTR_ERR(artpec6_pcie
->regmap
);
537 platform_set_drvdata(pdev
, artpec6_pcie
);
539 switch (artpec6_pcie
->mode
) {
540 case DW_PCIE_RC_TYPE
:
541 if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_HOST
))
544 ret
= artpec6_add_pcie_port(artpec6_pcie
, pdev
);
548 case DW_PCIE_EP_TYPE
: {
551 if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_EP
))
554 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
555 val
&= ~PCIECFG_DEVICE_TYPE_MASK
;
556 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
557 ret
= artpec6_add_pcie_ep(artpec6_pcie
, pdev
);
563 dev_err(dev
, "INVALID device type %d\n", artpec6_pcie
->mode
);
569 static const struct artpec_pcie_of_data artpec6_pcie_rc_of_data
= {
571 .mode
= DW_PCIE_RC_TYPE
,
574 static const struct artpec_pcie_of_data artpec6_pcie_ep_of_data
= {
576 .mode
= DW_PCIE_EP_TYPE
,
579 static const struct artpec_pcie_of_data artpec7_pcie_rc_of_data
= {
581 .mode
= DW_PCIE_RC_TYPE
,
584 static const struct artpec_pcie_of_data artpec7_pcie_ep_of_data
= {
586 .mode
= DW_PCIE_EP_TYPE
,
589 static const struct of_device_id artpec6_pcie_of_match
[] = {
591 .compatible
= "axis,artpec6-pcie",
592 .data
= &artpec6_pcie_rc_of_data
,
595 .compatible
= "axis,artpec6-pcie-ep",
596 .data
= &artpec6_pcie_ep_of_data
,
599 .compatible
= "axis,artpec7-pcie",
600 .data
= &artpec7_pcie_rc_of_data
,
603 .compatible
= "axis,artpec7-pcie-ep",
604 .data
= &artpec7_pcie_ep_of_data
,
609 static struct platform_driver artpec6_pcie_driver
= {
610 .probe
= artpec6_pcie_probe
,
612 .name
= "artpec6-pcie",
613 .of_match_table
= artpec6_pcie_of_match
,
614 .suppress_bind_attrs
= true,
617 builtin_platform_driver(artpec6_pcie_driver
);