OSDN Git Service

PCI: dra7xx: Remove unneeded use of IS_ERR_VALUE()
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / drivers / pci / host / pci-dra7xx.c
1 /*
2  * pcie-dra7xx - PCIe controller driver for TI DRA7xx SoCs
3  *
4  * Copyright (C) 2013-2014 Texas Instruments Incorporated - http://www.ti.com
5  *
6  * Authors: Kishon Vijay Abraham I <kishon@ti.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12
13 #include <linux/delay.h>
14 #include <linux/err.h>
15 #include <linux/interrupt.h>
16 #include <linux/irq.h>
17 #include <linux/irqdomain.h>
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/of_gpio.h>
21 #include <linux/pci.h>
22 #include <linux/phy/phy.h>
23 #include <linux/platform_device.h>
24 #include <linux/pm_runtime.h>
25 #include <linux/resource.h>
26 #include <linux/types.h>
27
28 #include "pcie-designware.h"
29
30 /* PCIe controller wrapper DRA7XX configuration registers */
31
32 #define PCIECTRL_DRA7XX_CONF_IRQSTATUS_MAIN             0x0024
33 #define PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MAIN         0x0028
34 #define ERR_SYS                                         BIT(0)
35 #define ERR_FATAL                                       BIT(1)
36 #define ERR_NONFATAL                                    BIT(2)
37 #define ERR_COR                                         BIT(3)
38 #define ERR_AXI                                         BIT(4)
39 #define ERR_ECRC                                        BIT(5)
40 #define PME_TURN_OFF                                    BIT(8)
41 #define PME_TO_ACK                                      BIT(9)
42 #define PM_PME                                          BIT(10)
43 #define LINK_REQ_RST                                    BIT(11)
44 #define LINK_UP_EVT                                     BIT(12)
45 #define CFG_BME_EVT                                     BIT(13)
46 #define CFG_MSE_EVT                                     BIT(14)
47 #define INTERRUPTS (ERR_SYS | ERR_FATAL | ERR_NONFATAL | ERR_COR | ERR_AXI | \
48                         ERR_ECRC | PME_TURN_OFF | PME_TO_ACK | PM_PME | \
49                         LINK_REQ_RST | LINK_UP_EVT | CFG_BME_EVT | CFG_MSE_EVT)
50
51 #define PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI              0x0034
52 #define PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MSI          0x0038
53 #define INTA                                            BIT(0)
54 #define INTB                                            BIT(1)
55 #define INTC                                            BIT(2)
56 #define INTD                                            BIT(3)
57 #define MSI                                             BIT(4)
58 #define LEG_EP_INTERRUPTS (INTA | INTB | INTC | INTD)
59
60 #define PCIECTRL_DRA7XX_CONF_DEVICE_CMD                 0x0104
61 #define LTSSM_EN                                        0x1
62
63 #define PCIECTRL_DRA7XX_CONF_PHY_CS                     0x010C
64 #define LINK_UP                                         BIT(16)
65
66 struct dra7xx_pcie {
67         void __iomem            *base;
68         struct phy              **phy;
69         int                     phy_count;
70         struct device           *dev;
71         struct pcie_port        pp;
72 };
73
74 #define to_dra7xx_pcie(x)       container_of((x), struct dra7xx_pcie, pp)
75
76 static inline u32 dra7xx_pcie_readl(struct dra7xx_pcie *pcie, u32 offset)
77 {
78         return readl(pcie->base + offset);
79 }
80
81 static inline void dra7xx_pcie_writel(struct dra7xx_pcie *pcie, u32 offset,
82                                       u32 value)
83 {
84         writel(value, pcie->base + offset);
85 }
86
87 static inline u32 dra7xx_pcie_readl_rc(struct pcie_port *pp, u32 offset)
88 {
89         return readl(pp->dbi_base + offset);
90 }
91
92 static inline void dra7xx_pcie_writel_rc(struct pcie_port *pp, u32 offset,
93                                          u32 value)
94 {
95         writel(value, pp->dbi_base + offset);
96 }
97
98 static int dra7xx_pcie_link_up(struct pcie_port *pp)
99 {
100         struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp);
101         u32 reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_PHY_CS);
102
103         return !!(reg & LINK_UP);
104 }
105
106 static int dra7xx_pcie_establish_link(struct pcie_port *pp)
107 {
108         struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp);
109         u32 reg;
110         unsigned int retries;
111
112         if (dw_pcie_link_up(pp)) {
113                 dev_err(pp->dev, "link is already up\n");
114                 return 0;
115         }
116
117         reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD);
118         reg |= LTSSM_EN;
119         dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg);
120
121         for (retries = 0; retries < 1000; retries++) {
122                 if (dw_pcie_link_up(pp))
123                         return 0;
124                 usleep_range(10, 20);
125         }
126
127         dev_err(pp->dev, "link is not up\n");
128         return -EINVAL;
129 }
130
131 static void dra7xx_pcie_enable_interrupts(struct pcie_port *pp)
132 {
133         struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp);
134
135         dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MAIN,
136                            ~INTERRUPTS);
137         dra7xx_pcie_writel(dra7xx,
138                            PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MAIN, INTERRUPTS);
139         dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI,
140                            ~LEG_EP_INTERRUPTS & ~MSI);
141
142         if (IS_ENABLED(CONFIG_PCI_MSI))
143                 dra7xx_pcie_writel(dra7xx,
144                                    PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MSI, MSI);
145         else
146                 dra7xx_pcie_writel(dra7xx,
147                                    PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MSI,
148                                    LEG_EP_INTERRUPTS);
149 }
150
151 static void dra7xx_pcie_host_init(struct pcie_port *pp)
152 {
153         dw_pcie_setup_rc(pp);
154         dra7xx_pcie_establish_link(pp);
155         if (IS_ENABLED(CONFIG_PCI_MSI))
156                 dw_pcie_msi_init(pp);
157         dra7xx_pcie_enable_interrupts(pp);
158 }
159
160 static struct pcie_host_ops dra7xx_pcie_host_ops = {
161         .link_up = dra7xx_pcie_link_up,
162         .host_init = dra7xx_pcie_host_init,
163 };
164
165 static int dra7xx_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
166                                 irq_hw_number_t hwirq)
167 {
168         irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
169         irq_set_chip_data(irq, domain->host_data);
170         set_irq_flags(irq, IRQF_VALID);
171
172         return 0;
173 }
174
175 static const struct irq_domain_ops intx_domain_ops = {
176         .map = dra7xx_pcie_intx_map,
177 };
178
179 static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp)
180 {
181         struct device *dev = pp->dev;
182         struct device_node *node = dev->of_node;
183         struct device_node *pcie_intc_node =  of_get_next_child(node, NULL);
184
185         if (!pcie_intc_node) {
186                 dev_err(dev, "No PCIe Intc node found\n");
187                 return PTR_ERR(pcie_intc_node);
188         }
189
190         pp->irq_domain = irq_domain_add_linear(pcie_intc_node, 4,
191                                                &intx_domain_ops, pp);
192         if (!pp->irq_domain) {
193                 dev_err(dev, "Failed to get a INTx IRQ domain\n");
194                 return PTR_ERR(pp->irq_domain);
195         }
196
197         return 0;
198 }
199
200 static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg)
201 {
202         struct pcie_port *pp = arg;
203         struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp);
204         u32 reg;
205
206         reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI);
207
208         switch (reg) {
209         case MSI:
210                 dw_handle_msi_irq(pp);
211                 break;
212         case INTA:
213         case INTB:
214         case INTC:
215         case INTD:
216                 generic_handle_irq(irq_find_mapping(pp->irq_domain, ffs(reg)));
217                 break;
218         }
219
220         dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI, reg);
221
222         return IRQ_HANDLED;
223 }
224
225
226 static irqreturn_t dra7xx_pcie_irq_handler(int irq, void *arg)
227 {
228         struct dra7xx_pcie *dra7xx = arg;
229         u32 reg;
230
231         reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MAIN);
232
233         if (reg & ERR_SYS)
234                 dev_dbg(dra7xx->dev, "System Error\n");
235
236         if (reg & ERR_FATAL)
237                 dev_dbg(dra7xx->dev, "Fatal Error\n");
238
239         if (reg & ERR_NONFATAL)
240                 dev_dbg(dra7xx->dev, "Non Fatal Error\n");
241
242         if (reg & ERR_COR)
243                 dev_dbg(dra7xx->dev, "Correctable Error\n");
244
245         if (reg & ERR_AXI)
246                 dev_dbg(dra7xx->dev, "AXI tag lookup fatal Error\n");
247
248         if (reg & ERR_ECRC)
249                 dev_dbg(dra7xx->dev, "ECRC Error\n");
250
251         if (reg & PME_TURN_OFF)
252                 dev_dbg(dra7xx->dev,
253                         "Power Management Event Turn-Off message received\n");
254
255         if (reg & PME_TO_ACK)
256                 dev_dbg(dra7xx->dev,
257                         "Power Management Turn-Off Ack message received\n");
258
259         if (reg & PM_PME)
260                 dev_dbg(dra7xx->dev,
261                         "PM Power Management Event message received\n");
262
263         if (reg & LINK_REQ_RST)
264                 dev_dbg(dra7xx->dev, "Link Request Reset\n");
265
266         if (reg & LINK_UP_EVT)
267                 dev_dbg(dra7xx->dev, "Link-up state change\n");
268
269         if (reg & CFG_BME_EVT)
270                 dev_dbg(dra7xx->dev, "CFG 'Bus Master Enable' change\n");
271
272         if (reg & CFG_MSE_EVT)
273                 dev_dbg(dra7xx->dev, "CFG 'Memory Space Enable' change\n");
274
275         dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MAIN, reg);
276
277         return IRQ_HANDLED;
278 }
279
280 static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
281                                        struct platform_device *pdev)
282 {
283         int ret;
284         struct pcie_port *pp;
285         struct resource *res;
286         struct device *dev = &pdev->dev;
287
288         pp = &dra7xx->pp;
289         pp->dev = dev;
290         pp->ops = &dra7xx_pcie_host_ops;
291
292         pp->irq = platform_get_irq(pdev, 1);
293         if (pp->irq < 0) {
294                 dev_err(dev, "missing IRQ resource\n");
295                 return -EINVAL;
296         }
297
298         ret = devm_request_irq(&pdev->dev, pp->irq,
299                                dra7xx_pcie_msi_irq_handler, IRQF_SHARED,
300                                "dra7-pcie-msi", pp);
301         if (ret) {
302                 dev_err(&pdev->dev, "failed to request irq\n");
303                 return ret;
304         }
305
306         if (!IS_ENABLED(CONFIG_PCI_MSI)) {
307                 ret = dra7xx_pcie_init_irq_domain(pp);
308                 if (ret < 0)
309                         return ret;
310         }
311
312         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_dbics");
313         pp->dbi_base = devm_ioremap(dev, res->start, resource_size(res));
314         if (!pp->dbi_base)
315                 return -ENOMEM;
316
317         ret = dw_pcie_host_init(pp);
318         if (ret) {
319                 dev_err(dra7xx->dev, "failed to initialize host\n");
320                 return ret;
321         }
322
323         return 0;
324 }
325
326 static int __init dra7xx_pcie_probe(struct platform_device *pdev)
327 {
328         u32 reg;
329         int ret;
330         int irq;
331         int i;
332         int phy_count;
333         struct phy **phy;
334         void __iomem *base;
335         struct resource *res;
336         struct dra7xx_pcie *dra7xx;
337         struct device *dev = &pdev->dev;
338         struct device_node *np = dev->of_node;
339         char name[10];
340         int gpio_sel;
341         enum of_gpio_flags flags;
342         unsigned long gpio_flags;
343
344         dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL);
345         if (!dra7xx)
346                 return -ENOMEM;
347
348         irq = platform_get_irq(pdev, 0);
349         if (irq < 0) {
350                 dev_err(dev, "missing IRQ resource\n");
351                 return -EINVAL;
352         }
353
354         ret = devm_request_irq(dev, irq, dra7xx_pcie_irq_handler,
355                                IRQF_SHARED, "dra7xx-pcie-main", dra7xx);
356         if (ret) {
357                 dev_err(dev, "failed to request irq\n");
358                 return ret;
359         }
360
361         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ti_conf");
362         base = devm_ioremap_nocache(dev, res->start, resource_size(res));
363         if (!base)
364                 return -ENOMEM;
365
366         phy_count = of_property_count_strings(np, "phy-names");
367         if (phy_count < 0) {
368                 dev_err(dev, "unable to find the strings\n");
369                 return phy_count;
370         }
371
372         phy = devm_kzalloc(dev, sizeof(*phy) * phy_count, GFP_KERNEL);
373         if (!phy)
374                 return -ENOMEM;
375
376         for (i = 0; i < phy_count; i++) {
377                 snprintf(name, sizeof(name), "pcie-phy%d", i);
378                 phy[i] = devm_phy_get(dev, name);
379                 if (IS_ERR(phy[i]))
380                         return PTR_ERR(phy[i]);
381
382                 ret = phy_init(phy[i]);
383                 if (ret < 0)
384                         goto err_phy;
385
386                 ret = phy_power_on(phy[i]);
387                 if (ret < 0) {
388                         phy_exit(phy[i]);
389                         goto err_phy;
390                 }
391         }
392
393         dra7xx->base = base;
394         dra7xx->phy = phy;
395         dra7xx->dev = dev;
396         dra7xx->phy_count = phy_count;
397
398         pm_runtime_enable(dev);
399         ret = pm_runtime_get_sync(dev);
400         if (ret < 0) {
401                 dev_err(dev, "pm_runtime_get_sync failed\n");
402                 goto err_get_sync;
403         }
404
405         gpio_sel = of_get_gpio_flags(dev->of_node, 0, &flags);
406         if (gpio_is_valid(gpio_sel)) {
407                 gpio_flags = (flags & OF_GPIO_ACTIVE_LOW) ?
408                                 GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH;
409                 ret = devm_gpio_request_one(dev, gpio_sel, gpio_flags,
410                                             "pcie_reset");
411                 if (ret) {
412                         dev_err(&pdev->dev, "gpio%d request failed, ret %d\n",
413                                 gpio_sel, ret);
414                         goto err_gpio;
415                 }
416         } else if (gpio_sel == -EPROBE_DEFER) {
417                 ret = -EPROBE_DEFER;
418                 goto err_gpio;
419         }
420
421         reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD);
422         reg &= ~LTSSM_EN;
423         dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg);
424
425         platform_set_drvdata(pdev, dra7xx);
426
427         ret = dra7xx_add_pcie_port(dra7xx, pdev);
428         if (ret < 0)
429                 goto err_gpio;
430
431         return 0;
432
433 err_gpio:
434         pm_runtime_put(dev);
435
436 err_get_sync:
437         pm_runtime_disable(dev);
438
439 err_phy:
440         while (--i >= 0) {
441                 phy_power_off(phy[i]);
442                 phy_exit(phy[i]);
443         }
444
445         return ret;
446 }
447
448 static int __exit dra7xx_pcie_remove(struct platform_device *pdev)
449 {
450         struct dra7xx_pcie *dra7xx = platform_get_drvdata(pdev);
451         struct pcie_port *pp = &dra7xx->pp;
452         struct device *dev = &pdev->dev;
453         int count = dra7xx->phy_count;
454
455         if (pp->irq_domain)
456                 irq_domain_remove(pp->irq_domain);
457         pm_runtime_put(dev);
458         pm_runtime_disable(dev);
459         while (count--) {
460                 phy_power_off(dra7xx->phy[count]);
461                 phy_exit(dra7xx->phy[count]);
462         }
463
464         return 0;
465 }
466
467 #ifdef CONFIG_PM_SLEEP
468 static int dra7xx_pcie_suspend(struct device *dev)
469 {
470         struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);
471         struct pcie_port *pp = &dra7xx->pp;
472         u32 val;
473
474         /* clear MSE */
475         val = dra7xx_pcie_readl_rc(pp, PCI_COMMAND);
476         val &= ~PCI_COMMAND_MEMORY;
477         dra7xx_pcie_writel_rc(pp, PCI_COMMAND, val);
478
479         return 0;
480 }
481
482 static int dra7xx_pcie_resume(struct device *dev)
483 {
484         struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);
485         struct pcie_port *pp = &dra7xx->pp;
486         u32 val;
487
488         /* set MSE */
489         val = dra7xx_pcie_readl_rc(pp, PCI_COMMAND);
490         val |= PCI_COMMAND_MEMORY;
491         dra7xx_pcie_writel_rc(pp, PCI_COMMAND, val);
492
493         return 0;
494 }
495
496 static int dra7xx_pcie_suspend_noirq(struct device *dev)
497 {
498         struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);
499         int count = dra7xx->phy_count;
500
501         while (count--) {
502                 phy_power_off(dra7xx->phy[count]);
503                 phy_exit(dra7xx->phy[count]);
504         }
505
506         return 0;
507 }
508
509 static int dra7xx_pcie_resume_noirq(struct device *dev)
510 {
511         struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);
512         int phy_count = dra7xx->phy_count;
513         int ret;
514         int i;
515
516         for (i = 0; i < phy_count; i++) {
517                 ret = phy_init(dra7xx->phy[i]);
518                 if (ret < 0)
519                         goto err_phy;
520
521                 ret = phy_power_on(dra7xx->phy[i]);
522                 if (ret < 0) {
523                         phy_exit(dra7xx->phy[i]);
524                         goto err_phy;
525                 }
526         }
527
528         return 0;
529
530 err_phy:
531         while (--i >= 0) {
532                 phy_power_off(dra7xx->phy[i]);
533                 phy_exit(dra7xx->phy[i]);
534         }
535
536         return ret;
537 }
538 #endif
539
540 static const struct dev_pm_ops dra7xx_pcie_pm_ops = {
541         SET_SYSTEM_SLEEP_PM_OPS(dra7xx_pcie_suspend, dra7xx_pcie_resume)
542         SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(dra7xx_pcie_suspend_noirq,
543                                       dra7xx_pcie_resume_noirq)
544 };
545
546 static const struct of_device_id of_dra7xx_pcie_match[] = {
547         { .compatible = "ti,dra7-pcie", },
548         {},
549 };
550 MODULE_DEVICE_TABLE(of, of_dra7xx_pcie_match);
551
552 static struct platform_driver dra7xx_pcie_driver = {
553         .remove         = __exit_p(dra7xx_pcie_remove),
554         .driver = {
555                 .name   = "dra7-pcie",
556                 .of_match_table = of_dra7xx_pcie_match,
557                 .pm     = &dra7xx_pcie_pm_ops,
558         },
559 };
560
561 module_platform_driver_probe(dra7xx_pcie_driver, dra7xx_pcie_probe);
562
563 MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
564 MODULE_DESCRIPTION("TI PCIe controller driver");
565 MODULE_LICENSE("GPL v2");