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 /* ARTPEC-6 specific registers */
56 #define PCIECFG_DBG_OEN BIT(24)
57 #define PCIECFG_CORE_RESET_REQ BIT(21)
58 #define PCIECFG_LTSSM_ENABLE BIT(20)
59 #define PCIECFG_DEVICE_TYPE_MASK GENMASK(19, 16)
60 #define PCIECFG_CLKREQ_B BIT(11)
61 #define PCIECFG_REFCLK_ENABLE BIT(10)
62 #define PCIECFG_PLL_ENABLE BIT(9)
63 #define PCIECFG_PCLK_ENABLE BIT(8)
64 #define PCIECFG_RISRCREN BIT(4)
65 #define PCIECFG_MODE_TX_DRV_EN BIT(3)
66 #define PCIECFG_CISRREN BIT(2)
67 #define PCIECFG_MACRO_ENABLE BIT(0)
68 /* ARTPEC-7 specific fields */
69 #define PCIECFG_REFCLKSEL BIT(23)
70 #define PCIECFG_NOC_RESET BIT(3)
73 /* ARTPEC-7 specific fields */
74 #define PCIESTAT_EXTREFCLK BIT(3)
77 #define NOCCFG_ENABLE_CLK_PCIE BIT(4)
78 #define NOCCFG_POWER_PCIE_IDLEACK BIT(3)
79 #define NOCCFG_POWER_PCIE_IDLE BIT(2)
80 #define NOCCFG_POWER_PCIE_IDLEREQ BIT(1)
82 #define PHY_STATUS 0x118
83 #define PHY_COSPLLLOCK BIT(0)
85 #define PHY_TX_ASIC_OUT 0x4040
86 #define PHY_TX_ASIC_OUT_TX_ACK BIT(0)
88 #define PHY_RX_ASIC_OUT 0x405c
89 #define PHY_RX_ASIC_OUT_ACK BIT(0)
91 static u32
artpec6_pcie_readl(struct artpec6_pcie
*artpec6_pcie
, u32 offset
)
95 regmap_read(artpec6_pcie
->regmap
, offset
, &val
);
99 static void artpec6_pcie_writel(struct artpec6_pcie
*artpec6_pcie
, u32 offset
, u32 val
)
101 regmap_write(artpec6_pcie
->regmap
, offset
, val
);
104 static u64
artpec6_pcie_cpu_addr_fixup(struct dw_pcie
*pci
, u64 pci_addr
)
106 struct artpec6_pcie
*artpec6_pcie
= to_artpec6_pcie(pci
);
107 struct pcie_port
*pp
= &pci
->pp
;
108 struct dw_pcie_ep
*ep
= &pci
->ep
;
110 switch (artpec6_pcie
->mode
) {
111 case DW_PCIE_RC_TYPE
:
112 return pci_addr
- pp
->cfg0_base
;
113 case DW_PCIE_EP_TYPE
:
114 return pci_addr
- ep
->phys_base
;
116 dev_err(pci
->dev
, "UNKNOWN device type\n");
121 static int artpec6_pcie_establish_link(struct dw_pcie
*pci
)
123 struct artpec6_pcie
*artpec6_pcie
= to_artpec6_pcie(pci
);
126 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
127 val
|= PCIECFG_LTSSM_ENABLE
;
128 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
133 static void artpec6_pcie_stop_link(struct dw_pcie
*pci
)
135 struct artpec6_pcie
*artpec6_pcie
= to_artpec6_pcie(pci
);
138 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
139 val
&= ~PCIECFG_LTSSM_ENABLE
;
140 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
143 static const struct dw_pcie_ops dw_pcie_ops
= {
144 .cpu_addr_fixup
= artpec6_pcie_cpu_addr_fixup
,
145 .start_link
= artpec6_pcie_establish_link
,
146 .stop_link
= artpec6_pcie_stop_link
,
149 static void artpec6_pcie_wait_for_phy_a6(struct artpec6_pcie
*artpec6_pcie
)
151 struct dw_pcie
*pci
= artpec6_pcie
->pci
;
152 struct device
*dev
= pci
->dev
;
154 unsigned int retries
;
158 usleep_range(1000, 2000);
159 val
= artpec6_pcie_readl(artpec6_pcie
, NOCCFG
);
162 (val
& (NOCCFG_POWER_PCIE_IDLEACK
| NOCCFG_POWER_PCIE_IDLE
)));
164 dev_err(dev
, "PCIe clock manager did not leave idle state\n");
168 usleep_range(1000, 2000);
169 val
= readl(artpec6_pcie
->phy_base
+ PHY_STATUS
);
171 } while (retries
&& !(val
& PHY_COSPLLLOCK
));
173 dev_err(dev
, "PHY PLL did not lock\n");
176 static void artpec6_pcie_wait_for_phy_a7(struct artpec6_pcie
*artpec6_pcie
)
178 struct dw_pcie
*pci
= artpec6_pcie
->pci
;
179 struct device
*dev
= pci
->dev
;
181 u16 phy_status_tx
, phy_status_rx
;
182 unsigned int retries
;
186 usleep_range(1000, 2000);
187 val
= artpec6_pcie_readl(artpec6_pcie
, NOCCFG
);
190 (val
& (NOCCFG_POWER_PCIE_IDLEACK
| NOCCFG_POWER_PCIE_IDLE
)));
192 dev_err(dev
, "PCIe clock manager did not leave idle state\n");
196 usleep_range(1000, 2000);
197 phy_status_tx
= readw(artpec6_pcie
->phy_base
+ PHY_TX_ASIC_OUT
);
198 phy_status_rx
= readw(artpec6_pcie
->phy_base
+ PHY_RX_ASIC_OUT
);
200 } while (retries
&& ((phy_status_tx
& PHY_TX_ASIC_OUT_TX_ACK
) ||
201 (phy_status_rx
& PHY_RX_ASIC_OUT_ACK
)));
203 dev_err(dev
, "PHY did not enter Pn state\n");
206 static void artpec6_pcie_wait_for_phy(struct artpec6_pcie
*artpec6_pcie
)
208 switch (artpec6_pcie
->variant
) {
210 artpec6_pcie_wait_for_phy_a6(artpec6_pcie
);
213 artpec6_pcie_wait_for_phy_a7(artpec6_pcie
);
218 static void artpec6_pcie_init_phy_a6(struct artpec6_pcie
*artpec6_pcie
)
222 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
223 val
|= PCIECFG_RISRCREN
| /* Receiver term. 50 Ohm */
224 PCIECFG_MODE_TX_DRV_EN
|
225 PCIECFG_CISRREN
| /* Reference clock term. 100 Ohm */
226 PCIECFG_MACRO_ENABLE
;
227 val
|= PCIECFG_REFCLK_ENABLE
;
228 val
&= ~PCIECFG_DBG_OEN
;
229 val
&= ~PCIECFG_CLKREQ_B
;
230 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
231 usleep_range(5000, 6000);
233 val
= artpec6_pcie_readl(artpec6_pcie
, NOCCFG
);
234 val
|= NOCCFG_ENABLE_CLK_PCIE
;
235 artpec6_pcie_writel(artpec6_pcie
, NOCCFG
, val
);
236 usleep_range(20, 30);
238 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
239 val
|= PCIECFG_PCLK_ENABLE
| PCIECFG_PLL_ENABLE
;
240 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
241 usleep_range(6000, 7000);
243 val
= artpec6_pcie_readl(artpec6_pcie
, NOCCFG
);
244 val
&= ~NOCCFG_POWER_PCIE_IDLEREQ
;
245 artpec6_pcie_writel(artpec6_pcie
, NOCCFG
, val
);
248 static void artpec6_pcie_init_phy_a7(struct artpec6_pcie
*artpec6_pcie
)
250 struct dw_pcie
*pci
= artpec6_pcie
->pci
;
254 /* Check if external reference clock is connected */
255 val
= artpec6_pcie_readl(artpec6_pcie
, PCIESTAT
);
256 extrefclk
= !!(val
& PCIESTAT_EXTREFCLK
);
257 dev_dbg(pci
->dev
, "Using reference clock: %s\n",
258 extrefclk
? "external" : "internal");
260 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
261 val
|= PCIECFG_RISRCREN
| /* Receiver term. 50 Ohm */
264 val
|= PCIECFG_REFCLKSEL
;
266 val
&= ~PCIECFG_REFCLKSEL
;
267 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
268 usleep_range(10, 20);
270 val
= artpec6_pcie_readl(artpec6_pcie
, NOCCFG
);
271 val
|= NOCCFG_ENABLE_CLK_PCIE
;
272 artpec6_pcie_writel(artpec6_pcie
, NOCCFG
, val
);
273 usleep_range(20, 30);
275 val
= artpec6_pcie_readl(artpec6_pcie
, NOCCFG
);
276 val
&= ~NOCCFG_POWER_PCIE_IDLEREQ
;
277 artpec6_pcie_writel(artpec6_pcie
, NOCCFG
, val
);
280 static void artpec6_pcie_init_phy(struct artpec6_pcie
*artpec6_pcie
)
282 switch (artpec6_pcie
->variant
) {
284 artpec6_pcie_init_phy_a6(artpec6_pcie
);
287 artpec6_pcie_init_phy_a7(artpec6_pcie
);
292 static void artpec6_pcie_set_nfts(struct artpec6_pcie
*artpec6_pcie
)
294 struct dw_pcie
*pci
= artpec6_pcie
->pci
;
297 if (artpec6_pcie
->variant
!= ARTPEC7
)
301 * Increase the N_FTS (Number of Fast Training Sequences)
302 * to be transmitted when transitioning from L0s to L0.
304 val
= dw_pcie_readl_dbi(pci
, ACK_F_ASPM_CTRL_OFF
);
305 val
&= ~ACK_N_FTS_MASK
;
306 val
|= ACK_N_FTS(180);
307 dw_pcie_writel_dbi(pci
, ACK_F_ASPM_CTRL_OFF
, val
);
310 * Set the Number of Fast Training Sequences that the core
311 * advertises as its N_FTS during Gen2 or Gen3 link training.
313 dw_pcie_link_set_n_fts(pci
, 180);
316 static void artpec6_pcie_assert_core_reset(struct artpec6_pcie
*artpec6_pcie
)
320 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
321 switch (artpec6_pcie
->variant
) {
323 val
|= PCIECFG_CORE_RESET_REQ
;
326 val
&= ~PCIECFG_NOC_RESET
;
329 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
332 static void artpec6_pcie_deassert_core_reset(struct artpec6_pcie
*artpec6_pcie
)
336 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
337 switch (artpec6_pcie
->variant
) {
339 val
&= ~PCIECFG_CORE_RESET_REQ
;
342 val
|= PCIECFG_NOC_RESET
;
345 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
346 usleep_range(100, 200);
349 static void artpec6_pcie_enable_interrupts(struct artpec6_pcie
*artpec6_pcie
)
351 struct dw_pcie
*pci
= artpec6_pcie
->pci
;
352 struct pcie_port
*pp
= &pci
->pp
;
354 if (IS_ENABLED(CONFIG_PCI_MSI
))
355 dw_pcie_msi_init(pp
);
358 static int artpec6_pcie_host_init(struct pcie_port
*pp
)
360 struct dw_pcie
*pci
= to_dw_pcie_from_pp(pp
);
361 struct artpec6_pcie
*artpec6_pcie
= to_artpec6_pcie(pci
);
363 artpec6_pcie_assert_core_reset(artpec6_pcie
);
364 artpec6_pcie_init_phy(artpec6_pcie
);
365 artpec6_pcie_deassert_core_reset(artpec6_pcie
);
366 artpec6_pcie_wait_for_phy(artpec6_pcie
);
367 artpec6_pcie_set_nfts(artpec6_pcie
);
368 dw_pcie_setup_rc(pp
);
369 artpec6_pcie_establish_link(pci
);
370 dw_pcie_wait_for_link(pci
);
371 artpec6_pcie_enable_interrupts(artpec6_pcie
);
376 static const struct dw_pcie_host_ops artpec6_pcie_host_ops
= {
377 .host_init
= artpec6_pcie_host_init
,
380 static int artpec6_add_pcie_port(struct artpec6_pcie
*artpec6_pcie
,
381 struct platform_device
*pdev
)
383 struct dw_pcie
*pci
= artpec6_pcie
->pci
;
384 struct pcie_port
*pp
= &pci
->pp
;
385 struct device
*dev
= pci
->dev
;
388 if (IS_ENABLED(CONFIG_PCI_MSI
)) {
389 pp
->msi_irq
= platform_get_irq_byname(pdev
, "msi");
390 if (pp
->msi_irq
< 0) {
391 dev_err(dev
, "failed to get MSI irq\n");
396 pp
->ops
= &artpec6_pcie_host_ops
;
398 ret
= dw_pcie_host_init(pp
);
400 dev_err(dev
, "failed to initialize host\n");
407 static void artpec6_pcie_ep_init(struct dw_pcie_ep
*ep
)
409 struct dw_pcie
*pci
= to_dw_pcie_from_ep(ep
);
410 struct artpec6_pcie
*artpec6_pcie
= to_artpec6_pcie(pci
);
413 artpec6_pcie_assert_core_reset(artpec6_pcie
);
414 artpec6_pcie_init_phy(artpec6_pcie
);
415 artpec6_pcie_deassert_core_reset(artpec6_pcie
);
416 artpec6_pcie_wait_for_phy(artpec6_pcie
);
417 artpec6_pcie_set_nfts(artpec6_pcie
);
419 for (bar
= 0; bar
< PCI_STD_NUM_BARS
; bar
++)
420 dw_pcie_ep_reset_bar(pci
, bar
);
423 static int artpec6_pcie_raise_irq(struct dw_pcie_ep
*ep
, u8 func_no
,
424 enum pci_epc_irq_type type
, u16 interrupt_num
)
426 struct dw_pcie
*pci
= to_dw_pcie_from_ep(ep
);
429 case PCI_EPC_IRQ_LEGACY
:
430 dev_err(pci
->dev
, "EP cannot trigger legacy IRQs\n");
432 case PCI_EPC_IRQ_MSI
:
433 return dw_pcie_ep_raise_msi_irq(ep
, func_no
, interrupt_num
);
435 dev_err(pci
->dev
, "UNKNOWN IRQ type\n");
441 static const struct dw_pcie_ep_ops pcie_ep_ops
= {
442 .ep_init
= artpec6_pcie_ep_init
,
443 .raise_irq
= artpec6_pcie_raise_irq
,
446 static int artpec6_add_pcie_ep(struct artpec6_pcie
*artpec6_pcie
,
447 struct platform_device
*pdev
)
450 struct dw_pcie_ep
*ep
;
451 struct resource
*res
;
452 struct device
*dev
= &pdev
->dev
;
453 struct dw_pcie
*pci
= artpec6_pcie
->pci
;
456 ep
->ops
= &pcie_ep_ops
;
458 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "dbi2");
459 pci
->dbi_base2
= devm_ioremap_resource(dev
, res
);
460 if (IS_ERR(pci
->dbi_base2
))
461 return PTR_ERR(pci
->dbi_base2
);
463 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "addr_space");
467 ep
->phys_base
= res
->start
;
468 ep
->addr_size
= resource_size(res
);
470 ret
= dw_pcie_ep_init(ep
);
472 dev_err(dev
, "failed to initialize endpoint\n");
479 static int artpec6_pcie_probe(struct platform_device
*pdev
)
481 struct device
*dev
= &pdev
->dev
;
483 struct artpec6_pcie
*artpec6_pcie
;
484 struct resource
*dbi_base
;
485 struct resource
*phy_base
;
487 const struct of_device_id
*match
;
488 const struct artpec_pcie_of_data
*data
;
489 enum artpec_pcie_variants variant
;
490 enum dw_pcie_device_mode mode
;
492 match
= of_match_device(artpec6_pcie_of_match
, dev
);
496 data
= (struct artpec_pcie_of_data
*)match
->data
;
497 variant
= (enum artpec_pcie_variants
)data
->variant
;
498 mode
= (enum dw_pcie_device_mode
)data
->mode
;
500 artpec6_pcie
= devm_kzalloc(dev
, sizeof(*artpec6_pcie
), GFP_KERNEL
);
504 pci
= devm_kzalloc(dev
, sizeof(*pci
), GFP_KERNEL
);
509 pci
->ops
= &dw_pcie_ops
;
511 artpec6_pcie
->pci
= pci
;
512 artpec6_pcie
->variant
= variant
;
513 artpec6_pcie
->mode
= mode
;
515 dbi_base
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "dbi");
516 pci
->dbi_base
= devm_ioremap_resource(dev
, dbi_base
);
517 if (IS_ERR(pci
->dbi_base
))
518 return PTR_ERR(pci
->dbi_base
);
520 phy_base
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "phy");
521 artpec6_pcie
->phy_base
= devm_ioremap_resource(dev
, phy_base
);
522 if (IS_ERR(artpec6_pcie
->phy_base
))
523 return PTR_ERR(artpec6_pcie
->phy_base
);
525 artpec6_pcie
->regmap
=
526 syscon_regmap_lookup_by_phandle(dev
->of_node
,
528 if (IS_ERR(artpec6_pcie
->regmap
))
529 return PTR_ERR(artpec6_pcie
->regmap
);
531 platform_set_drvdata(pdev
, artpec6_pcie
);
533 switch (artpec6_pcie
->mode
) {
534 case DW_PCIE_RC_TYPE
:
535 if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_HOST
))
538 ret
= artpec6_add_pcie_port(artpec6_pcie
, pdev
);
542 case DW_PCIE_EP_TYPE
: {
545 if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_EP
))
548 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
549 val
&= ~PCIECFG_DEVICE_TYPE_MASK
;
550 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
551 ret
= artpec6_add_pcie_ep(artpec6_pcie
, pdev
);
557 dev_err(dev
, "INVALID device type %d\n", artpec6_pcie
->mode
);
563 static const struct artpec_pcie_of_data artpec6_pcie_rc_of_data
= {
565 .mode
= DW_PCIE_RC_TYPE
,
568 static const struct artpec_pcie_of_data artpec6_pcie_ep_of_data
= {
570 .mode
= DW_PCIE_EP_TYPE
,
573 static const struct artpec_pcie_of_data artpec7_pcie_rc_of_data
= {
575 .mode
= DW_PCIE_RC_TYPE
,
578 static const struct artpec_pcie_of_data artpec7_pcie_ep_of_data
= {
580 .mode
= DW_PCIE_EP_TYPE
,
583 static const struct of_device_id artpec6_pcie_of_match
[] = {
585 .compatible
= "axis,artpec6-pcie",
586 .data
= &artpec6_pcie_rc_of_data
,
589 .compatible
= "axis,artpec6-pcie-ep",
590 .data
= &artpec6_pcie_ep_of_data
,
593 .compatible
= "axis,artpec7-pcie",
594 .data
= &artpec7_pcie_rc_of_data
,
597 .compatible
= "axis,artpec7-pcie-ep",
598 .data
= &artpec7_pcie_ep_of_data
,
603 static struct platform_driver artpec6_pcie_driver
= {
604 .probe
= artpec6_pcie_probe
,
606 .name
= "artpec6-pcie",
607 .of_match_table
= artpec6_pcie_of_match
,
608 .suppress_bind_attrs
= true,
611 builtin_platform_driver(artpec6_pcie_driver
);