xref: /OK3568_Linux_fs/kernel/drivers/pci/controller/pcie-rockchip.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Rockchip AXI PCIe host controller driver
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (c) 2016 Rockchip, Inc.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Author: Shawn Lin <shawn.lin@rock-chips.com>
8*4882a593Smuzhiyun  *         Wenrui Li <wenrui.li@rock-chips.com>
9*4882a593Smuzhiyun  *
10*4882a593Smuzhiyun  * Bits taken from Synopsys DesignWare Host controller driver and
11*4882a593Smuzhiyun  * ARM PCI Host generic driver.
12*4882a593Smuzhiyun  */
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #include <linux/clk.h>
15*4882a593Smuzhiyun #include <linux/delay.h>
16*4882a593Smuzhiyun #include <linux/gpio/consumer.h>
17*4882a593Smuzhiyun #include <linux/module.h>
18*4882a593Smuzhiyun #include <linux/of_pci.h>
19*4882a593Smuzhiyun #include <linux/phy/phy.h>
20*4882a593Smuzhiyun #include <linux/platform_device.h>
21*4882a593Smuzhiyun #include <linux/reset.h>
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #include "../pci.h"
24*4882a593Smuzhiyun #include "pcie-rockchip.h"
25*4882a593Smuzhiyun 
rockchip_pcie_parse_dt(struct rockchip_pcie * rockchip)26*4882a593Smuzhiyun int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
27*4882a593Smuzhiyun {
28*4882a593Smuzhiyun 	struct device *dev = rockchip->dev;
29*4882a593Smuzhiyun 	struct platform_device *pdev = to_platform_device(dev);
30*4882a593Smuzhiyun 	struct device_node *node = dev->of_node;
31*4882a593Smuzhiyun 	struct resource *regs;
32*4882a593Smuzhiyun 	int err;
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun 	if (rockchip->is_rc) {
35*4882a593Smuzhiyun 		regs = platform_get_resource_byname(pdev,
36*4882a593Smuzhiyun 						    IORESOURCE_MEM,
37*4882a593Smuzhiyun 						    "axi-base");
38*4882a593Smuzhiyun 		rockchip->reg_base = devm_pci_remap_cfg_resource(dev, regs);
39*4882a593Smuzhiyun 		if (IS_ERR(rockchip->reg_base))
40*4882a593Smuzhiyun 			return PTR_ERR(rockchip->reg_base);
41*4882a593Smuzhiyun 	} else {
42*4882a593Smuzhiyun 		rockchip->mem_res =
43*4882a593Smuzhiyun 			platform_get_resource_byname(pdev, IORESOURCE_MEM,
44*4882a593Smuzhiyun 						     "mem-base");
45*4882a593Smuzhiyun 		if (!rockchip->mem_res)
46*4882a593Smuzhiyun 			return -EINVAL;
47*4882a593Smuzhiyun 	}
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun 	rockchip->apb_base =
50*4882a593Smuzhiyun 		devm_platform_ioremap_resource_byname(pdev, "apb-base");
51*4882a593Smuzhiyun 	if (IS_ERR(rockchip->apb_base))
52*4882a593Smuzhiyun 		return PTR_ERR(rockchip->apb_base);
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	err = rockchip_pcie_get_phys(rockchip);
55*4882a593Smuzhiyun 	if (err)
56*4882a593Smuzhiyun 		return err;
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun 	rockchip->lanes = 1;
59*4882a593Smuzhiyun 	err = of_property_read_u32(node, "num-lanes", &rockchip->lanes);
60*4882a593Smuzhiyun 	if (!err && (rockchip->lanes == 0 ||
61*4882a593Smuzhiyun 		     rockchip->lanes == 3 ||
62*4882a593Smuzhiyun 		     rockchip->lanes > 4)) {
63*4882a593Smuzhiyun 		dev_warn(dev, "invalid num-lanes, default to use one lane\n");
64*4882a593Smuzhiyun 		rockchip->lanes = 1;
65*4882a593Smuzhiyun 	}
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun 	rockchip->link_gen = of_pci_get_max_link_speed(node);
68*4882a593Smuzhiyun 	if (rockchip->link_gen < 0 || rockchip->link_gen > 2)
69*4882a593Smuzhiyun 		rockchip->link_gen = 2;
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun 	rockchip->core_rst = devm_reset_control_get_exclusive(dev, "core");
72*4882a593Smuzhiyun 	if (IS_ERR(rockchip->core_rst)) {
73*4882a593Smuzhiyun 		if (PTR_ERR(rockchip->core_rst) != -EPROBE_DEFER)
74*4882a593Smuzhiyun 			dev_err(dev, "missing core reset property in node\n");
75*4882a593Smuzhiyun 		return PTR_ERR(rockchip->core_rst);
76*4882a593Smuzhiyun 	}
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 	rockchip->mgmt_rst = devm_reset_control_get_exclusive(dev, "mgmt");
79*4882a593Smuzhiyun 	if (IS_ERR(rockchip->mgmt_rst)) {
80*4882a593Smuzhiyun 		if (PTR_ERR(rockchip->mgmt_rst) != -EPROBE_DEFER)
81*4882a593Smuzhiyun 			dev_err(dev, "missing mgmt reset property in node\n");
82*4882a593Smuzhiyun 		return PTR_ERR(rockchip->mgmt_rst);
83*4882a593Smuzhiyun 	}
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	rockchip->mgmt_sticky_rst = devm_reset_control_get_exclusive(dev,
86*4882a593Smuzhiyun 								"mgmt-sticky");
87*4882a593Smuzhiyun 	if (IS_ERR(rockchip->mgmt_sticky_rst)) {
88*4882a593Smuzhiyun 		if (PTR_ERR(rockchip->mgmt_sticky_rst) != -EPROBE_DEFER)
89*4882a593Smuzhiyun 			dev_err(dev, "missing mgmt-sticky reset property in node\n");
90*4882a593Smuzhiyun 		return PTR_ERR(rockchip->mgmt_sticky_rst);
91*4882a593Smuzhiyun 	}
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	rockchip->pipe_rst = devm_reset_control_get_exclusive(dev, "pipe");
94*4882a593Smuzhiyun 	if (IS_ERR(rockchip->pipe_rst)) {
95*4882a593Smuzhiyun 		if (PTR_ERR(rockchip->pipe_rst) != -EPROBE_DEFER)
96*4882a593Smuzhiyun 			dev_err(dev, "missing pipe reset property in node\n");
97*4882a593Smuzhiyun 		return PTR_ERR(rockchip->pipe_rst);
98*4882a593Smuzhiyun 	}
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	rockchip->pm_rst = devm_reset_control_get_exclusive(dev, "pm");
101*4882a593Smuzhiyun 	if (IS_ERR(rockchip->pm_rst)) {
102*4882a593Smuzhiyun 		if (PTR_ERR(rockchip->pm_rst) != -EPROBE_DEFER)
103*4882a593Smuzhiyun 			dev_err(dev, "missing pm reset property in node\n");
104*4882a593Smuzhiyun 		return PTR_ERR(rockchip->pm_rst);
105*4882a593Smuzhiyun 	}
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 	rockchip->pclk_rst = devm_reset_control_get_exclusive(dev, "pclk");
108*4882a593Smuzhiyun 	if (IS_ERR(rockchip->pclk_rst)) {
109*4882a593Smuzhiyun 		if (PTR_ERR(rockchip->pclk_rst) != -EPROBE_DEFER)
110*4882a593Smuzhiyun 			dev_err(dev, "missing pclk reset property in node\n");
111*4882a593Smuzhiyun 		return PTR_ERR(rockchip->pclk_rst);
112*4882a593Smuzhiyun 	}
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 	rockchip->aclk_rst = devm_reset_control_get_exclusive(dev, "aclk");
115*4882a593Smuzhiyun 	if (IS_ERR(rockchip->aclk_rst)) {
116*4882a593Smuzhiyun 		if (PTR_ERR(rockchip->aclk_rst) != -EPROBE_DEFER)
117*4882a593Smuzhiyun 			dev_err(dev, "missing aclk reset property in node\n");
118*4882a593Smuzhiyun 		return PTR_ERR(rockchip->aclk_rst);
119*4882a593Smuzhiyun 	}
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 	if (rockchip->is_rc) {
122*4882a593Smuzhiyun 		rockchip->ep_gpio = devm_gpiod_get_optional(dev, "ep",
123*4882a593Smuzhiyun 							    GPIOD_OUT_HIGH);
124*4882a593Smuzhiyun 		if (IS_ERR(rockchip->ep_gpio))
125*4882a593Smuzhiyun 			return dev_err_probe(dev, PTR_ERR(rockchip->ep_gpio),
126*4882a593Smuzhiyun 					     "failed to get ep GPIO\n");
127*4882a593Smuzhiyun 	}
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	rockchip->aclk_pcie = devm_clk_get(dev, "aclk");
130*4882a593Smuzhiyun 	if (IS_ERR(rockchip->aclk_pcie)) {
131*4882a593Smuzhiyun 		dev_err(dev, "aclk clock not found\n");
132*4882a593Smuzhiyun 		return PTR_ERR(rockchip->aclk_pcie);
133*4882a593Smuzhiyun 	}
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun 	rockchip->aclk_perf_pcie = devm_clk_get(dev, "aclk-perf");
136*4882a593Smuzhiyun 	if (IS_ERR(rockchip->aclk_perf_pcie)) {
137*4882a593Smuzhiyun 		dev_err(dev, "aclk_perf clock not found\n");
138*4882a593Smuzhiyun 		return PTR_ERR(rockchip->aclk_perf_pcie);
139*4882a593Smuzhiyun 	}
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	rockchip->hclk_pcie = devm_clk_get(dev, "hclk");
142*4882a593Smuzhiyun 	if (IS_ERR(rockchip->hclk_pcie)) {
143*4882a593Smuzhiyun 		dev_err(dev, "hclk clock not found\n");
144*4882a593Smuzhiyun 		return PTR_ERR(rockchip->hclk_pcie);
145*4882a593Smuzhiyun 	}
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	rockchip->clk_pcie_pm = devm_clk_get(dev, "pm");
148*4882a593Smuzhiyun 	if (IS_ERR(rockchip->clk_pcie_pm)) {
149*4882a593Smuzhiyun 		dev_err(dev, "pm clock not found\n");
150*4882a593Smuzhiyun 		return PTR_ERR(rockchip->clk_pcie_pm);
151*4882a593Smuzhiyun 	}
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	return 0;
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rockchip_pcie_parse_dt);
156*4882a593Smuzhiyun 
rockchip_pcie_init_port(struct rockchip_pcie * rockchip)157*4882a593Smuzhiyun int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun 	struct device *dev = rockchip->dev;
160*4882a593Smuzhiyun 	int err, i;
161*4882a593Smuzhiyun 	u32 regs;
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	err = reset_control_assert(rockchip->aclk_rst);
164*4882a593Smuzhiyun 	if (err) {
165*4882a593Smuzhiyun 		dev_err(dev, "assert aclk_rst err %d\n", err);
166*4882a593Smuzhiyun 		return err;
167*4882a593Smuzhiyun 	}
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	err = reset_control_assert(rockchip->pclk_rst);
170*4882a593Smuzhiyun 	if (err) {
171*4882a593Smuzhiyun 		dev_err(dev, "assert pclk_rst err %d\n", err);
172*4882a593Smuzhiyun 		return err;
173*4882a593Smuzhiyun 	}
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	err = reset_control_assert(rockchip->pm_rst);
176*4882a593Smuzhiyun 	if (err) {
177*4882a593Smuzhiyun 		dev_err(dev, "assert pm_rst err %d\n", err);
178*4882a593Smuzhiyun 		return err;
179*4882a593Smuzhiyun 	}
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	for (i = 0; i < MAX_LANE_NUM; i++) {
182*4882a593Smuzhiyun 		err = phy_init(rockchip->phys[i]);
183*4882a593Smuzhiyun 		if (err) {
184*4882a593Smuzhiyun 			dev_err(dev, "init phy%d err %d\n", i, err);
185*4882a593Smuzhiyun 			goto err_exit_phy;
186*4882a593Smuzhiyun 		}
187*4882a593Smuzhiyun 	}
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun 	err = reset_control_assert(rockchip->core_rst);
190*4882a593Smuzhiyun 	if (err) {
191*4882a593Smuzhiyun 		dev_err(dev, "assert core_rst err %d\n", err);
192*4882a593Smuzhiyun 		goto err_exit_phy;
193*4882a593Smuzhiyun 	}
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun 	err = reset_control_assert(rockchip->mgmt_rst);
196*4882a593Smuzhiyun 	if (err) {
197*4882a593Smuzhiyun 		dev_err(dev, "assert mgmt_rst err %d\n", err);
198*4882a593Smuzhiyun 		goto err_exit_phy;
199*4882a593Smuzhiyun 	}
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 	err = reset_control_assert(rockchip->mgmt_sticky_rst);
202*4882a593Smuzhiyun 	if (err) {
203*4882a593Smuzhiyun 		dev_err(dev, "assert mgmt_sticky_rst err %d\n", err);
204*4882a593Smuzhiyun 		goto err_exit_phy;
205*4882a593Smuzhiyun 	}
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun 	err = reset_control_assert(rockchip->pipe_rst);
208*4882a593Smuzhiyun 	if (err) {
209*4882a593Smuzhiyun 		dev_err(dev, "assert pipe_rst err %d\n", err);
210*4882a593Smuzhiyun 		goto err_exit_phy;
211*4882a593Smuzhiyun 	}
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 	udelay(10);
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	err = reset_control_deassert(rockchip->pm_rst);
216*4882a593Smuzhiyun 	if (err) {
217*4882a593Smuzhiyun 		dev_err(dev, "deassert pm_rst err %d\n", err);
218*4882a593Smuzhiyun 		goto err_exit_phy;
219*4882a593Smuzhiyun 	}
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun 	err = reset_control_deassert(rockchip->aclk_rst);
222*4882a593Smuzhiyun 	if (err) {
223*4882a593Smuzhiyun 		dev_err(dev, "deassert aclk_rst err %d\n", err);
224*4882a593Smuzhiyun 		goto err_exit_phy;
225*4882a593Smuzhiyun 	}
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	err = reset_control_deassert(rockchip->pclk_rst);
228*4882a593Smuzhiyun 	if (err) {
229*4882a593Smuzhiyun 		dev_err(dev, "deassert pclk_rst err %d\n", err);
230*4882a593Smuzhiyun 		goto err_exit_phy;
231*4882a593Smuzhiyun 	}
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 	if (rockchip->link_gen == 2)
234*4882a593Smuzhiyun 		rockchip_pcie_write(rockchip, PCIE_CLIENT_GEN_SEL_2,
235*4882a593Smuzhiyun 				    PCIE_CLIENT_CONFIG);
236*4882a593Smuzhiyun 	else
237*4882a593Smuzhiyun 		rockchip_pcie_write(rockchip, PCIE_CLIENT_GEN_SEL_1,
238*4882a593Smuzhiyun 				    PCIE_CLIENT_CONFIG);
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 	regs = PCIE_CLIENT_LINK_TRAIN_ENABLE | PCIE_CLIENT_ARI_ENABLE |
241*4882a593Smuzhiyun 	       PCIE_CLIENT_CONF_LANE_NUM(rockchip->lanes);
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun 	if (rockchip->is_rc)
244*4882a593Smuzhiyun 		regs |= PCIE_CLIENT_CONF_ENABLE | PCIE_CLIENT_MODE_RC;
245*4882a593Smuzhiyun 	else
246*4882a593Smuzhiyun 		regs |= PCIE_CLIENT_CONF_DISABLE | PCIE_CLIENT_MODE_EP;
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	rockchip_pcie_write(rockchip, regs, PCIE_CLIENT_CONFIG);
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	for (i = 0; i < MAX_LANE_NUM; i++) {
251*4882a593Smuzhiyun 		err = phy_power_on(rockchip->phys[i]);
252*4882a593Smuzhiyun 		if (err) {
253*4882a593Smuzhiyun 			dev_err(dev, "power on phy%d err %d\n", i, err);
254*4882a593Smuzhiyun 			goto err_power_off_phy;
255*4882a593Smuzhiyun 		}
256*4882a593Smuzhiyun 	}
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun 	/*
259*4882a593Smuzhiyun 	 * Please don't reorder the deassert sequence of the following
260*4882a593Smuzhiyun 	 * four reset pins.
261*4882a593Smuzhiyun 	 */
262*4882a593Smuzhiyun 	err = reset_control_deassert(rockchip->mgmt_sticky_rst);
263*4882a593Smuzhiyun 	if (err) {
264*4882a593Smuzhiyun 		dev_err(dev, "deassert mgmt_sticky_rst err %d\n", err);
265*4882a593Smuzhiyun 		goto err_power_off_phy;
266*4882a593Smuzhiyun 	}
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	err = reset_control_deassert(rockchip->core_rst);
269*4882a593Smuzhiyun 	if (err) {
270*4882a593Smuzhiyun 		dev_err(dev, "deassert core_rst err %d\n", err);
271*4882a593Smuzhiyun 		goto err_power_off_phy;
272*4882a593Smuzhiyun 	}
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun 	err = reset_control_deassert(rockchip->mgmt_rst);
275*4882a593Smuzhiyun 	if (err) {
276*4882a593Smuzhiyun 		dev_err(dev, "deassert mgmt_rst err %d\n", err);
277*4882a593Smuzhiyun 		goto err_power_off_phy;
278*4882a593Smuzhiyun 	}
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 	err = reset_control_deassert(rockchip->pipe_rst);
281*4882a593Smuzhiyun 	if (err) {
282*4882a593Smuzhiyun 		dev_err(dev, "deassert pipe_rst err %d\n", err);
283*4882a593Smuzhiyun 		goto err_power_off_phy;
284*4882a593Smuzhiyun 	}
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	return 0;
287*4882a593Smuzhiyun err_power_off_phy:
288*4882a593Smuzhiyun 	while (i--)
289*4882a593Smuzhiyun 		phy_power_off(rockchip->phys[i]);
290*4882a593Smuzhiyun 	i = MAX_LANE_NUM;
291*4882a593Smuzhiyun err_exit_phy:
292*4882a593Smuzhiyun 	while (i--)
293*4882a593Smuzhiyun 		phy_exit(rockchip->phys[i]);
294*4882a593Smuzhiyun 	return err;
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rockchip_pcie_init_port);
297*4882a593Smuzhiyun 
rockchip_pcie_get_phys(struct rockchip_pcie * rockchip)298*4882a593Smuzhiyun int rockchip_pcie_get_phys(struct rockchip_pcie *rockchip)
299*4882a593Smuzhiyun {
300*4882a593Smuzhiyun 	struct device *dev = rockchip->dev;
301*4882a593Smuzhiyun 	struct phy *phy;
302*4882a593Smuzhiyun 	char *name;
303*4882a593Smuzhiyun 	u32 i;
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun 	phy = devm_phy_get(dev, "pcie-phy");
306*4882a593Smuzhiyun 	if (!IS_ERR(phy)) {
307*4882a593Smuzhiyun 		rockchip->legacy_phy = true;
308*4882a593Smuzhiyun 		rockchip->phys[0] = phy;
309*4882a593Smuzhiyun 		dev_warn(dev, "legacy phy model is deprecated!\n");
310*4882a593Smuzhiyun 		return 0;
311*4882a593Smuzhiyun 	}
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun 	if (PTR_ERR(phy) == -EPROBE_DEFER)
314*4882a593Smuzhiyun 		return PTR_ERR(phy);
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun 	dev_dbg(dev, "missing legacy phy; search for per-lane PHY\n");
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun 	for (i = 0; i < MAX_LANE_NUM; i++) {
319*4882a593Smuzhiyun 		name = kasprintf(GFP_KERNEL, "pcie-phy-%u", i);
320*4882a593Smuzhiyun 		if (!name)
321*4882a593Smuzhiyun 			return -ENOMEM;
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun 		phy = devm_of_phy_get(dev, dev->of_node, name);
324*4882a593Smuzhiyun 		kfree(name);
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun 		if (IS_ERR(phy)) {
327*4882a593Smuzhiyun 			if (PTR_ERR(phy) != -EPROBE_DEFER)
328*4882a593Smuzhiyun 				dev_err(dev, "missing phy for lane %d: %ld\n",
329*4882a593Smuzhiyun 					i, PTR_ERR(phy));
330*4882a593Smuzhiyun 			return PTR_ERR(phy);
331*4882a593Smuzhiyun 		}
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 		rockchip->phys[i] = phy;
334*4882a593Smuzhiyun 	}
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 	return 0;
337*4882a593Smuzhiyun }
338*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rockchip_pcie_get_phys);
339*4882a593Smuzhiyun 
rockchip_pcie_deinit_phys(struct rockchip_pcie * rockchip)340*4882a593Smuzhiyun void rockchip_pcie_deinit_phys(struct rockchip_pcie *rockchip)
341*4882a593Smuzhiyun {
342*4882a593Smuzhiyun 	int i;
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun 	for (i = 0; i < MAX_LANE_NUM; i++) {
345*4882a593Smuzhiyun 		/* inactive lanes are already powered off */
346*4882a593Smuzhiyun 		if (rockchip->lanes_map & BIT(i))
347*4882a593Smuzhiyun 			phy_power_off(rockchip->phys[i]);
348*4882a593Smuzhiyun 		phy_exit(rockchip->phys[i]);
349*4882a593Smuzhiyun 	}
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rockchip_pcie_deinit_phys);
352*4882a593Smuzhiyun 
rockchip_pcie_enable_clocks(struct rockchip_pcie * rockchip)353*4882a593Smuzhiyun int rockchip_pcie_enable_clocks(struct rockchip_pcie *rockchip)
354*4882a593Smuzhiyun {
355*4882a593Smuzhiyun 	struct device *dev = rockchip->dev;
356*4882a593Smuzhiyun 	int err;
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun 	err = clk_prepare_enable(rockchip->aclk_pcie);
359*4882a593Smuzhiyun 	if (err) {
360*4882a593Smuzhiyun 		dev_err(dev, "unable to enable aclk_pcie clock\n");
361*4882a593Smuzhiyun 		return err;
362*4882a593Smuzhiyun 	}
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	err = clk_prepare_enable(rockchip->aclk_perf_pcie);
365*4882a593Smuzhiyun 	if (err) {
366*4882a593Smuzhiyun 		dev_err(dev, "unable to enable aclk_perf_pcie clock\n");
367*4882a593Smuzhiyun 		goto err_aclk_perf_pcie;
368*4882a593Smuzhiyun 	}
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun 	err = clk_prepare_enable(rockchip->hclk_pcie);
371*4882a593Smuzhiyun 	if (err) {
372*4882a593Smuzhiyun 		dev_err(dev, "unable to enable hclk_pcie clock\n");
373*4882a593Smuzhiyun 		goto err_hclk_pcie;
374*4882a593Smuzhiyun 	}
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun 	err = clk_prepare_enable(rockchip->clk_pcie_pm);
377*4882a593Smuzhiyun 	if (err) {
378*4882a593Smuzhiyun 		dev_err(dev, "unable to enable clk_pcie_pm clock\n");
379*4882a593Smuzhiyun 		goto err_clk_pcie_pm;
380*4882a593Smuzhiyun 	}
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun 	return 0;
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun err_clk_pcie_pm:
385*4882a593Smuzhiyun 	clk_disable_unprepare(rockchip->hclk_pcie);
386*4882a593Smuzhiyun err_hclk_pcie:
387*4882a593Smuzhiyun 	clk_disable_unprepare(rockchip->aclk_perf_pcie);
388*4882a593Smuzhiyun err_aclk_perf_pcie:
389*4882a593Smuzhiyun 	clk_disable_unprepare(rockchip->aclk_pcie);
390*4882a593Smuzhiyun 	return err;
391*4882a593Smuzhiyun }
392*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rockchip_pcie_enable_clocks);
393*4882a593Smuzhiyun 
rockchip_pcie_disable_clocks(void * data)394*4882a593Smuzhiyun void rockchip_pcie_disable_clocks(void *data)
395*4882a593Smuzhiyun {
396*4882a593Smuzhiyun 	struct rockchip_pcie *rockchip = data;
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun 	clk_disable_unprepare(rockchip->clk_pcie_pm);
399*4882a593Smuzhiyun 	clk_disable_unprepare(rockchip->hclk_pcie);
400*4882a593Smuzhiyun 	clk_disable_unprepare(rockchip->aclk_perf_pcie);
401*4882a593Smuzhiyun 	clk_disable_unprepare(rockchip->aclk_pcie);
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rockchip_pcie_disable_clocks);
404*4882a593Smuzhiyun 
rockchip_pcie_cfg_configuration_accesses(struct rockchip_pcie * rockchip,u32 type)405*4882a593Smuzhiyun void rockchip_pcie_cfg_configuration_accesses(
406*4882a593Smuzhiyun 		struct rockchip_pcie *rockchip, u32 type)
407*4882a593Smuzhiyun {
408*4882a593Smuzhiyun 	u32 ob_desc_0;
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun 	/* Configuration Accesses for region 0 */
411*4882a593Smuzhiyun 	rockchip_pcie_write(rockchip, 0x0, PCIE_RC_BAR_CONF);
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 	rockchip_pcie_write(rockchip,
414*4882a593Smuzhiyun 			    (RC_REGION_0_ADDR_TRANS_L + RC_REGION_0_PASS_BITS),
415*4882a593Smuzhiyun 			    PCIE_CORE_OB_REGION_ADDR0);
416*4882a593Smuzhiyun 	rockchip_pcie_write(rockchip, RC_REGION_0_ADDR_TRANS_H,
417*4882a593Smuzhiyun 			    PCIE_CORE_OB_REGION_ADDR1);
418*4882a593Smuzhiyun 	ob_desc_0 = rockchip_pcie_read(rockchip, PCIE_CORE_OB_REGION_DESC0);
419*4882a593Smuzhiyun 	ob_desc_0 &= ~(RC_REGION_0_TYPE_MASK);
420*4882a593Smuzhiyun 	ob_desc_0 |= (type | (0x1 << 23));
421*4882a593Smuzhiyun 	rockchip_pcie_write(rockchip, ob_desc_0, PCIE_CORE_OB_REGION_DESC0);
422*4882a593Smuzhiyun 	rockchip_pcie_write(rockchip, 0x0, PCIE_CORE_OB_REGION_DESC1);
423*4882a593Smuzhiyun }
424*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rockchip_pcie_cfg_configuration_accesses);
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun MODULE_AUTHOR("Rockchip Inc");
427*4882a593Smuzhiyun MODULE_DESCRIPTION("Rockchip AXI PCIe driver");
428*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
429