]>
Commit | Line | Data |
---|---|---|
8cfab3cf | 1 | // SPDX-License-Identifier: GPL-2.0 |
fc5165db XS |
2 | /* |
3 | * PCIe host controller driver for Kirin Phone SoCs | |
4 | * | |
f6b6aefe | 5 | * Copyright (C) 2017 HiSilicon Electronics Co., Ltd. |
7ecd4a81 | 6 | * https://www.huawei.com |
fc5165db XS |
7 | * |
8 | * Author: Xiaowei Song <songxiaowei@huawei.com> | |
fc5165db XS |
9 | */ |
10 | ||
fc5165db XS |
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 | { | |
936fa5cd DZ |
150 | kirin_pcie->apb_base = |
151 | devm_platform_ioremap_resource_byname(pdev, "apb"); | |
fc5165db XS |
152 | if (IS_ERR(kirin_pcie->apb_base)) |
153 | return PTR_ERR(kirin_pcie->apb_base); | |
154 | ||
936fa5cd DZ |
155 | kirin_pcie->phy_base = |
156 | devm_platform_ioremap_resource_byname(pdev, "phy"); | |
fc5165db XS |
157 | if (IS_ERR(kirin_pcie->phy_base)) |
158 | return PTR_ERR(kirin_pcie->phy_base); | |
159 | ||
936fa5cd DZ |
160 | kirin_pcie->pci->dbi_base = |
161 | devm_platform_ioremap_resource_byname(pdev, "dbi"); | |
fc5165db XS |
162 | if (IS_ERR(kirin_pcie->pci->dbi_base)) |
163 | return PTR_ERR(kirin_pcie->pci->dbi_base); | |
164 | ||
165 | kirin_pcie->crgctrl = | |
166 | syscon_regmap_lookup_by_compatible("hisilicon,hi3660-crgctrl"); | |
167 | if (IS_ERR(kirin_pcie->crgctrl)) | |
168 | return PTR_ERR(kirin_pcie->crgctrl); | |
169 | ||
170 | kirin_pcie->sysctrl = | |
171 | syscon_regmap_lookup_by_compatible("hisilicon,hi3660-sctrl"); | |
172 | if (IS_ERR(kirin_pcie->sysctrl)) | |
173 | return PTR_ERR(kirin_pcie->sysctrl); | |
174 | ||
175 | return 0; | |
176 | } | |
177 | ||
178 | static int kirin_pcie_phy_init(struct kirin_pcie *kirin_pcie) | |
179 | { | |
180 | struct device *dev = kirin_pcie->pci->dev; | |
181 | u32 reg_val; | |
182 | ||
183 | reg_val = kirin_apb_phy_readl(kirin_pcie, PCIE_APB_PHY_CTRL1); | |
184 | reg_val &= ~PHY_REF_PAD_BIT; | |
185 | kirin_apb_phy_writel(kirin_pcie, reg_val, PCIE_APB_PHY_CTRL1); | |
186 | ||
187 | reg_val = kirin_apb_phy_readl(kirin_pcie, PCIE_APB_PHY_CTRL0); | |
188 | reg_val &= ~PHY_PWR_DOWN_BIT; | |
189 | kirin_apb_phy_writel(kirin_pcie, reg_val, PCIE_APB_PHY_CTRL0); | |
190 | usleep_range(TIME_PHY_PD_MIN, TIME_PHY_PD_MAX); | |
191 | ||
192 | reg_val = kirin_apb_phy_readl(kirin_pcie, PCIE_APB_PHY_CTRL1); | |
193 | reg_val &= ~PHY_RST_ACK_BIT; | |
194 | kirin_apb_phy_writel(kirin_pcie, reg_val, PCIE_APB_PHY_CTRL1); | |
195 | ||
196 | usleep_range(PIPE_CLK_WAIT_MIN, PIPE_CLK_WAIT_MAX); | |
197 | reg_val = kirin_apb_phy_readl(kirin_pcie, PCIE_APB_PHY_STATUS0); | |
198 | if (reg_val & PIPE_CLK_STABLE) { | |
199 | dev_err(dev, "PIPE clk is not stable\n"); | |
200 | return -EINVAL; | |
201 | } | |
202 | ||
203 | return 0; | |
204 | } | |
205 | ||
206 | static void kirin_pcie_oe_enable(struct kirin_pcie *kirin_pcie) | |
207 | { | |
208 | u32 val; | |
209 | ||
210 | regmap_read(kirin_pcie->sysctrl, SCTRL_PCIE_OE_OFFSET, &val); | |
211 | val |= PCIE_DEBOUNCE_PARAM; | |
212 | val &= ~PCIE_OE_BYPASS; | |
213 | regmap_write(kirin_pcie->sysctrl, SCTRL_PCIE_OE_OFFSET, val); | |
214 | } | |
215 | ||
216 | static int kirin_pcie_clk_ctrl(struct kirin_pcie *kirin_pcie, bool enable) | |
217 | { | |
218 | int ret = 0; | |
219 | ||
220 | if (!enable) | |
221 | goto close_clk; | |
222 | ||
223 | ret = clk_set_rate(kirin_pcie->phy_ref_clk, REF_CLK_FREQ); | |
224 | if (ret) | |
225 | return ret; | |
226 | ||
227 | ret = clk_prepare_enable(kirin_pcie->phy_ref_clk); | |
228 | if (ret) | |
229 | return ret; | |
230 | ||
231 | ret = clk_prepare_enable(kirin_pcie->apb_sys_clk); | |
232 | if (ret) | |
233 | goto apb_sys_fail; | |
234 | ||
235 | ret = clk_prepare_enable(kirin_pcie->apb_phy_clk); | |
236 | if (ret) | |
237 | goto apb_phy_fail; | |
238 | ||
239 | ret = clk_prepare_enable(kirin_pcie->pcie_aclk); | |
240 | if (ret) | |
241 | goto aclk_fail; | |
242 | ||
243 | ret = clk_prepare_enable(kirin_pcie->pcie_aux_clk); | |
244 | if (ret) | |
245 | goto aux_clk_fail; | |
246 | ||
247 | return 0; | |
248 | ||
249 | close_clk: | |
250 | clk_disable_unprepare(kirin_pcie->pcie_aux_clk); | |
251 | aux_clk_fail: | |
252 | clk_disable_unprepare(kirin_pcie->pcie_aclk); | |
253 | aclk_fail: | |
254 | clk_disable_unprepare(kirin_pcie->apb_phy_clk); | |
255 | apb_phy_fail: | |
256 | clk_disable_unprepare(kirin_pcie->apb_sys_clk); | |
257 | apb_sys_fail: | |
258 | clk_disable_unprepare(kirin_pcie->phy_ref_clk); | |
259 | ||
260 | return ret; | |
261 | } | |
262 | ||
263 | static int kirin_pcie_power_on(struct kirin_pcie *kirin_pcie) | |
264 | { | |
265 | int ret; | |
266 | ||
267 | /* Power supply for Host */ | |
268 | regmap_write(kirin_pcie->sysctrl, | |
269 | SCTRL_PCIE_CMOS_OFFSET, SCTRL_PCIE_CMOS_BIT); | |
270 | usleep_range(TIME_CMOS_MIN, TIME_CMOS_MAX); | |
271 | kirin_pcie_oe_enable(kirin_pcie); | |
272 | ||
273 | ret = kirin_pcie_clk_ctrl(kirin_pcie, true); | |
274 | if (ret) | |
275 | return ret; | |
276 | ||
277 | /* ISO disable, PCIeCtrl, PHY assert and clk gate clear */ | |
278 | regmap_write(kirin_pcie->sysctrl, | |
279 | SCTRL_PCIE_ISO_OFFSET, SCTRL_PCIE_ISO_BIT); | |
280 | regmap_write(kirin_pcie->crgctrl, | |
281 | CRGCTRL_PCIE_ASSERT_OFFSET, CRGCTRL_PCIE_ASSERT_BIT); | |
282 | regmap_write(kirin_pcie->sysctrl, | |
283 | SCTRL_PCIE_HPCLK_OFFSET, SCTRL_PCIE_HPCLK_BIT); | |
284 | ||
285 | ret = kirin_pcie_phy_init(kirin_pcie); | |
286 | if (ret) | |
287 | goto close_clk; | |
288 | ||
289 | /* perst assert Endpoint */ | |
290 | if (!gpio_request(kirin_pcie->gpio_id_reset, "pcie_perst")) { | |
291 | usleep_range(REF_2_PERST_MIN, REF_2_PERST_MAX); | |
292 | ret = gpio_direction_output(kirin_pcie->gpio_id_reset, 1); | |
293 | if (ret) | |
294 | goto close_clk; | |
295 | usleep_range(PERST_2_ACCESS_MIN, PERST_2_ACCESS_MAX); | |
296 | ||
297 | return 0; | |
298 | } | |
299 | ||
300 | close_clk: | |
301 | kirin_pcie_clk_ctrl(kirin_pcie, false); | |
302 | return ret; | |
303 | } | |
304 | ||
305 | static void kirin_pcie_sideband_dbi_w_mode(struct kirin_pcie *kirin_pcie, | |
306 | bool on) | |
307 | { | |
308 | u32 val; | |
309 | ||
310 | val = kirin_apb_ctrl_readl(kirin_pcie, SOC_PCIECTRL_CTRL0_ADDR); | |
311 | if (on) | |
312 | val = val | PCIE_ELBI_SLV_DBI_ENABLE; | |
313 | else | |
314 | val = val & ~PCIE_ELBI_SLV_DBI_ENABLE; | |
315 | ||
316 | kirin_apb_ctrl_writel(kirin_pcie, val, SOC_PCIECTRL_CTRL0_ADDR); | |
317 | } | |
318 | ||
319 | static void kirin_pcie_sideband_dbi_r_mode(struct kirin_pcie *kirin_pcie, | |
320 | bool on) | |
321 | { | |
322 | u32 val; | |
323 | ||
324 | val = kirin_apb_ctrl_readl(kirin_pcie, SOC_PCIECTRL_CTRL1_ADDR); | |
325 | if (on) | |
326 | val = val | PCIE_ELBI_SLV_DBI_ENABLE; | |
327 | else | |
328 | val = val & ~PCIE_ELBI_SLV_DBI_ENABLE; | |
329 | ||
330 | kirin_apb_ctrl_writel(kirin_pcie, val, SOC_PCIECTRL_CTRL1_ADDR); | |
331 | } | |
332 | ||
6408e6a7 | 333 | static int kirin_pcie_rd_own_conf(struct pci_bus *bus, unsigned int devfn, |
fc5165db XS |
334 | int where, int size, u32 *val) |
335 | { | |
6408e6a7 | 336 | struct dw_pcie *pci = to_dw_pcie_from_pp(bus->sysdata); |
fc5165db | 337 | |
6408e6a7 RH |
338 | if (PCI_SLOT(devfn)) { |
339 | *val = ~0; | |
340 | return PCIBIOS_DEVICE_NOT_FOUND; | |
341 | } | |
fc5165db | 342 | |
6408e6a7 RH |
343 | *val = dw_pcie_read_dbi(pci, where, size); |
344 | return PCIBIOS_SUCCESSFUL; | |
fc5165db XS |
345 | } |
346 | ||
6408e6a7 | 347 | static int kirin_pcie_wr_own_conf(struct pci_bus *bus, unsigned int devfn, |
fc5165db XS |
348 | int where, int size, u32 val) |
349 | { | |
6408e6a7 | 350 | struct dw_pcie *pci = to_dw_pcie_from_pp(bus->sysdata); |
fc5165db | 351 | |
6408e6a7 RH |
352 | if (PCI_SLOT(devfn)) |
353 | return PCIBIOS_DEVICE_NOT_FOUND; | |
fc5165db | 354 | |
6408e6a7 RH |
355 | dw_pcie_write_dbi(pci, where, size, val); |
356 | return PCIBIOS_SUCCESSFUL; | |
fc5165db XS |
357 | } |
358 | ||
6408e6a7 RH |
359 | static struct pci_ops kirin_pci_ops = { |
360 | .read = kirin_pcie_rd_own_conf, | |
361 | .write = kirin_pcie_wr_own_conf, | |
362 | }; | |
363 | ||
fc5165db XS |
364 | static u32 kirin_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base, |
365 | u32 reg, size_t size) | |
366 | { | |
367 | struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci); | |
368 | u32 ret; | |
369 | ||
370 | kirin_pcie_sideband_dbi_r_mode(kirin_pcie, true); | |
371 | dw_pcie_read(base + reg, size, &ret); | |
372 | kirin_pcie_sideband_dbi_r_mode(kirin_pcie, false); | |
373 | ||
374 | return ret; | |
375 | } | |
376 | ||
377 | static void kirin_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base, | |
378 | u32 reg, size_t size, u32 val) | |
379 | { | |
380 | struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci); | |
381 | ||
382 | kirin_pcie_sideband_dbi_w_mode(kirin_pcie, true); | |
383 | dw_pcie_write(base + reg, size, val); | |
384 | kirin_pcie_sideband_dbi_w_mode(kirin_pcie, false); | |
385 | } | |
386 | ||
387 | static int kirin_pcie_link_up(struct dw_pcie *pci) | |
388 | { | |
389 | struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci); | |
390 | u32 val = kirin_apb_ctrl_readl(kirin_pcie, PCIE_APB_PHY_STATUS0); | |
391 | ||
392 | if ((val & PCIE_LINKUP_ENABLE) == PCIE_LINKUP_ENABLE) | |
393 | return 1; | |
394 | ||
395 | return 0; | |
396 | } | |
397 | ||
398 | static int kirin_pcie_establish_link(struct pcie_port *pp) | |
399 | { | |
400 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | |
401 | struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci); | |
402 | struct device *dev = kirin_pcie->pci->dev; | |
403 | int count = 0; | |
404 | ||
405 | if (kirin_pcie_link_up(pci)) | |
406 | return 0; | |
407 | ||
408 | dw_pcie_setup_rc(pp); | |
409 | ||
410 | /* assert LTSSM enable */ | |
411 | kirin_apb_ctrl_writel(kirin_pcie, PCIE_LTSSM_ENABLE_BIT, | |
412 | PCIE_APP_LTSSM_ENABLE); | |
413 | ||
414 | /* check if the link is up or not */ | |
415 | while (!kirin_pcie_link_up(pci)) { | |
416 | usleep_range(LINK_WAIT_MIN, LINK_WAIT_MAX); | |
417 | count++; | |
418 | if (count == 1000) { | |
419 | dev_err(dev, "Link Fail\n"); | |
420 | return -EINVAL; | |
421 | } | |
422 | } | |
423 | ||
424 | return 0; | |
425 | } | |
426 | ||
4a301766 | 427 | static int kirin_pcie_host_init(struct pcie_port *pp) |
fc5165db | 428 | { |
6408e6a7 RH |
429 | pp->bridge->ops = &kirin_pci_ops; |
430 | ||
fc5165db | 431 | kirin_pcie_establish_link(pp); |
4a301766 | 432 | |
141cb3d4 XS |
433 | if (IS_ENABLED(CONFIG_PCI_MSI)) |
434 | dw_pcie_msi_init(pp); | |
435 | ||
4a301766 | 436 | return 0; |
fc5165db XS |
437 | } |
438 | ||
5ae6393e | 439 | static const struct dw_pcie_ops kirin_dw_pcie_ops = { |
fc5165db XS |
440 | .read_dbi = kirin_pcie_read_dbi, |
441 | .write_dbi = kirin_pcie_write_dbi, | |
442 | .link_up = kirin_pcie_link_up, | |
443 | }; | |
444 | ||
db2af315 | 445 | static const struct dw_pcie_host_ops kirin_pcie_host_ops = { |
fc5165db XS |
446 | .host_init = kirin_pcie_host_init, |
447 | }; | |
448 | ||
141cb3d4 XS |
449 | static int kirin_pcie_add_msi(struct dw_pcie *pci, |
450 | struct platform_device *pdev) | |
451 | { | |
452 | int irq; | |
453 | ||
454 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | |
455 | irq = platform_get_irq(pdev, 0); | |
caecb05c | 456 | if (irq < 0) |
141cb3d4 | 457 | return irq; |
141cb3d4 XS |
458 | |
459 | pci->pp.msi_irq = irq; | |
460 | } | |
461 | ||
462 | return 0; | |
463 | } | |
464 | ||
6870b673 NC |
465 | static int kirin_add_pcie_port(struct dw_pcie *pci, |
466 | struct platform_device *pdev) | |
fc5165db | 467 | { |
141cb3d4 XS |
468 | int ret; |
469 | ||
470 | ret = kirin_pcie_add_msi(pci, pdev); | |
471 | if (ret) | |
472 | return ret; | |
473 | ||
fc5165db XS |
474 | pci->pp.ops = &kirin_pcie_host_ops; |
475 | ||
476 | return dw_pcie_host_init(&pci->pp); | |
477 | } | |
478 | ||
479 | static int kirin_pcie_probe(struct platform_device *pdev) | |
480 | { | |
481 | struct device *dev = &pdev->dev; | |
482 | struct kirin_pcie *kirin_pcie; | |
483 | struct dw_pcie *pci; | |
484 | int ret; | |
485 | ||
486 | if (!dev->of_node) { | |
487 | dev_err(dev, "NULL node\n"); | |
488 | return -EINVAL; | |
489 | } | |
490 | ||
491 | kirin_pcie = devm_kzalloc(dev, sizeof(struct kirin_pcie), GFP_KERNEL); | |
492 | if (!kirin_pcie) | |
493 | return -ENOMEM; | |
494 | ||
495 | pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL); | |
496 | if (!pci) | |
497 | return -ENOMEM; | |
498 | ||
499 | pci->dev = dev; | |
500 | pci->ops = &kirin_dw_pcie_ops; | |
501 | kirin_pcie->pci = pci; | |
502 | ||
503 | ret = kirin_pcie_get_clk(kirin_pcie, pdev); | |
504 | if (ret) | |
505 | return ret; | |
506 | ||
507 | ret = kirin_pcie_get_resource(kirin_pcie, pdev); | |
508 | if (ret) | |
509 | return ret; | |
510 | ||
511 | kirin_pcie->gpio_id_reset = of_get_named_gpio(dev->of_node, | |
5db8f8d1 | 512 | "reset-gpios", 0); |
fc5165db XS |
513 | if (kirin_pcie->gpio_id_reset < 0) |
514 | return -ENODEV; | |
515 | ||
516 | ret = kirin_pcie_power_on(kirin_pcie); | |
517 | if (ret) | |
518 | return ret; | |
519 | ||
520 | platform_set_drvdata(pdev, kirin_pcie); | |
521 | ||
522 | return kirin_add_pcie_port(pci, pdev); | |
523 | } | |
524 | ||
525 | static const struct of_device_id kirin_pcie_match[] = { | |
526 | { .compatible = "hisilicon,kirin960-pcie" }, | |
527 | {}, | |
528 | }; | |
529 | ||
e734016d | 530 | static struct platform_driver kirin_pcie_driver = { |
fc5165db XS |
531 | .probe = kirin_pcie_probe, |
532 | .driver = { | |
533 | .name = "kirin-pcie", | |
534 | .of_match_table = kirin_pcie_match, | |
535 | .suppress_bind_attrs = true, | |
536 | }, | |
537 | }; | |
538 | builtin_platform_driver(kirin_pcie_driver); |