ipq806x: Add support for IPQ806x chip family
[15.05/openwrt.git] / target / linux / ipq806x / patches / 0138-PCI-qcom-Add-support-for-pcie-controllers-on-IPQ8064.patch
1 From 98567c99b4dcd80fc9e5dd97229ebb9a7f6dab03 Mon Sep 17 00:00:00 2001
2 From: Kumar Gala <galak@codeaurora.org>
3 Date: Fri, 16 May 2014 11:53:23 -0500
4 Subject: [PATCH 138/182] PCI: qcom: Add support for pcie controllers on
5  IPQ8064
6
7 ---
8  arch/arm/mach-qcom/Kconfig  |    2 +
9  drivers/pci/host/Makefile   |    1 +
10  drivers/pci/host/pci-qcom.c |  682 +++++++++++++++++++++++++++++++++++++++++++
11  3 files changed, 685 insertions(+)
12  create mode 100644 drivers/pci/host/pci-qcom.c
13
14 diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
15 index 63502cc..4d242e5 100644
16 --- a/arch/arm/mach-qcom/Kconfig
17 +++ b/arch/arm/mach-qcom/Kconfig
18 @@ -7,6 +7,8 @@ config ARCH_QCOM
19         select GENERIC_CLOCKEVENTS
20         select HAVE_SMP
21         select PINCTRL
22 +       select MIGHT_HAVE_PCI
23 +       select PCI_DOMAINS if PCI
24         select QCOM_SCM if SMP
25         help
26           Support for Qualcomm's devicetree based systems.
27 diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
28 index 13fb333..be80744 100644
29 --- a/drivers/pci/host/Makefile
30 +++ b/drivers/pci/host/Makefile
31 @@ -4,3 +4,4 @@ obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
32  obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
33  obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
34  obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
35 +obj-$(CONFIG_ARCH_QCOM) += pci-qcom.o
36 diff --git a/drivers/pci/host/pci-qcom.c b/drivers/pci/host/pci-qcom.c
37 new file mode 100644
38 index 0000000..76d7b88
39 --- /dev/null
40 +++ b/drivers/pci/host/pci-qcom.c
41 @@ -0,0 +1,682 @@
42 +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
43 + *
44 + * This program is free software; you can redistribute it and/or modify
45 + * it under the terms of the GNU General Public License version 2 and
46 + * only version 2 as published by the Free Software Foundation.
47 + *
48 + * This program is distributed in the hope that it will be useful,
49 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
50 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
51 + * GNU General Public License for more details.
52 + */
53 +
54 +/*
55 + * QCOM MSM PCIe controller driver.
56 + */
57 +
58 +#include <linux/kernel.h>
59 +#include <linux/pci.h>
60 +#include <linux/gpio.h>
61 +#include <linux/of_gpio.h>
62 +#include <linux/platform_device.h>
63 +#include <linux/of_address.h>
64 +#include <linux/clk.h>
65 +#include <linux/reset.h>
66 +#include <linux/delay.h>
67 +
68 +/* Root Complex Port vendor/device IDs */
69 +#define PCIE_VENDOR_ID_RCP             0x17cb
70 +#define PCIE_DEVICE_ID_RCP             0x0101
71 +
72 +#define __set(v, a, b) (((v) << (b)) & GENMASK(a, b))
73 +
74 +#define PCIE20_PARF_PCS_DEEMPH         0x34
75 +#define PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN1(x)       __set(x, 21, 16)
76 +#define PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(x) __set(x, 13, 8)
77 +#define PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(x)   __set(x, 5, 0)
78 +
79 +#define PCIE20_PARF_PCS_SWING          0x38
80 +#define PCIE20_PARF_PCS_SWING_TX_SWING_FULL(x)         __set(x, 14, 8)
81 +#define PCIE20_PARF_PCS_SWING_TX_SWING_LOW(x)          __set(x, 6, 0)
82 +
83 +#define PCIE20_PARF_PHY_CTRL           0x40
84 +#define PCIE20_PARF_PHY_CTRL_PHY_TX0_TERM_OFFST(x)     __set(x, 20, 16)
85 +#define PCIE20_PARF_PHY_CTRL_PHY_LOS_LEVEL(x)          __set(x, 12, 8)
86 +#define PCIE20_PARF_PHY_CTRL_PHY_RTUNE_REQ             (1 << 4)
87 +#define PCIE20_PARF_PHY_CTRL_PHY_TEST_BURNIN           (1 << 2)
88 +#define PCIE20_PARF_PHY_CTRL_PHY_TEST_BYPASS           (1 << 1)
89 +#define PCIE20_PARF_PHY_CTRL_PHY_TEST_PWR_DOWN         (1 << 0)
90 +
91 +#define PCIE20_PARF_PHY_REFCLK         0x4C
92 +#define PCIE20_PARF_CONFIG_BITS                0x50
93 +
94 +#define PCIE20_ELBI_SYS_CTRL           0x04
95 +#define PCIE20_ELBI_SYS_CTRL_LTSSM_EN  0x01
96 +
97 +#define PCIE20_CAP                     0x70
98 +#define PCIE20_CAP_LINKCTRLSTATUS      (PCIE20_CAP + 0x10)
99 +
100 +#define PCIE20_COMMAND_STATUS          0x04
101 +#define PCIE20_BUSNUMBERS              0x18
102 +#define PCIE20_MEMORY_BASE_LIMIT       0x20
103 +
104 +#define PCIE20_AXI_MSTR_RESP_COMP_CTRL0 0x818
105 +#define PCIE20_AXI_MSTR_RESP_COMP_CTRL1 0x81c
106 +#define PCIE20_PLR_IATU_VIEWPORT       0x900
107 +#define PCIE20_PLR_IATU_CTRL1          0x904
108 +#define PCIE20_PLR_IATU_CTRL2          0x908
109 +#define PCIE20_PLR_IATU_LBAR           0x90C
110 +#define PCIE20_PLR_IATU_UBAR           0x910
111 +#define PCIE20_PLR_IATU_LAR            0x914
112 +#define PCIE20_PLR_IATU_LTAR           0x918
113 +#define PCIE20_PLR_IATU_UTAR           0x91c
114 +
115 +#define MSM_PCIE_DEV_CFG_ADDR          0x01000000
116 +
117 +#define RD 0
118 +#define WR 1
119 +
120 +#define MAX_RC_NUM     3
121 +#define PCIE_BUS_PRIV_DATA(pdev) \
122 +       (((struct pci_sys_data *)pdev->bus->sysdata)->private_data)
123 +
124 +/* PCIe TLP types that we are interested in */
125 +#define PCI_CFG0_RDWR  0x4
126 +#define PCI_CFG1_RDWR  0x5
127 +
128 +#define readl_poll_timeout(addr, val, cond, sleep_us, timeout_us) \
129 +({ \
130 +       unsigned long timeout = jiffies + usecs_to_jiffies(timeout_us); \
131 +       might_sleep_if(timeout_us); \
132 +       for (;;) { \
133 +               (val) = readl(addr); \
134 +               if (cond) \
135 +                       break; \
136 +               if (timeout_us && time_after(jiffies, timeout)) { \
137 +                       (val) = readl(addr); \
138 +                       break; \
139 +               } \
140 +               if (sleep_us) \
141 +                       usleep_range(DIV_ROUND_UP(sleep_us, 4), sleep_us); \
142 +       } \
143 +       (cond) ? 0 : -ETIMEDOUT; \
144 +})
145 +
146 +struct qcom_pcie {
147 +       void __iomem            *elbi_base;
148 +       void __iomem            *parf_base;
149 +       void __iomem            *dwc_base;
150 +       void __iomem            *cfg_base;
151 +       int                     reset_gpio;
152 +       struct clk              *iface_clk;
153 +       struct clk              *bus_clk;
154 +       struct clk              *phy_clk;
155 +       int                     irq_int[4];
156 +       struct reset_control    *axi_reset;
157 +       struct reset_control    *ahb_reset;
158 +       struct reset_control    *por_reset;
159 +       struct reset_control    *pci_reset;
160 +       struct reset_control    *phy_reset;
161 +
162 +       struct resource         conf;
163 +       struct resource         io;
164 +       struct resource         mem;
165 +};
166 +
167 +static int qcom_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
168 +static int qcom_pcie_setup(int nr, struct pci_sys_data *sys);
169 +static int msm_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
170 +                           int size, u32 *val);
171 +static int msm_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
172 +                           int where, int size, u32 val);
173 +
174 +static struct pci_ops qcom_pcie_ops = {
175 +       .read = msm_pcie_rd_conf,
176 +       .write = msm_pcie_wr_conf,
177 +};
178 +
179 +static struct hw_pci qcom_hw_pci[MAX_RC_NUM] = {
180 +       {
181 +#ifdef CONFIG_PCI_DOMAINS
182 +               .domain = 0,
183 +#endif
184 +               .ops            = &qcom_pcie_ops,
185 +               .nr_controllers = 1,
186 +               .swizzle        = pci_common_swizzle,
187 +               .setup          = qcom_pcie_setup,
188 +               .map_irq        = qcom_pcie_map_irq,
189 +       },
190 +       {
191 +#ifdef CONFIG_PCI_DOMAINS
192 +               .domain = 1,
193 +#endif
194 +               .ops            = &qcom_pcie_ops,
195 +               .nr_controllers = 1,
196 +               .swizzle        = pci_common_swizzle,
197 +               .setup          = qcom_pcie_setup,
198 +               .map_irq        = qcom_pcie_map_irq,
199 +       },
200 +       {
201 +#ifdef CONFIG_PCI_DOMAINS
202 +               .domain = 2,
203 +#endif
204 +               .ops            = &qcom_pcie_ops,
205 +               .nr_controllers = 1,
206 +               .swizzle        = pci_common_swizzle,
207 +               .setup          = qcom_pcie_setup,
208 +               .map_irq        = qcom_pcie_map_irq,
209 +       },
210 +};
211 +
212 +static int nr_controllers;
213 +static DEFINE_SPINLOCK(qcom_hw_pci_lock);
214 +
215 +static inline struct qcom_pcie *sys_to_pcie(struct pci_sys_data *sys)
216 +{
217 +       return sys->private_data;
218 +}
219 +
220 +inline int is_msm_pcie_rc(struct pci_bus *bus)
221 +{
222 +       return (bus->number == 0);
223 +}
224 +
225 +static int qcom_pcie_is_link_up(struct qcom_pcie *dev)
226 +{
227 +       return readl_relaxed(dev->dwc_base + PCIE20_CAP_LINKCTRLSTATUS) & BIT(29);
228 +}
229 +
230 +inline int msm_pcie_get_cfgtype(struct pci_bus *bus)
231 +{
232 +       /*
233 +        * http://www.tldp.org/LDP/tlk/dd/pci.html
234 +        * Pass it onto the secondary bus interface unchanged if the
235 +        * bus number specified is greater than the secondary bus
236 +        * number and less than or equal to the subordinate bus
237 +        * number.
238 +        *
239 +        * Read/Write to the RC and Device/Switch connected to the RC
240 +        * are CFG0 type transactions. Rest have to be forwarded
241 +        * down stream as CFG1 transactions.
242 +        *
243 +        */
244 +       if (bus->number == 0)
245 +               return PCI_CFG0_RDWR;
246 +
247 +       return PCI_CFG0_RDWR;
248 +}
249 +
250 +void msm_pcie_config_cfgtype(struct pci_bus *bus, u32 devfn)
251 +{
252 +       uint32_t bdf, cfgtype;
253 +       struct qcom_pcie *dev = sys_to_pcie(bus->sysdata);
254 +
255 +       cfgtype = msm_pcie_get_cfgtype(bus);
256 +
257 +       if (cfgtype == PCI_CFG0_RDWR) {
258 +               bdf = MSM_PCIE_DEV_CFG_ADDR;
259 +       } else {
260 +               /*
261 +                * iATU Lower Target Address Register
262 +                *      Bits    Description
263 +                *      *-1:0   Forms bits [*:0] of the
264 +                *              start address of the new
265 +                *              address of the translated
266 +                *              region. The start address
267 +                *              must be aligned to a
268 +                *              CX_ATU_MIN_REGION_SIZE kB
269 +                *              boundary, so these bits are
270 +                *              always 0. A write to this
271 +                *              location is ignored by the
272 +                *              PCIe core.
273 +                *      31:*1   Forms bits [31:*] of the of
274 +                *              the new address of the
275 +                *              translated region.
276 +                *
277 +                *      * is log2(CX_ATU_MIN_REGION_SIZE)
278 +                */
279 +               bdf = (((bus->number & 0xff) << 24) & 0xff000000) |
280 +                               (((devfn & 0xff) << 16) & 0x00ff0000);
281 +       }
282 +
283 +       writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_VIEWPORT);
284 +       wmb();
285 +
286 +       /* Program Bdf Address */
287 +       writel_relaxed(bdf, dev->dwc_base + PCIE20_PLR_IATU_LTAR);
288 +       wmb();
289 +
290 +       /* Write Config Request Type */
291 +       writel_relaxed(cfgtype, dev->dwc_base + PCIE20_PLR_IATU_CTRL1);
292 +       wmb();
293 +}
294 +
295 +static inline int msm_pcie_oper_conf(struct pci_bus *bus, u32 devfn, int oper,
296 +                                    int where, int size, u32 *val)
297 +{
298 +       uint32_t word_offset, byte_offset, mask;
299 +       uint32_t rd_val, wr_val;
300 +       struct qcom_pcie *dev = sys_to_pcie(bus->sysdata);
301 +       void __iomem *config_base;
302 +       int rc;
303 +
304 +       rc = is_msm_pcie_rc(bus);
305 +
306 +       /*
307 +        * For downstream bus, make sure link is up
308 +        */
309 +       if (rc && (devfn != 0)) {
310 +               *val = ~0;
311 +               return PCIBIOS_DEVICE_NOT_FOUND;
312 +       } else if ((!rc) && (!qcom_pcie_is_link_up(dev))) {
313 +               *val = ~0;
314 +               return PCIBIOS_DEVICE_NOT_FOUND;
315 +       }
316 +
317 +       msm_pcie_config_cfgtype(bus, devfn);
318 +
319 +       word_offset = where & ~0x3;
320 +       byte_offset = where & 0x3;
321 +       mask = (~0 >> (8 * (4 - size))) << (8 * byte_offset);
322 +
323 +       config_base = (rc) ? dev->dwc_base : dev->cfg_base;
324 +       rd_val = readl_relaxed(config_base + word_offset);
325 +
326 +       if (oper == RD) {
327 +               *val = ((rd_val & mask) >> (8 * byte_offset));
328 +       } else {
329 +               wr_val = (rd_val & ~mask) |
330 +                               ((*val << (8 * byte_offset)) & mask);
331 +               writel_relaxed(wr_val, config_base + word_offset);
332 +               wmb(); /* ensure config data is written to hardware register */
333 +       }
334 +
335 +       return 0;
336 +}
337 +
338 +static int msm_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
339 +                           int size, u32 *val)
340 +{
341 +       return msm_pcie_oper_conf(bus, devfn, RD, where, size, val);
342 +}
343 +
344 +static int msm_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
345 +                           int where, int size, u32 val)
346 +{
347 +       /*
348 +        *Attempt to reset secondary bus is causing PCIE core to reset.
349 +        *Disable secondary bus reset functionality.
350 +        */
351 +       if ((bus->number == 0) && (where == PCI_BRIDGE_CONTROL) &&
352 +           (val & PCI_BRIDGE_CTL_BUS_RESET)) {
353 +               pr_info("PCIE secondary bus reset not supported\n");
354 +               val &= ~PCI_BRIDGE_CTL_BUS_RESET;
355 +       }
356 +
357 +       return msm_pcie_oper_conf(bus, devfn, WR, where, size, &val);
358 +}
359 +
360 +static int qcom_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
361 +{
362 +       struct qcom_pcie *pcie_dev = PCIE_BUS_PRIV_DATA(dev);
363 +
364 +       return pcie_dev->irq_int[pin-1];
365 +}
366 +
367 +static int qcom_pcie_setup(int nr, struct pci_sys_data *sys)
368 +{
369 +       struct qcom_pcie *qcom_pcie = sys->private_data;
370 +
371 +       /*
372 +        * specify linux PCI framework to allocate device memory (BARs)
373 +        * from msm_pcie_dev.dev_mem_res resource.
374 +        */
375 +       sys->mem_offset = 0;
376 +       sys->io_offset = 0;
377 +
378 +       pci_add_resource(&sys->resources, &qcom_pcie->mem);
379 +       pci_add_resource(&sys->resources, &qcom_pcie->io);
380 +
381 +       return 1;
382 +}
383 +
384 +static inline void qcom_elbi_writel_relaxed(struct qcom_pcie *pcie, u32 val, u32 reg)
385 +{
386 +       writel_relaxed(val, pcie->elbi_base + reg);
387 +}
388 +
389 +static inline u32 qcom_elbi_readl_relaxed(struct qcom_pcie *pcie, u32 reg)
390 +{
391 +       return readl_relaxed(pcie->elbi_base + reg);
392 +}
393 +
394 +static inline void qcom_parf_writel_relaxed(struct qcom_pcie *pcie, u32 val, u32 reg)
395 +{
396 +       writel_relaxed(val, pcie->parf_base + reg);
397 +}
398 +
399 +static inline u32 qcom_parf_readl_relaxed(struct qcom_pcie *pcie, u32 reg)
400 +{
401 +       return readl_relaxed(pcie->parf_base + reg);
402 +}
403 +
404 +static void msm_pcie_write_mask(void __iomem *addr,
405 +                               uint32_t clear_mask, uint32_t set_mask)
406 +{
407 +       uint32_t val;
408 +
409 +       val = (readl_relaxed(addr) & ~clear_mask) | set_mask;
410 +       writel_relaxed(val, addr);
411 +       wmb();  /* ensure data is written to hardware register */
412 +}
413 +
414 +static void qcom_pcie_config_controller(struct qcom_pcie *dev)
415 +{
416 +       /*
417 +        * program and enable address translation region 0 (device config
418 +        * address space); region type config;
419 +        * axi config address range to device config address range
420 +        */
421 +       writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_VIEWPORT);
422 +       /* ensure that hardware locks the region before programming it */
423 +       wmb();
424 +
425 +       writel_relaxed(4, dev->dwc_base + PCIE20_PLR_IATU_CTRL1);
426 +       writel_relaxed(BIT(31), dev->dwc_base + PCIE20_PLR_IATU_CTRL2);
427 +       writel_relaxed(dev->conf.start, dev->dwc_base + PCIE20_PLR_IATU_LBAR);
428 +       writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_UBAR);
429 +       writel_relaxed(dev->conf.end, dev->dwc_base + PCIE20_PLR_IATU_LAR);
430 +       writel_relaxed(MSM_PCIE_DEV_CFG_ADDR,
431 +                      dev->dwc_base + PCIE20_PLR_IATU_LTAR);
432 +       writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_UTAR);
433 +       /* ensure that hardware registers the configuration */
434 +       wmb();
435 +
436 +       /*
437 +        * program and enable address translation region 2 (device resource
438 +        * address space); region type memory;
439 +        * axi device bar address range to device bar address range
440 +        */
441 +       writel_relaxed(2, dev->dwc_base + PCIE20_PLR_IATU_VIEWPORT);
442 +       /* ensure that hardware locks the region before programming it */
443 +       wmb();
444 +
445 +       writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_CTRL1);
446 +       writel_relaxed(BIT(31), dev->dwc_base + PCIE20_PLR_IATU_CTRL2);
447 +       writel_relaxed(dev->mem.start, dev->dwc_base + PCIE20_PLR_IATU_LBAR);
448 +       writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_UBAR);
449 +       writel_relaxed(dev->mem.end, dev->dwc_base + PCIE20_PLR_IATU_LAR);
450 +       writel_relaxed(dev->mem.start,
451 +                      dev->dwc_base + PCIE20_PLR_IATU_LTAR);
452 +       writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_UTAR);
453 +       /* ensure that hardware registers the configuration */
454 +       wmb();
455 +
456 +       /* 1K PCIE buffer setting */
457 +       writel_relaxed(0x3, dev->dwc_base + PCIE20_AXI_MSTR_RESP_COMP_CTRL0);
458 +       writel_relaxed(0x1, dev->dwc_base + PCIE20_AXI_MSTR_RESP_COMP_CTRL1);
459 +       /* ensure that hardware registers the configuration */
460 +       wmb();
461 +}
462 +
463 +static int qcom_pcie_probe(struct platform_device *pdev)
464 +{
465 +       unsigned long flags;
466 +       struct qcom_pcie *qcom_pcie;
467 +       struct device_node *np = pdev->dev.of_node;
468 +       struct resource *elbi_base, *parf_base, *dwc_base;
469 +       struct hw_pci *hw;
470 +       struct of_pci_range range;
471 +       struct of_pci_range_parser parser;
472 +       int ret, i;
473 +       u32 val;
474 +
475 +       qcom_pcie = devm_kzalloc(&pdev->dev, sizeof(*qcom_pcie), GFP_KERNEL);
476 +       if (!qcom_pcie) {
477 +               dev_err(&pdev->dev, "no memory for qcom_pcie\n");
478 +               return -ENOMEM;
479 +       }
480 +
481 +       elbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "elbi");
482 +       qcom_pcie->elbi_base = devm_ioremap_resource(&pdev->dev, elbi_base);
483 +       if (IS_ERR(qcom_pcie->elbi_base)) {
484 +               dev_err(&pdev->dev, "Failed to ioremap elbi space\n");
485 +               return PTR_ERR(qcom_pcie->elbi_base);
486 +       }
487 +
488 +       parf_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "parf");
489 +       qcom_pcie->parf_base = devm_ioremap_resource(&pdev->dev, parf_base);
490 +       if (IS_ERR(qcom_pcie->parf_base)) {
491 +               dev_err(&pdev->dev, "Failed to ioremap parf space\n");
492 +               return PTR_ERR(qcom_pcie->parf_base);
493 +       }
494 +
495 +       dwc_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "base");
496 +       qcom_pcie->dwc_base = devm_ioremap_resource(&pdev->dev, dwc_base);
497 +       if (IS_ERR(qcom_pcie->dwc_base)) {
498 +               dev_err(&pdev->dev, "Failed to ioremap dwc_base space\n");
499 +               return PTR_ERR(qcom_pcie->dwc_base);
500 +       }
501 +
502 +       if (of_pci_range_parser_init(&parser, np)) {
503 +               dev_err(&pdev->dev, "missing ranges property\n");
504 +               return -EINVAL;
505 +       }
506 +
507 +       /* Get the I/O and memory ranges from DT */
508 +       for_each_of_pci_range(&parser, &range) {
509 +               switch (range.pci_space & 0x3) {
510 +               case 0:         /* cfg */
511 +                       of_pci_range_to_resource(&range, np, &qcom_pcie->conf);
512 +                       qcom_pcie->conf.flags = IORESOURCE_MEM;
513 +                       break;
514 +               case 1:         /* io */
515 +                       of_pci_range_to_resource(&range, np, &qcom_pcie->io);
516 +                       break;
517 +               default:        /* mem */
518 +                       of_pci_range_to_resource(&range, np, &qcom_pcie->mem);
519 +                       break;
520 +               }
521 +       }
522 +
523 +       qcom_pcie->cfg_base = devm_ioremap_resource(&pdev->dev, &qcom_pcie->conf);
524 +       if (IS_ERR(qcom_pcie->cfg_base)) {
525 +               dev_err(&pdev->dev, "Failed to ioremap PCIe cfg space\n");
526 +               return PTR_ERR(qcom_pcie->cfg_base);
527 +        }
528 +
529 +       qcom_pcie->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
530 +       if (!gpio_is_valid(qcom_pcie->reset_gpio)) {
531 +               dev_err(&pdev->dev, "pcie reset gpio is not valid\n");
532 +               return -EINVAL;
533 +       }
534 +
535 +       ret = devm_gpio_request_one(&pdev->dev, qcom_pcie->reset_gpio,
536 +                                   GPIOF_DIR_OUT, "pcie_reset");
537 +       if (ret) {
538 +               dev_err(&pdev->dev, "Failed to request pcie reset gpio\n");
539 +               return ret;
540 +       }
541 +
542 +       qcom_pcie->iface_clk = devm_clk_get(&pdev->dev, "iface");
543 +       if (IS_ERR(qcom_pcie->iface_clk)) {
544 +               dev_err(&pdev->dev, "Failed to get pcie iface clock\n");
545 +               return PTR_ERR(qcom_pcie->iface_clk);
546 +       }
547 +
548 +       qcom_pcie->phy_clk = devm_clk_get(&pdev->dev, "phy");
549 +       if (IS_ERR(qcom_pcie->phy_clk)) {
550 +               dev_err(&pdev->dev, "Failed to get pcie phy clock\n");
551 +               return PTR_ERR(qcom_pcie->phy_clk);
552 +       }
553 +
554 +       qcom_pcie->bus_clk = devm_clk_get(&pdev->dev, "core");
555 +       if (IS_ERR(qcom_pcie->bus_clk)) {
556 +               dev_err(&pdev->dev, "Failed to get pcie core clock\n");
557 +               return PTR_ERR(qcom_pcie->bus_clk);
558 +       }
559 +
560 +       qcom_pcie->axi_reset = devm_reset_control_get(&pdev->dev, "axi");
561 +       if (IS_ERR(qcom_pcie->axi_reset)) {
562 +               dev_err(&pdev->dev, "Failed to get axi reset\n");
563 +               return PTR_ERR(qcom_pcie->axi_reset);
564 +       }
565 +
566 +       qcom_pcie->ahb_reset = devm_reset_control_get(&pdev->dev, "ahb");
567 +       if (IS_ERR(qcom_pcie->ahb_reset)) {
568 +               dev_err(&pdev->dev, "Failed to get ahb reset\n");
569 +               return PTR_ERR(qcom_pcie->ahb_reset);
570 +       }
571 +
572 +       qcom_pcie->por_reset = devm_reset_control_get(&pdev->dev, "por");
573 +       if (IS_ERR(qcom_pcie->por_reset)) {
574 +               dev_err(&pdev->dev, "Failed to get por reset\n");
575 +               return PTR_ERR(qcom_pcie->por_reset);
576 +       }
577 +
578 +       qcom_pcie->pci_reset = devm_reset_control_get(&pdev->dev, "pci");
579 +       if (IS_ERR(qcom_pcie->pci_reset)) {
580 +               dev_err(&pdev->dev, "Failed to get pci reset\n");
581 +               return PTR_ERR(qcom_pcie->pci_reset);
582 +       }
583 +
584 +       qcom_pcie->phy_reset = devm_reset_control_get(&pdev->dev, "phy");
585 +       if (IS_ERR(qcom_pcie->phy_reset)) {
586 +               dev_err(&pdev->dev, "Failed to get phy reset\n");
587 +               return PTR_ERR(qcom_pcie->phy_reset);
588 +       }
589 +
590 +       for (i = 0; i < 4; i++) {
591 +               qcom_pcie->irq_int[i] = platform_get_irq(pdev, i+1);
592 +               if (qcom_pcie->irq_int[i] < 0) {
593 +                       dev_err(&pdev->dev, "failed to get irq resource\n");
594 +                       return qcom_pcie->irq_int[i];
595 +               }
596 +       }
597 +
598 +       gpio_set_value(qcom_pcie->reset_gpio, 0);
599 +       usleep_range(10000, 15000);
600 +
601 +       /* assert PCIe PARF reset while powering the core */
602 +       reset_control_assert(qcom_pcie->ahb_reset);
603 +
604 +       /* enable clocks */
605 +       ret = clk_prepare_enable(qcom_pcie->iface_clk);
606 +       if (ret)
607 +               return ret;
608 +       ret = clk_prepare_enable(qcom_pcie->phy_clk);
609 +       if (ret)
610 +               return ret;
611 +       ret = clk_prepare_enable(qcom_pcie->bus_clk);
612 +       if (ret)
613 +               return ret;
614 +
615 +       /*
616 +        * de-assert PCIe PARF reset;
617 +        * wait 1us before accessing PARF registers
618 +        */
619 +       reset_control_deassert(qcom_pcie->ahb_reset);
620 +       udelay(1);
621 +
622 +       /* enable PCIe clocks and resets */
623 +       msm_pcie_write_mask(qcom_pcie->parf_base + PCIE20_PARF_PHY_CTRL, BIT(0), 0);
624 +
625 +       /* Set Tx Termination Offset */
626 +       val = qcom_parf_readl_relaxed(qcom_pcie, PCIE20_PARF_PHY_CTRL);
627 +       val |= PCIE20_PARF_PHY_CTRL_PHY_TX0_TERM_OFFST(7);
628 +       qcom_parf_writel_relaxed(qcom_pcie, val, PCIE20_PARF_PHY_CTRL);
629 +
630 +       /* PARF programming */
631 +       qcom_parf_writel_relaxed(qcom_pcie, PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN1(0x18) |
632 +                       PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(0x18) |
633 +                       PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(0x22),
634 +                       PCIE20_PARF_PCS_DEEMPH);
635 +       qcom_parf_writel_relaxed(qcom_pcie, PCIE20_PARF_PCS_SWING_TX_SWING_FULL(0x78) |
636 +                       PCIE20_PARF_PCS_SWING_TX_SWING_LOW(0x78),
637 +                       PCIE20_PARF_PCS_SWING);
638 +       qcom_parf_writel_relaxed(qcom_pcie, (4<<24), PCIE20_PARF_CONFIG_BITS);
639 +       /* ensure that hardware registers the PARF configuration */
640 +       wmb();
641 +
642 +       /* enable reference clock */
643 +       msm_pcie_write_mask(qcom_pcie->parf_base + PCIE20_PARF_PHY_REFCLK, BIT(12), BIT(16));
644 +
645 +       /* ensure that access is enabled before proceeding */
646 +       wmb();
647 +
648 +       /* de-assert PICe PHY, Core, POR and AXI clk domain resets */
649 +       reset_control_deassert(qcom_pcie->phy_reset);
650 +       reset_control_deassert(qcom_pcie->pci_reset);
651 +       reset_control_deassert(qcom_pcie->por_reset);
652 +       reset_control_deassert(qcom_pcie->axi_reset);
653 +
654 +       /* wait 150ms for clock acquisition */
655 +       usleep_range(10000, 15000);
656 +
657 +       /* de-assert PCIe reset link to bring EP out of reset */
658 +       gpio_set_value(qcom_pcie->reset_gpio, 1 - 0);
659 +       usleep_range(10000, 15000);
660 +
661 +       /* enable link training */
662 +       val = qcom_elbi_readl_relaxed(qcom_pcie, PCIE20_ELBI_SYS_CTRL);
663 +       val |= PCIE20_ELBI_SYS_CTRL_LTSSM_EN;
664 +       qcom_elbi_writel_relaxed(qcom_pcie, val, PCIE20_ELBI_SYS_CTRL);
665 +       wmb();
666 +
667 +       /* poll for link to come up for upto 100ms */
668 +       ret = readl_poll_timeout(
669 +                       (qcom_pcie->dwc_base + PCIE20_CAP_LINKCTRLSTATUS),
670 +                       val, (val & BIT(29)), 10000, 100000);
671 +
672 +       printk("link initialized %d\n", ret);
673 +
674 +       qcom_pcie_config_controller(qcom_pcie);
675 +
676 +       platform_set_drvdata(pdev, qcom_pcie);
677 +
678 +       spin_lock_irqsave(&qcom_hw_pci_lock, flags);
679 +       qcom_hw_pci[nr_controllers].private_data = (void **)&qcom_pcie;
680 +       hw = &qcom_hw_pci[nr_controllers];
681 +       nr_controllers++;
682 +       spin_unlock_irqrestore(&qcom_hw_pci_lock, flags);
683 +
684 +       pci_common_init(hw);
685 +
686 +       return 0;
687 +}
688 +
689 +static int __exit qcom_pcie_remove(struct platform_device *pdev)
690 +{
691 +       struct qcom_pcie *qcom_pcie = platform_get_drvdata(pdev);
692 +
693 +       return 0;
694 +}
695 +
696 +static struct of_device_id qcom_pcie_match[] = {
697 +       {       .compatible = "qcom,pcie-ipq8064", },
698 +       {}
699 +};
700 +
701 +static struct platform_driver qcom_pcie_driver = {
702 +       .probe  = qcom_pcie_probe,
703 +       .remove = qcom_pcie_remove,
704 +       .driver = {
705 +               .name           = "qcom_pcie",
706 +               .owner          = THIS_MODULE,
707 +               .of_match_table = qcom_pcie_match,
708 +       },
709 +};
710 +
711 +static int qcom_pcie_init(void)
712 +{
713 +       return platform_driver_register(&qcom_pcie_driver);
714 +}
715 +subsys_initcall(qcom_pcie_init);
716 +
717 +/* RC do not represent the right class; set it to PCI_CLASS_BRIDGE_PCI */
718 +static void msm_pcie_fixup_early(struct pci_dev *dev)
719 +{
720 +       if (dev->hdr_type == 1)
721 +               dev->class = (dev->class & 0xff) | (PCI_CLASS_BRIDGE_PCI << 8);
722 +}
723 +DECLARE_PCI_FIXUP_EARLY(PCIE_VENDOR_ID_RCP, PCIE_DEVICE_ID_RCP, msm_pcie_fixup_early);
724 -- 
725 1.7.10.4
726