blob: d6d3a9e202505d00d09152c8223e6fa93b6e6779 [file] [log] [blame]
Srinath Mannam48487042020-05-12 13:29:50 +05301// SPDX-License-Identifier: GPL-2.0+
2/*
Bharat Gooty2cb32602021-08-23 14:57:24 +05303 * Copyright (C) 2020-2021 Broadcom
Srinath Mannam48487042020-05-12 13:29:50 +05304 *
5 */
6
7#include <common.h>
8#include <dm.h>
9#include <errno.h>
10#include <generic-phy.h>
11#include <pci.h>
12#include <malloc.h>
13#include <asm/io.h>
14#include <dm/device_compat.h>
Bharat Gooty2cb32602021-08-23 14:57:24 +053015#include <linux/delay.h>
Srinath Mannam48487042020-05-12 13:29:50 +053016#include <linux/log2.h>
17
18#define EP_PERST_SOURCE_SELECT_SHIFT 2
19#define EP_PERST_SOURCE_SELECT BIT(EP_PERST_SOURCE_SELECT_SHIFT)
20#define EP_MODE_SURVIVE_PERST_SHIFT 1
21#define EP_MODE_SURVIVE_PERST BIT(EP_MODE_SURVIVE_PERST_SHIFT)
22#define RC_PCIE_RST_OUTPUT_SHIFT 0
23#define RC_PCIE_RST_OUTPUT BIT(RC_PCIE_RST_OUTPUT_SHIFT)
24
25#define CFG_IND_ADDR_MASK 0x00001ffc
26
Pali Rohár3264b612021-11-24 18:00:32 +010027#define CFG_ADDR_CFG_ECAM_MASK 0xfffffffc
Srinath Mannam48487042020-05-12 13:29:50 +053028#define CFG_ADDR_CFG_TYPE_MASK 0x00000003
29
30#define IPROC_PCI_PM_CAP 0x48
31#define IPROC_PCI_PM_CAP_MASK 0xffff
32#define IPROC_PCI_EXP_CAP 0xac
33
34#define IPROC_PCIE_REG_INVALID 0xffff
35
36#define PCI_EXP_TYPE_ROOT_PORT 0x4 /* Root Port */
37#define PCI_EXP_RTCTL 28 /* Root Control */
38/* CRS Software Visibility capability */
39#define PCI_EXP_RTCAP_CRSVIS 0x0001
40
41#define PCI_EXP_LNKSTA 18 /* Link Status */
42#define PCI_EXP_LNKSTA_NLW 0x03f0 /* Negotiated Link Width */
43
44#define PCIE_PHYLINKUP_SHIFT 3
45#define PCIE_PHYLINKUP BIT(PCIE_PHYLINKUP_SHIFT)
46#define PCIE_DL_ACTIVE_SHIFT 2
47#define PCIE_DL_ACTIVE BIT(PCIE_DL_ACTIVE_SHIFT)
48
49/* derive the enum index of the outbound/inbound mapping registers */
50#define MAP_REG(base_reg, index) ((base_reg) + (index) * 2)
51
52/*
53 * Maximum number of outbound mapping window sizes that can be supported by any
54 * OARR/OMAP mapping pair
55 */
56#define MAX_NUM_OB_WINDOW_SIZES 4
57
58#define OARR_VALID_SHIFT 0
59#define OARR_VALID BIT(OARR_VALID_SHIFT)
60#define OARR_SIZE_CFG_SHIFT 1
61
62/*
63 * Maximum number of inbound mapping region sizes that can be supported by an
64 * IARR
65 */
66#define MAX_NUM_IB_REGION_SIZES 9
67
68#define IMAP_VALID_SHIFT 0
69#define IMAP_VALID BIT(IMAP_VALID_SHIFT)
70
71#define APB_ERR_EN_SHIFT 0
72#define APB_ERR_EN BIT(APB_ERR_EN_SHIFT)
73
74/**
75 * iProc PCIe host registers
76 */
77enum iproc_pcie_reg {
78 /* clock/reset signal control */
79 IPROC_PCIE_CLK_CTRL = 0,
80
81 /*
82 * To allow MSI to be steered to an external MSI controller (e.g., ARM
83 * GICv3 ITS)
84 */
85 IPROC_PCIE_MSI_GIC_MODE,
86
87 /*
88 * IPROC_PCIE_MSI_BASE_ADDR and IPROC_PCIE_MSI_WINDOW_SIZE define the
89 * window where the MSI posted writes are written, for the writes to be
90 * interpreted as MSI writes.
91 */
92 IPROC_PCIE_MSI_BASE_ADDR,
93 IPROC_PCIE_MSI_WINDOW_SIZE,
94
95 /*
96 * To hold the address of the register where the MSI writes are
97 * programed. When ARM GICv3 ITS is used, this should be programmed
98 * with the address of the GITS_TRANSLATER register.
99 */
100 IPROC_PCIE_MSI_ADDR_LO,
101 IPROC_PCIE_MSI_ADDR_HI,
102
103 /* enable MSI */
104 IPROC_PCIE_MSI_EN_CFG,
105
106 /* allow access to root complex configuration space */
107 IPROC_PCIE_CFG_IND_ADDR,
108 IPROC_PCIE_CFG_IND_DATA,
109
110 /* allow access to device configuration space */
111 IPROC_PCIE_CFG_ADDR,
112 IPROC_PCIE_CFG_DATA,
113
114 /* enable INTx */
115 IPROC_PCIE_INTX_EN,
116 IPROC_PCIE_INTX_CSR,
117
118 /* outbound address mapping */
119 IPROC_PCIE_OARR0,
120 IPROC_PCIE_OMAP0,
121 IPROC_PCIE_OARR1,
122 IPROC_PCIE_OMAP1,
123 IPROC_PCIE_OARR2,
124 IPROC_PCIE_OMAP2,
125 IPROC_PCIE_OARR3,
126 IPROC_PCIE_OMAP3,
127
128 /* inbound address mapping */
129 IPROC_PCIE_IARR0,
130 IPROC_PCIE_IMAP0,
131 IPROC_PCIE_IARR1,
132 IPROC_PCIE_IMAP1,
133 IPROC_PCIE_IARR2,
134 IPROC_PCIE_IMAP2,
135 IPROC_PCIE_IARR3,
136 IPROC_PCIE_IMAP3,
137 IPROC_PCIE_IARR4,
138 IPROC_PCIE_IMAP4,
139
140 /* config read status */
141 IPROC_PCIE_CFG_RD_STATUS,
142
143 /* link status */
144 IPROC_PCIE_LINK_STATUS,
145
146 /* enable APB error for unsupported requests */
147 IPROC_PCIE_APB_ERR_EN,
148
149 /* Ordering Mode configuration registers */
150 IPROC_PCIE_ORDERING_CFG,
151 IPROC_PCIE_IMAP0_RO_CONTROL,
152 IPROC_PCIE_IMAP1_RO_CONTROL,
153 IPROC_PCIE_IMAP2_RO_CONTROL,
154 IPROC_PCIE_IMAP3_RO_CONTROL,
155 IPROC_PCIE_IMAP4_RO_CONTROL,
156
157 /* total number of core registers */
158 IPROC_PCIE_MAX_NUM_REG,
159};
160
161/* iProc PCIe PAXB v2 registers */
162static const u16 iproc_pcie_reg_paxb_v2[] = {
163 [IPROC_PCIE_CLK_CTRL] = 0x000,
164 [IPROC_PCIE_CFG_IND_ADDR] = 0x120,
165 [IPROC_PCIE_CFG_IND_DATA] = 0x124,
166 [IPROC_PCIE_CFG_ADDR] = 0x1f8,
167 [IPROC_PCIE_CFG_DATA] = 0x1fc,
168 [IPROC_PCIE_INTX_EN] = 0x330,
169 [IPROC_PCIE_INTX_CSR] = 0x334,
170 [IPROC_PCIE_OARR0] = 0xd20,
171 [IPROC_PCIE_OMAP0] = 0xd40,
172 [IPROC_PCIE_OARR1] = 0xd28,
173 [IPROC_PCIE_OMAP1] = 0xd48,
174 [IPROC_PCIE_OARR2] = 0xd60,
175 [IPROC_PCIE_OMAP2] = 0xd68,
176 [IPROC_PCIE_OARR3] = 0xdf0,
177 [IPROC_PCIE_OMAP3] = 0xdf8,
178 [IPROC_PCIE_IARR0] = 0xd00,
179 [IPROC_PCIE_IMAP0] = 0xc00,
180 [IPROC_PCIE_IARR2] = 0xd10,
181 [IPROC_PCIE_IMAP2] = 0xcc0,
182 [IPROC_PCIE_IARR3] = 0xe00,
183 [IPROC_PCIE_IMAP3] = 0xe08,
184 [IPROC_PCIE_IARR4] = 0xe68,
185 [IPROC_PCIE_IMAP4] = 0xe70,
186 [IPROC_PCIE_CFG_RD_STATUS] = 0xee0,
187 [IPROC_PCIE_LINK_STATUS] = 0xf0c,
188 [IPROC_PCIE_APB_ERR_EN] = 0xf40,
189 [IPROC_PCIE_ORDERING_CFG] = 0x2000,
190 [IPROC_PCIE_IMAP0_RO_CONTROL] = 0x201c,
191 [IPROC_PCIE_IMAP1_RO_CONTROL] = 0x2020,
192 [IPROC_PCIE_IMAP2_RO_CONTROL] = 0x2024,
193 [IPROC_PCIE_IMAP3_RO_CONTROL] = 0x2028,
194 [IPROC_PCIE_IMAP4_RO_CONTROL] = 0x202c,
195};
196
197/* iProc PCIe PAXC v2 registers */
198static const u16 iproc_pcie_reg_paxc_v2[] = {
199 [IPROC_PCIE_MSI_GIC_MODE] = 0x050,
200 [IPROC_PCIE_MSI_BASE_ADDR] = 0x074,
201 [IPROC_PCIE_MSI_WINDOW_SIZE] = 0x078,
202 [IPROC_PCIE_MSI_ADDR_LO] = 0x07c,
203 [IPROC_PCIE_MSI_ADDR_HI] = 0x080,
204 [IPROC_PCIE_MSI_EN_CFG] = 0x09c,
205 [IPROC_PCIE_CFG_IND_ADDR] = 0x1f0,
206 [IPROC_PCIE_CFG_IND_DATA] = 0x1f4,
207 [IPROC_PCIE_CFG_ADDR] = 0x1f8,
208 [IPROC_PCIE_CFG_DATA] = 0x1fc,
209};
210
211/**
212 * List of device IDs of controllers that have corrupted
213 * capability list that require SW fixup
214 */
215static const u16 iproc_pcie_corrupt_cap_did[] = {
216 0x16cd,
217 0x16f0,
218 0xd802,
219 0xd804
220};
221
222enum iproc_pcie_type {
223 IPROC_PCIE_PAXB_V2,
224 IPROC_PCIE_PAXC,
225 IPROC_PCIE_PAXC_V2,
226};
227
228/**
229 * struct iproc_pcie_ob - iProc PCIe outbound mapping
230 *
231 * @axi_offset: offset from the AXI address to the internal address used by
232 * the iProc PCIe core
233 * @nr_windows: total number of supported outbound mapping windows
234 */
235struct iproc_pcie_ob {
236 resource_size_t axi_offset;
237 unsigned int nr_windows;
238};
239
240/**
241 * struct iproc_pcie_ib - iProc PCIe inbound mapping
242 *
243 * @nr_regions: total number of supported inbound mapping regions
244 */
245struct iproc_pcie_ib {
246 unsigned int nr_regions;
247};
248
249/**
250 * struct iproc_pcie_ob_map - outbound mapping controller specific parameters
251 *
252 * @window_sizes: list of supported outbound mapping window sizes in MB
253 * @nr_sizes: number of supported outbound mapping window sizes
254 */
255struct iproc_pcie_ob_map {
256 resource_size_t window_sizes[MAX_NUM_OB_WINDOW_SIZES];
257 unsigned int nr_sizes;
258};
259
260static const struct iproc_pcie_ob_map paxb_v2_ob_map[] = {
261 {
262 /* OARR0/OMAP0 */
263 .window_sizes = { 128, 256 },
264 .nr_sizes = 2,
265 },
266 {
267 /* OARR1/OMAP1 */
268 .window_sizes = { 128, 256 },
269 .nr_sizes = 2,
270 },
271 {
272 /* OARR2/OMAP2 */
273 .window_sizes = { 128, 256, 512, 1024 },
274 .nr_sizes = 4,
275 },
276 {
277 /* OARR3/OMAP3 */
278 .window_sizes = { 128, 256, 512, 1024 },
279 .nr_sizes = 4,
280 },
281};
282
283/**
284 * iProc PCIe inbound mapping type
285 */
286enum iproc_pcie_ib_map_type {
287 /* for DDR memory */
288 IPROC_PCIE_IB_MAP_MEM = 0,
289
290 /* for device I/O memory */
291 IPROC_PCIE_IB_MAP_IO,
292
293 /* invalid or unused */
294 IPROC_PCIE_IB_MAP_INVALID
295};
296
297/**
298 * struct iproc_pcie_ib_map - inbound mapping controller specific parameters
299 *
300 * @type: inbound mapping region type
301 * @size_unit: inbound mapping region size unit, could be SZ_1K, SZ_1M, or SZ_1G
302 * @region_sizes: list of supported inbound mapping region sizes in KB, MB, or
303 * GB, depedning on the size unit
304 * @nr_sizes: number of supported inbound mapping region sizes
305 * @nr_windows: number of supported inbound mapping windows for the region
306 * @imap_addr_offset: register offset between the upper and lower 32-bit
307 * IMAP address registers
308 * @imap_window_offset: register offset between each IMAP window
309 */
310struct iproc_pcie_ib_map {
311 enum iproc_pcie_ib_map_type type;
312 unsigned int size_unit;
313 resource_size_t region_sizes[MAX_NUM_IB_REGION_SIZES];
314 unsigned int nr_sizes;
315 unsigned int nr_windows;
316 u16 imap_addr_offset;
317 u16 imap_window_offset;
318};
319
320static const struct iproc_pcie_ib_map paxb_v2_ib_map[] = {
321 {
322 /* IARR0/IMAP0 */
323 .type = IPROC_PCIE_IB_MAP_IO,
324 .size_unit = SZ_1K,
325 .region_sizes = { 32 },
326 .nr_sizes = 1,
327 .nr_windows = 8,
328 .imap_addr_offset = 0x40,
329 .imap_window_offset = 0x4,
330 },
331 {
332 /* IARR1/IMAP1 (currently unused) */
333 .type = IPROC_PCIE_IB_MAP_INVALID,
334 },
335 {
336 /* IARR2/IMAP2 */
337 .type = IPROC_PCIE_IB_MAP_MEM,
338 .size_unit = SZ_1M,
339 .region_sizes = { 64, 128, 256, 512, 1024, 2048, 4096, 8192,
340 16384 },
341 .nr_sizes = 9,
342 .nr_windows = 1,
343 .imap_addr_offset = 0x4,
344 .imap_window_offset = 0x8,
345 },
346 {
347 /* IARR3/IMAP3 */
348 .type = IPROC_PCIE_IB_MAP_MEM,
349 .size_unit = SZ_1G,
350 .region_sizes = { 1, 2, 4, 8, 16, 32 },
351 .nr_sizes = 6,
352 .nr_windows = 8,
353 .imap_addr_offset = 0x4,
354 .imap_window_offset = 0x8,
355 },
356 {
357 /* IARR4/IMAP4 */
358 .type = IPROC_PCIE_IB_MAP_MEM,
359 .size_unit = SZ_1G,
360 .region_sizes = { 32, 64, 128, 256, 512 },
361 .nr_sizes = 5,
362 .nr_windows = 8,
363 .imap_addr_offset = 0x4,
364 .imap_window_offset = 0x8,
365 },
366};
367
368/**
369 * struct iproc_pcie - iproc pcie device instance
370 *
371 * @dev: pointer to pcie udevice
372 * @base: device I/O base address
373 * @type: pci device type, PAXC or PAXB
374 * @reg_offsets: pointer to pcie host register
375 * @fix_paxc_cap: paxc capability
376 * @need_ob_cfg: outbound mapping status
377 * @ob: pcie outbound mapping
378 * @ob_map: pointer to outbound mapping parameters
379 * @need_ib_cfg: inbound mapping status
380 * @ib: pcie inbound mapping
381 * @ib_map: pointer to inbound mapping parameters
382 * @ep_is_internal: ep status
383 * @phy: phy device
384 * @link_is_active: link up status
385 * @has_apb_err_disable: apb error status
386 */
387struct iproc_pcie {
388 struct udevice *dev;
389 void __iomem *base;
390 enum iproc_pcie_type type;
391 u16 *reg_offsets;
392 bool fix_paxc_cap;
393 bool need_ob_cfg;
394 struct iproc_pcie_ob ob;
395 const struct iproc_pcie_ob_map *ob_map;
396 bool need_ib_cfg;
397 struct iproc_pcie_ib ib;
398 const struct iproc_pcie_ib_map *ib_map;
399 bool ep_is_internal;
400 struct phy phy;
401 bool link_is_active;
402 bool has_apb_err_disable;
403};
404
405static inline bool iproc_pcie_reg_is_invalid(u16 reg_offset)
406{
407 return !!(reg_offset == IPROC_PCIE_REG_INVALID);
408}
409
410static inline u16 iproc_pcie_reg_offset(struct iproc_pcie *pcie,
411 enum iproc_pcie_reg reg)
412{
413 return pcie->reg_offsets[reg];
414}
415
416static inline u32 iproc_pcie_read_reg(struct iproc_pcie *pcie,
417 enum iproc_pcie_reg reg)
418{
419 u16 offset = iproc_pcie_reg_offset(pcie, reg);
420
421 if (iproc_pcie_reg_is_invalid(offset))
422 return 0;
423
424 return readl(pcie->base + offset);
425}
426
427static inline void iproc_pcie_write_reg(struct iproc_pcie *pcie,
428 enum iproc_pcie_reg reg, u32 val)
429{
430 u16 offset = iproc_pcie_reg_offset(pcie, reg);
431
432 if (iproc_pcie_reg_is_invalid(offset))
433 return;
434
435 writel(val, pcie->base + offset);
436}
437
438static int iproc_pcie_map_ep_cfg_reg(const struct udevice *udev, pci_dev_t bdf,
439 uint where, void **paddress)
440{
441 struct iproc_pcie *pcie = dev_get_priv(udev);
442 unsigned int busno = PCI_BUS(bdf);
443 unsigned int slot = PCI_DEV(bdf);
444 unsigned int fn = PCI_FUNC(bdf);
445
446 u16 offset;
447 u32 val;
448
449 /* root complex access */
450 if (busno == 0) {
451 if (slot > 0 || fn > 0)
452 return -ENODEV;
453
454 iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_IND_ADDR,
455 where & CFG_IND_ADDR_MASK);
456 offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_IND_DATA);
457 if (iproc_pcie_reg_is_invalid(offset))
458 return -ENODEV;
459
460 *paddress = (pcie->base + offset);
461 return 0;
462 }
463
464 if (!pcie->link_is_active)
465 return -ENODEV;
466
467 /* EP device access */
Pali Rohár3264b612021-11-24 18:00:32 +0100468 val = (PCIE_ECAM_OFFSET(busno, slot, fn, where) & CFG_ADDR_CFG_ECAM_MASK)
469 | (1 & CFG_ADDR_CFG_TYPE_MASK);
Srinath Mannam48487042020-05-12 13:29:50 +0530470
471 iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_ADDR, val);
472 offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_DATA);
473
474 if (iproc_pcie_reg_is_invalid(offset))
475 return -ENODEV;
476
477 *paddress = (pcie->base + offset);
478
479 return 0;
480}
481
482static void iproc_pcie_fix_cap(struct iproc_pcie *pcie, int where, ulong *val)
483{
484 u32 i, dev_id;
485
486 switch (where & ~0x3) {
487 case PCI_VENDOR_ID:
488 dev_id = *val >> 16;
489
490 /*
491 * Activate fixup for those controllers that have corrupted
492 * capability list registers
493 */
494 for (i = 0; i < ARRAY_SIZE(iproc_pcie_corrupt_cap_did); i++)
495 if (dev_id == iproc_pcie_corrupt_cap_did[i])
496 pcie->fix_paxc_cap = true;
497 break;
498
499 case IPROC_PCI_PM_CAP:
500 if (pcie->fix_paxc_cap) {
501 /* advertise PM, force next capability to PCIe */
502 *val &= ~IPROC_PCI_PM_CAP_MASK;
503 *val |= IPROC_PCI_EXP_CAP << 8 | PCI_CAP_ID_PM;
504 }
505 break;
506
507 case IPROC_PCI_EXP_CAP:
508 if (pcie->fix_paxc_cap) {
509 /* advertise root port, version 2, terminate here */
510 *val = (PCI_EXP_TYPE_ROOT_PORT << 4 | 2) << 16 |
511 PCI_CAP_ID_EXP;
512 }
513 break;
514
515 case IPROC_PCI_EXP_CAP + PCI_EXP_RTCTL:
516 /* Don't advertise CRS SV support */
517 *val &= ~(PCI_EXP_RTCAP_CRSVIS << 16);
518 break;
519
520 default:
521 break;
522 }
523}
524
525static int iproc_pci_raw_config_read32(struct iproc_pcie *pcie,
526 unsigned int devfn, int where,
527 int size, u32 *val)
528{
529 void __iomem *addr;
530 int ret;
531
532 ret = iproc_pcie_map_ep_cfg_reg(pcie->dev, devfn, where & ~0x3, &addr);
533 if (ret) {
534 *val = ~0;
535 return -EINVAL;
536 }
537
538 *val = readl(addr);
539
540 if (size <= 2)
541 *val = (*val >> (8 * (where & 3))) & ((1 << (size * 8)) - 1);
542
543 return 0;
544}
545
546static int iproc_pci_raw_config_write32(struct iproc_pcie *pcie,
547 unsigned int devfn, int where,
548 int size, u32 val)
549{
550 void __iomem *addr;
551 int ret;
552 u32 mask, tmp;
553
554 ret = iproc_pcie_map_ep_cfg_reg(pcie->dev, devfn, where & ~0x3, &addr);
555 if (ret)
556 return -EINVAL;
557
558 if (size == 4) {
559 writel(val, addr);
560 return 0;
561 }
562
563 mask = ~(((1 << (size * 8)) - 1) << ((where & 0x3) * 8));
564 tmp = readl(addr) & mask;
565 tmp |= val << ((where & 0x3) * 8);
566 writel(tmp, addr);
567 return 0;
568}
569
570/**
571 * iproc_pcie_apb_err_disable() - configure apb error
572 *
573 * APB error forwarding can be disabled during access of configuration
574 * registers of the endpoint device, to prevent unsupported requests
575 * (typically seen during enumeration with multi-function devices) from
576 * triggering a system exception.
577 *
578 * @bus: pcie udevice
579 * @bdf: pdf value
580 * @disabled: flag to enable/disabled apb error
581 */
582static inline void iproc_pcie_apb_err_disable(const struct udevice *bus,
583 pci_dev_t bdf, bool disable)
584{
585 struct iproc_pcie *pcie = dev_get_priv(bus);
586 u32 val;
587
588 if (PCI_BUS(bdf) && pcie->has_apb_err_disable) {
589 val = iproc_pcie_read_reg(pcie, IPROC_PCIE_APB_ERR_EN);
590 if (disable)
591 val &= ~APB_ERR_EN;
592 else
593 val |= APB_ERR_EN;
594 iproc_pcie_write_reg(pcie, IPROC_PCIE_APB_ERR_EN, val);
595 }
596}
597
598static int iproc_pcie_config_read32(const struct udevice *bus, pci_dev_t bdf,
599 uint offset, ulong *valuep,
600 enum pci_size_t size)
601{
602 struct iproc_pcie *pcie = dev_get_priv(bus);
603 int ret;
604 ulong data;
605
606 iproc_pcie_apb_err_disable(bus, bdf, true);
607 ret = pci_generic_mmap_read_config(bus, iproc_pcie_map_ep_cfg_reg,
608 bdf, offset, &data, PCI_SIZE_32);
609 iproc_pcie_apb_err_disable(bus, bdf, false);
610 if (size <= PCI_SIZE_16)
611 *valuep = (data >> (8 * (offset & 3))) &
612 ((1 << (BIT(size) * 8)) - 1);
613 else
614 *valuep = data;
615
616 if (!ret && PCI_BUS(bdf) == 0)
617 iproc_pcie_fix_cap(pcie, offset, valuep);
618
619 return ret;
620}
621
622static int iproc_pcie_config_write32(struct udevice *bus, pci_dev_t bdf,
623 uint offset, ulong value,
624 enum pci_size_t size)
625{
626 void *addr;
627 ulong mask, tmp;
628 int ret;
629
630 ret = iproc_pcie_map_ep_cfg_reg(bus, bdf, offset, &addr);
631 if (ret)
632 return ret;
633
634 if (size == PCI_SIZE_32) {
635 writel(value, addr);
636 return ret;
637 }
638
639 iproc_pcie_apb_err_disable(bus, bdf, true);
640 mask = ~(((1 << (BIT(size) * 8)) - 1) << ((offset & 0x3) * 8));
641 tmp = readl(addr) & mask;
642 tmp |= (value << ((offset & 0x3) * 8));
643 writel(tmp, addr);
644 iproc_pcie_apb_err_disable(bus, bdf, false);
645
646 return ret;
647}
648
649const static struct dm_pci_ops iproc_pcie_ops = {
650 .read_config = iproc_pcie_config_read32,
651 .write_config = iproc_pcie_config_write32,
652};
653
654static int iproc_pcie_rev_init(struct iproc_pcie *pcie)
655{
656 unsigned int reg_idx;
657 const u16 *regs;
658 u16 num_elements;
659
660 switch (pcie->type) {
661 case IPROC_PCIE_PAXC_V2:
662 pcie->ep_is_internal = true;
663 regs = iproc_pcie_reg_paxc_v2;
664 num_elements = ARRAY_SIZE(iproc_pcie_reg_paxc_v2);
665 break;
666 case IPROC_PCIE_PAXB_V2:
667 regs = iproc_pcie_reg_paxb_v2;
668 num_elements = ARRAY_SIZE(iproc_pcie_reg_paxb_v2);
669 pcie->has_apb_err_disable = true;
670 if (pcie->need_ob_cfg) {
671 pcie->ob.axi_offset = 0;
672 pcie->ob_map = paxb_v2_ob_map;
673 pcie->ob.nr_windows = ARRAY_SIZE(paxb_v2_ob_map);
674 }
675 pcie->need_ib_cfg = true;
676 pcie->ib.nr_regions = ARRAY_SIZE(paxb_v2_ib_map);
677 pcie->ib_map = paxb_v2_ib_map;
678 break;
679 default:
680 dev_dbg(pcie->dev, "incompatible iProc PCIe interface\n");
681 return -EINVAL;
682 }
683
684 pcie->reg_offsets = calloc(IPROC_PCIE_MAX_NUM_REG,
685 sizeof(*pcie->reg_offsets));
686 if (!pcie->reg_offsets)
687 return -ENOMEM;
688
689 /* go through the register table and populate all valid registers */
690 pcie->reg_offsets[0] = (pcie->type == IPROC_PCIE_PAXC_V2) ?
691 IPROC_PCIE_REG_INVALID : regs[0];
692 for (reg_idx = 1; reg_idx < num_elements; reg_idx++)
693 pcie->reg_offsets[reg_idx] = regs[reg_idx] ?
694 regs[reg_idx] : IPROC_PCIE_REG_INVALID;
695
696 return 0;
697}
698
699static inline bool iproc_pcie_ob_is_valid(struct iproc_pcie *pcie,
700 int window_idx)
701{
702 u32 val;
703
704 val = iproc_pcie_read_reg(pcie, MAP_REG(IPROC_PCIE_OARR0, window_idx));
705
706 return !!(val & OARR_VALID);
707}
708
709static inline int iproc_pcie_ob_write(struct iproc_pcie *pcie, int window_idx,
710 int size_idx, u64 axi_addr, u64 pci_addr)
711{
712 u16 oarr_offset, omap_offset;
713
714 /*
715 * Derive the OARR/OMAP offset from the first pair (OARR0/OMAP0) based
716 * on window index.
717 */
718 oarr_offset = iproc_pcie_reg_offset(pcie, MAP_REG(IPROC_PCIE_OARR0,
719 window_idx));
720 omap_offset = iproc_pcie_reg_offset(pcie, MAP_REG(IPROC_PCIE_OMAP0,
721 window_idx));
722 if (iproc_pcie_reg_is_invalid(oarr_offset) ||
723 iproc_pcie_reg_is_invalid(omap_offset))
724 return -EINVAL;
725
726 /*
727 * Program the OARR registers. The upper 32-bit OARR register is
728 * always right after the lower 32-bit OARR register.
729 */
730 writel(lower_32_bits(axi_addr) | (size_idx << OARR_SIZE_CFG_SHIFT) |
731 OARR_VALID, pcie->base + oarr_offset);
732 writel(upper_32_bits(axi_addr), pcie->base + oarr_offset + 4);
733
734 /* now program the OMAP registers */
735 writel(lower_32_bits(pci_addr), pcie->base + omap_offset);
736 writel(upper_32_bits(pci_addr), pcie->base + omap_offset + 4);
737
738 debug("ob window [%d]: offset 0x%x axi %pap pci %pap\n",
739 window_idx, oarr_offset, &axi_addr, &pci_addr);
740 debug("oarr lo 0x%x oarr hi 0x%x\n",
741 readl(pcie->base + oarr_offset),
742 readl(pcie->base + oarr_offset + 4));
743 debug("omap lo 0x%x omap hi 0x%x\n",
744 readl(pcie->base + omap_offset),
745 readl(pcie->base + omap_offset + 4));
746
747 return 0;
748}
749
750/**
751 * iproc_pcie_setup_ob() - setup outbound address mapping
752 *
753 * Some iProc SoCs require the SW to configure the outbound address mapping
754 * Outbound address translation:
755 *
756 * iproc_pcie_address = axi_address - axi_offset
757 * OARR = iproc_pcie_address
758 * OMAP = pci_addr
759 * axi_addr -> iproc_pcie_address -> OARR -> OMAP -> pci_address
760 *
761 * @pcie: pcie device
762 * @axi_addr: axi address to be translated
763 * @pci_addr: pci address
764 * @size: window size
765 *
766 * @return: 0 on success and -ve on failure
767 */
768static int iproc_pcie_setup_ob(struct iproc_pcie *pcie, u64 axi_addr,
769 u64 pci_addr, resource_size_t size)
770{
771 struct iproc_pcie_ob *ob = &pcie->ob;
772 int ret = -EINVAL, window_idx, size_idx;
773
774 if (axi_addr < ob->axi_offset) {
775 pr_err("axi address %pap less than offset %pap\n",
776 &axi_addr, &ob->axi_offset);
777 return -EINVAL;
778 }
779
780 /*
781 * Translate the AXI address to the internal address used by the iProc
782 * PCIe core before programming the OARR
783 */
784 axi_addr -= ob->axi_offset;
785
786 /* iterate through all OARR/OMAP mapping windows */
787 for (window_idx = ob->nr_windows - 1; window_idx >= 0; window_idx--) {
788 const struct iproc_pcie_ob_map *ob_map =
789 &pcie->ob_map[window_idx];
790
791 /*
792 * If current outbound window is already in use, move on to the
793 * next one.
794 */
795 if (iproc_pcie_ob_is_valid(pcie, window_idx))
796 continue;
797
798 /*
799 * Iterate through all supported window sizes within the
800 * OARR/OMAP pair to find a match. Go through the window sizes
801 * in a descending order.
802 */
803 for (size_idx = ob_map->nr_sizes - 1; size_idx >= 0;
804 size_idx--) {
805 resource_size_t window_size =
806 ob_map->window_sizes[size_idx] * SZ_1M;
807
808 /*
809 * Keep iterating until we reach the last window and
810 * with the minimal window size at index zero. In this
811 * case, we take a compromise by mapping it using the
812 * minimum window size that can be supported
813 */
814 if (size < window_size) {
815 if (size_idx > 0 || window_idx > 0)
816 continue;
817
818 /*
819 * For the corner case of reaching the minimal
820 * window size that can be supported on the
821 * last window
822 */
823 axi_addr = ALIGN_DOWN(axi_addr, window_size);
824 pci_addr = ALIGN_DOWN(pci_addr, window_size);
825 size = window_size;
826 }
827
828 if (!IS_ALIGNED(axi_addr, window_size) ||
829 !IS_ALIGNED(pci_addr, window_size)) {
830 pr_err("axi %pap or pci %pap not aligned\n",
831 &axi_addr, &pci_addr);
832 return -EINVAL;
833 }
834
835 /*
836 * Match found! Program both OARR and OMAP and mark
837 * them as a valid entry.
838 */
839 ret = iproc_pcie_ob_write(pcie, window_idx, size_idx,
840 axi_addr, pci_addr);
841 if (ret)
842 goto err_ob;
843
844 size -= window_size;
845 if (size == 0)
846 return 0;
847
848 /*
849 * If we are here, we are done with the current window,
850 * but not yet finished all mappings. Need to move on
851 * to the next window.
852 */
853 axi_addr += window_size;
854 pci_addr += window_size;
855 break;
856 }
857 }
858
859err_ob:
860 pr_err("unable to configure outbound mapping\n");
861 pr_err("axi %pap, axi offset %pap, pci %pap, res size %pap\n",
862 &axi_addr, &ob->axi_offset, &pci_addr, &size);
863
864 return ret;
865}
866
867static int iproc_pcie_map_ranges(struct udevice *dev)
868{
869 struct iproc_pcie *pcie = dev_get_priv(dev);
870 struct udevice *bus = pci_get_controller(dev);
871 struct pci_controller *hose = dev_get_uclass_priv(bus);
872 int i, ret;
873
874 for (i = 0; i < hose->region_count; i++) {
875 if (hose->regions[i].flags == PCI_REGION_MEM ||
876 hose->regions[i].flags == PCI_REGION_PREFETCH) {
Bharat Gooty2cb32602021-08-23 14:57:24 +0530877 debug("%d: bus_addr %p, axi_addr %p, size 0x%llx\n",
Srinath Mannam48487042020-05-12 13:29:50 +0530878 i, &hose->regions[i].bus_start,
879 &hose->regions[i].phys_start,
880 hose->regions[i].size);
881 ret = iproc_pcie_setup_ob(pcie,
882 hose->regions[i].phys_start,
883 hose->regions[i].bus_start,
884 hose->regions[i].size);
885 if (ret)
886 return ret;
887 }
888 }
889
890 return 0;
891}
892
893static inline bool iproc_pcie_ib_is_in_use(struct iproc_pcie *pcie,
894 int region_idx)
895{
896 const struct iproc_pcie_ib_map *ib_map = &pcie->ib_map[region_idx];
897 u32 val;
898
899 val = iproc_pcie_read_reg(pcie, MAP_REG(IPROC_PCIE_IARR0, region_idx));
900
901 return !!(val & (BIT(ib_map->nr_sizes) - 1));
902}
903
904static inline bool
905iproc_pcie_ib_check_type(const struct iproc_pcie_ib_map *ib_map,
906 enum iproc_pcie_ib_map_type type)
907{
908 return !!(ib_map->type == type);
909}
910
911static int iproc_pcie_ib_write(struct iproc_pcie *pcie, int region_idx,
912 int size_idx, int nr_windows, u64 axi_addr,
913 u64 pci_addr, resource_size_t size)
914{
915 const struct iproc_pcie_ib_map *ib_map = &pcie->ib_map[region_idx];
916 u16 iarr_offset, imap_offset;
917 u32 val;
918 int window_idx;
919
920 iarr_offset = iproc_pcie_reg_offset(pcie, MAP_REG(IPROC_PCIE_IARR0,
921 region_idx));
922 imap_offset = iproc_pcie_reg_offset(pcie, MAP_REG(IPROC_PCIE_IMAP0,
923 region_idx));
924 if (iproc_pcie_reg_is_invalid(iarr_offset) ||
925 iproc_pcie_reg_is_invalid(imap_offset))
926 return -EINVAL;
927
928 debug("ib region [%d]: offset 0x%x axi %pap pci %pap\n",
929 region_idx, iarr_offset, &axi_addr, &pci_addr);
930
931 /*
932 * Program the IARR registers. The upper 32-bit IARR register is
933 * always right after the lower 32-bit IARR register.
934 */
935 writel(lower_32_bits(pci_addr) | BIT(size_idx),
936 pcie->base + iarr_offset);
937 writel(upper_32_bits(pci_addr), pcie->base + iarr_offset + 4);
938
939 debug("iarr lo 0x%x iarr hi 0x%x\n",
940 readl(pcie->base + iarr_offset),
941 readl(pcie->base + iarr_offset + 4));
942
943 /*
944 * Now program the IMAP registers. Each IARR region may have one or
945 * more IMAP windows.
946 */
947 size >>= ilog2(nr_windows);
948 for (window_idx = 0; window_idx < nr_windows; window_idx++) {
949 val = readl(pcie->base + imap_offset);
950 val |= lower_32_bits(axi_addr) | IMAP_VALID;
951 writel(val, pcie->base + imap_offset);
952 writel(upper_32_bits(axi_addr),
953 pcie->base + imap_offset + ib_map->imap_addr_offset);
954
955 debug("imap window [%d] lo 0x%x hi 0x%x\n",
956 window_idx, readl(pcie->base + imap_offset),
957 readl(pcie->base + imap_offset +
958 ib_map->imap_addr_offset));
959
960 imap_offset += ib_map->imap_window_offset;
961 axi_addr += size;
962 }
963
964 return 0;
965}
966
967/**
968 * iproc_pcie_setup_ib() - setup inbound address mapping
969 *
970 * @pcie: pcie device
971 * @axi_addr: axi address to be translated
972 * @pci_addr: pci address
973 * @size: window size
974 * @type: inbound mapping type
975 *
976 * @return: 0 on success and -ve on failure
977 */
978static int iproc_pcie_setup_ib(struct iproc_pcie *pcie, u64 axi_addr,
979 u64 pci_addr, resource_size_t size,
980 enum iproc_pcie_ib_map_type type)
981{
982 struct iproc_pcie_ib *ib = &pcie->ib;
983 int ret;
984 unsigned int region_idx, size_idx;
985
986 /* iterate through all IARR mapping regions */
987 for (region_idx = 0; region_idx < ib->nr_regions; region_idx++) {
988 const struct iproc_pcie_ib_map *ib_map =
989 &pcie->ib_map[region_idx];
990
991 /*
992 * If current inbound region is already in use or not a
993 * compatible type, move on to the next.
994 */
995 if (iproc_pcie_ib_is_in_use(pcie, region_idx) ||
996 !iproc_pcie_ib_check_type(ib_map, type))
997 continue;
998
999 /* iterate through all supported region sizes to find a match */
1000 for (size_idx = 0; size_idx < ib_map->nr_sizes; size_idx++) {
1001 resource_size_t region_size =
1002 ib_map->region_sizes[size_idx] * ib_map->size_unit;
1003
1004 if (size != region_size)
1005 continue;
1006
1007 if (!IS_ALIGNED(axi_addr, region_size) ||
1008 !IS_ALIGNED(pci_addr, region_size)) {
1009 pr_err("axi %pap or pci %pap not aligned\n",
1010 &axi_addr, &pci_addr);
1011 return -EINVAL;
1012 }
1013
1014 /* Match found! Program IARR and all IMAP windows. */
1015 ret = iproc_pcie_ib_write(pcie, region_idx, size_idx,
1016 ib_map->nr_windows, axi_addr,
1017 pci_addr, size);
1018 if (ret)
1019 goto err_ib;
1020 else
1021 return 0;
1022 }
1023 }
1024 ret = -EINVAL;
1025
1026err_ib:
1027 pr_err("unable to configure inbound mapping\n");
1028 pr_err("axi %pap, pci %pap, res size %pap\n",
1029 &axi_addr, &pci_addr, &size);
1030
1031 return ret;
1032}
1033
1034static int iproc_pcie_map_dma_ranges(struct iproc_pcie *pcie)
1035{
1036 int ret;
1037 struct pci_region regions;
1038 int i = 0;
1039
1040 while (!pci_get_dma_regions(pcie->dev, &regions, i)) {
1041 dev_dbg(pcie->dev,
Bharat Gooty2cb32602021-08-23 14:57:24 +05301042 "dma %d: bus_addr %#llx, axi_addr %#llx, size %#llx\n",
Srinath Mannam48487042020-05-12 13:29:50 +05301043 i, regions.bus_start, regions.phys_start, regions.size);
1044
1045 /* Each range entry corresponds to an inbound mapping region */
1046 ret = iproc_pcie_setup_ib(pcie, regions.phys_start,
1047 regions.bus_start,
1048 regions.size,
1049 IPROC_PCIE_IB_MAP_MEM);
1050 if (ret)
1051 return ret;
1052 i++;
1053 }
1054 return 0;
1055}
1056
1057static void iproc_pcie_reset_map_regs(struct iproc_pcie *pcie)
1058{
1059 struct iproc_pcie_ib *ib = &pcie->ib;
1060 struct iproc_pcie_ob *ob = &pcie->ob;
1061 int window_idx, region_idx;
1062
1063 if (pcie->ep_is_internal)
1064 return;
1065
1066 /* iterate through all OARR mapping regions */
1067 for (window_idx = ob->nr_windows - 1; window_idx >= 0; window_idx--) {
1068 iproc_pcie_write_reg(pcie, MAP_REG(IPROC_PCIE_OARR0,
1069 window_idx), 0);
1070 }
1071
1072 /* iterate through all IARR mapping regions */
1073 for (region_idx = 0; region_idx < ib->nr_regions; region_idx++) {
1074 iproc_pcie_write_reg(pcie, MAP_REG(IPROC_PCIE_IARR0,
1075 region_idx), 0);
1076 }
1077}
1078
1079static void iproc_pcie_reset(struct iproc_pcie *pcie)
1080{
1081 u32 val;
1082
1083 /*
1084 * PAXC and the internal emulated endpoint device downstream should not
1085 * be reset. If firmware has been loaded on the endpoint device at an
1086 * earlier boot stage, reset here causes issues.
1087 */
1088 if (pcie->ep_is_internal)
1089 return;
1090
1091 /*
1092 * Select perst_b signal as reset source. Put the device into reset,
1093 * and then bring it out of reset
1094 */
1095 val = iproc_pcie_read_reg(pcie, IPROC_PCIE_CLK_CTRL);
1096 val &= ~EP_PERST_SOURCE_SELECT & ~EP_MODE_SURVIVE_PERST &
1097 ~RC_PCIE_RST_OUTPUT;
1098 iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val);
1099 udelay(250);
1100
1101 val |= RC_PCIE_RST_OUTPUT;
1102 iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val);
1103 mdelay(100);
1104}
1105
1106static inline bool iproc_pcie_link_is_active(struct iproc_pcie *pcie)
1107{
1108 u32 val;
1109
1110 val = iproc_pcie_read_reg(pcie, IPROC_PCIE_LINK_STATUS);
1111 return !!((val & PCIE_PHYLINKUP) && (val & PCIE_DL_ACTIVE));
1112}
1113
1114static int iproc_pcie_check_link(struct iproc_pcie *pcie)
1115{
1116 u32 link_status, class;
1117
1118 pcie->link_is_active = false;
Pali Rohár253373d2022-01-05 10:50:20 +01001119 /* force class to PCI bridge Normal decode (0x060400) */
Srinath Mannam48487042020-05-12 13:29:50 +05301120#define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c
Pali Rohár253373d2022-01-05 10:50:20 +01001121#define PCI_BRIDGE_CTRL_REG_CLASS_MASK 0xffffff
Srinath Mannam48487042020-05-12 13:29:50 +05301122 iproc_pci_raw_config_read32(pcie, 0,
1123 PCI_BRIDGE_CTRL_REG_OFFSET,
1124 4, &class);
Pali Rohár253373d2022-01-05 10:50:20 +01001125 class &= ~PCI_BRIDGE_CTRL_REG_CLASS_MASK;
Pali Rohárd7b90402022-02-18 13:18:40 +01001126 class |= PCI_CLASS_BRIDGE_PCI_NORMAL;
Srinath Mannam48487042020-05-12 13:29:50 +05301127 iproc_pci_raw_config_write32(pcie, 0,
1128 PCI_BRIDGE_CTRL_REG_OFFSET,
1129 4, class);
1130
1131 /*
1132 * PAXC connects to emulated endpoint devices directly and does not
1133 * have a Serdes. Therefore skip the link detection logic here.
1134 */
1135 if (pcie->ep_is_internal) {
1136 pcie->link_is_active = true;
1137 return 0;
1138 }
1139
1140 if (!iproc_pcie_link_is_active(pcie)) {
1141 pr_err("PHY or data link is INACTIVE!\n");
1142 return -ENODEV;
1143 }
1144
1145#define PCI_TARGET_LINK_SPEED_MASK 0xf
1146#define PCI_TARGET_LINK_WIDTH_MASK 0x3f
1147#define PCI_TARGET_LINK_WIDTH_OFFSET 0x4
1148
1149 /* check link status to see if link is active */
1150 iproc_pci_raw_config_read32(pcie, 0,
1151 IPROC_PCI_EXP_CAP + PCI_EXP_LNKSTA,
1152 2, &link_status);
1153 if (link_status & PCI_EXP_LNKSTA_NLW)
1154 pcie->link_is_active = true;
1155
1156 if (pcie->link_is_active)
1157 pr_info("link UP @ Speed Gen-%d and width-x%d\n",
1158 link_status & PCI_TARGET_LINK_SPEED_MASK,
1159 (link_status >> PCI_TARGET_LINK_WIDTH_OFFSET) &
1160 PCI_TARGET_LINK_WIDTH_MASK);
1161 else
1162 pr_info("link DOWN\n");
1163
1164 return 0;
1165}
1166
1167static int iproc_pcie_probe(struct udevice *dev)
1168{
1169 struct iproc_pcie *pcie = dev_get_priv(dev);
1170 int ret;
1171
1172 pcie->type = (enum iproc_pcie_type)dev_get_driver_data(dev);
1173 debug("PAX type %d\n", pcie->type);
1174 pcie->base = dev_read_addr_ptr(dev);
1175 debug("PAX reg base %p\n", pcie->base);
1176
1177 if (!pcie->base)
1178 return -ENODEV;
1179
1180 if (dev_read_bool(dev, "brcm,pcie-ob"))
1181 pcie->need_ob_cfg = true;
1182
1183 pcie->dev = dev;
1184 ret = iproc_pcie_rev_init(pcie);
1185 if (ret)
1186 return ret;
1187
1188 if (!pcie->ep_is_internal) {
1189 ret = generic_phy_get_by_name(dev, "pcie-phy", &pcie->phy);
1190 if (!ret) {
1191 ret = generic_phy_init(&pcie->phy);
1192 if (ret) {
1193 pr_err("failed to init %s PHY\n", dev->name);
1194 return ret;
1195 }
1196
1197 ret = generic_phy_power_on(&pcie->phy);
1198 if (ret) {
1199 pr_err("power on %s PHY failed\n", dev->name);
1200 goto err_exit_phy;
1201 }
1202 }
1203 }
1204
1205 iproc_pcie_reset(pcie);
1206
1207 if (pcie->need_ob_cfg) {
1208 ret = iproc_pcie_map_ranges(dev);
1209 if (ret) {
1210 pr_err("outbound map failed\n");
1211 goto err_power_off_phy;
1212 }
1213 }
1214
1215 if (pcie->need_ib_cfg) {
1216 ret = iproc_pcie_map_dma_ranges(pcie);
1217 if (ret) {
1218 pr_err("inbound map failed\n");
1219 goto err_power_off_phy;
1220 }
1221 }
1222
1223 if (iproc_pcie_check_link(pcie))
1224 pr_info("no PCIe EP device detected\n");
1225
1226 return 0;
1227
1228err_power_off_phy:
1229 generic_phy_power_off(&pcie->phy);
1230err_exit_phy:
1231 generic_phy_exit(&pcie->phy);
1232 return ret;
1233}
1234
1235static int iproc_pcie_remove(struct udevice *dev)
1236{
1237 struct iproc_pcie *pcie = dev_get_priv(dev);
1238 int ret;
1239
1240 iproc_pcie_reset_map_regs(pcie);
1241
1242 if (generic_phy_valid(&pcie->phy)) {
1243 ret = generic_phy_power_off(&pcie->phy);
1244 if (ret) {
1245 pr_err("failed to power off PCIe phy\n");
1246 return ret;
1247 }
1248
1249 ret = generic_phy_exit(&pcie->phy);
1250 if (ret) {
1251 pr_err("failed to power off PCIe phy\n");
1252 return ret;
1253 }
1254 }
1255
1256 return 0;
1257}
1258
1259static const struct udevice_id pci_iproc_ids[] = {
1260 { .compatible = "brcm,iproc-pcie-paxb-v2",
1261 .data = IPROC_PCIE_PAXB_V2 },
1262 { .compatible = "brcm,iproc-pcie-paxc-v2",
1263 .data = IPROC_PCIE_PAXC_V2 },
1264 { }
1265};
1266
1267U_BOOT_DRIVER(pci_iproc) = {
1268 .name = "pci_iproc",
1269 .id = UCLASS_PCI,
1270 .of_match = pci_iproc_ids,
1271 .ops = &iproc_pcie_ops,
1272 .probe = iproc_pcie_probe,
1273 .remove = iproc_pcie_remove,
Simon Glass41575d82020-12-03 16:55:17 -07001274 .priv_auto = sizeof(struct iproc_pcie),
Simon Glass4d7bab12021-01-24 14:32:43 -07001275 .flags = DM_FLAG_OS_PREPARE,
Srinath Mannam48487042020-05-12 13:29:50 +05301276};