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 /* ARTPEC-6 specific registers */
49 #define PCIECFG_DBG_OEN BIT(24)
50 #define PCIECFG_CORE_RESET_REQ BIT(21)
51 #define PCIECFG_LTSSM_ENABLE BIT(20)
52 #define PCIECFG_DEVICE_TYPE_MASK GENMASK(19, 16)
53 #define PCIECFG_CLKREQ_B BIT(11)
54 #define PCIECFG_REFCLK_ENABLE BIT(10)
55 #define PCIECFG_PLL_ENABLE BIT(9)
56 #define PCIECFG_PCLK_ENABLE BIT(8)
57 #define PCIECFG_RISRCREN BIT(4)
58 #define PCIECFG_MODE_TX_DRV_EN BIT(3)
59 #define PCIECFG_CISRREN BIT(2)
60 #define PCIECFG_MACRO_ENABLE BIT(0)
61 /* ARTPEC-7 specific fields */
62 #define PCIECFG_REFCLKSEL BIT(23)
63 #define PCIECFG_NOC_RESET BIT(3)
66 /* ARTPEC-7 specific fields */
67 #define PCIESTAT_EXTREFCLK BIT(3)
70 #define NOCCFG_ENABLE_CLK_PCIE BIT(4)
71 #define NOCCFG_POWER_PCIE_IDLEACK BIT(3)
72 #define NOCCFG_POWER_PCIE_IDLE BIT(2)
73 #define NOCCFG_POWER_PCIE_IDLEREQ BIT(1)
75 #define PHY_STATUS 0x118
76 #define PHY_COSPLLLOCK BIT(0)
78 #define PHY_TX_ASIC_OUT 0x4040
79 #define PHY_TX_ASIC_OUT_TX_ACK BIT(0)
81 #define PHY_RX_ASIC_OUT 0x405c
82 #define PHY_RX_ASIC_OUT_ACK BIT(0)
84 static u32
artpec6_pcie_readl(struct artpec6_pcie
*artpec6_pcie
, u32 offset
)
88 regmap_read(artpec6_pcie
->regmap
, offset
, &val
);
92 static void artpec6_pcie_writel(struct artpec6_pcie
*artpec6_pcie
, u32 offset
, u32 val
)
94 regmap_write(artpec6_pcie
->regmap
, offset
, val
);
97 static u64
artpec6_pcie_cpu_addr_fixup(struct dw_pcie
*pci
, u64 pci_addr
)
99 struct artpec6_pcie
*artpec6_pcie
= to_artpec6_pcie(pci
);
100 struct pcie_port
*pp
= &pci
->pp
;
101 struct dw_pcie_ep
*ep
= &pci
->ep
;
103 switch (artpec6_pcie
->mode
) {
104 case DW_PCIE_RC_TYPE
:
105 return pci_addr
- pp
->cfg0_base
;
106 case DW_PCIE_EP_TYPE
:
107 return pci_addr
- ep
->phys_base
;
109 dev_err(pci
->dev
, "UNKNOWN device type\n");
114 static int artpec6_pcie_establish_link(struct dw_pcie
*pci
)
116 struct artpec6_pcie
*artpec6_pcie
= to_artpec6_pcie(pci
);
119 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
120 val
|= PCIECFG_LTSSM_ENABLE
;
121 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
126 static void artpec6_pcie_stop_link(struct dw_pcie
*pci
)
128 struct artpec6_pcie
*artpec6_pcie
= to_artpec6_pcie(pci
);
131 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
132 val
&= ~PCIECFG_LTSSM_ENABLE
;
133 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
136 static const struct dw_pcie_ops dw_pcie_ops
= {
137 .cpu_addr_fixup
= artpec6_pcie_cpu_addr_fixup
,
138 .start_link
= artpec6_pcie_establish_link
,
139 .stop_link
= artpec6_pcie_stop_link
,
142 static void artpec6_pcie_wait_for_phy_a6(struct artpec6_pcie
*artpec6_pcie
)
144 struct dw_pcie
*pci
= artpec6_pcie
->pci
;
145 struct device
*dev
= pci
->dev
;
147 unsigned int retries
;
151 usleep_range(1000, 2000);
152 val
= artpec6_pcie_readl(artpec6_pcie
, NOCCFG
);
155 (val
& (NOCCFG_POWER_PCIE_IDLEACK
| NOCCFG_POWER_PCIE_IDLE
)));
157 dev_err(dev
, "PCIe clock manager did not leave idle state\n");
161 usleep_range(1000, 2000);
162 val
= readl(artpec6_pcie
->phy_base
+ PHY_STATUS
);
164 } while (retries
&& !(val
& PHY_COSPLLLOCK
));
166 dev_err(dev
, "PHY PLL did not lock\n");
169 static void artpec6_pcie_wait_for_phy_a7(struct artpec6_pcie
*artpec6_pcie
)
171 struct dw_pcie
*pci
= artpec6_pcie
->pci
;
172 struct device
*dev
= pci
->dev
;
174 u16 phy_status_tx
, phy_status_rx
;
175 unsigned int retries
;
179 usleep_range(1000, 2000);
180 val
= artpec6_pcie_readl(artpec6_pcie
, NOCCFG
);
183 (val
& (NOCCFG_POWER_PCIE_IDLEACK
| NOCCFG_POWER_PCIE_IDLE
)));
185 dev_err(dev
, "PCIe clock manager did not leave idle state\n");
189 usleep_range(1000, 2000);
190 phy_status_tx
= readw(artpec6_pcie
->phy_base
+ PHY_TX_ASIC_OUT
);
191 phy_status_rx
= readw(artpec6_pcie
->phy_base
+ PHY_RX_ASIC_OUT
);
193 } while (retries
&& ((phy_status_tx
& PHY_TX_ASIC_OUT_TX_ACK
) ||
194 (phy_status_rx
& PHY_RX_ASIC_OUT_ACK
)));
196 dev_err(dev
, "PHY did not enter Pn state\n");
199 static void artpec6_pcie_wait_for_phy(struct artpec6_pcie
*artpec6_pcie
)
201 switch (artpec6_pcie
->variant
) {
203 artpec6_pcie_wait_for_phy_a6(artpec6_pcie
);
206 artpec6_pcie_wait_for_phy_a7(artpec6_pcie
);
211 static void artpec6_pcie_init_phy_a6(struct artpec6_pcie
*artpec6_pcie
)
215 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
216 val
|= PCIECFG_RISRCREN
| /* Receiver term. 50 Ohm */
217 PCIECFG_MODE_TX_DRV_EN
|
218 PCIECFG_CISRREN
| /* Reference clock term. 100 Ohm */
219 PCIECFG_MACRO_ENABLE
;
220 val
|= PCIECFG_REFCLK_ENABLE
;
221 val
&= ~PCIECFG_DBG_OEN
;
222 val
&= ~PCIECFG_CLKREQ_B
;
223 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
224 usleep_range(5000, 6000);
226 val
= artpec6_pcie_readl(artpec6_pcie
, NOCCFG
);
227 val
|= NOCCFG_ENABLE_CLK_PCIE
;
228 artpec6_pcie_writel(artpec6_pcie
, NOCCFG
, val
);
229 usleep_range(20, 30);
231 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
232 val
|= PCIECFG_PCLK_ENABLE
| PCIECFG_PLL_ENABLE
;
233 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
234 usleep_range(6000, 7000);
236 val
= artpec6_pcie_readl(artpec6_pcie
, NOCCFG
);
237 val
&= ~NOCCFG_POWER_PCIE_IDLEREQ
;
238 artpec6_pcie_writel(artpec6_pcie
, NOCCFG
, val
);
241 static void artpec6_pcie_init_phy_a7(struct artpec6_pcie
*artpec6_pcie
)
243 struct dw_pcie
*pci
= artpec6_pcie
->pci
;
247 /* Check if external reference clock is connected */
248 val
= artpec6_pcie_readl(artpec6_pcie
, PCIESTAT
);
249 extrefclk
= !!(val
& PCIESTAT_EXTREFCLK
);
250 dev_dbg(pci
->dev
, "Using reference clock: %s\n",
251 extrefclk
? "external" : "internal");
253 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
254 val
|= PCIECFG_RISRCREN
| /* Receiver term. 50 Ohm */
257 val
|= PCIECFG_REFCLKSEL
;
259 val
&= ~PCIECFG_REFCLKSEL
;
260 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
261 usleep_range(10, 20);
263 val
= artpec6_pcie_readl(artpec6_pcie
, NOCCFG
);
264 val
|= NOCCFG_ENABLE_CLK_PCIE
;
265 artpec6_pcie_writel(artpec6_pcie
, NOCCFG
, val
);
266 usleep_range(20, 30);
268 val
= artpec6_pcie_readl(artpec6_pcie
, NOCCFG
);
269 val
&= ~NOCCFG_POWER_PCIE_IDLEREQ
;
270 artpec6_pcie_writel(artpec6_pcie
, NOCCFG
, val
);
273 static void artpec6_pcie_init_phy(struct artpec6_pcie
*artpec6_pcie
)
275 switch (artpec6_pcie
->variant
) {
277 artpec6_pcie_init_phy_a6(artpec6_pcie
);
280 artpec6_pcie_init_phy_a7(artpec6_pcie
);
285 static void artpec6_pcie_assert_core_reset(struct artpec6_pcie
*artpec6_pcie
)
289 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
290 switch (artpec6_pcie
->variant
) {
292 val
|= PCIECFG_CORE_RESET_REQ
;
295 val
&= ~PCIECFG_NOC_RESET
;
298 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
301 static void artpec6_pcie_deassert_core_reset(struct artpec6_pcie
*artpec6_pcie
)
305 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
306 switch (artpec6_pcie
->variant
) {
308 val
&= ~PCIECFG_CORE_RESET_REQ
;
311 val
|= PCIECFG_NOC_RESET
;
314 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
315 usleep_range(100, 200);
318 static int artpec6_pcie_host_init(struct pcie_port
*pp
)
320 struct dw_pcie
*pci
= to_dw_pcie_from_pp(pp
);
321 struct artpec6_pcie
*artpec6_pcie
= to_artpec6_pcie(pci
);
323 if (artpec6_pcie
->variant
== ARTPEC7
) {
327 artpec6_pcie_assert_core_reset(artpec6_pcie
);
328 artpec6_pcie_init_phy(artpec6_pcie
);
329 artpec6_pcie_deassert_core_reset(artpec6_pcie
);
330 artpec6_pcie_wait_for_phy(artpec6_pcie
);
335 static const struct dw_pcie_host_ops artpec6_pcie_host_ops
= {
336 .host_init
= artpec6_pcie_host_init
,
339 static void artpec6_pcie_ep_init(struct dw_pcie_ep
*ep
)
341 struct dw_pcie
*pci
= to_dw_pcie_from_ep(ep
);
342 struct artpec6_pcie
*artpec6_pcie
= to_artpec6_pcie(pci
);
345 artpec6_pcie_assert_core_reset(artpec6_pcie
);
346 artpec6_pcie_init_phy(artpec6_pcie
);
347 artpec6_pcie_deassert_core_reset(artpec6_pcie
);
348 artpec6_pcie_wait_for_phy(artpec6_pcie
);
350 for (bar
= 0; bar
< PCI_STD_NUM_BARS
; bar
++)
351 dw_pcie_ep_reset_bar(pci
, bar
);
354 static int artpec6_pcie_raise_irq(struct dw_pcie_ep
*ep
, u8 func_no
,
355 enum pci_epc_irq_type type
, u16 interrupt_num
)
357 struct dw_pcie
*pci
= to_dw_pcie_from_ep(ep
);
360 case PCI_EPC_IRQ_LEGACY
:
361 dev_err(pci
->dev
, "EP cannot trigger legacy IRQs\n");
363 case PCI_EPC_IRQ_MSI
:
364 return dw_pcie_ep_raise_msi_irq(ep
, func_no
, interrupt_num
);
366 dev_err(pci
->dev
, "UNKNOWN IRQ type\n");
372 static const struct dw_pcie_ep_ops pcie_ep_ops
= {
373 .ep_init
= artpec6_pcie_ep_init
,
374 .raise_irq
= artpec6_pcie_raise_irq
,
377 static int artpec6_pcie_probe(struct platform_device
*pdev
)
379 struct device
*dev
= &pdev
->dev
;
381 struct artpec6_pcie
*artpec6_pcie
;
383 const struct of_device_id
*match
;
384 const struct artpec_pcie_of_data
*data
;
385 enum artpec_pcie_variants variant
;
386 enum dw_pcie_device_mode mode
;
388 match
= of_match_device(artpec6_pcie_of_match
, dev
);
392 data
= (struct artpec_pcie_of_data
*)match
->data
;
393 variant
= (enum artpec_pcie_variants
)data
->variant
;
394 mode
= (enum dw_pcie_device_mode
)data
->mode
;
396 artpec6_pcie
= devm_kzalloc(dev
, sizeof(*artpec6_pcie
), GFP_KERNEL
);
400 pci
= devm_kzalloc(dev
, sizeof(*pci
), GFP_KERNEL
);
405 pci
->ops
= &dw_pcie_ops
;
407 artpec6_pcie
->pci
= pci
;
408 artpec6_pcie
->variant
= variant
;
409 artpec6_pcie
->mode
= mode
;
411 artpec6_pcie
->phy_base
=
412 devm_platform_ioremap_resource_byname(pdev
, "phy");
413 if (IS_ERR(artpec6_pcie
->phy_base
))
414 return PTR_ERR(artpec6_pcie
->phy_base
);
416 artpec6_pcie
->regmap
=
417 syscon_regmap_lookup_by_phandle(dev
->of_node
,
419 if (IS_ERR(artpec6_pcie
->regmap
))
420 return PTR_ERR(artpec6_pcie
->regmap
);
422 platform_set_drvdata(pdev
, artpec6_pcie
);
424 switch (artpec6_pcie
->mode
) {
425 case DW_PCIE_RC_TYPE
:
426 if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_HOST
))
429 pci
->pp
.ops
= &artpec6_pcie_host_ops
;
431 ret
= dw_pcie_host_init(&pci
->pp
);
435 case DW_PCIE_EP_TYPE
: {
438 if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_EP
))
441 val
= artpec6_pcie_readl(artpec6_pcie
, PCIECFG
);
442 val
&= ~PCIECFG_DEVICE_TYPE_MASK
;
443 artpec6_pcie_writel(artpec6_pcie
, PCIECFG
, val
);
445 pci
->ep
.ops
= &pcie_ep_ops
;
447 return dw_pcie_ep_init(&pci
->ep
);
451 dev_err(dev
, "INVALID device type %d\n", artpec6_pcie
->mode
);
457 static const struct artpec_pcie_of_data artpec6_pcie_rc_of_data
= {
459 .mode
= DW_PCIE_RC_TYPE
,
462 static const struct artpec_pcie_of_data artpec6_pcie_ep_of_data
= {
464 .mode
= DW_PCIE_EP_TYPE
,
467 static const struct artpec_pcie_of_data artpec7_pcie_rc_of_data
= {
469 .mode
= DW_PCIE_RC_TYPE
,
472 static const struct artpec_pcie_of_data artpec7_pcie_ep_of_data
= {
474 .mode
= DW_PCIE_EP_TYPE
,
477 static const struct of_device_id artpec6_pcie_of_match
[] = {
479 .compatible
= "axis,artpec6-pcie",
480 .data
= &artpec6_pcie_rc_of_data
,
483 .compatible
= "axis,artpec6-pcie-ep",
484 .data
= &artpec6_pcie_ep_of_data
,
487 .compatible
= "axis,artpec7-pcie",
488 .data
= &artpec7_pcie_rc_of_data
,
491 .compatible
= "axis,artpec7-pcie-ep",
492 .data
= &artpec7_pcie_ep_of_data
,
497 static struct platform_driver artpec6_pcie_driver
= {
498 .probe
= artpec6_pcie_probe
,
500 .name
= "artpec6-pcie",
501 .of_match_table
= artpec6_pcie_of_match
,
502 .suppress_bind_attrs
= true,
505 builtin_platform_driver(artpec6_pcie_driver
);