Commit | Line | Data |
---|---|---|
736759ef | 1 | // SPDX-License-Identifier: GPL-2.0+ |
8961def5 ST |
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 | * | |
96291d56 | 9 | * Bits taken from Synopsys DesignWare Host controller driver and |
8961def5 | 10 | * ARM PCI Host generic driver. |
8961def5 ST |
11 | */ |
12 | ||
13 | #include <linux/interrupt.h> | |
14 | #include <linux/irq.h> | |
15 | #include <linux/irqdomain.h> | |
16 | #include <linux/kernel.h> | |
da4eafca | 17 | #include <linux/init.h> |
8961def5 ST |
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 | ||
9e2aee80 RH |
26 | #include "../pci.h" |
27 | ||
8961def5 ST |
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 | |
aac2e96b | 61 | #define XILINX_PCIE_IMR_ENABLE_MASK 0x1FF30F0D |
8961def5 ST |
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 | ||
8961def5 ST |
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 | |
b584fa1f BKG |
103 | * @msi_domain: MSI IRQ domain pointer |
104 | * @leg_domain: Legacy IRQ domain pointer | |
8961def5 ST |
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; | |
b584fa1f BKG |
113 | struct irq_domain *msi_domain; |
114 | struct irq_domain *leg_domain; | |
8961def5 ST |
115 | struct list_head resources; |
116 | }; | |
117 | ||
118 | static DECLARE_BITMAP(msi_irq_in_use, XILINX_NUM_MSI_IRQS); | |
119 | ||
8961def5 ST |
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 | ||
1eaa8702 | 130 | static inline bool xilinx_pcie_link_up(struct xilinx_pcie_port *port) |
8961def5 ST |
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 | { | |
5d07188e | 142 | struct device *dev = port->dev; |
abc596b9 | 143 | unsigned long val = pcie_read(port, XILINX_PCIE_REG_RPEFR); |
8961def5 ST |
144 | |
145 | if (val & XILINX_PCIE_RPEFR_ERR_VALID) { | |
5d07188e | 146 | dev_dbg(dev, "Requester ID %lu\n", |
8961def5 ST |
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 | { | |
4c01f3b0 | 162 | struct xilinx_pcie_port *port = bus->sysdata; |
8961def5 ST |
163 | |
164 | /* Check if link is up when trying to access downstream ports */ | |
165 | if (bus->number != port->root_busno) | |
1eaa8702 | 166 | if (!xilinx_pcie_link_up(port)) |
8961def5 ST |
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 | ||
8961def5 ST |
173 | return true; |
174 | } | |
175 | ||
176 | /** | |
029e2151 | 177 | * xilinx_pcie_map_bus - Get configuration base |
8961def5 ST |
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 | */ | |
029e2151 RH |
185 | static void __iomem *xilinx_pcie_map_bus(struct pci_bus *bus, |
186 | unsigned int devfn, int where) | |
8961def5 | 187 | { |
4c01f3b0 | 188 | struct xilinx_pcie_port *port = bus->sysdata; |
8961def5 ST |
189 | int relbus; |
190 | ||
029e2151 RH |
191 | if (!xilinx_pcie_valid_device(bus, devfn)) |
192 | return NULL; | |
193 | ||
8961def5 ST |
194 | relbus = (bus->number << ECAM_BUS_NUM_SHIFT) | |
195 | (devfn << ECAM_DEV_NUM_SHIFT); | |
196 | ||
197 | return port->reg_base + relbus + where; | |
198 | } | |
199 | ||
8961def5 ST |
200 | /* PCIe operations */ |
201 | static struct pci_ops xilinx_pcie_ops = { | |
029e2151 RH |
202 | .map_bus = xilinx_pcie_map_bus, |
203 | .read = pci_generic_config_read, | |
204 | .write = pci_generic_config_write, | |
8961def5 ST |
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 | { | |
8961def5 ST |
215 | struct msi_desc *msi; |
216 | struct xilinx_pcie_port *port; | |
8a4036ed BKG |
217 | struct irq_data *d = irq_get_irq_data(irq); |
218 | irq_hw_number_t hwirq = irqd_to_hwirq(d); | |
8961def5 | 219 | |
8a4036ed | 220 | if (!test_bit(hwirq, msi_irq_in_use)) { |
e39758e0 | 221 | msi = irq_get_msi_desc(irq); |
4c01f3b0 | 222 | port = msi_desc_to_pci_sysdata(msi); |
8961def5 | 223 | dev_err(port->dev, "Trying to free unused MSI#%d\n", irq); |
e39758e0 | 224 | } else { |
8a4036ed | 225 | clear_bit(hwirq, msi_irq_in_use); |
e39758e0 | 226 | } |
8961def5 ST |
227 | } |
228 | ||
229 | /** | |
230 | * xilinx_pcie_assign_msi - Allocate MSI number | |
8961def5 ST |
231 | * |
232 | * Return: A valid IRQ on success and error value on failure. | |
233 | */ | |
e59e5ff9 | 234 | static int xilinx_pcie_assign_msi(void) |
8961def5 ST |
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 | */ | |
c2791b80 YW |
252 | static void xilinx_msi_teardown_irq(struct msi_controller *chip, |
253 | unsigned int irq) | |
8961def5 ST |
254 | { |
255 | xilinx_pcie_destroy_msi(irq); | |
b328f3ce | 256 | irq_dispose_mapping(irq); |
8961def5 ST |
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 | */ | |
c2791b80 | 267 | static int xilinx_pcie_msi_setup_irq(struct msi_controller *chip, |
8961def5 ST |
268 | struct pci_dev *pdev, |
269 | struct msi_desc *desc) | |
270 | { | |
4c01f3b0 | 271 | struct xilinx_pcie_port *port = pdev->bus->sysdata; |
8961def5 ST |
272 | unsigned int irq; |
273 | int hwirq; | |
274 | struct msi_msg msg; | |
275 | phys_addr_t msg_addr; | |
276 | ||
e59e5ff9 | 277 | hwirq = xilinx_pcie_assign_msi(); |
f9dd0ce6 DC |
278 | if (hwirq < 0) |
279 | return hwirq; | |
8961def5 | 280 | |
b584fa1f | 281 | irq = irq_create_mapping(port->msi_domain, hwirq); |
8961def5 ST |
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 | ||
83a18912 | 293 | pci_write_msi_msg(irq, &msg); |
8961def5 ST |
294 | |
295 | return 0; | |
296 | } | |
297 | ||
298 | /* MSI Chip Descriptor */ | |
c2791b80 | 299 | static struct msi_controller xilinx_pcie_msi_chip = { |
8961def5 ST |
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", | |
280510f1 TG |
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, | |
8961def5 ST |
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); | |
8961def5 ST |
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 | ||
8961def5 ST |
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); | |
8961def5 ST |
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, | |
5c125683 | 371 | .xlate = pci_irqd_intx_xlate, |
8961def5 ST |
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; | |
5d07188e | 386 | struct device *dev = port->dev; |
d0b5dda6 | 387 | u32 val, mask, status; |
8961def5 ST |
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) | |
5d07188e | 398 | dev_warn(dev, "Link Down\n"); |
8961def5 ST |
399 | |
400 | if (status & XILINX_PCIE_INTR_ECRC_ERR) | |
5d07188e | 401 | dev_warn(dev, "ECRC failed\n"); |
8961def5 ST |
402 | |
403 | if (status & XILINX_PCIE_INTR_STR_ERR) | |
5d07188e | 404 | dev_warn(dev, "Streaming error\n"); |
8961def5 ST |
405 | |
406 | if (status & XILINX_PCIE_INTR_HOT_RESET) | |
5d07188e | 407 | dev_info(dev, "Hot reset\n"); |
8961def5 ST |
408 | |
409 | if (status & XILINX_PCIE_INTR_CFG_TIMEOUT) | |
5d07188e | 410 | dev_warn(dev, "ECAM access timeout\n"); |
8961def5 ST |
411 | |
412 | if (status & XILINX_PCIE_INTR_CORRECTABLE) { | |
5d07188e | 413 | dev_warn(dev, "Correctable error message\n"); |
8961def5 ST |
414 | xilinx_pcie_clear_err_interrupts(port); |
415 | } | |
416 | ||
417 | if (status & XILINX_PCIE_INTR_NONFATAL) { | |
5d07188e | 418 | dev_warn(dev, "Non fatal error message\n"); |
8961def5 ST |
419 | xilinx_pcie_clear_err_interrupts(port); |
420 | } | |
421 | ||
422 | if (status & XILINX_PCIE_INTR_FATAL) { | |
5d07188e | 423 | dev_warn(dev, "Fatal error message\n"); |
8961def5 ST |
424 | xilinx_pcie_clear_err_interrupts(port); |
425 | } | |
426 | ||
d0b5dda6 | 427 | if (status & (XILINX_PCIE_INTR_INTX | XILINX_PCIE_INTR_MSI)) { |
8961def5 ST |
428 | val = pcie_read(port, XILINX_PCIE_REG_RPIFR1); |
429 | ||
430 | /* Check whether interrupt valid */ | |
431 | if (!(val & XILINX_PCIE_RPIFR1_INTR_VALID)) { | |
5d07188e | 432 | dev_warn(dev, "RP Intr FIFO1 read error\n"); |
3cd049ab | 433 | goto error; |
8961def5 ST |
434 | } |
435 | ||
d0b5dda6 PB |
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 { | |
5c125683 PB |
441 | val = (val & XILINX_PCIE_RPIFR1_INTR_MASK) >> |
442 | XILINX_PCIE_RPIFR1_INTR_SHIFT; | |
d0b5dda6 | 443 | val = irq_find_mapping(port->leg_domain, val); |
e4a8f8ee | 444 | } |
8961def5 | 445 | |
d0b5dda6 PB |
446 | /* Clear interrupt FIFO register 1 */ |
447 | pcie_write(port, XILINX_PCIE_RPIFR1_ALL_MASK, | |
448 | XILINX_PCIE_REG_RPIFR1); | |
8961def5 | 449 | |
d0b5dda6 PB |
450 | /* Handle the interrupt */ |
451 | if (IS_ENABLED(CONFIG_PCI_MSI) || | |
452 | !(val & XILINX_PCIE_RPIFR1_MSI_INTR)) | |
453 | generic_handle_irq(val); | |
8961def5 ST |
454 | } |
455 | ||
456 | if (status & XILINX_PCIE_INTR_SLV_UNSUPP) | |
5d07188e | 457 | dev_warn(dev, "Slave unsupported request\n"); |
8961def5 ST |
458 | |
459 | if (status & XILINX_PCIE_INTR_SLV_UNEXP) | |
5d07188e | 460 | dev_warn(dev, "Slave unexpected completion\n"); |
8961def5 ST |
461 | |
462 | if (status & XILINX_PCIE_INTR_SLV_COMPL) | |
5d07188e | 463 | dev_warn(dev, "Slave completion timeout\n"); |
8961def5 ST |
464 | |
465 | if (status & XILINX_PCIE_INTR_SLV_ERRP) | |
5d07188e | 466 | dev_warn(dev, "Slave Error Poison\n"); |
8961def5 ST |
467 | |
468 | if (status & XILINX_PCIE_INTR_SLV_CMPABT) | |
5d07188e | 469 | dev_warn(dev, "Slave Completer Abort\n"); |
8961def5 ST |
470 | |
471 | if (status & XILINX_PCIE_INTR_SLV_ILLBUR) | |
5d07188e | 472 | dev_warn(dev, "Slave Illegal Burst\n"); |
8961def5 ST |
473 | |
474 | if (status & XILINX_PCIE_INTR_MST_DECERR) | |
5d07188e | 475 | dev_warn(dev, "Master decode error\n"); |
8961def5 ST |
476 | |
477 | if (status & XILINX_PCIE_INTR_MST_SLVERR) | |
5d07188e | 478 | dev_warn(dev, "Master slave error\n"); |
8961def5 ST |
479 | |
480 | if (status & XILINX_PCIE_INTR_MST_ERRP) | |
5d07188e | 481 | dev_warn(dev, "Master error poison\n"); |
8961def5 | 482 | |
3cd049ab | 483 | error: |
8961def5 ST |
484 | /* Clear the Interrupt Decode register */ |
485 | pcie_write(port, status, XILINX_PCIE_REG_IDR); | |
486 | ||
487 | return IRQ_HANDLED; | |
488 | } | |
489 | ||
8961def5 ST |
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"); | |
cec6dba2 | 506 | return -ENODEV; |
8961def5 ST |
507 | } |
508 | ||
5c125683 | 509 | port->leg_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, |
8961def5 ST |
510 | &intx_domain_ops, |
511 | port); | |
8c3f9bd8 | 512 | of_node_put(pcie_intc_node); |
b584fa1f | 513 | if (!port->leg_domain) { |
8961def5 | 514 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); |
cec6dba2 | 515 | return -ENODEV; |
8961def5 ST |
516 | } |
517 | ||
518 | /* Setup MSI */ | |
519 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | |
b584fa1f | 520 | port->msi_domain = irq_domain_add_linear(node, |
8961def5 ST |
521 | XILINX_NUM_MSI_IRQS, |
522 | &msi_domain_ops, | |
523 | &xilinx_pcie_msi_chip); | |
b584fa1f | 524 | if (!port->msi_domain) { |
8961def5 | 525 | dev_err(dev, "Failed to get a MSI IRQ domain\n"); |
cec6dba2 | 526 | return -ENODEV; |
8961def5 ST |
527 | } |
528 | ||
529 | xilinx_pcie_enable_msi(port); | |
530 | } | |
531 | ||
532 | return 0; | |
533 | } | |
534 | ||
535 | /** | |
536 | * xilinx_pcie_init_port - Initialize hardware | |
537 | * @port: PCIe port information | |
538 | */ | |
539 | static void xilinx_pcie_init_port(struct xilinx_pcie_port *port) | |
540 | { | |
5d07188e BH |
541 | struct device *dev = port->dev; |
542 | ||
1eaa8702 | 543 | if (xilinx_pcie_link_up(port)) |
5d07188e | 544 | dev_info(dev, "PCIe Link is UP\n"); |
8961def5 | 545 | else |
5d07188e | 546 | dev_info(dev, "PCIe Link is DOWN\n"); |
8961def5 ST |
547 | |
548 | /* Disable all interrupts */ | |
549 | pcie_write(port, ~XILINX_PCIE_IDR_ALL_MASK, | |
550 | XILINX_PCIE_REG_IMR); | |
551 | ||
552 | /* Clear pending interrupts */ | |
553 | pcie_write(port, pcie_read(port, XILINX_PCIE_REG_IDR) & | |
554 | XILINX_PCIE_IMR_ALL_MASK, | |
555 | XILINX_PCIE_REG_IDR); | |
556 | ||
aac2e96b PB |
557 | /* Enable all interrupts we handle */ |
558 | pcie_write(port, XILINX_PCIE_IMR_ENABLE_MASK, XILINX_PCIE_REG_IMR); | |
8961def5 ST |
559 | |
560 | /* Enable the Bridge enable bit */ | |
561 | pcie_write(port, pcie_read(port, XILINX_PCIE_REG_RPSC) | | |
562 | XILINX_PCIE_REG_RPSC_BEN, | |
563 | XILINX_PCIE_REG_RPSC); | |
564 | } | |
565 | ||
8961def5 ST |
566 | /** |
567 | * xilinx_pcie_parse_dt - Parse Device tree | |
568 | * @port: PCIe port information | |
569 | * | |
570 | * Return: '0' on success and error value on failure | |
571 | */ | |
572 | static int xilinx_pcie_parse_dt(struct xilinx_pcie_port *port) | |
573 | { | |
574 | struct device *dev = port->dev; | |
575 | struct device_node *node = dev->of_node; | |
576 | struct resource regs; | |
8961def5 ST |
577 | int err; |
578 | ||
8961def5 ST |
579 | err = of_address_to_resource(node, 0, ®s); |
580 | if (err) { | |
581 | dev_err(dev, "missing \"reg\" property\n"); | |
582 | return err; | |
583 | } | |
584 | ||
eb21f9e8 | 585 | port->reg_base = devm_pci_remap_cfg_resource(dev, ®s); |
8961def5 ST |
586 | if (IS_ERR(port->reg_base)) |
587 | return PTR_ERR(port->reg_base); | |
588 | ||
589 | port->irq = irq_of_parse_and_map(node, 0); | |
590 | err = devm_request_irq(dev, port->irq, xilinx_pcie_intr_handler, | |
8ff0ef99 GS |
591 | IRQF_SHARED | IRQF_NO_THREAD, |
592 | "xilinx-pcie", port); | |
8961def5 ST |
593 | if (err) { |
594 | dev_err(dev, "unable to request irq %d\n", port->irq); | |
595 | return err; | |
596 | } | |
597 | ||
598 | return 0; | |
599 | } | |
600 | ||
601 | /** | |
602 | * xilinx_pcie_probe - Probe function | |
603 | * @pdev: Platform device pointer | |
604 | * | |
605 | * Return: '0' on success and error value on failure | |
606 | */ | |
607 | static int xilinx_pcie_probe(struct platform_device *pdev) | |
608 | { | |
8961def5 | 609 | struct device *dev = &pdev->dev; |
5d07188e | 610 | struct xilinx_pcie_port *port; |
ec6bd78a | 611 | struct pci_bus *bus, *child; |
8c790a82 | 612 | struct pci_host_bridge *bridge; |
8961def5 | 613 | int err; |
0259882e BKG |
614 | resource_size_t iobase = 0; |
615 | LIST_HEAD(res); | |
8961def5 ST |
616 | |
617 | if (!dev->of_node) | |
618 | return -ENODEV; | |
619 | ||
8c790a82 LP |
620 | bridge = devm_pci_alloc_host_bridge(dev, sizeof(*port)); |
621 | if (!bridge) | |
622 | return -ENODEV; | |
623 | ||
624 | port = pci_host_bridge_priv(bridge); | |
8961def5 ST |
625 | |
626 | port->dev = dev; | |
627 | ||
628 | err = xilinx_pcie_parse_dt(port); | |
629 | if (err) { | |
630 | dev_err(dev, "Parsing DT failed\n"); | |
631 | return err; | |
632 | } | |
633 | ||
634 | xilinx_pcie_init_port(port); | |
635 | ||
636 | err = xilinx_pcie_init_irq_domain(port); | |
637 | if (err) { | |
638 | dev_err(dev, "Failed creating IRQ Domain\n"); | |
639 | return err; | |
640 | } | |
641 | ||
5bd51b35 | 642 | err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &res, |
055f87a2 | 643 | &iobase); |
8961def5 | 644 | if (err) { |
0259882e | 645 | dev_err(dev, "Getting bridge resources failed\n"); |
8961def5 ST |
646 | return err; |
647 | } | |
93a5b5e5 BH |
648 | |
649 | err = devm_request_pci_bus_resources(dev, &res); | |
650 | if (err) | |
651 | goto error; | |
652 | ||
8c790a82 LP |
653 | |
654 | list_splice_init(&res, &bridge->windows); | |
655 | bridge->dev.parent = dev; | |
656 | bridge->sysdata = port; | |
657 | bridge->busnr = 0; | |
658 | bridge->ops = &xilinx_pcie_ops; | |
cc2eaaef LP |
659 | bridge->map_irq = of_irq_parse_and_map_pci; |
660 | bridge->swizzle_irq = pci_common_swizzle; | |
8dd26dc8 YW |
661 | |
662 | #ifdef CONFIG_PCI_MSI | |
5d07188e | 663 | xilinx_pcie_msi_chip.dev = dev; |
8c790a82 | 664 | bridge->msi = &xilinx_pcie_msi_chip; |
8dd26dc8 | 665 | #endif |
8c790a82 LP |
666 | err = pci_scan_root_bus_bridge(bridge); |
667 | if (err < 0) | |
668 | goto error; | |
669 | ||
670 | bus = bridge->bus; | |
671 | ||
4c01f3b0 | 672 | pci_assign_unassigned_bus_resources(bus); |
ec6bd78a BH |
673 | list_for_each_entry(child, &bus->children, node) |
674 | pcie_bus_configure_settings(child); | |
4c01f3b0 | 675 | pci_bus_add_devices(bus); |
8961def5 | 676 | return 0; |
c41be7a6 BH |
677 | |
678 | error: | |
679 | pci_free_resource_list(&res); | |
680 | return err; | |
8961def5 ST |
681 | } |
682 | ||
fdc71ce9 | 683 | static const struct of_device_id xilinx_pcie_of_match[] = { |
8961def5 ST |
684 | { .compatible = "xlnx,axi-pcie-host-1.00.a", }, |
685 | {} | |
686 | }; | |
687 | ||
688 | static struct platform_driver xilinx_pcie_driver = { | |
689 | .driver = { | |
690 | .name = "xilinx-pcie", | |
8961def5 ST |
691 | .of_match_table = xilinx_pcie_of_match, |
692 | .suppress_bind_attrs = true, | |
693 | }, | |
694 | .probe = xilinx_pcie_probe, | |
8961def5 | 695 | }; |
da4eafca | 696 | builtin_platform_driver(xilinx_pcie_driver); |