aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/armada-370-xp-mpic.txt3
-rw-r--r--Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt14
-rw-r--r--Documentation/devicetree/bindings/pci/mvebu-pci.txt10
-rw-r--r--arch/arm/mach-dove/board-dt.c39
-rw-r--r--drivers/irqchip/irq-armada-370-xp.c202
-rw-r--r--drivers/pci/host/Kconfig2
-rw-r--r--drivers/pci/host/pci-mvebu.c121
7 files changed, 307 insertions, 84 deletions
diff --git a/Documentation/devicetree/bindings/arm/armada-370-xp-mpic.txt b/Documentation/devicetree/bindings/arm/armada-370-xp-mpic.txt
index 61df564c0d23..d74091a8a3bf 100644
--- a/Documentation/devicetree/bindings/arm/armada-370-xp-mpic.txt
+++ b/Documentation/devicetree/bindings/arm/armada-370-xp-mpic.txt
@@ -4,6 +4,8 @@ Marvell Armada 370 and Armada XP Interrupt Controller
4Required properties: 4Required properties:
5- compatible: Should be "marvell,mpic" 5- compatible: Should be "marvell,mpic"
6- interrupt-controller: Identifies the node as an interrupt controller. 6- interrupt-controller: Identifies the node as an interrupt controller.
7- msi-controller: Identifies the node as an PCI Message Signaled
8 Interrupt controller.
7- #interrupt-cells: The number of cells to define the interrupts. Should be 1. 9- #interrupt-cells: The number of cells to define the interrupts. Should be 1.
8 The cell is the IRQ number 10 The cell is the IRQ number
9 11
@@ -24,6 +26,7 @@ Example:
24 #address-cells = <1>; 26 #address-cells = <1>;
25 #size-cells = <1>; 27 #size-cells = <1>;
26 interrupt-controller; 28 interrupt-controller;
29 msi-controller;
27 reg = <0xd0020a00 0x1d0>, 30 reg = <0xd0020a00 0x1d0>,
28 <0xd0021070 0x58>; 31 <0xd0021070 0x58>;
29 }; 32 };
diff --git a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
index cffc93d97f54..fc2910fa7e45 100644
--- a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
+++ b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
@@ -1,10 +1,10 @@
1* Gated Clock bindings for Marvell Orion SoCs 1* Gated Clock bindings for Marvell EBU SoCs
2 2
3Marvell Dove and Kirkwood allow some peripheral clocks to be gated to save 3Marvell Armada 370/XP, Dove and Kirkwood allow some peripheral clocks to be
4some power. The clock consumer should specify the desired clock by having 4gated to save some power. The clock consumer should specify the desired clock
5the clock ID in its "clocks" phandle cell. The clock ID is directly mapped to 5by having the clock ID in its "clocks" phandle cell. The clock ID is directly
6the corresponding clock gating control bit in HW to ease manual clock lookup 6mapped to the corresponding clock gating control bit in HW to ease manual clock
7in datasheet. 7lookup in datasheet.
8 8
9The following is a list of provided IDs for Armada 370: 9The following is a list of provided IDs for Armada 370:
10ID Clock Peripheral 10ID Clock Peripheral
@@ -94,6 +94,8 @@ ID Clock Peripheral
94 94
95Required properties: 95Required properties:
96- compatible : shall be one of the following: 96- compatible : shall be one of the following:
97 "marvell,armada-370-gating-clock" - for Armada 370 SoC clock gating
98 "marvell,armada-xp-gating-clock" - for Armada XP SoC clock gating
97 "marvell,dove-gating-clock" - for Dove SoC clock gating 99 "marvell,dove-gating-clock" - for Dove SoC clock gating
98 "marvell,kirkwood-gating-clock" - for Kirkwood SoC clock gating 100 "marvell,kirkwood-gating-clock" - for Kirkwood SoC clock gating
99- reg : shall be the register address of the Clock Gating Control register 101- reg : shall be the register address of the Clock Gating Control register
diff --git a/Documentation/devicetree/bindings/pci/mvebu-pci.txt b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
index 9556e2fedf6d..08c716b2c6b6 100644
--- a/Documentation/devicetree/bindings/pci/mvebu-pci.txt
+++ b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
@@ -5,6 +5,7 @@ Mandatory properties:
5- compatible: one of the following values: 5- compatible: one of the following values:
6 marvell,armada-370-pcie 6 marvell,armada-370-pcie
7 marvell,armada-xp-pcie 7 marvell,armada-xp-pcie
8 marvell,dove-pcie
8 marvell,kirkwood-pcie 9 marvell,kirkwood-pcie
9- #address-cells, set to <3> 10- #address-cells, set to <3>
10- #size-cells, set to <2> 11- #size-cells, set to <2>
@@ -14,6 +15,8 @@ Mandatory properties:
14- ranges: ranges describing the MMIO registers to control the PCIe 15- ranges: ranges describing the MMIO registers to control the PCIe
15 interfaces, and ranges describing the MBus windows needed to access 16 interfaces, and ranges describing the MBus windows needed to access
16 the memory and I/O regions of each PCIe interface. 17 the memory and I/O regions of each PCIe interface.
18- msi-parent: Link to the hardware entity that serves as the Message
19 Signaled Interrupt controller for this PCI controller.
17 20
18The ranges describing the MMIO registers have the following layout: 21The ranges describing the MMIO registers have the following layout:
19 22
@@ -74,6 +77,8 @@ and the following optional properties:
74- marvell,pcie-lane: the physical PCIe lane number, for ports having 77- marvell,pcie-lane: the physical PCIe lane number, for ports having
75 multiple lanes. If this property is not found, we assume that the 78 multiple lanes. If this property is not found, we assume that the
76 value is 0. 79 value is 0.
80- reset-gpios: optional gpio to PERST#
81- reset-delay-us: delay in us to wait after reset de-assertion
77 82
78Example: 83Example:
79 84
@@ -86,6 +91,7 @@ pcie-controller {
86 #size-cells = <2>; 91 #size-cells = <2>;
87 92
88 bus-range = <0x00 0xff>; 93 bus-range = <0x00 0xff>;
94 msi-parent = <&mpic>;
89 95
90 ranges = 96 ranges =
91 <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 /* Port 0.0 registers */ 97 <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 /* Port 0.0 registers */
@@ -135,6 +141,10 @@ pcie-controller {
135 interrupt-map = <0 0 0 0 &mpic 58>; 141 interrupt-map = <0 0 0 0 &mpic 58>;
136 marvell,pcie-port = <0>; 142 marvell,pcie-port = <0>;
137 marvell,pcie-lane = <0>; 143 marvell,pcie-lane = <0>;
144 /* low-active PERST# reset on GPIO 25 */
145 reset-gpios = <&gpio0 25 1>;
146 /* wait 20ms for device settle after reset deassertion */
147 reset-delay-us = <20000>;
138 clocks = <&gateclk 5>; 148 clocks = <&gateclk 5>;
139 status = "disabled"; 149 status = "disabled";
140 }; 150 };
diff --git a/arch/arm/mach-dove/board-dt.c b/arch/arm/mach-dove/board-dt.c
index 49f72a848423..9a116d796323 100644
--- a/arch/arm/mach-dove/board-dt.c
+++ b/arch/arm/mach-dove/board-dt.c
@@ -23,41 +23,12 @@
23#include <plat/irq.h> 23#include <plat/irq.h>
24#include "common.h" 24#include "common.h"
25 25
26/*
27 * There are still devices that doesn't even know about DT,
28 * get clock gates here and add a clock lookup.
29 */
30static void __init dove_legacy_clk_init(void)
31{
32 struct device_node *np = of_find_compatible_node(NULL, NULL,
33 "marvell,dove-gating-clock");
34 struct of_phandle_args clkspec;
35
36 clkspec.np = np;
37 clkspec.args_count = 1;
38
39 clkspec.args[0] = CLOCK_GATING_BIT_PCIE0;
40 orion_clkdev_add("0", "pcie",
41 of_clk_get_from_provider(&clkspec));
42
43 clkspec.args[0] = CLOCK_GATING_BIT_PCIE1;
44 orion_clkdev_add("1", "pcie",
45 of_clk_get_from_provider(&clkspec));
46}
47
48static void __init dove_dt_time_init(void) 26static void __init dove_dt_time_init(void)
49{ 27{
50 of_clk_init(NULL); 28 of_clk_init(NULL);
51 clocksource_of_init(); 29 clocksource_of_init();
52} 30}
53 31
54static void __init dove_dt_init_early(void)
55{
56 mvebu_mbus_init("marvell,dove-mbus",
57 BRIDGE_WINS_BASE, BRIDGE_WINS_SZ,
58 DOVE_MC_WINS_BASE, DOVE_MC_WINS_SZ);
59}
60
61static void __init dove_dt_init(void) 32static void __init dove_dt_init(void)
62{ 33{
63 pr_info("Dove 88AP510 SoC\n"); 34 pr_info("Dove 88AP510 SoC\n");
@@ -65,14 +36,7 @@ static void __init dove_dt_init(void)
65#ifdef CONFIG_CACHE_TAUROS2 36#ifdef CONFIG_CACHE_TAUROS2
66 tauros2_init(0); 37 tauros2_init(0);
67#endif 38#endif
68 dove_setup_cpu_wins(); 39 BUG_ON(mvebu_mbus_dt_init());
69
70 /* Setup clocks for legacy devices */
71 dove_legacy_clk_init();
72
73 /* Internal devices not ported to DT yet */
74 dove_pcie_init(1, 1);
75
76 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 40 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
77} 41}
78 42
@@ -83,7 +47,6 @@ static const char * const dove_dt_board_compat[] = {
83 47
84DT_MACHINE_START(DOVE_DT, "Marvell Dove (Flattened Device Tree)") 48DT_MACHINE_START(DOVE_DT, "Marvell Dove (Flattened Device Tree)")
85 .map_io = dove_map_io, 49 .map_io = dove_map_io,
86 .init_early = dove_dt_init_early,
87 .init_time = dove_dt_time_init, 50 .init_time = dove_dt_time_init,
88 .init_machine = dove_dt_init, 51 .init_machine = dove_dt_init,
89 .restart = dove_restart, 52 .restart = dove_restart,
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
index bb328a366122..433cc8568dec 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -21,7 +21,10 @@
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/of_address.h> 22#include <linux/of_address.h>
23#include <linux/of_irq.h> 23#include <linux/of_irq.h>
24#include <linux/of_pci.h>
24#include <linux/irqdomain.h> 25#include <linux/irqdomain.h>
26#include <linux/slab.h>
27#include <linux/msi.h>
25#include <asm/mach/arch.h> 28#include <asm/mach/arch.h>
26#include <asm/exception.h> 29#include <asm/exception.h>
27#include <asm/smp_plat.h> 30#include <asm/smp_plat.h>
@@ -51,12 +54,22 @@
51#define IPI_DOORBELL_START (0) 54#define IPI_DOORBELL_START (0)
52#define IPI_DOORBELL_END (8) 55#define IPI_DOORBELL_END (8)
53#define IPI_DOORBELL_MASK 0xFF 56#define IPI_DOORBELL_MASK 0xFF
57#define PCI_MSI_DOORBELL_START (16)
58#define PCI_MSI_DOORBELL_NR (16)
59#define PCI_MSI_DOORBELL_END (32)
60#define PCI_MSI_DOORBELL_MASK 0xFFFF0000
54 61
55static DEFINE_RAW_SPINLOCK(irq_controller_lock); 62static DEFINE_RAW_SPINLOCK(irq_controller_lock);
56 63
57static void __iomem *per_cpu_int_base; 64static void __iomem *per_cpu_int_base;
58static void __iomem *main_int_base; 65static void __iomem *main_int_base;
59static struct irq_domain *armada_370_xp_mpic_domain; 66static struct irq_domain *armada_370_xp_mpic_domain;
67#ifdef CONFIG_PCI_MSI
68static struct irq_domain *armada_370_xp_msi_domain;
69static DECLARE_BITMAP(msi_used, PCI_MSI_DOORBELL_NR);
70static DEFINE_MUTEX(msi_used_lock);
71static phys_addr_t msi_doorbell_addr;
72#endif
60 73
61/* 74/*
62 * In SMP mode: 75 * In SMP mode:
@@ -87,6 +100,144 @@ static void armada_370_xp_irq_unmask(struct irq_data *d)
87 ARMADA_370_XP_INT_CLEAR_MASK_OFFS); 100 ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
88} 101}
89 102
103#ifdef CONFIG_PCI_MSI
104
105static int armada_370_xp_alloc_msi(void)
106{
107 int hwirq;
108
109 mutex_lock(&msi_used_lock);
110 hwirq = find_first_zero_bit(&msi_used, PCI_MSI_DOORBELL_NR);
111 if (hwirq >= PCI_MSI_DOORBELL_NR)
112 hwirq = -ENOSPC;
113 else
114 set_bit(hwirq, msi_used);
115 mutex_unlock(&msi_used_lock);
116
117 return hwirq;
118}
119
120static void armada_370_xp_free_msi(int hwirq)
121{
122 mutex_lock(&msi_used_lock);
123 if (!test_bit(hwirq, msi_used))
124 pr_err("trying to free unused MSI#%d\n", hwirq);
125 else
126 clear_bit(hwirq, msi_used);
127 mutex_unlock(&msi_used_lock);
128}
129
130static int armada_370_xp_setup_msi_irq(struct msi_chip *chip,
131 struct pci_dev *pdev,
132 struct msi_desc *desc)
133{
134 struct msi_msg msg;
135 irq_hw_number_t hwirq;
136 int virq;
137
138 hwirq = armada_370_xp_alloc_msi();
139 if (hwirq < 0)
140 return hwirq;
141
142 virq = irq_create_mapping(armada_370_xp_msi_domain, hwirq);
143 if (!virq) {
144 armada_370_xp_free_msi(hwirq);
145 return -EINVAL;
146 }
147
148 irq_set_msi_desc(virq, desc);
149
150 msg.address_lo = msi_doorbell_addr;
151 msg.address_hi = 0;
152 msg.data = 0xf00 | (hwirq + 16);
153
154 write_msi_msg(virq, &msg);
155 return 0;
156}
157
158static void armada_370_xp_teardown_msi_irq(struct msi_chip *chip,
159 unsigned int irq)
160{
161 struct irq_data *d = irq_get_irq_data(irq);
162 irq_dispose_mapping(irq);
163 armada_370_xp_free_msi(d->hwirq);
164}
165
166static struct irq_chip armada_370_xp_msi_irq_chip = {
167 .name = "armada_370_xp_msi_irq",
168 .irq_enable = unmask_msi_irq,
169 .irq_disable = mask_msi_irq,
170 .irq_mask = mask_msi_irq,
171 .irq_unmask = unmask_msi_irq,
172};
173
174static int armada_370_xp_msi_map(struct irq_domain *domain, unsigned int virq,
175 irq_hw_number_t hw)
176{
177 irq_set_chip_and_handler(virq, &armada_370_xp_msi_irq_chip,
178 handle_simple_irq);
179 set_irq_flags(virq, IRQF_VALID);
180
181 return 0;
182}
183
184static const struct irq_domain_ops armada_370_xp_msi_irq_ops = {
185 .map = armada_370_xp_msi_map,
186};
187
188static int armada_370_xp_msi_init(struct device_node *node,
189 phys_addr_t main_int_phys_base)
190{
191 struct msi_chip *msi_chip;
192 u32 reg;
193 int ret;
194
195 msi_doorbell_addr = main_int_phys_base +
196 ARMADA_370_XP_SW_TRIG_INT_OFFS;
197
198 msi_chip = kzalloc(sizeof(*msi_chip), GFP_KERNEL);
199 if (!msi_chip)
200 return -ENOMEM;
201
202 msi_chip->setup_irq = armada_370_xp_setup_msi_irq;
203 msi_chip->teardown_irq = armada_370_xp_teardown_msi_irq;
204 msi_chip->of_node = node;
205
206 armada_370_xp_msi_domain =
207 irq_domain_add_linear(NULL, PCI_MSI_DOORBELL_NR,
208 &armada_370_xp_msi_irq_ops,
209 NULL);
210 if (!armada_370_xp_msi_domain) {
211 kfree(msi_chip);
212 return -ENOMEM;
213 }
214
215 ret = of_pci_msi_chip_add(msi_chip);
216 if (ret < 0) {
217 irq_domain_remove(armada_370_xp_msi_domain);
218 kfree(msi_chip);
219 return ret;
220 }
221
222 reg = readl(per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_MSK_OFFS)
223 | PCI_MSI_DOORBELL_MASK;
224
225 writel(reg, per_cpu_int_base +
226 ARMADA_370_XP_IN_DRBEL_MSK_OFFS);
227
228 /* Unmask IPI interrupt */
229 writel(1, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
230
231 return 0;
232}
233#else
234static inline int armada_370_xp_msi_init(struct device_node *node,
235 phys_addr_t main_int_phys_base)
236{
237 return 0;
238}
239#endif
240
90#ifdef CONFIG_SMP 241#ifdef CONFIG_SMP
91static int armada_xp_set_affinity(struct irq_data *d, 242static int armada_xp_set_affinity(struct irq_data *d,
92 const struct cpumask *mask_val, bool force) 243 const struct cpumask *mask_val, bool force)
@@ -214,12 +365,39 @@ armada_370_xp_handle_irq(struct pt_regs *regs)
214 if (irqnr > 1022) 365 if (irqnr > 1022)
215 break; 366 break;
216 367
217 if (irqnr > 0) { 368 if (irqnr > 1) {
218 irqnr = irq_find_mapping(armada_370_xp_mpic_domain, 369 irqnr = irq_find_mapping(armada_370_xp_mpic_domain,
219 irqnr); 370 irqnr);
220 handle_IRQ(irqnr, regs); 371 handle_IRQ(irqnr, regs);
221 continue; 372 continue;
222 } 373 }
374
375#ifdef CONFIG_PCI_MSI
376 /* MSI handling */
377 if (irqnr == 1) {
378 u32 msimask, msinr;
379
380 msimask = readl_relaxed(per_cpu_int_base +
381 ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS)
382 & PCI_MSI_DOORBELL_MASK;
383
384 writel(~PCI_MSI_DOORBELL_MASK, per_cpu_int_base +
385 ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS);
386
387 for (msinr = PCI_MSI_DOORBELL_START;
388 msinr < PCI_MSI_DOORBELL_END; msinr++) {
389 int irq;
390
391 if (!(msimask & BIT(msinr)))
392 continue;
393
394 irq = irq_find_mapping(armada_370_xp_msi_domain,
395 msinr - 16);
396 handle_IRQ(irq, regs);
397 }
398 }
399#endif
400
223#ifdef CONFIG_SMP 401#ifdef CONFIG_SMP
224 /* IPI Handling */ 402 /* IPI Handling */
225 if (irqnr == 0) { 403 if (irqnr == 0) {
@@ -248,12 +426,25 @@ armada_370_xp_handle_irq(struct pt_regs *regs)
248static int __init armada_370_xp_mpic_of_init(struct device_node *node, 426static int __init armada_370_xp_mpic_of_init(struct device_node *node,
249 struct device_node *parent) 427 struct device_node *parent)
250{ 428{
429 struct resource main_int_res, per_cpu_int_res;
251 u32 control; 430 u32 control;
252 431
253 main_int_base = of_iomap(node, 0); 432 BUG_ON(of_address_to_resource(node, 0, &main_int_res));
254 per_cpu_int_base = of_iomap(node, 1); 433 BUG_ON(of_address_to_resource(node, 1, &per_cpu_int_res));
434
435 BUG_ON(!request_mem_region(main_int_res.start,
436 resource_size(&main_int_res),
437 node->full_name));
438 BUG_ON(!request_mem_region(per_cpu_int_res.start,
439 resource_size(&per_cpu_int_res),
440 node->full_name));
255 441
442 main_int_base = ioremap(main_int_res.start,
443 resource_size(&main_int_res));
256 BUG_ON(!main_int_base); 444 BUG_ON(!main_int_base);
445
446 per_cpu_int_base = ioremap(per_cpu_int_res.start,
447 resource_size(&per_cpu_int_res));
257 BUG_ON(!per_cpu_int_base); 448 BUG_ON(!per_cpu_int_base);
258 449
259 control = readl(main_int_base + ARMADA_370_XP_INT_CONTROL); 450 control = readl(main_int_base + ARMADA_370_XP_INT_CONTROL);
@@ -262,8 +453,7 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
262 irq_domain_add_linear(node, (control >> 2) & 0x3ff, 453 irq_domain_add_linear(node, (control >> 2) & 0x3ff,
263 &armada_370_xp_mpic_irq_ops, NULL); 454 &armada_370_xp_mpic_irq_ops, NULL);
264 455
265 if (!armada_370_xp_mpic_domain) 456 BUG_ON(!armada_370_xp_mpic_domain);
266 panic("Unable to add Armada_370_Xp MPIC irq domain (DT)\n");
267 457
268 irq_set_default_host(armada_370_xp_mpic_domain); 458 irq_set_default_host(armada_370_xp_mpic_domain);
269 459
@@ -280,6 +470,8 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
280 470
281#endif 471#endif
282 472
473 armada_370_xp_msi_init(node, main_int_res.start);
474
283 set_handle_irq(armada_370_xp_handle_irq); 475 set_handle_irq(armada_370_xp_handle_irq);
284 476
285 return 0; 477 return 0;
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 3d9504811126..43186feb4294 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -3,7 +3,7 @@ menu "PCI host controller drivers"
3 3
4config PCI_MVEBU 4config PCI_MVEBU
5 bool "Marvell EBU PCIe controller" 5 bool "Marvell EBU PCIe controller"
6 depends on ARCH_MVEBU || ARCH_KIRKWOOD 6 depends on ARCH_MVEBU || ARCH_DOVE || ARCH_KIRKWOOD
7 depends on OF 7 depends on OF
8 8
9config PCIE_DW 9config PCIE_DW
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index 729d5a101d62..77f8a7c58597 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -9,13 +9,17 @@
9#include <linux/kernel.h> 9#include <linux/kernel.h>
10#include <linux/pci.h> 10#include <linux/pci.h>
11#include <linux/clk.h> 11#include <linux/clk.h>
12#include <linux/delay.h>
13#include <linux/gpio.h>
12#include <linux/module.h> 14#include <linux/module.h>
13#include <linux/mbus.h> 15#include <linux/mbus.h>
16#include <linux/msi.h>
14#include <linux/slab.h> 17#include <linux/slab.h>
15#include <linux/platform_device.h> 18#include <linux/platform_device.h>
16#include <linux/of_address.h> 19#include <linux/of_address.h>
17#include <linux/of_pci.h>
18#include <linux/of_irq.h> 20#include <linux/of_irq.h>
21#include <linux/of_gpio.h>
22#include <linux/of_pci.h>
19#include <linux/of_platform.h> 23#include <linux/of_platform.h>
20 24
21/* 25/*
@@ -103,6 +107,7 @@ struct mvebu_pcie_port;
103struct mvebu_pcie { 107struct mvebu_pcie {
104 struct platform_device *pdev; 108 struct platform_device *pdev;
105 struct mvebu_pcie_port *ports; 109 struct mvebu_pcie_port *ports;
110 struct msi_chip *msi;
106 struct resource io; 111 struct resource io;
107 struct resource realio; 112 struct resource realio;
108 struct resource mem; 113 struct resource mem;
@@ -124,6 +129,9 @@ struct mvebu_pcie_port {
124 unsigned int io_target; 129 unsigned int io_target;
125 unsigned int io_attr; 130 unsigned int io_attr;
126 struct clk *clk; 131 struct clk *clk;
132 int reset_gpio;
133 int reset_active_low;
134 char *reset_name;
127 struct mvebu_sw_pci_bridge bridge; 135 struct mvebu_sw_pci_bridge bridge;
128 struct device_node *dn; 136 struct device_node *dn;
129 struct mvebu_pcie *pcie; 137 struct mvebu_pcie *pcie;
@@ -163,7 +171,7 @@ static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie_port *port, int nr)
163 * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks 171 * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
164 * WIN[0-3] -> DRAM bank[0-3] 172 * WIN[0-3] -> DRAM bank[0-3]
165 */ 173 */
166static void __init mvebu_pcie_setup_wins(struct mvebu_pcie_port *port) 174static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
167{ 175{
168 const struct mbus_dram_target_info *dram; 176 const struct mbus_dram_target_info *dram;
169 u32 size; 177 u32 size;
@@ -215,7 +223,7 @@ static void __init mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
215 port->base + PCIE_BAR_CTRL_OFF(1)); 223 port->base + PCIE_BAR_CTRL_OFF(1));
216} 224}
217 225
218static void __init mvebu_pcie_setup_hw(struct mvebu_pcie_port *port) 226static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
219{ 227{
220 u16 cmd; 228 u16 cmd;
221 u32 mask; 229 u32 mask;
@@ -626,7 +634,7 @@ static struct pci_ops mvebu_pcie_ops = {
626 .write = mvebu_pcie_wr_conf, 634 .write = mvebu_pcie_wr_conf,
627}; 635};
628 636
629static int __init mvebu_pcie_setup(int nr, struct pci_sys_data *sys) 637static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
630{ 638{
631 struct mvebu_pcie *pcie = sys_to_pcie(sys); 639 struct mvebu_pcie *pcie = sys_to_pcie(sys);
632 int i; 640 int i;
@@ -645,7 +653,7 @@ static int __init mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
645 return 1; 653 return 1;
646} 654}
647 655
648static int __init mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) 656static int mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
649{ 657{
650 struct of_irq oirq; 658 struct of_irq oirq;
651 int ret; 659 int ret;
@@ -673,6 +681,12 @@ static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
673 return bus; 681 return bus;
674} 682}
675 683
684void mvebu_pcie_add_bus(struct pci_bus *bus)
685{
686 struct mvebu_pcie *pcie = sys_to_pcie(bus->sysdata);
687 bus->msi = pcie->msi;
688}
689
676resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev, 690resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
677 const struct resource *res, 691 const struct resource *res,
678 resource_size_t start, 692 resource_size_t start,
@@ -696,7 +710,7 @@ resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
696 return start; 710 return start;
697} 711}
698 712
699static void __init mvebu_pcie_enable(struct mvebu_pcie *pcie) 713static void mvebu_pcie_enable(struct mvebu_pcie *pcie)
700{ 714{
701 struct hw_pci hw; 715 struct hw_pci hw;
702 716
@@ -709,6 +723,7 @@ static void __init mvebu_pcie_enable(struct mvebu_pcie *pcie)
709 hw.map_irq = mvebu_pcie_map_irq; 723 hw.map_irq = mvebu_pcie_map_irq;
710 hw.ops = &mvebu_pcie_ops; 724 hw.ops = &mvebu_pcie_ops;
711 hw.align_resource = mvebu_pcie_align_resource; 725 hw.align_resource = mvebu_pcie_align_resource;
726 hw.add_bus = mvebu_pcie_add_bus;
712 727
713 pci_common_init(&hw); 728 pci_common_init(&hw);
714} 729}
@@ -718,10 +733,8 @@ static void __init mvebu_pcie_enable(struct mvebu_pcie *pcie)
718 * <...> property for one that matches the given port/lane. Once 733 * <...> property for one that matches the given port/lane. Once
719 * found, maps it. 734 * found, maps it.
720 */ 735 */
721static void __iomem * __init 736static void __iomem *mvebu_pcie_map_registers(struct platform_device *pdev,
722mvebu_pcie_map_registers(struct platform_device *pdev, 737 struct device_node *np, struct mvebu_pcie_port *port)
723 struct device_node *np,
724 struct mvebu_pcie_port *port)
725{ 738{
726 struct resource regs; 739 struct resource regs;
727 int ret = 0; 740 int ret = 0;
@@ -777,7 +790,22 @@ static int mvebu_get_tgt_attr(struct device_node *np, int devfn,
777 return -ENOENT; 790 return -ENOENT;
778} 791}
779 792
780static int __init mvebu_pcie_probe(struct platform_device *pdev) 793static void mvebu_pcie_msi_enable(struct mvebu_pcie *pcie)
794{
795 struct device_node *msi_node;
796
797 msi_node = of_parse_phandle(pcie->pdev->dev.of_node,
798 "msi-parent", 0);
799 if (!msi_node)
800 return;
801
802 pcie->msi = of_pci_find_msi_chip_by_node(msi_node);
803
804 if (pcie->msi)
805 pcie->msi->dev = &pcie->pdev->dev;
806}
807
808static int mvebu_pcie_probe(struct platform_device *pdev)
781{ 809{
782 struct mvebu_pcie *pcie; 810 struct mvebu_pcie *pcie;
783 struct device_node *np = pdev->dev.of_node; 811 struct device_node *np = pdev->dev.of_node;
@@ -790,6 +818,7 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
790 return -ENOMEM; 818 return -ENOMEM;
791 819
792 pcie->pdev = pdev; 820 pcie->pdev = pdev;
821 platform_set_drvdata(pdev, pcie);
793 822
794 /* Get the PCIe memory and I/O aperture */ 823 /* Get the PCIe memory and I/O aperture */
795 mvebu_mbus_get_pcie_mem_aperture(&pcie->mem); 824 mvebu_mbus_get_pcie_mem_aperture(&pcie->mem);
@@ -818,13 +847,14 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
818 return ret; 847 return ret;
819 } 848 }
820 849
850 i = 0;
821 for_each_child_of_node(pdev->dev.of_node, child) { 851 for_each_child_of_node(pdev->dev.of_node, child) {
822 if (!of_device_is_available(child)) 852 if (!of_device_is_available(child))
823 continue; 853 continue;
824 pcie->nports++; 854 i++;
825 } 855 }
826 856
827 pcie->ports = devm_kzalloc(&pdev->dev, pcie->nports * 857 pcie->ports = devm_kzalloc(&pdev->dev, i *
828 sizeof(struct mvebu_pcie_port), 858 sizeof(struct mvebu_pcie_port),
829 GFP_KERNEL); 859 GFP_KERNEL);
830 if (!pcie->ports) 860 if (!pcie->ports)
@@ -833,6 +863,7 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
833 i = 0; 863 i = 0;
834 for_each_child_of_node(pdev->dev.of_node, child) { 864 for_each_child_of_node(pdev->dev.of_node, child) {
835 struct mvebu_pcie_port *port = &pcie->ports[i]; 865 struct mvebu_pcie_port *port = &pcie->ports[i];
866 enum of_gpio_flags flags;
836 867
837 if (!of_device_is_available(child)) 868 if (!of_device_is_available(child))
838 continue; 869 continue;
@@ -873,11 +904,47 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
873 continue; 904 continue;
874 } 905 }
875 906
907 port->reset_gpio = of_get_named_gpio_flags(child,
908 "reset-gpios", 0, &flags);
909 if (gpio_is_valid(port->reset_gpio)) {
910 u32 reset_udelay = 20000;
911
912 port->reset_active_low = flags & OF_GPIO_ACTIVE_LOW;
913 port->reset_name = kasprintf(GFP_KERNEL,
914 "pcie%d.%d-reset", port->port, port->lane);
915 of_property_read_u32(child, "reset-delay-us",
916 &reset_udelay);
917
918 ret = devm_gpio_request_one(&pdev->dev,
919 port->reset_gpio, GPIOF_DIR_OUT, port->reset_name);
920 if (ret) {
921 if (ret == -EPROBE_DEFER)
922 return ret;
923 continue;
924 }
925
926 gpio_set_value(port->reset_gpio,
927 (port->reset_active_low) ? 1 : 0);
928 msleep(reset_udelay/1000);
929 }
930
931 port->clk = of_clk_get_by_name(child, NULL);
932 if (IS_ERR(port->clk)) {
933 dev_err(&pdev->dev, "PCIe%d.%d: cannot get clock\n",
934 port->port, port->lane);
935 continue;
936 }
937
938 ret = clk_prepare_enable(port->clk);
939 if (ret)
940 continue;
941
876 port->base = mvebu_pcie_map_registers(pdev, child, port); 942 port->base = mvebu_pcie_map_registers(pdev, child, port);
877 if (IS_ERR(port->base)) { 943 if (IS_ERR(port->base)) {
878 dev_err(&pdev->dev, "PCIe%d.%d: cannot map registers\n", 944 dev_err(&pdev->dev, "PCIe%d.%d: cannot map registers\n",
879 port->port, port->lane); 945 port->port, port->lane);
880 port->base = NULL; 946 port->base = NULL;
947 clk_disable_unprepare(port->clk);
881 continue; 948 continue;
882 } 949 }
883 950
@@ -893,25 +960,14 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
893 port->port, port->lane); 960 port->port, port->lane);
894 } 961 }
895 962
896 port->clk = of_clk_get_by_name(child, NULL);
897 if (IS_ERR(port->clk)) {
898 dev_err(&pdev->dev, "PCIe%d.%d: cannot get clock\n",
899 port->port, port->lane);
900 iounmap(port->base);
901 port->haslink = 0;
902 continue;
903 }
904
905 port->dn = child; 963 port->dn = child;
906
907 clk_prepare_enable(port->clk);
908 spin_lock_init(&port->conf_lock); 964 spin_lock_init(&port->conf_lock);
909
910 mvebu_sw_pci_bridge_init(port); 965 mvebu_sw_pci_bridge_init(port);
911
912 i++; 966 i++;
913 } 967 }
914 968
969 pcie->nports = i;
970 mvebu_pcie_msi_enable(pcie);
915 mvebu_pcie_enable(pcie); 971 mvebu_pcie_enable(pcie);
916 972
917 return 0; 973 return 0;
@@ -920,6 +976,7 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
920static const struct of_device_id mvebu_pcie_of_match_table[] = { 976static const struct of_device_id mvebu_pcie_of_match_table[] = {
921 { .compatible = "marvell,armada-xp-pcie", }, 977 { .compatible = "marvell,armada-xp-pcie", },
922 { .compatible = "marvell,armada-370-pcie", }, 978 { .compatible = "marvell,armada-370-pcie", },
979 { .compatible = "marvell,dove-pcie", },
923 { .compatible = "marvell,kirkwood-pcie", }, 980 { .compatible = "marvell,kirkwood-pcie", },
924 {}, 981 {},
925}; 982};
@@ -931,16 +988,12 @@ static struct platform_driver mvebu_pcie_driver = {
931 .name = "mvebu-pcie", 988 .name = "mvebu-pcie",
932 .of_match_table = 989 .of_match_table =
933 of_match_ptr(mvebu_pcie_of_match_table), 990 of_match_ptr(mvebu_pcie_of_match_table),
991 /* driver unloading/unbinding currently not supported */
992 .suppress_bind_attrs = true,
934 }, 993 },
994 .probe = mvebu_pcie_probe,
935}; 995};
936 996module_platform_driver(mvebu_pcie_driver);
937static int __init mvebu_pcie_init(void)
938{
939 return platform_driver_probe(&mvebu_pcie_driver,
940 mvebu_pcie_probe);
941}
942
943subsys_initcall(mvebu_pcie_init);
944 997
945MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>"); 998MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
946MODULE_DESCRIPTION("Marvell EBU PCIe driver"); 999MODULE_DESCRIPTION("Marvell EBU PCIe driver");