1 // SPDX-License-Identifier: GPL-2.0+
3 * Rockchip AXI PCIe host controller driver
5 * Copyright (c) 2016 Rockchip, Inc.
7 * Author: Shawn Lin <shawn.lin@rock-chips.com>
8 * Wenrui Li <wenrui.li@rock-chips.com>
10 * Bits taken from Synopsys DesignWare Host controller driver and
11 * ARM PCI Host generic driver.
14 #include <linux/clk.h>
15 #include <linux/delay.h>
16 #include <linux/gpio/consumer.h>
17 #include <linux/of_pci.h>
18 #include <linux/phy/phy.h>
19 #include <linux/platform_device.h>
20 #include <linux/reset.h>
23 #include "pcie-rockchip.h"
25 int rockchip_pcie_parse_dt(struct rockchip_pcie
*rockchip
)
27 struct device
*dev
= rockchip
->dev
;
28 struct platform_device
*pdev
= to_platform_device(dev
);
29 struct device_node
*node
= dev
->of_node
;
30 struct resource
*regs
;
33 if (rockchip
->is_rc
) {
34 regs
= platform_get_resource_byname(pdev
,
37 rockchip
->reg_base
= devm_pci_remap_cfg_resource(dev
, regs
);
38 if (IS_ERR(rockchip
->reg_base
))
39 return PTR_ERR(rockchip
->reg_base
);
42 platform_get_resource_byname(pdev
, IORESOURCE_MEM
,
44 if (!rockchip
->mem_res
)
49 devm_platform_ioremap_resource_byname(pdev
, "apb-base");
50 if (IS_ERR(rockchip
->apb_base
))
51 return PTR_ERR(rockchip
->apb_base
);
53 err
= rockchip_pcie_get_phys(rockchip
);
58 err
= of_property_read_u32(node
, "num-lanes", &rockchip
->lanes
);
59 if (!err
&& (rockchip
->lanes
== 0 ||
60 rockchip
->lanes
== 3 ||
61 rockchip
->lanes
> 4)) {
62 dev_warn(dev
, "invalid num-lanes, default to use one lane\n");
66 rockchip
->link_gen
= of_pci_get_max_link_speed(node
);
67 if (rockchip
->link_gen
< 0 || rockchip
->link_gen
> 2)
68 rockchip
->link_gen
= 2;
70 rockchip
->core_rst
= devm_reset_control_get_exclusive(dev
, "core");
71 if (IS_ERR(rockchip
->core_rst
)) {
72 if (PTR_ERR(rockchip
->core_rst
) != -EPROBE_DEFER
)
73 dev_err(dev
, "missing core reset property in node\n");
74 return PTR_ERR(rockchip
->core_rst
);
77 rockchip
->mgmt_rst
= devm_reset_control_get_exclusive(dev
, "mgmt");
78 if (IS_ERR(rockchip
->mgmt_rst
)) {
79 if (PTR_ERR(rockchip
->mgmt_rst
) != -EPROBE_DEFER
)
80 dev_err(dev
, "missing mgmt reset property in node\n");
81 return PTR_ERR(rockchip
->mgmt_rst
);
84 rockchip
->mgmt_sticky_rst
= devm_reset_control_get_exclusive(dev
,
86 if (IS_ERR(rockchip
->mgmt_sticky_rst
)) {
87 if (PTR_ERR(rockchip
->mgmt_sticky_rst
) != -EPROBE_DEFER
)
88 dev_err(dev
, "missing mgmt-sticky reset property in node\n");
89 return PTR_ERR(rockchip
->mgmt_sticky_rst
);
92 rockchip
->pipe_rst
= devm_reset_control_get_exclusive(dev
, "pipe");
93 if (IS_ERR(rockchip
->pipe_rst
)) {
94 if (PTR_ERR(rockchip
->pipe_rst
) != -EPROBE_DEFER
)
95 dev_err(dev
, "missing pipe reset property in node\n");
96 return PTR_ERR(rockchip
->pipe_rst
);
99 rockchip
->pm_rst
= devm_reset_control_get_exclusive(dev
, "pm");
100 if (IS_ERR(rockchip
->pm_rst
)) {
101 if (PTR_ERR(rockchip
->pm_rst
) != -EPROBE_DEFER
)
102 dev_err(dev
, "missing pm reset property in node\n");
103 return PTR_ERR(rockchip
->pm_rst
);
106 rockchip
->pclk_rst
= devm_reset_control_get_exclusive(dev
, "pclk");
107 if (IS_ERR(rockchip
->pclk_rst
)) {
108 if (PTR_ERR(rockchip
->pclk_rst
) != -EPROBE_DEFER
)
109 dev_err(dev
, "missing pclk reset property in node\n");
110 return PTR_ERR(rockchip
->pclk_rst
);
113 rockchip
->aclk_rst
= devm_reset_control_get_exclusive(dev
, "aclk");
114 if (IS_ERR(rockchip
->aclk_rst
)) {
115 if (PTR_ERR(rockchip
->aclk_rst
) != -EPROBE_DEFER
)
116 dev_err(dev
, "missing aclk reset property in node\n");
117 return PTR_ERR(rockchip
->aclk_rst
);
120 if (rockchip
->is_rc
) {
121 rockchip
->ep_gpio
= devm_gpiod_get(dev
, "ep", GPIOD_OUT_HIGH
);
122 if (IS_ERR(rockchip
->ep_gpio
)) {
123 dev_err(dev
, "missing ep-gpios property in node\n");
124 return PTR_ERR(rockchip
->ep_gpio
);
128 rockchip
->aclk_pcie
= devm_clk_get(dev
, "aclk");
129 if (IS_ERR(rockchip
->aclk_pcie
)) {
130 dev_err(dev
, "aclk clock not found\n");
131 return PTR_ERR(rockchip
->aclk_pcie
);
134 rockchip
->aclk_perf_pcie
= devm_clk_get(dev
, "aclk-perf");
135 if (IS_ERR(rockchip
->aclk_perf_pcie
)) {
136 dev_err(dev
, "aclk_perf clock not found\n");
137 return PTR_ERR(rockchip
->aclk_perf_pcie
);
140 rockchip
->hclk_pcie
= devm_clk_get(dev
, "hclk");
141 if (IS_ERR(rockchip
->hclk_pcie
)) {
142 dev_err(dev
, "hclk clock not found\n");
143 return PTR_ERR(rockchip
->hclk_pcie
);
146 rockchip
->clk_pcie_pm
= devm_clk_get(dev
, "pm");
147 if (IS_ERR(rockchip
->clk_pcie_pm
)) {
148 dev_err(dev
, "pm clock not found\n");
149 return PTR_ERR(rockchip
->clk_pcie_pm
);
154 EXPORT_SYMBOL_GPL(rockchip_pcie_parse_dt
);
156 int rockchip_pcie_init_port(struct rockchip_pcie
*rockchip
)
158 struct device
*dev
= rockchip
->dev
;
162 err
= reset_control_assert(rockchip
->aclk_rst
);
164 dev_err(dev
, "assert aclk_rst err %d\n", err
);
168 err
= reset_control_assert(rockchip
->pclk_rst
);
170 dev_err(dev
, "assert pclk_rst err %d\n", err
);
174 err
= reset_control_assert(rockchip
->pm_rst
);
176 dev_err(dev
, "assert pm_rst err %d\n", err
);
180 for (i
= 0; i
< MAX_LANE_NUM
; i
++) {
181 err
= phy_init(rockchip
->phys
[i
]);
183 dev_err(dev
, "init phy%d err %d\n", i
, err
);
188 err
= reset_control_assert(rockchip
->core_rst
);
190 dev_err(dev
, "assert core_rst err %d\n", err
);
194 err
= reset_control_assert(rockchip
->mgmt_rst
);
196 dev_err(dev
, "assert mgmt_rst err %d\n", err
);
200 err
= reset_control_assert(rockchip
->mgmt_sticky_rst
);
202 dev_err(dev
, "assert mgmt_sticky_rst err %d\n", err
);
206 err
= reset_control_assert(rockchip
->pipe_rst
);
208 dev_err(dev
, "assert pipe_rst err %d\n", err
);
214 err
= reset_control_deassert(rockchip
->pm_rst
);
216 dev_err(dev
, "deassert pm_rst err %d\n", err
);
220 err
= reset_control_deassert(rockchip
->aclk_rst
);
222 dev_err(dev
, "deassert aclk_rst err %d\n", err
);
226 err
= reset_control_deassert(rockchip
->pclk_rst
);
228 dev_err(dev
, "deassert pclk_rst err %d\n", err
);
232 if (rockchip
->link_gen
== 2)
233 rockchip_pcie_write(rockchip
, PCIE_CLIENT_GEN_SEL_2
,
236 rockchip_pcie_write(rockchip
, PCIE_CLIENT_GEN_SEL_1
,
239 regs
= PCIE_CLIENT_LINK_TRAIN_ENABLE
| PCIE_CLIENT_ARI_ENABLE
|
240 PCIE_CLIENT_CONF_LANE_NUM(rockchip
->lanes
);
243 regs
|= PCIE_CLIENT_CONF_ENABLE
| PCIE_CLIENT_MODE_RC
;
245 regs
|= PCIE_CLIENT_CONF_DISABLE
| PCIE_CLIENT_MODE_EP
;
247 rockchip_pcie_write(rockchip
, regs
, PCIE_CLIENT_CONFIG
);
249 for (i
= 0; i
< MAX_LANE_NUM
; i
++) {
250 err
= phy_power_on(rockchip
->phys
[i
]);
252 dev_err(dev
, "power on phy%d err %d\n", i
, err
);
253 goto err_power_off_phy
;
258 * Please don't reorder the deassert sequence of the following
261 err
= reset_control_deassert(rockchip
->mgmt_sticky_rst
);
263 dev_err(dev
, "deassert mgmt_sticky_rst err %d\n", err
);
264 goto err_power_off_phy
;
267 err
= reset_control_deassert(rockchip
->core_rst
);
269 dev_err(dev
, "deassert core_rst err %d\n", err
);
270 goto err_power_off_phy
;
273 err
= reset_control_deassert(rockchip
->mgmt_rst
);
275 dev_err(dev
, "deassert mgmt_rst err %d\n", err
);
276 goto err_power_off_phy
;
279 err
= reset_control_deassert(rockchip
->pipe_rst
);
281 dev_err(dev
, "deassert pipe_rst err %d\n", err
);
282 goto err_power_off_phy
;
288 phy_power_off(rockchip
->phys
[i
]);
292 phy_exit(rockchip
->phys
[i
]);
295 EXPORT_SYMBOL_GPL(rockchip_pcie_init_port
);
297 int rockchip_pcie_get_phys(struct rockchip_pcie
*rockchip
)
299 struct device
*dev
= rockchip
->dev
;
304 phy
= devm_phy_get(dev
, "pcie-phy");
306 rockchip
->legacy_phy
= true;
307 rockchip
->phys
[0] = phy
;
308 dev_warn(dev
, "legacy phy model is deprecated!\n");
312 if (PTR_ERR(phy
) == -EPROBE_DEFER
)
315 dev_dbg(dev
, "missing legacy phy; search for per-lane PHY\n");
317 for (i
= 0; i
< MAX_LANE_NUM
; i
++) {
318 name
= kasprintf(GFP_KERNEL
, "pcie-phy-%u", i
);
322 phy
= devm_of_phy_get(dev
, dev
->of_node
, name
);
326 if (PTR_ERR(phy
) != -EPROBE_DEFER
)
327 dev_err(dev
, "missing phy for lane %d: %ld\n",
332 rockchip
->phys
[i
] = phy
;
337 EXPORT_SYMBOL_GPL(rockchip_pcie_get_phys
);
339 void rockchip_pcie_deinit_phys(struct rockchip_pcie
*rockchip
)
343 for (i
= 0; i
< MAX_LANE_NUM
; i
++) {
344 /* inactive lanes are already powered off */
345 if (rockchip
->lanes_map
& BIT(i
))
346 phy_power_off(rockchip
->phys
[i
]);
347 phy_exit(rockchip
->phys
[i
]);
350 EXPORT_SYMBOL_GPL(rockchip_pcie_deinit_phys
);
352 int rockchip_pcie_enable_clocks(struct rockchip_pcie
*rockchip
)
354 struct device
*dev
= rockchip
->dev
;
357 err
= clk_prepare_enable(rockchip
->aclk_pcie
);
359 dev_err(dev
, "unable to enable aclk_pcie clock\n");
363 err
= clk_prepare_enable(rockchip
->aclk_perf_pcie
);
365 dev_err(dev
, "unable to enable aclk_perf_pcie clock\n");
366 goto err_aclk_perf_pcie
;
369 err
= clk_prepare_enable(rockchip
->hclk_pcie
);
371 dev_err(dev
, "unable to enable hclk_pcie clock\n");
375 err
= clk_prepare_enable(rockchip
->clk_pcie_pm
);
377 dev_err(dev
, "unable to enable clk_pcie_pm clock\n");
378 goto err_clk_pcie_pm
;
384 clk_disable_unprepare(rockchip
->hclk_pcie
);
386 clk_disable_unprepare(rockchip
->aclk_perf_pcie
);
388 clk_disable_unprepare(rockchip
->aclk_pcie
);
391 EXPORT_SYMBOL_GPL(rockchip_pcie_enable_clocks
);
393 void rockchip_pcie_disable_clocks(void *data
)
395 struct rockchip_pcie
*rockchip
= data
;
397 clk_disable_unprepare(rockchip
->clk_pcie_pm
);
398 clk_disable_unprepare(rockchip
->hclk_pcie
);
399 clk_disable_unprepare(rockchip
->aclk_perf_pcie
);
400 clk_disable_unprepare(rockchip
->aclk_pcie
);
402 EXPORT_SYMBOL_GPL(rockchip_pcie_disable_clocks
);
404 void rockchip_pcie_cfg_configuration_accesses(
405 struct rockchip_pcie
*rockchip
, u32 type
)
409 /* Configuration Accesses for region 0 */
410 rockchip_pcie_write(rockchip
, 0x0, PCIE_RC_BAR_CONF
);
412 rockchip_pcie_write(rockchip
,
413 (RC_REGION_0_ADDR_TRANS_L
+ RC_REGION_0_PASS_BITS
),
414 PCIE_CORE_OB_REGION_ADDR0
);
415 rockchip_pcie_write(rockchip
, RC_REGION_0_ADDR_TRANS_H
,
416 PCIE_CORE_OB_REGION_ADDR1
);
417 ob_desc_0
= rockchip_pcie_read(rockchip
, PCIE_CORE_OB_REGION_DESC0
);
418 ob_desc_0
&= ~(RC_REGION_0_TYPE_MASK
);
419 ob_desc_0
|= (type
| (0x1 << 23));
420 rockchip_pcie_write(rockchip
, ob_desc_0
, PCIE_CORE_OB_REGION_DESC0
);
421 rockchip_pcie_write(rockchip
, 0x0, PCIE_CORE_OB_REGION_DESC1
);
423 EXPORT_SYMBOL_GPL(rockchip_pcie_cfg_configuration_accesses
);