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