aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhil Edworthy <phil.edworthy@renesas.com>2014-05-12 06:57:49 -0400
committerBjorn Helgaas <bhelgaas@google.com>2014-05-27 22:39:17 -0400
commit290c1fb35860540223bef1be021944d02232889d (patch)
tree57b6c974ebdc0da583cca652f4b23d113b7d633c
parentc25da4778803b41e11fd82dd5576c35c09b5f0e0 (diff)
PCI: rcar: Add MSI support for PCIe
Add MSI support to the R-Car PCIe driver. Signed-off-by: Phil Edworthy <phil.edworthy@renesas.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Lucas Stach <l.stach@pengutronix.de> Acked-by: Simon Horman <horms+renesas@verge.net.au>
-rw-r--r--drivers/pci/host/pcie-rcar.c242
1 files changed, 241 insertions, 1 deletions
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index 3c524b9e60e5..8e06124aa80f 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -15,8 +15,11 @@
15#include <linux/clk.h> 15#include <linux/clk.h>
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/irq.h>
19#include <linux/irqdomain.h>
18#include <linux/kernel.h> 20#include <linux/kernel.h>
19#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/msi.h>
20#include <linux/of_address.h> 23#include <linux/of_address.h>
21#include <linux/of_irq.h> 24#include <linux/of_irq.h>
22#include <linux/of_pci.h> 25#include <linux/of_pci.h>
@@ -35,6 +38,7 @@
35#define PCIECDR 0x000020 38#define PCIECDR 0x000020
36#define PCIEMSR 0x000028 39#define PCIEMSR 0x000028
37#define PCIEINTXR 0x000400 40#define PCIEINTXR 0x000400
41#define PCIEMSITXR 0x000840
38 42
39/* Transfer control */ 43/* Transfer control */
40#define PCIETCTLR 0x02000 44#define PCIETCTLR 0x02000
@@ -43,6 +47,11 @@
43#define DATA_LINK_ACTIVE 1 47#define DATA_LINK_ACTIVE 1
44#define PCIEERRFR 0x02020 48#define PCIEERRFR 0x02020
45#define UNSUPPORTED_REQUEST (1 << 4) 49#define UNSUPPORTED_REQUEST (1 << 4)
50#define PCIEMSIFR 0x02044
51#define PCIEMSIALR 0x02048
52#define MSIFE 1
53#define PCIEMSIAUR 0x0204c
54#define PCIEMSIIER 0x02050
46 55
47/* root port address */ 56/* root port address */
48#define PCIEPRAR(x) (0x02080 + ((x) * 0x4)) 57#define PCIEPRAR(x) (0x02080 + ((x) * 0x4))
@@ -85,6 +94,8 @@
85#define H1_PCIEPHYDOUTR 0x040014 94#define H1_PCIEPHYDOUTR 0x040014
86#define H1_PCIEPHYSR 0x040018 95#define H1_PCIEPHYSR 0x040018
87 96
97#define INT_PCI_MSI_NR 32
98
88#define RCONF(x) (PCICONF(0)+(x)) 99#define RCONF(x) (PCICONF(0)+(x))
89#define RPMCAP(x) (PMCAP(0)+(x)) 100#define RPMCAP(x) (PMCAP(0)+(x))
90#define REXPCAP(x) (EXPCAP(0)+(x)) 101#define REXPCAP(x) (EXPCAP(0)+(x))
@@ -97,6 +108,21 @@
97#define PCI_MAX_RESOURCES 4 108#define PCI_MAX_RESOURCES 4
98#define MAX_NR_INBOUND_MAPS 6 109#define MAX_NR_INBOUND_MAPS 6
99 110
111struct rcar_msi {
112 DECLARE_BITMAP(used, INT_PCI_MSI_NR);
113 struct irq_domain *domain;
114 struct msi_chip chip;
115 unsigned long pages;
116 struct mutex lock;
117 int irq1;
118 int irq2;
119};
120
121static inline struct rcar_msi *to_rcar_msi(struct msi_chip *chip)
122{
123 return container_of(chip, struct rcar_msi, chip);
124}
125
100/* Structure representing the PCIe interface */ 126/* Structure representing the PCIe interface */
101struct rcar_pcie { 127struct rcar_pcie {
102 struct device *dev; 128 struct device *dev;
@@ -106,6 +132,7 @@ struct rcar_pcie {
106 int root_bus_nr; 132 int root_bus_nr;
107 struct clk *clk; 133 struct clk *clk;
108 struct clk *bus_clk; 134 struct clk *bus_clk;
135 struct rcar_msi msi;
109}; 136};
110 137
111static inline struct rcar_pcie *sys_to_pcie(struct pci_sys_data *sys) 138static inline struct rcar_pcie *sys_to_pcie(struct pci_sys_data *sys)
@@ -356,10 +383,20 @@ static int rcar_pcie_setup(int nr, struct pci_sys_data *sys)
356 return 1; 383 return 1;
357} 384}
358 385
386static void rcar_pcie_add_bus(struct pci_bus *bus)
387{
388 if (IS_ENABLED(CONFIG_PCI_MSI)) {
389 struct rcar_pcie *pcie = sys_to_pcie(bus->sysdata);
390
391 bus->msi = &pcie->msi.chip;
392 }
393}
394
359struct hw_pci rcar_pci = { 395struct hw_pci rcar_pci = {
360 .setup = rcar_pcie_setup, 396 .setup = rcar_pcie_setup,
361 .map_irq = of_irq_parse_and_map_pci, 397 .map_irq = of_irq_parse_and_map_pci,
362 .ops = &rcar_pcie_ops, 398 .ops = &rcar_pcie_ops,
399 .add_bus = rcar_pcie_add_bus,
363}; 400};
364 401
365static void rcar_pcie_enable(struct rcar_pcie *pcie) 402static void rcar_pcie_enable(struct rcar_pcie *pcie)
@@ -477,6 +514,10 @@ static int rcar_pcie_hw_init(struct rcar_pcie *pcie)
477 /* Enable MAC data scrambling. */ 514 /* Enable MAC data scrambling. */
478 rcar_rmw32(pcie, MACCTLR, SCRAMBLE_DISABLE, 0); 515 rcar_rmw32(pcie, MACCTLR, SCRAMBLE_DISABLE, 0);
479 516
517 /* Enable MSI */
518 if (IS_ENABLED(CONFIG_PCI_MSI))
519 pci_write_reg(pcie, 0x101f0000, PCIEMSITXR);
520
480 /* Finish initialization - establish a PCI Express link */ 521 /* Finish initialization - establish a PCI Express link */
481 pci_write_reg(pcie, CFINIT, PCIETCTLR); 522 pci_write_reg(pcie, CFINIT, PCIETCTLR);
482 523
@@ -530,11 +571,184 @@ static int rcar_pcie_hw_init_h1(struct rcar_pcie *pcie)
530 return -ETIMEDOUT; 571 return -ETIMEDOUT;
531} 572}
532 573
574static int rcar_msi_alloc(struct rcar_msi *chip)
575{
576 int msi;
577
578 mutex_lock(&chip->lock);
579
580 msi = find_first_zero_bit(chip->used, INT_PCI_MSI_NR);
581 if (msi < INT_PCI_MSI_NR)
582 set_bit(msi, chip->used);
583 else
584 msi = -ENOSPC;
585
586 mutex_unlock(&chip->lock);
587
588 return msi;
589}
590
591static void rcar_msi_free(struct rcar_msi *chip, unsigned long irq)
592{
593 mutex_lock(&chip->lock);
594 clear_bit(irq, chip->used);
595 mutex_unlock(&chip->lock);
596}
597
598static irqreturn_t rcar_pcie_msi_irq(int irq, void *data)
599{
600 struct rcar_pcie *pcie = data;
601 struct rcar_msi *msi = &pcie->msi;
602 unsigned long reg;
603
604 reg = pci_read_reg(pcie, PCIEMSIFR);
605
606 /* MSI & INTx share an interrupt - we only handle MSI here */
607 if (!reg)
608 return IRQ_NONE;
609
610 while (reg) {
611 unsigned int index = find_first_bit(&reg, 32);
612 unsigned int irq;
613
614 /* clear the interrupt */
615 pci_write_reg(pcie, 1 << index, PCIEMSIFR);
616
617 irq = irq_find_mapping(msi->domain, index);
618 if (irq) {
619 if (test_bit(index, msi->used))
620 generic_handle_irq(irq);
621 else
622 dev_info(pcie->dev, "unhandled MSI\n");
623 } else {
624 /* Unknown MSI, just clear it */
625 dev_dbg(pcie->dev, "unexpected MSI\n");
626 }
627
628 /* see if there's any more pending in this vector */
629 reg = pci_read_reg(pcie, PCIEMSIFR);
630 }
631
632 return IRQ_HANDLED;
633}
634
635static int rcar_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
636 struct msi_desc *desc)
637{
638 struct rcar_msi *msi = to_rcar_msi(chip);
639 struct rcar_pcie *pcie = container_of(chip, struct rcar_pcie, msi.chip);
640 struct msi_msg msg;
641 unsigned int irq;
642 int hwirq;
643
644 hwirq = rcar_msi_alloc(msi);
645 if (hwirq < 0)
646 return hwirq;
647
648 irq = irq_create_mapping(msi->domain, hwirq);
649 if (!irq) {
650 rcar_msi_free(msi, hwirq);
651 return -EINVAL;
652 }
653
654 irq_set_msi_desc(irq, desc);
655
656 msg.address_lo = pci_read_reg(pcie, PCIEMSIALR) & ~MSIFE;
657 msg.address_hi = pci_read_reg(pcie, PCIEMSIAUR);
658 msg.data = hwirq;
659
660 write_msi_msg(irq, &msg);
661
662 return 0;
663}
664
665static void rcar_msi_teardown_irq(struct msi_chip *chip, unsigned int irq)
666{
667 struct rcar_msi *msi = to_rcar_msi(chip);
668 struct irq_data *d = irq_get_irq_data(irq);
669
670 rcar_msi_free(msi, d->hwirq);
671}
672
673static struct irq_chip rcar_msi_irq_chip = {
674 .name = "R-Car PCIe MSI",
675 .irq_enable = unmask_msi_irq,
676 .irq_disable = mask_msi_irq,
677 .irq_mask = mask_msi_irq,
678 .irq_unmask = unmask_msi_irq,
679};
680
681static int rcar_msi_map(struct irq_domain *domain, unsigned int irq,
682 irq_hw_number_t hwirq)
683{
684 irq_set_chip_and_handler(irq, &rcar_msi_irq_chip, handle_simple_irq);
685 irq_set_chip_data(irq, domain->host_data);
686 set_irq_flags(irq, IRQF_VALID);
687
688 return 0;
689}
690
691static const struct irq_domain_ops msi_domain_ops = {
692 .map = rcar_msi_map,
693};
694
695static int rcar_pcie_enable_msi(struct rcar_pcie *pcie)
696{
697 struct platform_device *pdev = to_platform_device(pcie->dev);
698 struct rcar_msi *msi = &pcie->msi;
699 unsigned long base;
700 int err;
701
702 mutex_init(&msi->lock);
703
704 msi->chip.dev = pcie->dev;
705 msi->chip.setup_irq = rcar_msi_setup_irq;
706 msi->chip.teardown_irq = rcar_msi_teardown_irq;
707
708 msi->domain = irq_domain_add_linear(pcie->dev->of_node, INT_PCI_MSI_NR,
709 &msi_domain_ops, &msi->chip);
710 if (!msi->domain) {
711 dev_err(&pdev->dev, "failed to create IRQ domain\n");
712 return -ENOMEM;
713 }
714
715 /* Two irqs are for MSI, but they are also used for non-MSI irqs */
716 err = devm_request_irq(&pdev->dev, msi->irq1, rcar_pcie_msi_irq,
717 IRQF_SHARED, rcar_msi_irq_chip.name, pcie);
718 if (err < 0) {
719 dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
720 goto err;
721 }
722
723 err = devm_request_irq(&pdev->dev, msi->irq2, rcar_pcie_msi_irq,
724 IRQF_SHARED, rcar_msi_irq_chip.name, pcie);
725 if (err < 0) {
726 dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
727 goto err;
728 }
729
730 /* setup MSI data target */
731 msi->pages = __get_free_pages(GFP_KERNEL, 0);
732 base = virt_to_phys((void *)msi->pages);
733
734 pci_write_reg(pcie, base | MSIFE, PCIEMSIALR);
735 pci_write_reg(pcie, 0, PCIEMSIAUR);
736
737 /* enable all MSI interrupts */
738 pci_write_reg(pcie, 0xffffffff, PCIEMSIIER);
739
740 return 0;
741
742err:
743 irq_domain_remove(msi->domain);
744 return err;
745}
746
533static int rcar_pcie_get_resources(struct platform_device *pdev, 747static int rcar_pcie_get_resources(struct platform_device *pdev,
534 struct rcar_pcie *pcie) 748 struct rcar_pcie *pcie)
535{ 749{
536 struct resource res; 750 struct resource res;
537 int err; 751 int err, i;
538 752
539 err = of_address_to_resource(pdev->dev.of_node, 0, &res); 753 err = of_address_to_resource(pdev->dev.of_node, 0, &res);
540 if (err) 754 if (err)
@@ -559,6 +773,22 @@ static int rcar_pcie_get_resources(struct platform_device *pdev,
559 if (err) 773 if (err)
560 goto err_map_reg; 774 goto err_map_reg;
561 775
776 i = irq_of_parse_and_map(pdev->dev.of_node, 0);
777 if (i < 0) {
778 dev_err(pcie->dev, "cannot get platform resources for msi interrupt\n");
779 err = -ENOENT;
780 goto err_map_reg;
781 }
782 pcie->msi.irq1 = i;
783
784 i = irq_of_parse_and_map(pdev->dev.of_node, 1);
785 if (i < 0) {
786 dev_err(pcie->dev, "cannot get platform resources for msi interrupt\n");
787 err = -ENOENT;
788 goto err_map_reg;
789 }
790 pcie->msi.irq2 = i;
791
562 pcie->base = devm_ioremap_resource(&pdev->dev, &res); 792 pcie->base = devm_ioremap_resource(&pdev->dev, &res);
563 if (IS_ERR(pcie->base)) { 793 if (IS_ERR(pcie->base)) {
564 err = PTR_ERR(pcie->base); 794 err = PTR_ERR(pcie->base);
@@ -732,6 +962,16 @@ static int rcar_pcie_probe(struct platform_device *pdev)
732 if (err) 962 if (err)
733 return err; 963 return err;
734 964
965 if (IS_ENABLED(CONFIG_PCI_MSI)) {
966 err = rcar_pcie_enable_msi(pcie);
967 if (err < 0) {
968 dev_err(&pdev->dev,
969 "failed to enable MSI support: %d\n",
970 err);
971 return err;
972 }
973 }
974
735 of_id = of_match_device(rcar_pcie_of_match, pcie->dev); 975 of_id = of_match_device(rcar_pcie_of_match, pcie->dev);
736 if (!of_id || !of_id->data) 976 if (!of_id || !of_id->data)
737 return -EINVAL; 977 return -EINVAL;