diff options
Diffstat (limited to 'drivers/pci/controller/dwc/pcie-kirin.c')
-rw-r--r-- | drivers/pci/controller/dwc/pcie-kirin.c | 515 |
1 files changed, 515 insertions, 0 deletions
diff --git a/drivers/pci/controller/dwc/pcie-kirin.c b/drivers/pci/controller/dwc/pcie-kirin.c new file mode 100644 index 000000000000..d2970a009eb5 --- /dev/null +++ b/drivers/pci/controller/dwc/pcie-kirin.c | |||
@@ -0,0 +1,515 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * PCIe host controller driver for Kirin Phone SoCs | ||
4 | * | ||
5 | * Copyright (C) 2017 Hilisicon Electronics Co., Ltd. | ||
6 | * http://www.huawei.com | ||
7 | * | ||
8 | * Author: Xiaowei Song <songxiaowei@huawei.com> | ||
9 | */ | ||
10 | |||
11 | #include <linux/compiler.h> | ||
12 | #include <linux/clk.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/gpio.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/mfd/syscon.h> | ||
18 | #include <linux/of_address.h> | ||
19 | #include <linux/of_gpio.h> | ||
20 | #include <linux/of_pci.h> | ||
21 | #include <linux/pci.h> | ||
22 | #include <linux/pci_regs.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/regmap.h> | ||
25 | #include <linux/resource.h> | ||
26 | #include <linux/types.h> | ||
27 | #include "pcie-designware.h" | ||
28 | |||
29 | #define to_kirin_pcie(x) dev_get_drvdata((x)->dev) | ||
30 | |||
31 | #define REF_CLK_FREQ 100000000 | ||
32 | |||
33 | /* PCIe ELBI registers */ | ||
34 | #define SOC_PCIECTRL_CTRL0_ADDR 0x000 | ||
35 | #define SOC_PCIECTRL_CTRL1_ADDR 0x004 | ||
36 | #define SOC_PCIEPHY_CTRL2_ADDR 0x008 | ||
37 | #define SOC_PCIEPHY_CTRL3_ADDR 0x00c | ||
38 | #define PCIE_ELBI_SLV_DBI_ENABLE (0x1 << 21) | ||
39 | |||
40 | /* info located in APB */ | ||
41 | #define PCIE_APP_LTSSM_ENABLE 0x01c | ||
42 | #define PCIE_APB_PHY_CTRL0 0x0 | ||
43 | #define PCIE_APB_PHY_CTRL1 0x4 | ||
44 | #define PCIE_APB_PHY_STATUS0 0x400 | ||
45 | #define PCIE_LINKUP_ENABLE (0x8020) | ||
46 | #define PCIE_LTSSM_ENABLE_BIT (0x1 << 11) | ||
47 | #define PIPE_CLK_STABLE (0x1 << 19) | ||
48 | #define PHY_REF_PAD_BIT (0x1 << 8) | ||
49 | #define PHY_PWR_DOWN_BIT (0x1 << 22) | ||
50 | #define PHY_RST_ACK_BIT (0x1 << 16) | ||
51 | |||
52 | /* info located in sysctrl */ | ||
53 | #define SCTRL_PCIE_CMOS_OFFSET 0x60 | ||
54 | #define SCTRL_PCIE_CMOS_BIT 0x10 | ||
55 | #define SCTRL_PCIE_ISO_OFFSET 0x44 | ||
56 | #define SCTRL_PCIE_ISO_BIT 0x30 | ||
57 | #define SCTRL_PCIE_HPCLK_OFFSET 0x190 | ||
58 | #define SCTRL_PCIE_HPCLK_BIT 0x184000 | ||
59 | #define SCTRL_PCIE_OE_OFFSET 0x14a | ||
60 | #define PCIE_DEBOUNCE_PARAM 0xF0F400 | ||
61 | #define PCIE_OE_BYPASS (0x3 << 28) | ||
62 | |||
63 | /* peri_crg ctrl */ | ||
64 | #define CRGCTRL_PCIE_ASSERT_OFFSET 0x88 | ||
65 | #define CRGCTRL_PCIE_ASSERT_BIT 0x8c000000 | ||
66 | |||
67 | /* Time for delay */ | ||
68 | #define REF_2_PERST_MIN 20000 | ||
69 | #define REF_2_PERST_MAX 25000 | ||
70 | #define PERST_2_ACCESS_MIN 10000 | ||
71 | #define PERST_2_ACCESS_MAX 12000 | ||
72 | #define LINK_WAIT_MIN 900 | ||
73 | #define LINK_WAIT_MAX 1000 | ||
74 | #define PIPE_CLK_WAIT_MIN 550 | ||
75 | #define PIPE_CLK_WAIT_MAX 600 | ||
76 | #define TIME_CMOS_MIN 100 | ||
77 | #define TIME_CMOS_MAX 105 | ||
78 | #define TIME_PHY_PD_MIN 10 | ||
79 | #define TIME_PHY_PD_MAX 11 | ||
80 | |||
81 | struct kirin_pcie { | ||
82 | struct dw_pcie *pci; | ||
83 | void __iomem *apb_base; | ||
84 | void __iomem *phy_base; | ||
85 | struct regmap *crgctrl; | ||
86 | struct regmap *sysctrl; | ||
87 | struct clk *apb_sys_clk; | ||
88 | struct clk *apb_phy_clk; | ||
89 | struct clk *phy_ref_clk; | ||
90 | struct clk *pcie_aclk; | ||
91 | struct clk *pcie_aux_clk; | ||
92 | int gpio_id_reset; | ||
93 | }; | ||
94 | |||
95 | /* Registers in PCIeCTRL */ | ||
96 | static inline void kirin_apb_ctrl_writel(struct kirin_pcie *kirin_pcie, | ||
97 | u32 val, u32 reg) | ||
98 | { | ||
99 | writel(val, kirin_pcie->apb_base + reg); | ||
100 | } | ||
101 | |||
102 | static inline u32 kirin_apb_ctrl_readl(struct kirin_pcie *kirin_pcie, u32 reg) | ||
103 | { | ||
104 | return readl(kirin_pcie->apb_base + reg); | ||
105 | } | ||
106 | |||
107 | /* Registers in PCIePHY */ | ||
108 | static inline void kirin_apb_phy_writel(struct kirin_pcie *kirin_pcie, | ||
109 | u32 val, u32 reg) | ||
110 | { | ||
111 | writel(val, kirin_pcie->phy_base + reg); | ||
112 | } | ||
113 | |||
114 | static inline u32 kirin_apb_phy_readl(struct kirin_pcie *kirin_pcie, u32 reg) | ||
115 | { | ||
116 | return readl(kirin_pcie->phy_base + reg); | ||
117 | } | ||
118 | |||
119 | static long kirin_pcie_get_clk(struct kirin_pcie *kirin_pcie, | ||
120 | struct platform_device *pdev) | ||
121 | { | ||
122 | struct device *dev = &pdev->dev; | ||
123 | |||
124 | kirin_pcie->phy_ref_clk = devm_clk_get(dev, "pcie_phy_ref"); | ||
125 | if (IS_ERR(kirin_pcie->phy_ref_clk)) | ||
126 | return PTR_ERR(kirin_pcie->phy_ref_clk); | ||
127 | |||
128 | kirin_pcie->pcie_aux_clk = devm_clk_get(dev, "pcie_aux"); | ||
129 | if (IS_ERR(kirin_pcie->pcie_aux_clk)) | ||
130 | return PTR_ERR(kirin_pcie->pcie_aux_clk); | ||
131 | |||
132 | kirin_pcie->apb_phy_clk = devm_clk_get(dev, "pcie_apb_phy"); | ||
133 | if (IS_ERR(kirin_pcie->apb_phy_clk)) | ||
134 | return PTR_ERR(kirin_pcie->apb_phy_clk); | ||
135 | |||
136 | kirin_pcie->apb_sys_clk = devm_clk_get(dev, "pcie_apb_sys"); | ||
137 | if (IS_ERR(kirin_pcie->apb_sys_clk)) | ||
138 | return PTR_ERR(kirin_pcie->apb_sys_clk); | ||
139 | |||
140 | kirin_pcie->pcie_aclk = devm_clk_get(dev, "pcie_aclk"); | ||
141 | if (IS_ERR(kirin_pcie->pcie_aclk)) | ||
142 | return PTR_ERR(kirin_pcie->pcie_aclk); | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | static long kirin_pcie_get_resource(struct kirin_pcie *kirin_pcie, | ||
148 | struct platform_device *pdev) | ||
149 | { | ||
150 | struct device *dev = &pdev->dev; | ||
151 | struct resource *apb; | ||
152 | struct resource *phy; | ||
153 | struct resource *dbi; | ||
154 | |||
155 | apb = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apb"); | ||
156 | kirin_pcie->apb_base = devm_ioremap_resource(dev, apb); | ||
157 | if (IS_ERR(kirin_pcie->apb_base)) | ||
158 | return PTR_ERR(kirin_pcie->apb_base); | ||
159 | |||
160 | phy = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy"); | ||
161 | kirin_pcie->phy_base = devm_ioremap_resource(dev, phy); | ||
162 | if (IS_ERR(kirin_pcie->phy_base)) | ||
163 | return PTR_ERR(kirin_pcie->phy_base); | ||
164 | |||
165 | dbi = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); | ||
166 | kirin_pcie->pci->dbi_base = devm_ioremap_resource(dev, dbi); | ||
167 | if (IS_ERR(kirin_pcie->pci->dbi_base)) | ||
168 | return PTR_ERR(kirin_pcie->pci->dbi_base); | ||
169 | |||
170 | kirin_pcie->crgctrl = | ||
171 | syscon_regmap_lookup_by_compatible("hisilicon,hi3660-crgctrl"); | ||
172 | if (IS_ERR(kirin_pcie->crgctrl)) | ||
173 | return PTR_ERR(kirin_pcie->crgctrl); | ||
174 | |||
175 | kirin_pcie->sysctrl = | ||
176 | syscon_regmap_lookup_by_compatible("hisilicon,hi3660-sctrl"); | ||
177 | if (IS_ERR(kirin_pcie->sysctrl)) | ||
178 | return PTR_ERR(kirin_pcie->sysctrl); | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static int kirin_pcie_phy_init(struct kirin_pcie *kirin_pcie) | ||
184 | { | ||
185 | struct device *dev = kirin_pcie->pci->dev; | ||
186 | u32 reg_val; | ||
187 | |||
188 | reg_val = kirin_apb_phy_readl(kirin_pcie, PCIE_APB_PHY_CTRL1); | ||
189 | reg_val &= ~PHY_REF_PAD_BIT; | ||
190 | kirin_apb_phy_writel(kirin_pcie, reg_val, PCIE_APB_PHY_CTRL1); | ||
191 | |||
192 | reg_val = kirin_apb_phy_readl(kirin_pcie, PCIE_APB_PHY_CTRL0); | ||
193 | reg_val &= ~PHY_PWR_DOWN_BIT; | ||
194 | kirin_apb_phy_writel(kirin_pcie, reg_val, PCIE_APB_PHY_CTRL0); | ||
195 | usleep_range(TIME_PHY_PD_MIN, TIME_PHY_PD_MAX); | ||
196 | |||
197 | reg_val = kirin_apb_phy_readl(kirin_pcie, PCIE_APB_PHY_CTRL1); | ||
198 | reg_val &= ~PHY_RST_ACK_BIT; | ||
199 | kirin_apb_phy_writel(kirin_pcie, reg_val, PCIE_APB_PHY_CTRL1); | ||
200 | |||
201 | usleep_range(PIPE_CLK_WAIT_MIN, PIPE_CLK_WAIT_MAX); | ||
202 | reg_val = kirin_apb_phy_readl(kirin_pcie, PCIE_APB_PHY_STATUS0); | ||
203 | if (reg_val & PIPE_CLK_STABLE) { | ||
204 | dev_err(dev, "PIPE clk is not stable\n"); | ||
205 | return -EINVAL; | ||
206 | } | ||
207 | |||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | static void kirin_pcie_oe_enable(struct kirin_pcie *kirin_pcie) | ||
212 | { | ||
213 | u32 val; | ||
214 | |||
215 | regmap_read(kirin_pcie->sysctrl, SCTRL_PCIE_OE_OFFSET, &val); | ||
216 | val |= PCIE_DEBOUNCE_PARAM; | ||
217 | val &= ~PCIE_OE_BYPASS; | ||
218 | regmap_write(kirin_pcie->sysctrl, SCTRL_PCIE_OE_OFFSET, val); | ||
219 | } | ||
220 | |||
221 | static int kirin_pcie_clk_ctrl(struct kirin_pcie *kirin_pcie, bool enable) | ||
222 | { | ||
223 | int ret = 0; | ||
224 | |||
225 | if (!enable) | ||
226 | goto close_clk; | ||
227 | |||
228 | ret = clk_set_rate(kirin_pcie->phy_ref_clk, REF_CLK_FREQ); | ||
229 | if (ret) | ||
230 | return ret; | ||
231 | |||
232 | ret = clk_prepare_enable(kirin_pcie->phy_ref_clk); | ||
233 | if (ret) | ||
234 | return ret; | ||
235 | |||
236 | ret = clk_prepare_enable(kirin_pcie->apb_sys_clk); | ||
237 | if (ret) | ||
238 | goto apb_sys_fail; | ||
239 | |||
240 | ret = clk_prepare_enable(kirin_pcie->apb_phy_clk); | ||
241 | if (ret) | ||
242 | goto apb_phy_fail; | ||
243 | |||
244 | ret = clk_prepare_enable(kirin_pcie->pcie_aclk); | ||
245 | if (ret) | ||
246 | goto aclk_fail; | ||
247 | |||
248 | ret = clk_prepare_enable(kirin_pcie->pcie_aux_clk); | ||
249 | if (ret) | ||
250 | goto aux_clk_fail; | ||
251 | |||
252 | return 0; | ||
253 | |||
254 | close_clk: | ||
255 | clk_disable_unprepare(kirin_pcie->pcie_aux_clk); | ||
256 | aux_clk_fail: | ||
257 | clk_disable_unprepare(kirin_pcie->pcie_aclk); | ||
258 | aclk_fail: | ||
259 | clk_disable_unprepare(kirin_pcie->apb_phy_clk); | ||
260 | apb_phy_fail: | ||
261 | clk_disable_unprepare(kirin_pcie->apb_sys_clk); | ||
262 | apb_sys_fail: | ||
263 | clk_disable_unprepare(kirin_pcie->phy_ref_clk); | ||
264 | |||
265 | return ret; | ||
266 | } | ||
267 | |||
268 | static int kirin_pcie_power_on(struct kirin_pcie *kirin_pcie) | ||
269 | { | ||
270 | int ret; | ||
271 | |||
272 | /* Power supply for Host */ | ||
273 | regmap_write(kirin_pcie->sysctrl, | ||
274 | SCTRL_PCIE_CMOS_OFFSET, SCTRL_PCIE_CMOS_BIT); | ||
275 | usleep_range(TIME_CMOS_MIN, TIME_CMOS_MAX); | ||
276 | kirin_pcie_oe_enable(kirin_pcie); | ||
277 | |||
278 | ret = kirin_pcie_clk_ctrl(kirin_pcie, true); | ||
279 | if (ret) | ||
280 | return ret; | ||
281 | |||
282 | /* ISO disable, PCIeCtrl, PHY assert and clk gate clear */ | ||
283 | regmap_write(kirin_pcie->sysctrl, | ||
284 | SCTRL_PCIE_ISO_OFFSET, SCTRL_PCIE_ISO_BIT); | ||
285 | regmap_write(kirin_pcie->crgctrl, | ||
286 | CRGCTRL_PCIE_ASSERT_OFFSET, CRGCTRL_PCIE_ASSERT_BIT); | ||
287 | regmap_write(kirin_pcie->sysctrl, | ||
288 | SCTRL_PCIE_HPCLK_OFFSET, SCTRL_PCIE_HPCLK_BIT); | ||
289 | |||
290 | ret = kirin_pcie_phy_init(kirin_pcie); | ||
291 | if (ret) | ||
292 | goto close_clk; | ||
293 | |||
294 | /* perst assert Endpoint */ | ||
295 | if (!gpio_request(kirin_pcie->gpio_id_reset, "pcie_perst")) { | ||
296 | usleep_range(REF_2_PERST_MIN, REF_2_PERST_MAX); | ||
297 | ret = gpio_direction_output(kirin_pcie->gpio_id_reset, 1); | ||
298 | if (ret) | ||
299 | goto close_clk; | ||
300 | usleep_range(PERST_2_ACCESS_MIN, PERST_2_ACCESS_MAX); | ||
301 | |||
302 | return 0; | ||
303 | } | ||
304 | |||
305 | close_clk: | ||
306 | kirin_pcie_clk_ctrl(kirin_pcie, false); | ||
307 | return ret; | ||
308 | } | ||
309 | |||
310 | static void kirin_pcie_sideband_dbi_w_mode(struct kirin_pcie *kirin_pcie, | ||
311 | bool on) | ||
312 | { | ||
313 | u32 val; | ||
314 | |||
315 | val = kirin_apb_ctrl_readl(kirin_pcie, SOC_PCIECTRL_CTRL0_ADDR); | ||
316 | if (on) | ||
317 | val = val | PCIE_ELBI_SLV_DBI_ENABLE; | ||
318 | else | ||
319 | val = val & ~PCIE_ELBI_SLV_DBI_ENABLE; | ||
320 | |||
321 | kirin_apb_ctrl_writel(kirin_pcie, val, SOC_PCIECTRL_CTRL0_ADDR); | ||
322 | } | ||
323 | |||
324 | static void kirin_pcie_sideband_dbi_r_mode(struct kirin_pcie *kirin_pcie, | ||
325 | bool on) | ||
326 | { | ||
327 | u32 val; | ||
328 | |||
329 | val = kirin_apb_ctrl_readl(kirin_pcie, SOC_PCIECTRL_CTRL1_ADDR); | ||
330 | if (on) | ||
331 | val = val | PCIE_ELBI_SLV_DBI_ENABLE; | ||
332 | else | ||
333 | val = val & ~PCIE_ELBI_SLV_DBI_ENABLE; | ||
334 | |||
335 | kirin_apb_ctrl_writel(kirin_pcie, val, SOC_PCIECTRL_CTRL1_ADDR); | ||
336 | } | ||
337 | |||
338 | static int kirin_pcie_rd_own_conf(struct pcie_port *pp, | ||
339 | int where, int size, u32 *val) | ||
340 | { | ||
341 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | ||
342 | struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci); | ||
343 | int ret; | ||
344 | |||
345 | kirin_pcie_sideband_dbi_r_mode(kirin_pcie, true); | ||
346 | ret = dw_pcie_read(pci->dbi_base + where, size, val); | ||
347 | kirin_pcie_sideband_dbi_r_mode(kirin_pcie, false); | ||
348 | |||
349 | return ret; | ||
350 | } | ||
351 | |||
352 | static int kirin_pcie_wr_own_conf(struct pcie_port *pp, | ||
353 | int where, int size, u32 val) | ||
354 | { | ||
355 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | ||
356 | struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci); | ||
357 | int ret; | ||
358 | |||
359 | kirin_pcie_sideband_dbi_w_mode(kirin_pcie, true); | ||
360 | ret = dw_pcie_write(pci->dbi_base + where, size, val); | ||
361 | kirin_pcie_sideband_dbi_w_mode(kirin_pcie, false); | ||
362 | |||
363 | return ret; | ||
364 | } | ||
365 | |||
366 | static u32 kirin_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base, | ||
367 | u32 reg, size_t size) | ||
368 | { | ||
369 | struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci); | ||
370 | u32 ret; | ||
371 | |||
372 | kirin_pcie_sideband_dbi_r_mode(kirin_pcie, true); | ||
373 | dw_pcie_read(base + reg, size, &ret); | ||
374 | kirin_pcie_sideband_dbi_r_mode(kirin_pcie, false); | ||
375 | |||
376 | return ret; | ||
377 | } | ||
378 | |||
379 | static void kirin_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base, | ||
380 | u32 reg, size_t size, u32 val) | ||
381 | { | ||
382 | struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci); | ||
383 | |||
384 | kirin_pcie_sideband_dbi_w_mode(kirin_pcie, true); | ||
385 | dw_pcie_write(base + reg, size, val); | ||
386 | kirin_pcie_sideband_dbi_w_mode(kirin_pcie, false); | ||
387 | } | ||
388 | |||
389 | static int kirin_pcie_link_up(struct dw_pcie *pci) | ||
390 | { | ||
391 | struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci); | ||
392 | u32 val = kirin_apb_ctrl_readl(kirin_pcie, PCIE_APB_PHY_STATUS0); | ||
393 | |||
394 | if ((val & PCIE_LINKUP_ENABLE) == PCIE_LINKUP_ENABLE) | ||
395 | return 1; | ||
396 | |||
397 | return 0; | ||
398 | } | ||
399 | |||
400 | static int kirin_pcie_establish_link(struct pcie_port *pp) | ||
401 | { | ||
402 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | ||
403 | struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci); | ||
404 | struct device *dev = kirin_pcie->pci->dev; | ||
405 | int count = 0; | ||
406 | |||
407 | if (kirin_pcie_link_up(pci)) | ||
408 | return 0; | ||
409 | |||
410 | dw_pcie_setup_rc(pp); | ||
411 | |||
412 | /* assert LTSSM enable */ | ||
413 | kirin_apb_ctrl_writel(kirin_pcie, PCIE_LTSSM_ENABLE_BIT, | ||
414 | PCIE_APP_LTSSM_ENABLE); | ||
415 | |||
416 | /* check if the link is up or not */ | ||
417 | while (!kirin_pcie_link_up(pci)) { | ||
418 | usleep_range(LINK_WAIT_MIN, LINK_WAIT_MAX); | ||
419 | count++; | ||
420 | if (count == 1000) { | ||
421 | dev_err(dev, "Link Fail\n"); | ||
422 | return -EINVAL; | ||
423 | } | ||
424 | } | ||
425 | |||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | static int kirin_pcie_host_init(struct pcie_port *pp) | ||
430 | { | ||
431 | kirin_pcie_establish_link(pp); | ||
432 | |||
433 | return 0; | ||
434 | } | ||
435 | |||
436 | static struct dw_pcie_ops kirin_dw_pcie_ops = { | ||
437 | .read_dbi = kirin_pcie_read_dbi, | ||
438 | .write_dbi = kirin_pcie_write_dbi, | ||
439 | .link_up = kirin_pcie_link_up, | ||
440 | }; | ||
441 | |||
442 | static const struct dw_pcie_host_ops kirin_pcie_host_ops = { | ||
443 | .rd_own_conf = kirin_pcie_rd_own_conf, | ||
444 | .wr_own_conf = kirin_pcie_wr_own_conf, | ||
445 | .host_init = kirin_pcie_host_init, | ||
446 | }; | ||
447 | |||
448 | static int __init kirin_add_pcie_port(struct dw_pcie *pci, | ||
449 | struct platform_device *pdev) | ||
450 | { | ||
451 | pci->pp.ops = &kirin_pcie_host_ops; | ||
452 | |||
453 | return dw_pcie_host_init(&pci->pp); | ||
454 | } | ||
455 | |||
456 | static int kirin_pcie_probe(struct platform_device *pdev) | ||
457 | { | ||
458 | struct device *dev = &pdev->dev; | ||
459 | struct kirin_pcie *kirin_pcie; | ||
460 | struct dw_pcie *pci; | ||
461 | int ret; | ||
462 | |||
463 | if (!dev->of_node) { | ||
464 | dev_err(dev, "NULL node\n"); | ||
465 | return -EINVAL; | ||
466 | } | ||
467 | |||
468 | kirin_pcie = devm_kzalloc(dev, sizeof(struct kirin_pcie), GFP_KERNEL); | ||
469 | if (!kirin_pcie) | ||
470 | return -ENOMEM; | ||
471 | |||
472 | pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL); | ||
473 | if (!pci) | ||
474 | return -ENOMEM; | ||
475 | |||
476 | pci->dev = dev; | ||
477 | pci->ops = &kirin_dw_pcie_ops; | ||
478 | kirin_pcie->pci = pci; | ||
479 | |||
480 | ret = kirin_pcie_get_clk(kirin_pcie, pdev); | ||
481 | if (ret) | ||
482 | return ret; | ||
483 | |||
484 | ret = kirin_pcie_get_resource(kirin_pcie, pdev); | ||
485 | if (ret) | ||
486 | return ret; | ||
487 | |||
488 | kirin_pcie->gpio_id_reset = of_get_named_gpio(dev->of_node, | ||
489 | "reset-gpios", 0); | ||
490 | if (kirin_pcie->gpio_id_reset < 0) | ||
491 | return -ENODEV; | ||
492 | |||
493 | ret = kirin_pcie_power_on(kirin_pcie); | ||
494 | if (ret) | ||
495 | return ret; | ||
496 | |||
497 | platform_set_drvdata(pdev, kirin_pcie); | ||
498 | |||
499 | return kirin_add_pcie_port(pci, pdev); | ||
500 | } | ||
501 | |||
502 | static const struct of_device_id kirin_pcie_match[] = { | ||
503 | { .compatible = "hisilicon,kirin960-pcie" }, | ||
504 | {}, | ||
505 | }; | ||
506 | |||
507 | static struct platform_driver kirin_pcie_driver = { | ||
508 | .probe = kirin_pcie_probe, | ||
509 | .driver = { | ||
510 | .name = "kirin-pcie", | ||
511 | .of_match_table = kirin_pcie_match, | ||
512 | .suppress_bind_attrs = true, | ||
513 | }, | ||
514 | }; | ||
515 | builtin_platform_driver(kirin_pcie_driver); | ||