diff options
Diffstat (limited to 'drivers/pci/controller/pcie-xilinx.c')
-rw-r--r-- | drivers/pci/controller/pcie-xilinx.c | 702 |
1 files changed, 702 insertions, 0 deletions
diff --git a/drivers/pci/controller/pcie-xilinx.c b/drivers/pci/controller/pcie-xilinx.c new file mode 100644 index 000000000000..b110a3a814e3 --- /dev/null +++ b/drivers/pci/controller/pcie-xilinx.c | |||
@@ -0,0 +1,702 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0+ | ||
2 | /* | ||
3 | * PCIe host controller driver for Xilinx AXI PCIe Bridge | ||
4 | * | ||
5 | * Copyright (c) 2012 - 2014 Xilinx, Inc. | ||
6 | * | ||
7 | * Based on the Tegra PCIe driver | ||
8 | * | ||
9 | * Bits taken from Synopsys DesignWare Host controller driver and | ||
10 | * ARM PCI Host generic driver. | ||
11 | */ | ||
12 | |||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/irqdomain.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/msi.h> | ||
19 | #include <linux/of_address.h> | ||
20 | #include <linux/of_pci.h> | ||
21 | #include <linux/of_platform.h> | ||
22 | #include <linux/of_irq.h> | ||
23 | #include <linux/pci.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | |||
26 | #include "../pci.h" | ||
27 | |||
28 | /* Register definitions */ | ||
29 | #define XILINX_PCIE_REG_BIR 0x00000130 | ||
30 | #define XILINX_PCIE_REG_IDR 0x00000138 | ||
31 | #define XILINX_PCIE_REG_IMR 0x0000013c | ||
32 | #define XILINX_PCIE_REG_PSCR 0x00000144 | ||
33 | #define XILINX_PCIE_REG_RPSC 0x00000148 | ||
34 | #define XILINX_PCIE_REG_MSIBASE1 0x0000014c | ||
35 | #define XILINX_PCIE_REG_MSIBASE2 0x00000150 | ||
36 | #define XILINX_PCIE_REG_RPEFR 0x00000154 | ||
37 | #define XILINX_PCIE_REG_RPIFR1 0x00000158 | ||
38 | #define XILINX_PCIE_REG_RPIFR2 0x0000015c | ||
39 | |||
40 | /* Interrupt registers definitions */ | ||
41 | #define XILINX_PCIE_INTR_LINK_DOWN BIT(0) | ||
42 | #define XILINX_PCIE_INTR_ECRC_ERR BIT(1) | ||
43 | #define XILINX_PCIE_INTR_STR_ERR BIT(2) | ||
44 | #define XILINX_PCIE_INTR_HOT_RESET BIT(3) | ||
45 | #define XILINX_PCIE_INTR_CFG_TIMEOUT BIT(8) | ||
46 | #define XILINX_PCIE_INTR_CORRECTABLE BIT(9) | ||
47 | #define XILINX_PCIE_INTR_NONFATAL BIT(10) | ||
48 | #define XILINX_PCIE_INTR_FATAL BIT(11) | ||
49 | #define XILINX_PCIE_INTR_INTX BIT(16) | ||
50 | #define XILINX_PCIE_INTR_MSI BIT(17) | ||
51 | #define XILINX_PCIE_INTR_SLV_UNSUPP BIT(20) | ||
52 | #define XILINX_PCIE_INTR_SLV_UNEXP BIT(21) | ||
53 | #define XILINX_PCIE_INTR_SLV_COMPL BIT(22) | ||
54 | #define XILINX_PCIE_INTR_SLV_ERRP BIT(23) | ||
55 | #define XILINX_PCIE_INTR_SLV_CMPABT BIT(24) | ||
56 | #define XILINX_PCIE_INTR_SLV_ILLBUR BIT(25) | ||
57 | #define XILINX_PCIE_INTR_MST_DECERR BIT(26) | ||
58 | #define XILINX_PCIE_INTR_MST_SLVERR BIT(27) | ||
59 | #define XILINX_PCIE_INTR_MST_ERRP BIT(28) | ||
60 | #define XILINX_PCIE_IMR_ALL_MASK 0x1FF30FED | ||
61 | #define XILINX_PCIE_IMR_ENABLE_MASK 0x1FF30F0D | ||
62 | #define XILINX_PCIE_IDR_ALL_MASK 0xFFFFFFFF | ||
63 | |||
64 | /* Root Port Error FIFO Read Register definitions */ | ||
65 | #define XILINX_PCIE_RPEFR_ERR_VALID BIT(18) | ||
66 | #define XILINX_PCIE_RPEFR_REQ_ID GENMASK(15, 0) | ||
67 | #define XILINX_PCIE_RPEFR_ALL_MASK 0xFFFFFFFF | ||
68 | |||
69 | /* Root Port Interrupt FIFO Read Register 1 definitions */ | ||
70 | #define XILINX_PCIE_RPIFR1_INTR_VALID BIT(31) | ||
71 | #define XILINX_PCIE_RPIFR1_MSI_INTR BIT(30) | ||
72 | #define XILINX_PCIE_RPIFR1_INTR_MASK GENMASK(28, 27) | ||
73 | #define XILINX_PCIE_RPIFR1_ALL_MASK 0xFFFFFFFF | ||
74 | #define XILINX_PCIE_RPIFR1_INTR_SHIFT 27 | ||
75 | |||
76 | /* Bridge Info Register definitions */ | ||
77 | #define XILINX_PCIE_BIR_ECAM_SZ_MASK GENMASK(18, 16) | ||
78 | #define XILINX_PCIE_BIR_ECAM_SZ_SHIFT 16 | ||
79 | |||
80 | /* Root Port Interrupt FIFO Read Register 2 definitions */ | ||
81 | #define XILINX_PCIE_RPIFR2_MSG_DATA GENMASK(15, 0) | ||
82 | |||
83 | /* Root Port Status/control Register definitions */ | ||
84 | #define XILINX_PCIE_REG_RPSC_BEN BIT(0) | ||
85 | |||
86 | /* Phy Status/Control Register definitions */ | ||
87 | #define XILINX_PCIE_REG_PSCR_LNKUP BIT(11) | ||
88 | |||
89 | /* ECAM definitions */ | ||
90 | #define ECAM_BUS_NUM_SHIFT 20 | ||
91 | #define ECAM_DEV_NUM_SHIFT 12 | ||
92 | |||
93 | /* Number of MSI IRQs */ | ||
94 | #define XILINX_NUM_MSI_IRQS 128 | ||
95 | |||
96 | /** | ||
97 | * struct xilinx_pcie_port - PCIe port information | ||
98 | * @reg_base: IO Mapped Register Base | ||
99 | * @irq: Interrupt number | ||
100 | * @msi_pages: MSI pages | ||
101 | * @root_busno: Root Bus number | ||
102 | * @dev: Device pointer | ||
103 | * @msi_domain: MSI IRQ domain pointer | ||
104 | * @leg_domain: Legacy IRQ domain pointer | ||
105 | * @resources: Bus Resources | ||
106 | */ | ||
107 | struct xilinx_pcie_port { | ||
108 | void __iomem *reg_base; | ||
109 | u32 irq; | ||
110 | unsigned long msi_pages; | ||
111 | u8 root_busno; | ||
112 | struct device *dev; | ||
113 | struct irq_domain *msi_domain; | ||
114 | struct irq_domain *leg_domain; | ||
115 | struct list_head resources; | ||
116 | }; | ||
117 | |||
118 | static DECLARE_BITMAP(msi_irq_in_use, XILINX_NUM_MSI_IRQS); | ||
119 | |||
120 | static inline u32 pcie_read(struct xilinx_pcie_port *port, u32 reg) | ||
121 | { | ||
122 | return readl(port->reg_base + reg); | ||
123 | } | ||
124 | |||
125 | static inline void pcie_write(struct xilinx_pcie_port *port, u32 val, u32 reg) | ||
126 | { | ||
127 | writel(val, port->reg_base + reg); | ||
128 | } | ||
129 | |||
130 | static inline bool xilinx_pcie_link_up(struct xilinx_pcie_port *port) | ||
131 | { | ||
132 | return (pcie_read(port, XILINX_PCIE_REG_PSCR) & | ||
133 | XILINX_PCIE_REG_PSCR_LNKUP) ? 1 : 0; | ||
134 | } | ||
135 | |||
136 | /** | ||
137 | * xilinx_pcie_clear_err_interrupts - Clear Error Interrupts | ||
138 | * @port: PCIe port information | ||
139 | */ | ||
140 | static void xilinx_pcie_clear_err_interrupts(struct xilinx_pcie_port *port) | ||
141 | { | ||
142 | struct device *dev = port->dev; | ||
143 | unsigned long val = pcie_read(port, XILINX_PCIE_REG_RPEFR); | ||
144 | |||
145 | if (val & XILINX_PCIE_RPEFR_ERR_VALID) { | ||
146 | dev_dbg(dev, "Requester ID %lu\n", | ||
147 | val & XILINX_PCIE_RPEFR_REQ_ID); | ||
148 | pcie_write(port, XILINX_PCIE_RPEFR_ALL_MASK, | ||
149 | XILINX_PCIE_REG_RPEFR); | ||
150 | } | ||
151 | } | ||
152 | |||
153 | /** | ||
154 | * xilinx_pcie_valid_device - Check if a valid device is present on bus | ||
155 | * @bus: PCI Bus structure | ||
156 | * @devfn: device/function | ||
157 | * | ||
158 | * Return: 'true' on success and 'false' if invalid device is found | ||
159 | */ | ||
160 | static bool xilinx_pcie_valid_device(struct pci_bus *bus, unsigned int devfn) | ||
161 | { | ||
162 | struct xilinx_pcie_port *port = bus->sysdata; | ||
163 | |||
164 | /* Check if link is up when trying to access downstream ports */ | ||
165 | if (bus->number != port->root_busno) | ||
166 | if (!xilinx_pcie_link_up(port)) | ||
167 | return false; | ||
168 | |||
169 | /* Only one device down on each root port */ | ||
170 | if (bus->number == port->root_busno && devfn > 0) | ||
171 | return false; | ||
172 | |||
173 | return true; | ||
174 | } | ||
175 | |||
176 | /** | ||
177 | * xilinx_pcie_map_bus - Get configuration base | ||
178 | * @bus: PCI Bus structure | ||
179 | * @devfn: Device/function | ||
180 | * @where: Offset from base | ||
181 | * | ||
182 | * Return: Base address of the configuration space needed to be | ||
183 | * accessed. | ||
184 | */ | ||
185 | static void __iomem *xilinx_pcie_map_bus(struct pci_bus *bus, | ||
186 | unsigned int devfn, int where) | ||
187 | { | ||
188 | struct xilinx_pcie_port *port = bus->sysdata; | ||
189 | int relbus; | ||
190 | |||
191 | if (!xilinx_pcie_valid_device(bus, devfn)) | ||
192 | return NULL; | ||
193 | |||
194 | relbus = (bus->number << ECAM_BUS_NUM_SHIFT) | | ||
195 | (devfn << ECAM_DEV_NUM_SHIFT); | ||
196 | |||
197 | return port->reg_base + relbus + where; | ||
198 | } | ||
199 | |||
200 | /* PCIe operations */ | ||
201 | static struct pci_ops xilinx_pcie_ops = { | ||
202 | .map_bus = xilinx_pcie_map_bus, | ||
203 | .read = pci_generic_config_read, | ||
204 | .write = pci_generic_config_write, | ||
205 | }; | ||
206 | |||
207 | /* MSI functions */ | ||
208 | |||
209 | /** | ||
210 | * xilinx_pcie_destroy_msi - Free MSI number | ||
211 | * @irq: IRQ to be freed | ||
212 | */ | ||
213 | static void xilinx_pcie_destroy_msi(unsigned int irq) | ||
214 | { | ||
215 | struct msi_desc *msi; | ||
216 | struct xilinx_pcie_port *port; | ||
217 | struct irq_data *d = irq_get_irq_data(irq); | ||
218 | irq_hw_number_t hwirq = irqd_to_hwirq(d); | ||
219 | |||
220 | if (!test_bit(hwirq, msi_irq_in_use)) { | ||
221 | msi = irq_get_msi_desc(irq); | ||
222 | port = msi_desc_to_pci_sysdata(msi); | ||
223 | dev_err(port->dev, "Trying to free unused MSI#%d\n", irq); | ||
224 | } else { | ||
225 | clear_bit(hwirq, msi_irq_in_use); | ||
226 | } | ||
227 | } | ||
228 | |||
229 | /** | ||
230 | * xilinx_pcie_assign_msi - Allocate MSI number | ||
231 | * | ||
232 | * Return: A valid IRQ on success and error value on failure. | ||
233 | */ | ||
234 | static int xilinx_pcie_assign_msi(void) | ||
235 | { | ||
236 | int pos; | ||
237 | |||
238 | pos = find_first_zero_bit(msi_irq_in_use, XILINX_NUM_MSI_IRQS); | ||
239 | if (pos < XILINX_NUM_MSI_IRQS) | ||
240 | set_bit(pos, msi_irq_in_use); | ||
241 | else | ||
242 | return -ENOSPC; | ||
243 | |||
244 | return pos; | ||
245 | } | ||
246 | |||
247 | /** | ||
248 | * xilinx_msi_teardown_irq - Destroy the MSI | ||
249 | * @chip: MSI Chip descriptor | ||
250 | * @irq: MSI IRQ to destroy | ||
251 | */ | ||
252 | static void xilinx_msi_teardown_irq(struct msi_controller *chip, | ||
253 | unsigned int irq) | ||
254 | { | ||
255 | xilinx_pcie_destroy_msi(irq); | ||
256 | irq_dispose_mapping(irq); | ||
257 | } | ||
258 | |||
259 | /** | ||
260 | * xilinx_pcie_msi_setup_irq - Setup MSI request | ||
261 | * @chip: MSI chip pointer | ||
262 | * @pdev: PCIe device pointer | ||
263 | * @desc: MSI descriptor pointer | ||
264 | * | ||
265 | * Return: '0' on success and error value on failure | ||
266 | */ | ||
267 | static int xilinx_pcie_msi_setup_irq(struct msi_controller *chip, | ||
268 | struct pci_dev *pdev, | ||
269 | struct msi_desc *desc) | ||
270 | { | ||
271 | struct xilinx_pcie_port *port = pdev->bus->sysdata; | ||
272 | unsigned int irq; | ||
273 | int hwirq; | ||
274 | struct msi_msg msg; | ||
275 | phys_addr_t msg_addr; | ||
276 | |||
277 | hwirq = xilinx_pcie_assign_msi(); | ||
278 | if (hwirq < 0) | ||
279 | return hwirq; | ||
280 | |||
281 | irq = irq_create_mapping(port->msi_domain, hwirq); | ||
282 | if (!irq) | ||
283 | return -EINVAL; | ||
284 | |||
285 | irq_set_msi_desc(irq, desc); | ||
286 | |||
287 | msg_addr = virt_to_phys((void *)port->msi_pages); | ||
288 | |||
289 | msg.address_hi = 0; | ||
290 | msg.address_lo = msg_addr; | ||
291 | msg.data = irq; | ||
292 | |||
293 | pci_write_msi_msg(irq, &msg); | ||
294 | |||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | /* MSI Chip Descriptor */ | ||
299 | static struct msi_controller xilinx_pcie_msi_chip = { | ||
300 | .setup_irq = xilinx_pcie_msi_setup_irq, | ||
301 | .teardown_irq = xilinx_msi_teardown_irq, | ||
302 | }; | ||
303 | |||
304 | /* HW Interrupt Chip Descriptor */ | ||
305 | static struct irq_chip xilinx_msi_irq_chip = { | ||
306 | .name = "Xilinx PCIe MSI", | ||
307 | .irq_enable = pci_msi_unmask_irq, | ||
308 | .irq_disable = pci_msi_mask_irq, | ||
309 | .irq_mask = pci_msi_mask_irq, | ||
310 | .irq_unmask = pci_msi_unmask_irq, | ||
311 | }; | ||
312 | |||
313 | /** | ||
314 | * xilinx_pcie_msi_map - Set the handler for the MSI and mark IRQ as valid | ||
315 | * @domain: IRQ domain | ||
316 | * @irq: Virtual IRQ number | ||
317 | * @hwirq: HW interrupt number | ||
318 | * | ||
319 | * Return: Always returns 0. | ||
320 | */ | ||
321 | static int xilinx_pcie_msi_map(struct irq_domain *domain, unsigned int irq, | ||
322 | irq_hw_number_t hwirq) | ||
323 | { | ||
324 | irq_set_chip_and_handler(irq, &xilinx_msi_irq_chip, handle_simple_irq); | ||
325 | irq_set_chip_data(irq, domain->host_data); | ||
326 | |||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | /* IRQ Domain operations */ | ||
331 | static const struct irq_domain_ops msi_domain_ops = { | ||
332 | .map = xilinx_pcie_msi_map, | ||
333 | }; | ||
334 | |||
335 | /** | ||
336 | * xilinx_pcie_enable_msi - Enable MSI support | ||
337 | * @port: PCIe port information | ||
338 | */ | ||
339 | static void xilinx_pcie_enable_msi(struct xilinx_pcie_port *port) | ||
340 | { | ||
341 | phys_addr_t msg_addr; | ||
342 | |||
343 | port->msi_pages = __get_free_pages(GFP_KERNEL, 0); | ||
344 | msg_addr = virt_to_phys((void *)port->msi_pages); | ||
345 | pcie_write(port, 0x0, XILINX_PCIE_REG_MSIBASE1); | ||
346 | pcie_write(port, msg_addr, XILINX_PCIE_REG_MSIBASE2); | ||
347 | } | ||
348 | |||
349 | /* INTx Functions */ | ||
350 | |||
351 | /** | ||
352 | * xilinx_pcie_intx_map - Set the handler for the INTx and mark IRQ as valid | ||
353 | * @domain: IRQ domain | ||
354 | * @irq: Virtual IRQ number | ||
355 | * @hwirq: HW interrupt number | ||
356 | * | ||
357 | * Return: Always returns 0. | ||
358 | */ | ||
359 | static int xilinx_pcie_intx_map(struct irq_domain *domain, unsigned int irq, | ||
360 | irq_hw_number_t hwirq) | ||
361 | { | ||
362 | irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq); | ||
363 | irq_set_chip_data(irq, domain->host_data); | ||
364 | |||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | /* INTx IRQ Domain operations */ | ||
369 | static const struct irq_domain_ops intx_domain_ops = { | ||
370 | .map = xilinx_pcie_intx_map, | ||
371 | .xlate = pci_irqd_intx_xlate, | ||
372 | }; | ||
373 | |||
374 | /* PCIe HW Functions */ | ||
375 | |||
376 | /** | ||
377 | * xilinx_pcie_intr_handler - Interrupt Service Handler | ||
378 | * @irq: IRQ number | ||
379 | * @data: PCIe port information | ||
380 | * | ||
381 | * Return: IRQ_HANDLED on success and IRQ_NONE on failure | ||
382 | */ | ||
383 | static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data) | ||
384 | { | ||
385 | struct xilinx_pcie_port *port = (struct xilinx_pcie_port *)data; | ||
386 | struct device *dev = port->dev; | ||
387 | u32 val, mask, status; | ||
388 | |||
389 | /* Read interrupt decode and mask registers */ | ||
390 | val = pcie_read(port, XILINX_PCIE_REG_IDR); | ||
391 | mask = pcie_read(port, XILINX_PCIE_REG_IMR); | ||
392 | |||
393 | status = val & mask; | ||
394 | if (!status) | ||
395 | return IRQ_NONE; | ||
396 | |||
397 | if (status & XILINX_PCIE_INTR_LINK_DOWN) | ||
398 | dev_warn(dev, "Link Down\n"); | ||
399 | |||
400 | if (status & XILINX_PCIE_INTR_ECRC_ERR) | ||
401 | dev_warn(dev, "ECRC failed\n"); | ||
402 | |||
403 | if (status & XILINX_PCIE_INTR_STR_ERR) | ||
404 | dev_warn(dev, "Streaming error\n"); | ||
405 | |||
406 | if (status & XILINX_PCIE_INTR_HOT_RESET) | ||
407 | dev_info(dev, "Hot reset\n"); | ||
408 | |||
409 | if (status & XILINX_PCIE_INTR_CFG_TIMEOUT) | ||
410 | dev_warn(dev, "ECAM access timeout\n"); | ||
411 | |||
412 | if (status & XILINX_PCIE_INTR_CORRECTABLE) { | ||
413 | dev_warn(dev, "Correctable error message\n"); | ||
414 | xilinx_pcie_clear_err_interrupts(port); | ||
415 | } | ||
416 | |||
417 | if (status & XILINX_PCIE_INTR_NONFATAL) { | ||
418 | dev_warn(dev, "Non fatal error message\n"); | ||
419 | xilinx_pcie_clear_err_interrupts(port); | ||
420 | } | ||
421 | |||
422 | if (status & XILINX_PCIE_INTR_FATAL) { | ||
423 | dev_warn(dev, "Fatal error message\n"); | ||
424 | xilinx_pcie_clear_err_interrupts(port); | ||
425 | } | ||
426 | |||
427 | if (status & (XILINX_PCIE_INTR_INTX | XILINX_PCIE_INTR_MSI)) { | ||
428 | val = pcie_read(port, XILINX_PCIE_REG_RPIFR1); | ||
429 | |||
430 | /* Check whether interrupt valid */ | ||
431 | if (!(val & XILINX_PCIE_RPIFR1_INTR_VALID)) { | ||
432 | dev_warn(dev, "RP Intr FIFO1 read error\n"); | ||
433 | goto error; | ||
434 | } | ||
435 | |||
436 | /* Decode the IRQ number */ | ||
437 | if (val & XILINX_PCIE_RPIFR1_MSI_INTR) { | ||
438 | val = pcie_read(port, XILINX_PCIE_REG_RPIFR2) & | ||
439 | XILINX_PCIE_RPIFR2_MSG_DATA; | ||
440 | } else { | ||
441 | val = (val & XILINX_PCIE_RPIFR1_INTR_MASK) >> | ||
442 | XILINX_PCIE_RPIFR1_INTR_SHIFT; | ||
443 | val = irq_find_mapping(port->leg_domain, val); | ||
444 | } | ||
445 | |||
446 | /* Clear interrupt FIFO register 1 */ | ||
447 | pcie_write(port, XILINX_PCIE_RPIFR1_ALL_MASK, | ||
448 | XILINX_PCIE_REG_RPIFR1); | ||
449 | |||
450 | /* Handle the interrupt */ | ||
451 | if (IS_ENABLED(CONFIG_PCI_MSI) || | ||
452 | !(val & XILINX_PCIE_RPIFR1_MSI_INTR)) | ||
453 | generic_handle_irq(val); | ||
454 | } | ||
455 | |||
456 | if (status & XILINX_PCIE_INTR_SLV_UNSUPP) | ||
457 | dev_warn(dev, "Slave unsupported request\n"); | ||
458 | |||
459 | if (status & XILINX_PCIE_INTR_SLV_UNEXP) | ||
460 | dev_warn(dev, "Slave unexpected completion\n"); | ||
461 | |||
462 | if (status & XILINX_PCIE_INTR_SLV_COMPL) | ||
463 | dev_warn(dev, "Slave completion timeout\n"); | ||
464 | |||
465 | if (status & XILINX_PCIE_INTR_SLV_ERRP) | ||
466 | dev_warn(dev, "Slave Error Poison\n"); | ||
467 | |||
468 | if (status & XILINX_PCIE_INTR_SLV_CMPABT) | ||
469 | dev_warn(dev, "Slave Completer Abort\n"); | ||
470 | |||
471 | if (status & XILINX_PCIE_INTR_SLV_ILLBUR) | ||
472 | dev_warn(dev, "Slave Illegal Burst\n"); | ||
473 | |||
474 | if (status & XILINX_PCIE_INTR_MST_DECERR) | ||
475 | dev_warn(dev, "Master decode error\n"); | ||
476 | |||
477 | if (status & XILINX_PCIE_INTR_MST_SLVERR) | ||
478 | dev_warn(dev, "Master slave error\n"); | ||
479 | |||
480 | if (status & XILINX_PCIE_INTR_MST_ERRP) | ||
481 | dev_warn(dev, "Master error poison\n"); | ||
482 | |||
483 | error: | ||
484 | /* Clear the Interrupt Decode register */ | ||
485 | pcie_write(port, status, XILINX_PCIE_REG_IDR); | ||
486 | |||
487 | return IRQ_HANDLED; | ||
488 | } | ||
489 | |||
490 | /** | ||
491 | * xilinx_pcie_init_irq_domain - Initialize IRQ domain | ||
492 | * @port: PCIe port information | ||
493 | * | ||
494 | * Return: '0' on success and error value on failure | ||
495 | */ | ||
496 | static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port) | ||
497 | { | ||
498 | struct device *dev = port->dev; | ||
499 | struct device_node *node = dev->of_node; | ||
500 | struct device_node *pcie_intc_node; | ||
501 | |||
502 | /* Setup INTx */ | ||
503 | pcie_intc_node = of_get_next_child(node, NULL); | ||
504 | if (!pcie_intc_node) { | ||
505 | dev_err(dev, "No PCIe Intc node found\n"); | ||
506 | return -ENODEV; | ||
507 | } | ||
508 | |||
509 | port->leg_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, | ||
510 | &intx_domain_ops, | ||
511 | port); | ||
512 | if (!port->leg_domain) { | ||
513 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); | ||
514 | return -ENODEV; | ||
515 | } | ||
516 | |||
517 | /* Setup MSI */ | ||
518 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | ||
519 | port->msi_domain = irq_domain_add_linear(node, | ||
520 | XILINX_NUM_MSI_IRQS, | ||
521 | &msi_domain_ops, | ||
522 | &xilinx_pcie_msi_chip); | ||
523 | if (!port->msi_domain) { | ||
524 | dev_err(dev, "Failed to get a MSI IRQ domain\n"); | ||
525 | return -ENODEV; | ||
526 | } | ||
527 | |||
528 | xilinx_pcie_enable_msi(port); | ||
529 | } | ||
530 | |||
531 | return 0; | ||
532 | } | ||
533 | |||
534 | /** | ||
535 | * xilinx_pcie_init_port - Initialize hardware | ||
536 | * @port: PCIe port information | ||
537 | */ | ||
538 | static void xilinx_pcie_init_port(struct xilinx_pcie_port *port) | ||
539 | { | ||
540 | struct device *dev = port->dev; | ||
541 | |||
542 | if (xilinx_pcie_link_up(port)) | ||
543 | dev_info(dev, "PCIe Link is UP\n"); | ||
544 | else | ||
545 | dev_info(dev, "PCIe Link is DOWN\n"); | ||
546 | |||
547 | /* Disable all interrupts */ | ||
548 | pcie_write(port, ~XILINX_PCIE_IDR_ALL_MASK, | ||
549 | XILINX_PCIE_REG_IMR); | ||
550 | |||
551 | /* Clear pending interrupts */ | ||
552 | pcie_write(port, pcie_read(port, XILINX_PCIE_REG_IDR) & | ||
553 | XILINX_PCIE_IMR_ALL_MASK, | ||
554 | XILINX_PCIE_REG_IDR); | ||
555 | |||
556 | /* Enable all interrupts we handle */ | ||
557 | pcie_write(port, XILINX_PCIE_IMR_ENABLE_MASK, XILINX_PCIE_REG_IMR); | ||
558 | |||
559 | /* Enable the Bridge enable bit */ | ||
560 | pcie_write(port, pcie_read(port, XILINX_PCIE_REG_RPSC) | | ||
561 | XILINX_PCIE_REG_RPSC_BEN, | ||
562 | XILINX_PCIE_REG_RPSC); | ||
563 | } | ||
564 | |||
565 | /** | ||
566 | * xilinx_pcie_parse_dt - Parse Device tree | ||
567 | * @port: PCIe port information | ||
568 | * | ||
569 | * Return: '0' on success and error value on failure | ||
570 | */ | ||
571 | static int xilinx_pcie_parse_dt(struct xilinx_pcie_port *port) | ||
572 | { | ||
573 | struct device *dev = port->dev; | ||
574 | struct device_node *node = dev->of_node; | ||
575 | struct resource regs; | ||
576 | const char *type; | ||
577 | int err; | ||
578 | |||
579 | type = of_get_property(node, "device_type", NULL); | ||
580 | if (!type || strcmp(type, "pci")) { | ||
581 | dev_err(dev, "invalid \"device_type\" %s\n", type); | ||
582 | return -EINVAL; | ||
583 | } | ||
584 | |||
585 | err = of_address_to_resource(node, 0, ®s); | ||
586 | if (err) { | ||
587 | dev_err(dev, "missing \"reg\" property\n"); | ||
588 | return err; | ||
589 | } | ||
590 | |||
591 | port->reg_base = devm_pci_remap_cfg_resource(dev, ®s); | ||
592 | if (IS_ERR(port->reg_base)) | ||
593 | return PTR_ERR(port->reg_base); | ||
594 | |||
595 | port->irq = irq_of_parse_and_map(node, 0); | ||
596 | err = devm_request_irq(dev, port->irq, xilinx_pcie_intr_handler, | ||
597 | IRQF_SHARED | IRQF_NO_THREAD, | ||
598 | "xilinx-pcie", port); | ||
599 | if (err) { | ||
600 | dev_err(dev, "unable to request irq %d\n", port->irq); | ||
601 | return err; | ||
602 | } | ||
603 | |||
604 | return 0; | ||
605 | } | ||
606 | |||
607 | /** | ||
608 | * xilinx_pcie_probe - Probe function | ||
609 | * @pdev: Platform device pointer | ||
610 | * | ||
611 | * Return: '0' on success and error value on failure | ||
612 | */ | ||
613 | static int xilinx_pcie_probe(struct platform_device *pdev) | ||
614 | { | ||
615 | struct device *dev = &pdev->dev; | ||
616 | struct xilinx_pcie_port *port; | ||
617 | struct pci_bus *bus, *child; | ||
618 | struct pci_host_bridge *bridge; | ||
619 | int err; | ||
620 | resource_size_t iobase = 0; | ||
621 | LIST_HEAD(res); | ||
622 | |||
623 | if (!dev->of_node) | ||
624 | return -ENODEV; | ||
625 | |||
626 | bridge = devm_pci_alloc_host_bridge(dev, sizeof(*port)); | ||
627 | if (!bridge) | ||
628 | return -ENODEV; | ||
629 | |||
630 | port = pci_host_bridge_priv(bridge); | ||
631 | |||
632 | port->dev = dev; | ||
633 | |||
634 | err = xilinx_pcie_parse_dt(port); | ||
635 | if (err) { | ||
636 | dev_err(dev, "Parsing DT failed\n"); | ||
637 | return err; | ||
638 | } | ||
639 | |||
640 | xilinx_pcie_init_port(port); | ||
641 | |||
642 | err = xilinx_pcie_init_irq_domain(port); | ||
643 | if (err) { | ||
644 | dev_err(dev, "Failed creating IRQ Domain\n"); | ||
645 | return err; | ||
646 | } | ||
647 | |||
648 | err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &res, | ||
649 | &iobase); | ||
650 | if (err) { | ||
651 | dev_err(dev, "Getting bridge resources failed\n"); | ||
652 | return err; | ||
653 | } | ||
654 | |||
655 | err = devm_request_pci_bus_resources(dev, &res); | ||
656 | if (err) | ||
657 | goto error; | ||
658 | |||
659 | |||
660 | list_splice_init(&res, &bridge->windows); | ||
661 | bridge->dev.parent = dev; | ||
662 | bridge->sysdata = port; | ||
663 | bridge->busnr = 0; | ||
664 | bridge->ops = &xilinx_pcie_ops; | ||
665 | bridge->map_irq = of_irq_parse_and_map_pci; | ||
666 | bridge->swizzle_irq = pci_common_swizzle; | ||
667 | |||
668 | #ifdef CONFIG_PCI_MSI | ||
669 | xilinx_pcie_msi_chip.dev = dev; | ||
670 | bridge->msi = &xilinx_pcie_msi_chip; | ||
671 | #endif | ||
672 | err = pci_scan_root_bus_bridge(bridge); | ||
673 | if (err < 0) | ||
674 | goto error; | ||
675 | |||
676 | bus = bridge->bus; | ||
677 | |||
678 | pci_assign_unassigned_bus_resources(bus); | ||
679 | list_for_each_entry(child, &bus->children, node) | ||
680 | pcie_bus_configure_settings(child); | ||
681 | pci_bus_add_devices(bus); | ||
682 | return 0; | ||
683 | |||
684 | error: | ||
685 | pci_free_resource_list(&res); | ||
686 | return err; | ||
687 | } | ||
688 | |||
689 | static const struct of_device_id xilinx_pcie_of_match[] = { | ||
690 | { .compatible = "xlnx,axi-pcie-host-1.00.a", }, | ||
691 | {} | ||
692 | }; | ||
693 | |||
694 | static struct platform_driver xilinx_pcie_driver = { | ||
695 | .driver = { | ||
696 | .name = "xilinx-pcie", | ||
697 | .of_match_table = xilinx_pcie_of_match, | ||
698 | .suppress_bind_attrs = true, | ||
699 | }, | ||
700 | .probe = xilinx_pcie_probe, | ||
701 | }; | ||
702 | builtin_platform_driver(xilinx_pcie_driver); | ||