aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/host/pci-imx6.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/host/pci-imx6.c')
-rw-r--r--drivers/pci/host/pci-imx6.c147
1 files changed, 55 insertions, 92 deletions
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index ee082509b0ba..a5645ae4aef0 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -25,6 +25,7 @@
25#include <linux/resource.h> 25#include <linux/resource.h>
26#include <linux/signal.h> 26#include <linux/signal.h>
27#include <linux/types.h> 27#include <linux/types.h>
28#include <linux/interrupt.h>
28 29
29#include "pcie-designware.h" 30#include "pcie-designware.h"
30 31
@@ -32,13 +33,9 @@
32 33
33struct imx6_pcie { 34struct imx6_pcie {
34 int reset_gpio; 35 int reset_gpio;
35 int power_on_gpio; 36 struct clk *pcie_bus;
36 int wake_up_gpio; 37 struct clk *pcie_phy;
37 int disable_gpio; 38 struct clk *pcie;
38 struct clk *lvds_gate;
39 struct clk *sata_ref_100m;
40 struct clk *pcie_ref_125m;
41 struct clk *pcie_axi;
42 struct pcie_port pp; 39 struct pcie_port pp;
43 struct regmap *iomuxc_gpr; 40 struct regmap *iomuxc_gpr;
44 void __iomem *mem_base; 41 void __iomem *mem_base;
@@ -231,36 +228,27 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp)
231 struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp); 228 struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
232 int ret; 229 int ret;
233 230
234 if (gpio_is_valid(imx6_pcie->power_on_gpio))
235 gpio_set_value(imx6_pcie->power_on_gpio, 1);
236
237 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, 231 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
238 IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18); 232 IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18);
239 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, 233 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
240 IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16); 234 IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
241 235
242 ret = clk_prepare_enable(imx6_pcie->sata_ref_100m); 236 ret = clk_prepare_enable(imx6_pcie->pcie_phy);
243 if (ret) {
244 dev_err(pp->dev, "unable to enable sata_ref_100m\n");
245 goto err_sata_ref;
246 }
247
248 ret = clk_prepare_enable(imx6_pcie->pcie_ref_125m);
249 if (ret) { 237 if (ret) {
250 dev_err(pp->dev, "unable to enable pcie_ref_125m\n"); 238 dev_err(pp->dev, "unable to enable pcie_phy clock\n");
251 goto err_pcie_ref; 239 goto err_pcie_phy;
252 } 240 }
253 241
254 ret = clk_prepare_enable(imx6_pcie->lvds_gate); 242 ret = clk_prepare_enable(imx6_pcie->pcie_bus);
255 if (ret) { 243 if (ret) {
256 dev_err(pp->dev, "unable to enable lvds_gate\n"); 244 dev_err(pp->dev, "unable to enable pcie_bus clock\n");
257 goto err_lvds_gate; 245 goto err_pcie_bus;
258 } 246 }
259 247
260 ret = clk_prepare_enable(imx6_pcie->pcie_axi); 248 ret = clk_prepare_enable(imx6_pcie->pcie);
261 if (ret) { 249 if (ret) {
262 dev_err(pp->dev, "unable to enable pcie_axi\n"); 250 dev_err(pp->dev, "unable to enable pcie clock\n");
263 goto err_pcie_axi; 251 goto err_pcie;
264 } 252 }
265 253
266 /* allow the clocks to stabilize */ 254 /* allow the clocks to stabilize */
@@ -274,13 +262,11 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp)
274 } 262 }
275 return 0; 263 return 0;
276 264
277err_pcie_axi: 265err_pcie:
278 clk_disable_unprepare(imx6_pcie->lvds_gate); 266 clk_disable_unprepare(imx6_pcie->pcie_bus);
279err_lvds_gate: 267err_pcie_bus:
280 clk_disable_unprepare(imx6_pcie->pcie_ref_125m); 268 clk_disable_unprepare(imx6_pcie->pcie_phy);
281err_pcie_ref: 269err_pcie_phy:
282 clk_disable_unprepare(imx6_pcie->sata_ref_100m);
283err_sata_ref:
284 return ret; 270 return ret;
285 271
286} 272}
@@ -329,6 +315,13 @@ static int imx6_pcie_wait_for_link(struct pcie_port *pp)
329 return 0; 315 return 0;
330} 316}
331 317
318static irqreturn_t imx6_pcie_msi_handler(int irq, void *arg)
319{
320 struct pcie_port *pp = arg;
321
322 return dw_handle_msi_irq(pp);
323}
324
332static int imx6_pcie_start_link(struct pcie_port *pp) 325static int imx6_pcie_start_link(struct pcie_port *pp)
333{ 326{
334 struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp); 327 struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
@@ -403,6 +396,9 @@ static void imx6_pcie_host_init(struct pcie_port *pp)
403 dw_pcie_setup_rc(pp); 396 dw_pcie_setup_rc(pp);
404 397
405 imx6_pcie_start_link(pp); 398 imx6_pcie_start_link(pp);
399
400 if (IS_ENABLED(CONFIG_PCI_MSI))
401 dw_pcie_msi_init(pp);
406} 402}
407 403
408static void imx6_pcie_reset_phy(struct pcie_port *pp) 404static void imx6_pcie_reset_phy(struct pcie_port *pp)
@@ -487,15 +483,25 @@ static struct pcie_host_ops imx6_pcie_host_ops = {
487 .host_init = imx6_pcie_host_init, 483 .host_init = imx6_pcie_host_init,
488}; 484};
489 485
490static int imx6_add_pcie_port(struct pcie_port *pp, 486static int __init imx6_add_pcie_port(struct pcie_port *pp,
491 struct platform_device *pdev) 487 struct platform_device *pdev)
492{ 488{
493 int ret; 489 int ret;
494 490
495 pp->irq = platform_get_irq(pdev, 0); 491 if (IS_ENABLED(CONFIG_PCI_MSI)) {
496 if (!pp->irq) { 492 pp->msi_irq = platform_get_irq_byname(pdev, "msi");
497 dev_err(&pdev->dev, "failed to get irq\n"); 493 if (pp->msi_irq <= 0) {
498 return -ENODEV; 494 dev_err(&pdev->dev, "failed to get MSI irq\n");
495 return -ENODEV;
496 }
497
498 ret = devm_request_irq(&pdev->dev, pp->msi_irq,
499 imx6_pcie_msi_handler,
500 IRQF_SHARED, "mx6-pcie-msi", pp);
501 if (ret) {
502 dev_err(&pdev->dev, "failed to request MSI irq\n");
503 return -ENODEV;
504 }
499 } 505 }
500 506
501 pp->root_bus_nr = -1; 507 pp->root_bus_nr = -1;
@@ -546,69 +552,26 @@ static int __init imx6_pcie_probe(struct platform_device *pdev)
546 } 552 }
547 } 553 }
548 554
549 imx6_pcie->power_on_gpio = of_get_named_gpio(np, "power-on-gpio", 0);
550 if (gpio_is_valid(imx6_pcie->power_on_gpio)) {
551 ret = devm_gpio_request_one(&pdev->dev,
552 imx6_pcie->power_on_gpio,
553 GPIOF_OUT_INIT_LOW,
554 "PCIe power enable");
555 if (ret) {
556 dev_err(&pdev->dev, "unable to get power-on gpio\n");
557 return ret;
558 }
559 }
560
561 imx6_pcie->wake_up_gpio = of_get_named_gpio(np, "wake-up-gpio", 0);
562 if (gpio_is_valid(imx6_pcie->wake_up_gpio)) {
563 ret = devm_gpio_request_one(&pdev->dev,
564 imx6_pcie->wake_up_gpio,
565 GPIOF_IN,
566 "PCIe wake up");
567 if (ret) {
568 dev_err(&pdev->dev, "unable to get wake-up gpio\n");
569 return ret;
570 }
571 }
572
573 imx6_pcie->disable_gpio = of_get_named_gpio(np, "disable-gpio", 0);
574 if (gpio_is_valid(imx6_pcie->disable_gpio)) {
575 ret = devm_gpio_request_one(&pdev->dev,
576 imx6_pcie->disable_gpio,
577 GPIOF_OUT_INIT_HIGH,
578 "PCIe disable endpoint");
579 if (ret) {
580 dev_err(&pdev->dev, "unable to get disable-ep gpio\n");
581 return ret;
582 }
583 }
584
585 /* Fetch clocks */ 555 /* Fetch clocks */
586 imx6_pcie->lvds_gate = devm_clk_get(&pdev->dev, "lvds_gate"); 556 imx6_pcie->pcie_phy = devm_clk_get(&pdev->dev, "pcie_phy");
587 if (IS_ERR(imx6_pcie->lvds_gate)) { 557 if (IS_ERR(imx6_pcie->pcie_phy)) {
588 dev_err(&pdev->dev,
589 "lvds_gate clock select missing or invalid\n");
590 return PTR_ERR(imx6_pcie->lvds_gate);
591 }
592
593 imx6_pcie->sata_ref_100m = devm_clk_get(&pdev->dev, "sata_ref_100m");
594 if (IS_ERR(imx6_pcie->sata_ref_100m)) {
595 dev_err(&pdev->dev, 558 dev_err(&pdev->dev,
596 "sata_ref_100m clock source missing or invalid\n"); 559 "pcie_phy clock source missing or invalid\n");
597 return PTR_ERR(imx6_pcie->sata_ref_100m); 560 return PTR_ERR(imx6_pcie->pcie_phy);
598 } 561 }
599 562
600 imx6_pcie->pcie_ref_125m = devm_clk_get(&pdev->dev, "pcie_ref_125m"); 563 imx6_pcie->pcie_bus = devm_clk_get(&pdev->dev, "pcie_bus");
601 if (IS_ERR(imx6_pcie->pcie_ref_125m)) { 564 if (IS_ERR(imx6_pcie->pcie_bus)) {
602 dev_err(&pdev->dev, 565 dev_err(&pdev->dev,
603 "pcie_ref_125m clock source missing or invalid\n"); 566 "pcie_bus clock source missing or invalid\n");
604 return PTR_ERR(imx6_pcie->pcie_ref_125m); 567 return PTR_ERR(imx6_pcie->pcie_bus);
605 } 568 }
606 569
607 imx6_pcie->pcie_axi = devm_clk_get(&pdev->dev, "pcie_axi"); 570 imx6_pcie->pcie = devm_clk_get(&pdev->dev, "pcie");
608 if (IS_ERR(imx6_pcie->pcie_axi)) { 571 if (IS_ERR(imx6_pcie->pcie)) {
609 dev_err(&pdev->dev, 572 dev_err(&pdev->dev,
610 "pcie_axi clock source missing or invalid\n"); 573 "pcie clock source missing or invalid\n");
611 return PTR_ERR(imx6_pcie->pcie_axi); 574 return PTR_ERR(imx6_pcie->pcie);
612 } 575 }
613 576
614 /* Grab GPR config register range */ 577 /* Grab GPR config register range */