1 // SPDX-License-Identifier: GPL-2.0
3 * PCIe host controller driver for Rockchip SoCs.
5 * Copyright (C) 2021 Rockchip Electronics Co., Ltd.
6 * http://www.rock-chips.com
8 * Author: Simon Xue <xxm@rock-chips.com>
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>
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>
24 #include "pcie-designware.h"
27 * The upper 16 bits of PCIE_CLIENT_CONFIG are a write
28 * mask for the lower 16 bits.
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)
34 #define to_rockchip_pcie(x) dev_get_drvdata((x)->dev)
36 #define PCIE_CLIENT_RC_MODE HIWORD_UPDATE_BIT(0x40)
37 #define PCIE_CLIENT_EP_MODE HIWORD_UPDATE(0xf0, 0x0)
38 #define PCIE_CLIENT_ENABLE_LTSSM HIWORD_UPDATE_BIT(0xc)
39 #define PCIE_CLIENT_DISABLE_LTSSM HIWORD_UPDATE(0x0c, 0x8)
40 #define PCIE_CLIENT_INTR_STATUS_MISC 0x10
41 #define PCIE_CLIENT_INTR_MASK_MISC 0x24
42 #define PCIE_SMLH_LINKUP BIT(16)
43 #define PCIE_RDLH_LINKUP BIT(17)
44 #define PCIE_LINKUP (PCIE_SMLH_LINKUP | PCIE_RDLH_LINKUP)
45 #define PCIE_RDLH_LINK_UP_CHGED BIT(1)
46 #define PCIE_LINK_REQ_RST_NOT_INT BIT(2)
47 #define PCIE_L0S_ENTRY 0x11
48 #define PCIE_CLIENT_GENERAL_CONTROL 0x0
49 #define PCIE_CLIENT_INTR_STATUS_LEGACY 0x8
50 #define PCIE_CLIENT_INTR_MASK_LEGACY 0x1c
51 #define PCIE_CLIENT_GENERAL_DEBUG 0x104
52 #define PCIE_CLIENT_HOT_RESET_CTRL 0x180
53 #define PCIE_CLIENT_LTSSM_STATUS 0x300
54 #define PCIE_LTSSM_ENABLE_ENHANCE BIT(4)
55 #define PCIE_LTSSM_STATUS_MASK GENMASK(5, 0)
57 struct rockchip_pcie
{
59 void __iomem
*apb_base
;
61 struct clk_bulk_data
*clks
;
63 struct reset_control
*rst
;
64 struct gpio_desc
*rst_gpio
;
65 struct regulator
*vpcie3v3
;
66 struct irq_domain
*irq_domain
;
67 const struct rockchip_pcie_of_data
*data
;
70 struct rockchip_pcie_of_data
{
71 enum dw_pcie_device_mode mode
;
72 const struct pci_epc_features
*epc_features
;
75 static int rockchip_pcie_readl_apb(struct rockchip_pcie
*rockchip
, u32 reg
)
77 return readl_relaxed(rockchip
->apb_base
+ reg
);
80 static void rockchip_pcie_writel_apb(struct rockchip_pcie
*rockchip
, u32 val
,
83 writel_relaxed(val
, rockchip
->apb_base
+ reg
);
86 static void rockchip_pcie_intx_handler(struct irq_desc
*desc
)
88 struct irq_chip
*chip
= irq_desc_get_chip(desc
);
89 struct rockchip_pcie
*rockchip
= irq_desc_get_handler_data(desc
);
90 unsigned long reg
, hwirq
;
92 chained_irq_enter(chip
, desc
);
94 reg
= rockchip_pcie_readl_apb(rockchip
, PCIE_CLIENT_INTR_STATUS_LEGACY
);
96 for_each_set_bit(hwirq
, ®
, 4)
97 generic_handle_domain_irq(rockchip
->irq_domain
, hwirq
);
99 chained_irq_exit(chip
, desc
);
102 static void rockchip_intx_mask(struct irq_data
*data
)
104 rockchip_pcie_writel_apb(irq_data_get_irq_chip_data(data
),
105 HIWORD_UPDATE_BIT(BIT(data
->hwirq
)),
106 PCIE_CLIENT_INTR_MASK_LEGACY
);
109 static void rockchip_intx_unmask(struct irq_data
*data
)
111 rockchip_pcie_writel_apb(irq_data_get_irq_chip_data(data
),
112 HIWORD_DISABLE_BIT(BIT(data
->hwirq
)),
113 PCIE_CLIENT_INTR_MASK_LEGACY
);
116 static struct irq_chip rockchip_intx_irq_chip
= {
118 .irq_mask
= rockchip_intx_mask
,
119 .irq_unmask
= rockchip_intx_unmask
,
120 .flags
= IRQCHIP_SKIP_SET_WAKE
| IRQCHIP_MASK_ON_SUSPEND
,
123 static int rockchip_pcie_intx_map(struct irq_domain
*domain
, unsigned int irq
,
124 irq_hw_number_t hwirq
)
126 irq_set_chip_and_handler(irq
, &rockchip_intx_irq_chip
, handle_level_irq
);
127 irq_set_chip_data(irq
, domain
->host_data
);
132 static const struct irq_domain_ops intx_domain_ops
= {
133 .map
= rockchip_pcie_intx_map
,
136 static int rockchip_pcie_init_irq_domain(struct rockchip_pcie
*rockchip
)
138 struct device
*dev
= rockchip
->pci
.dev
;
139 struct device_node
*intc
;
141 intc
= of_get_child_by_name(dev
->of_node
, "legacy-interrupt-controller");
143 dev_err(dev
, "missing child interrupt-controller node\n");
147 rockchip
->irq_domain
= irq_domain_add_linear(intc
, PCI_NUM_INTX
,
148 &intx_domain_ops
, rockchip
);
150 if (!rockchip
->irq_domain
) {
151 dev_err(dev
, "failed to get a INTx IRQ domain\n");
158 static u32
rockchip_pcie_get_ltssm(struct rockchip_pcie
*rockchip
)
160 return rockchip_pcie_readl_apb(rockchip
, PCIE_CLIENT_LTSSM_STATUS
);
163 static void rockchip_pcie_enable_ltssm(struct rockchip_pcie
*rockchip
)
165 rockchip_pcie_writel_apb(rockchip
, PCIE_CLIENT_ENABLE_LTSSM
,
166 PCIE_CLIENT_GENERAL_CONTROL
);
169 static void rockchip_pcie_disable_ltssm(struct rockchip_pcie
*rockchip
)
171 rockchip_pcie_writel_apb(rockchip
, PCIE_CLIENT_DISABLE_LTSSM
,
172 PCIE_CLIENT_GENERAL_CONTROL
);
175 static int rockchip_pcie_link_up(struct dw_pcie
*pci
)
177 struct rockchip_pcie
*rockchip
= to_rockchip_pcie(pci
);
178 u32 val
= rockchip_pcie_get_ltssm(rockchip
);
180 if ((val
& PCIE_LINKUP
) == PCIE_LINKUP
&&
181 (val
& PCIE_LTSSM_STATUS_MASK
) == PCIE_L0S_ENTRY
)
187 static int rockchip_pcie_start_link(struct dw_pcie
*pci
)
189 struct rockchip_pcie
*rockchip
= to_rockchip_pcie(pci
);
192 gpiod_set_value_cansleep(rockchip
->rst_gpio
, 0);
194 rockchip_pcie_enable_ltssm(rockchip
);
197 * PCIe requires the refclk to be stable for 100µs prior to releasing
198 * PERST. See table 2-4 in section 2.6.2 AC Specifications of the PCI
199 * Express Card Electromechanical Specification, 1.1. However, we don't
200 * know if the refclk is coming from RC's PHY or external OSC. If it's
201 * from RC, so enabling LTSSM is the just right place to release #PERST.
202 * We need more extra time as before, rather than setting just
203 * 100us as we don't know how long should the device need to reset.
206 gpiod_set_value_cansleep(rockchip
->rst_gpio
, 1);
211 static void rockchip_pcie_stop_link(struct dw_pcie
*pci
)
213 struct rockchip_pcie
*rockchip
= to_rockchip_pcie(pci
);
215 rockchip_pcie_disable_ltssm(rockchip
);
218 static int rockchip_pcie_host_init(struct dw_pcie_rp
*pp
)
220 struct dw_pcie
*pci
= to_dw_pcie_from_pp(pp
);
221 struct rockchip_pcie
*rockchip
= to_rockchip_pcie(pci
);
222 struct device
*dev
= rockchip
->pci
.dev
;
225 irq
= of_irq_get_byname(dev
->of_node
, "legacy");
229 ret
= rockchip_pcie_init_irq_domain(rockchip
);
231 dev_err(dev
, "failed to init irq domain\n");
233 irq_set_chained_handler_and_data(irq
, rockchip_pcie_intx_handler
,
239 static const struct dw_pcie_host_ops rockchip_pcie_host_ops
= {
240 .init
= rockchip_pcie_host_init
,
243 static void rockchip_pcie_ep_init(struct dw_pcie_ep
*ep
)
245 struct dw_pcie
*pci
= to_dw_pcie_from_ep(ep
);
248 for (bar
= 0; bar
< PCI_STD_NUM_BARS
; bar
++)
249 dw_pcie_ep_reset_bar(pci
, bar
);
252 static int rockchip_pcie_raise_irq(struct dw_pcie_ep
*ep
, u8 func_no
,
253 unsigned int type
, u16 interrupt_num
)
255 struct dw_pcie
*pci
= to_dw_pcie_from_ep(ep
);
259 return dw_pcie_ep_raise_intx_irq(ep
, func_no
);
261 return dw_pcie_ep_raise_msi_irq(ep
, func_no
, interrupt_num
);
263 return dw_pcie_ep_raise_msix_irq(ep
, func_no
, interrupt_num
);
265 dev_err(pci
->dev
, "UNKNOWN IRQ type\n");
271 static const struct pci_epc_features rockchip_pcie_epc_features_rk3568
= {
272 .linkup_notifier
= true,
274 .msix_capable
= true,
276 .bar
[BAR_0
] = { .type
= BAR_FIXED
, .fixed_size
= SZ_1M
, },
277 .bar
[BAR_1
] = { .type
= BAR_FIXED
, .fixed_size
= SZ_1M
, },
278 .bar
[BAR_2
] = { .type
= BAR_FIXED
, .fixed_size
= SZ_1M
, },
279 .bar
[BAR_3
] = { .type
= BAR_FIXED
, .fixed_size
= SZ_1M
, },
280 .bar
[BAR_4
] = { .type
= BAR_FIXED
, .fixed_size
= SZ_1M
, },
281 .bar
[BAR_5
] = { .type
= BAR_FIXED
, .fixed_size
= SZ_1M
, },
285 * BAR4 on rk3588 exposes the ATU Port Logic Structure to the host regardless of
286 * iATU settings for BAR4. This means that BAR4 cannot be used by an EPF driver,
287 * so mark it as RESERVED. (rockchip_pcie_ep_init() will disable all BARs by
288 * default.) If the host could write to BAR4, the iATU settings (for all other
289 * BARs) would be overwritten, resulting in (all other BARs) no longer working.
291 static const struct pci_epc_features rockchip_pcie_epc_features_rk3588
= {
292 .linkup_notifier
= true,
294 .msix_capable
= true,
296 .bar
[BAR_0
] = { .type
= BAR_FIXED
, .fixed_size
= SZ_1M
, },
297 .bar
[BAR_1
] = { .type
= BAR_FIXED
, .fixed_size
= SZ_1M
, },
298 .bar
[BAR_2
] = { .type
= BAR_FIXED
, .fixed_size
= SZ_1M
, },
299 .bar
[BAR_3
] = { .type
= BAR_FIXED
, .fixed_size
= SZ_1M
, },
300 .bar
[BAR_4
] = { .type
= BAR_RESERVED
, },
301 .bar
[BAR_5
] = { .type
= BAR_FIXED
, .fixed_size
= SZ_1M
, },
304 static const struct pci_epc_features
*
305 rockchip_pcie_get_features(struct dw_pcie_ep
*ep
)
307 struct dw_pcie
*pci
= to_dw_pcie_from_ep(ep
);
308 struct rockchip_pcie
*rockchip
= to_rockchip_pcie(pci
);
310 return rockchip
->data
->epc_features
;
313 static const struct dw_pcie_ep_ops rockchip_pcie_ep_ops
= {
314 .init
= rockchip_pcie_ep_init
,
315 .raise_irq
= rockchip_pcie_raise_irq
,
316 .get_features
= rockchip_pcie_get_features
,
319 static int rockchip_pcie_clk_init(struct rockchip_pcie
*rockchip
)
321 struct device
*dev
= rockchip
->pci
.dev
;
324 ret
= devm_clk_bulk_get_all(dev
, &rockchip
->clks
);
326 return dev_err_probe(dev
, ret
, "failed to get clocks\n");
328 rockchip
->clk_cnt
= ret
;
330 ret
= clk_bulk_prepare_enable(rockchip
->clk_cnt
, rockchip
->clks
);
332 return dev_err_probe(dev
, ret
, "failed to enable clocks\n");
337 static int rockchip_pcie_resource_get(struct platform_device
*pdev
,
338 struct rockchip_pcie
*rockchip
)
340 rockchip
->apb_base
= devm_platform_ioremap_resource_byname(pdev
, "apb");
341 if (IS_ERR(rockchip
->apb_base
))
342 return dev_err_probe(&pdev
->dev
, PTR_ERR(rockchip
->apb_base
),
343 "failed to map apb registers\n");
345 rockchip
->rst_gpio
= devm_gpiod_get_optional(&pdev
->dev
, "reset",
347 if (IS_ERR(rockchip
->rst_gpio
))
348 return dev_err_probe(&pdev
->dev
, PTR_ERR(rockchip
->rst_gpio
),
349 "failed to get reset gpio\n");
351 rockchip
->rst
= devm_reset_control_array_get_exclusive(&pdev
->dev
);
352 if (IS_ERR(rockchip
->rst
))
353 return dev_err_probe(&pdev
->dev
, PTR_ERR(rockchip
->rst
),
354 "failed to get reset lines\n");
359 static int rockchip_pcie_phy_init(struct rockchip_pcie
*rockchip
)
361 struct device
*dev
= rockchip
->pci
.dev
;
364 rockchip
->phy
= devm_phy_get(dev
, "pcie-phy");
365 if (IS_ERR(rockchip
->phy
))
366 return dev_err_probe(dev
, PTR_ERR(rockchip
->phy
),
369 ret
= phy_init(rockchip
->phy
);
373 ret
= phy_power_on(rockchip
->phy
);
375 phy_exit(rockchip
->phy
);
380 static void rockchip_pcie_phy_deinit(struct rockchip_pcie
*rockchip
)
382 phy_exit(rockchip
->phy
);
383 phy_power_off(rockchip
->phy
);
386 static const struct dw_pcie_ops dw_pcie_ops
= {
387 .link_up
= rockchip_pcie_link_up
,
388 .start_link
= rockchip_pcie_start_link
,
389 .stop_link
= rockchip_pcie_stop_link
,
392 static irqreturn_t
rockchip_pcie_ep_sys_irq_thread(int irq
, void *arg
)
394 struct rockchip_pcie
*rockchip
= arg
;
395 struct dw_pcie
*pci
= &rockchip
->pci
;
396 struct device
*dev
= pci
->dev
;
399 reg
= rockchip_pcie_readl_apb(rockchip
, PCIE_CLIENT_INTR_STATUS_MISC
);
400 rockchip_pcie_writel_apb(rockchip
, reg
, PCIE_CLIENT_INTR_STATUS_MISC
);
402 dev_dbg(dev
, "PCIE_CLIENT_INTR_STATUS_MISC: %#x\n", reg
);
403 dev_dbg(dev
, "LTSSM_STATUS: %#x\n", rockchip_pcie_get_ltssm(rockchip
));
405 if (reg
& PCIE_LINK_REQ_RST_NOT_INT
) {
406 dev_dbg(dev
, "hot reset or link-down reset\n");
407 dw_pcie_ep_linkdown(&pci
->ep
);
410 if (reg
& PCIE_RDLH_LINK_UP_CHGED
) {
411 val
= rockchip_pcie_get_ltssm(rockchip
);
412 if ((val
& PCIE_LINKUP
) == PCIE_LINKUP
) {
413 dev_dbg(dev
, "link up\n");
414 dw_pcie_ep_linkup(&pci
->ep
);
421 static int rockchip_pcie_configure_rc(struct rockchip_pcie
*rockchip
)
423 struct dw_pcie_rp
*pp
;
426 if (!IS_ENABLED(CONFIG_PCIE_ROCKCHIP_DW_HOST
))
429 /* LTSSM enable control mode */
430 val
= HIWORD_UPDATE_BIT(PCIE_LTSSM_ENABLE_ENHANCE
);
431 rockchip_pcie_writel_apb(rockchip
, val
, PCIE_CLIENT_HOT_RESET_CTRL
);
433 rockchip_pcie_writel_apb(rockchip
, PCIE_CLIENT_RC_MODE
,
434 PCIE_CLIENT_GENERAL_CONTROL
);
436 pp
= &rockchip
->pci
.pp
;
437 pp
->ops
= &rockchip_pcie_host_ops
;
439 return dw_pcie_host_init(pp
);
442 static int rockchip_pcie_configure_ep(struct platform_device
*pdev
,
443 struct rockchip_pcie
*rockchip
)
445 struct device
*dev
= &pdev
->dev
;
449 if (!IS_ENABLED(CONFIG_PCIE_ROCKCHIP_DW_EP
))
452 irq
= platform_get_irq_byname(pdev
, "sys");
454 dev_err(dev
, "missing sys IRQ resource\n");
458 ret
= devm_request_threaded_irq(dev
, irq
, NULL
,
459 rockchip_pcie_ep_sys_irq_thread
,
460 IRQF_ONESHOT
, "pcie-sys", rockchip
);
462 dev_err(dev
, "failed to request PCIe sys IRQ\n");
466 /* LTSSM enable control mode */
467 val
= HIWORD_UPDATE_BIT(PCIE_LTSSM_ENABLE_ENHANCE
);
468 rockchip_pcie_writel_apb(rockchip
, val
, PCIE_CLIENT_HOT_RESET_CTRL
);
470 rockchip_pcie_writel_apb(rockchip
, PCIE_CLIENT_EP_MODE
,
471 PCIE_CLIENT_GENERAL_CONTROL
);
473 rockchip
->pci
.ep
.ops
= &rockchip_pcie_ep_ops
;
474 rockchip
->pci
.ep
.page_size
= SZ_64K
;
476 dma_set_mask_and_coherent(dev
, DMA_BIT_MASK(64));
478 ret
= dw_pcie_ep_init(&rockchip
->pci
.ep
);
480 dev_err(dev
, "failed to initialize endpoint\n");
484 ret
= dw_pcie_ep_init_registers(&rockchip
->pci
.ep
);
486 dev_err(dev
, "failed to initialize DWC endpoint registers\n");
487 dw_pcie_ep_deinit(&rockchip
->pci
.ep
);
491 pci_epc_init_notify(rockchip
->pci
.ep
.epc
);
493 /* unmask DLL up/down indicator and hot reset/link-down reset */
494 rockchip_pcie_writel_apb(rockchip
, 0x60000, PCIE_CLIENT_INTR_MASK_MISC
);
499 static int rockchip_pcie_probe(struct platform_device
*pdev
)
501 struct device
*dev
= &pdev
->dev
;
502 struct rockchip_pcie
*rockchip
;
503 const struct rockchip_pcie_of_data
*data
;
506 data
= of_device_get_match_data(dev
);
510 rockchip
= devm_kzalloc(dev
, sizeof(*rockchip
), GFP_KERNEL
);
514 platform_set_drvdata(pdev
, rockchip
);
516 rockchip
->pci
.dev
= dev
;
517 rockchip
->pci
.ops
= &dw_pcie_ops
;
518 rockchip
->data
= data
;
520 ret
= rockchip_pcie_resource_get(pdev
, rockchip
);
524 ret
= reset_control_assert(rockchip
->rst
);
528 /* DON'T MOVE ME: must be enable before PHY init */
529 rockchip
->vpcie3v3
= devm_regulator_get_optional(dev
, "vpcie3v3");
530 if (IS_ERR(rockchip
->vpcie3v3
)) {
531 if (PTR_ERR(rockchip
->vpcie3v3
) != -ENODEV
)
532 return dev_err_probe(dev
, PTR_ERR(rockchip
->vpcie3v3
),
533 "failed to get vpcie3v3 regulator\n");
534 rockchip
->vpcie3v3
= NULL
;
536 ret
= regulator_enable(rockchip
->vpcie3v3
);
538 return dev_err_probe(dev
, ret
,
539 "failed to enable vpcie3v3 regulator\n");
542 ret
= rockchip_pcie_phy_init(rockchip
);
544 goto disable_regulator
;
546 ret
= reset_control_deassert(rockchip
->rst
);
550 ret
= rockchip_pcie_clk_init(rockchip
);
554 switch (data
->mode
) {
555 case DW_PCIE_RC_TYPE
:
556 ret
= rockchip_pcie_configure_rc(rockchip
);
560 case DW_PCIE_EP_TYPE
:
561 ret
= rockchip_pcie_configure_ep(pdev
, rockchip
);
566 dev_err(dev
, "INVALID device type %d\n", data
->mode
);
574 clk_bulk_disable_unprepare(rockchip
->clk_cnt
, rockchip
->clks
);
576 rockchip_pcie_phy_deinit(rockchip
);
578 if (rockchip
->vpcie3v3
)
579 regulator_disable(rockchip
->vpcie3v3
);
584 static const struct rockchip_pcie_of_data rockchip_pcie_rc_of_data_rk3568
= {
585 .mode
= DW_PCIE_RC_TYPE
,
588 static const struct rockchip_pcie_of_data rockchip_pcie_ep_of_data_rk3568
= {
589 .mode
= DW_PCIE_EP_TYPE
,
590 .epc_features
= &rockchip_pcie_epc_features_rk3568
,
593 static const struct rockchip_pcie_of_data rockchip_pcie_ep_of_data_rk3588
= {
594 .mode
= DW_PCIE_EP_TYPE
,
595 .epc_features
= &rockchip_pcie_epc_features_rk3588
,
598 static const struct of_device_id rockchip_pcie_of_match
[] = {
600 .compatible
= "rockchip,rk3568-pcie",
601 .data
= &rockchip_pcie_rc_of_data_rk3568
,
604 .compatible
= "rockchip,rk3568-pcie-ep",
605 .data
= &rockchip_pcie_ep_of_data_rk3568
,
608 .compatible
= "rockchip,rk3588-pcie-ep",
609 .data
= &rockchip_pcie_ep_of_data_rk3588
,
614 static struct platform_driver rockchip_pcie_driver
= {
616 .name
= "rockchip-dw-pcie",
617 .of_match_table
= rockchip_pcie_of_match
,
618 .suppress_bind_attrs
= true,
620 .probe
= rockchip_pcie_probe
,
622 builtin_platform_driver(rockchip_pcie_driver
);