1
2
3
4
5
6
7
8
9
10
11
12#include <common.h>
13#include <dm.h>
14#include <log.h>
15#include <malloc.h>
16#include <asm/global_data.h>
17#include <dm/device-internal.h>
18#include <dm/lists.h>
19#include <dm/of_access.h>
20#include <pci.h>
21#include <asm/io.h>
22#include <asm/arch/cpu.h>
23#include <asm/arch/soc.h>
24#include <linux/bitops.h>
25#include <linux/errno.h>
26#include <linux/ioport.h>
27#include <linux/mbus.h>
28
29DECLARE_GLOBAL_DATA_PTR;
30
31
32#define SELECT(x, n) ((x >> n) & 1UL)
33
34#define PCIE_DEV_ID_OFF 0x0000
35#define PCIE_CMD_OFF 0x0004
36#define PCIE_DEV_REV_OFF 0x0008
37#define PCIE_BAR_LO_OFF(n) (0x0010 + ((n) << 3))
38#define PCIE_BAR_HI_OFF(n) (0x0014 + ((n) << 3))
39#define PCIE_EXP_ROM_BAR_OFF 0x0030
40#define PCIE_CAPAB_OFF 0x0060
41#define PCIE_CTRL_STAT_OFF 0x0068
42#define PCIE_HEADER_LOG_4_OFF 0x0128
43#define PCIE_BAR_CTRL_OFF(n) (0x1804 + (((n) - 1) * 4))
44#define PCIE_WIN04_CTRL_OFF(n) (0x1820 + ((n) << 4))
45#define PCIE_WIN04_BASE_OFF(n) (0x1824 + ((n) << 4))
46#define PCIE_WIN04_REMAP_OFF(n) (0x182c + ((n) << 4))
47#define PCIE_WIN5_CTRL_OFF 0x1880
48#define PCIE_WIN5_BASE_OFF 0x1884
49#define PCIE_WIN5_REMAP_OFF 0x188c
50#define PCIE_CONF_ADDR_OFF 0x18f8
51#define PCIE_CONF_ADDR_EN BIT(31)
52#define PCIE_CONF_REG(r) ((((r) & 0xf00) << 16) | ((r) & 0xfc))
53#define PCIE_CONF_BUS(b) (((b) & 0xff) << 16)
54#define PCIE_CONF_DEV(d) (((d) & 0x1f) << 11)
55#define PCIE_CONF_FUNC(f) (((f) & 0x7) << 8)
56#define PCIE_CONF_ADDR(b, d, f, reg) \
57 (PCIE_CONF_BUS(b) | PCIE_CONF_DEV(d) | \
58 PCIE_CONF_FUNC(f) | PCIE_CONF_REG(reg) | \
59 PCIE_CONF_ADDR_EN)
60#define PCIE_CONF_DATA_OFF 0x18fc
61#define PCIE_MASK_OFF 0x1910
62#define PCIE_MASK_ENABLE_INTS (0xf << 24)
63#define PCIE_CTRL_OFF 0x1a00
64#define PCIE_CTRL_X1_MODE BIT(0)
65#define PCIE_CTRL_RC_MODE BIT(1)
66#define PCIE_STAT_OFF 0x1a04
67#define PCIE_STAT_BUS (0xff << 8)
68#define PCIE_STAT_DEV (0x1f << 16)
69#define PCIE_STAT_LINK_DOWN BIT(0)
70#define PCIE_DEBUG_CTRL 0x1a60
71#define PCIE_DEBUG_SOFT_RESET BIT(20)
72
73struct mvebu_pcie {
74 struct pci_controller hose;
75 void __iomem *base;
76 void __iomem *membase;
77 struct resource mem;
78 void __iomem *iobase;
79 struct resource io;
80 u32 port;
81 u32 lane;
82 int devfn;
83 u32 lane_mask;
84 int first_busno;
85 int sec_busno;
86 char name[16];
87 unsigned int mem_target;
88 unsigned int mem_attr;
89 unsigned int io_target;
90 unsigned int io_attr;
91 u32 cfgcache[(0x3c - 0x10) / 4];
92};
93
94
95
96
97
98
99static void __iomem *mvebu_pcie_membase = (void __iomem *)MBUS_PCI_MEM_BASE;
100static void __iomem *mvebu_pcie_iobase = (void __iomem *)MBUS_PCI_IO_BASE;
101
102static inline bool mvebu_pcie_link_up(struct mvebu_pcie *pcie)
103{
104 u32 val;
105 val = readl(pcie->base + PCIE_STAT_OFF);
106 return !(val & PCIE_STAT_LINK_DOWN);
107}
108
109static void mvebu_pcie_set_local_bus_nr(struct mvebu_pcie *pcie, int busno)
110{
111 u32 stat;
112
113 stat = readl(pcie->base + PCIE_STAT_OFF);
114 stat &= ~PCIE_STAT_BUS;
115 stat |= busno << 8;
116 writel(stat, pcie->base + PCIE_STAT_OFF);
117}
118
119static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie *pcie, int devno)
120{
121 u32 stat;
122
123 stat = readl(pcie->base + PCIE_STAT_OFF);
124 stat &= ~PCIE_STAT_DEV;
125 stat |= devno << 16;
126 writel(stat, pcie->base + PCIE_STAT_OFF);
127}
128
129static inline struct mvebu_pcie *hose_to_pcie(struct pci_controller *hose)
130{
131 return container_of(hose, struct mvebu_pcie, hose);
132}
133
134static bool mvebu_pcie_valid_addr(struct mvebu_pcie *pcie,
135 int busno, int dev, int func)
136{
137
138 if (busno == pcie->first_busno && (dev != 0 || func != 0))
139 return false;
140
141
142 if (busno != pcie->first_busno && !mvebu_pcie_link_up(pcie))
143 return false;
144
145
146 if (busno == pcie->sec_busno && dev != 0)
147 return false;
148
149 return true;
150}
151
152static int mvebu_pcie_read_config(const struct udevice *bus, pci_dev_t bdf,
153 uint offset, ulong *valuep,
154 enum pci_size_t size)
155{
156 struct mvebu_pcie *pcie = dev_get_plat(bus);
157 int busno = PCI_BUS(bdf) - dev_seq(bus);
158 u32 addr, data;
159
160 debug("PCIE CFG read: (b,d,f)=(%2d,%2d,%2d) ",
161 PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
162
163 if (!mvebu_pcie_valid_addr(pcie, busno, PCI_DEV(bdf), PCI_FUNC(bdf))) {
164 debug("- out of range\n");
165 *valuep = pci_get_ff(size);
166 return 0;
167 }
168
169
170
171
172
173
174
175
176
177 if (busno == pcie->first_busno && ((offset >= 0x10 && offset < 0x34) ||
178 (offset >= 0x38 && offset < 0x3c))) {
179 data = pcie->cfgcache[(offset - 0x10) / 4];
180 debug("(addr,size,val)=(0x%04x, %d, 0x%08x) from cfgcache\n",
181 offset, size, data);
182 *valuep = pci_conv_32_to_size(data, offset, size);
183 return 0;
184 }
185
186
187
188
189
190 if (busno == pcie->first_busno)
191 addr = PCIE_CONF_ADDR(pcie->sec_busno, 1, 0, offset);
192 else
193 addr = PCIE_CONF_ADDR(busno, PCI_DEV(bdf), PCI_FUNC(bdf), offset);
194
195
196 writel(addr, pcie->base + PCIE_CONF_ADDR_OFF);
197
198
199 switch (size) {
200 case PCI_SIZE_8:
201 data = readb(pcie->base + PCIE_CONF_DATA_OFF + (offset & 3));
202 break;
203 case PCI_SIZE_16:
204 data = readw(pcie->base + PCIE_CONF_DATA_OFF + (offset & 2));
205 break;
206 case PCI_SIZE_32:
207 data = readl(pcie->base + PCIE_CONF_DATA_OFF);
208 break;
209 default:
210 return -EINVAL;
211 }
212
213 if (busno == pcie->first_busno &&
214 (offset & ~3) == (PCI_HEADER_TYPE & ~3)) {
215
216
217
218
219
220 data = pci_conv_size_to_32(data, 0, offset, size);
221 data &= ~0x007f0000;
222 data |= PCI_HEADER_TYPE_BRIDGE << 16;
223 data = pci_conv_32_to_size(data, offset, size);
224 }
225
226 debug("(addr,size,val)=(0x%04x, %d, 0x%08x)\n", offset, size, data);
227 *valuep = data;
228
229 return 0;
230}
231
232static int mvebu_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
233 uint offset, ulong value,
234 enum pci_size_t size)
235{
236 struct mvebu_pcie *pcie = dev_get_plat(bus);
237 int busno = PCI_BUS(bdf) - dev_seq(bus);
238 u32 addr, data;
239
240 debug("PCIE CFG write: (b,d,f)=(%2d,%2d,%2d) ",
241 PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
242 debug("(addr,size,val)=(0x%04x, %d, 0x%08lx)\n", offset, size, value);
243
244 if (!mvebu_pcie_valid_addr(pcie, busno, PCI_DEV(bdf), PCI_FUNC(bdf))) {
245 debug("- out of range\n");
246 return 0;
247 }
248
249
250
251
252
253
254
255
256 if (busno == pcie->first_busno && ((offset >= 0x10 && offset < 0x34) ||
257 (offset >= 0x38 && offset < 0x3c))) {
258 debug("Writing to cfgcache only\n");
259 data = pcie->cfgcache[(offset - 0x10) / 4];
260 data = pci_conv_size_to_32(data, value, offset, size);
261
262 if ((offset & ~3) == PCI_BASE_ADDRESS_0 ||
263 (offset & ~3) == PCI_BASE_ADDRESS_1 ||
264 (offset & ~3) == PCI_ROM_ADDRESS1)
265 data = 0x0;
266 pcie->cfgcache[(offset - 0x10) / 4] = data;
267
268 if (offset == PCI_PRIMARY_BUS) {
269 pcie->first_busno = data & 0xff;
270 debug("Primary bus number was changed to %d\n",
271 pcie->first_busno);
272 }
273
274 if (offset == PCI_SECONDARY_BUS ||
275 (offset == PCI_PRIMARY_BUS && size != PCI_SIZE_8)) {
276 pcie->sec_busno = (data >> 8) & 0xff;
277 mvebu_pcie_set_local_bus_nr(pcie, pcie->sec_busno);
278 debug("Secondary bus number was changed to %d\n",
279 pcie->sec_busno);
280 }
281 return 0;
282 }
283
284
285
286
287
288 if (busno == pcie->first_busno)
289 addr = PCIE_CONF_ADDR(pcie->sec_busno, 1, 0, offset);
290 else
291 addr = PCIE_CONF_ADDR(busno, PCI_DEV(bdf), PCI_FUNC(bdf), offset);
292
293
294 writel(addr, pcie->base + PCIE_CONF_ADDR_OFF);
295
296
297 switch (size) {
298 case PCI_SIZE_8:
299 writeb(value, pcie->base + PCIE_CONF_DATA_OFF + (offset & 3));
300 break;
301 case PCI_SIZE_16:
302 writew(value, pcie->base + PCIE_CONF_DATA_OFF + (offset & 2));
303 break;
304 case PCI_SIZE_32:
305 writel(value, pcie->base + PCIE_CONF_DATA_OFF);
306 break;
307 default:
308 return -EINVAL;
309 }
310
311 return 0;
312}
313
314
315
316
317
318
319static void mvebu_pcie_setup_wins(struct mvebu_pcie *pcie)
320{
321 const struct mbus_dram_target_info *dram = mvebu_mbus_dram_info();
322 u32 size;
323 int i;
324
325
326 for (i = 1; i < 3; i++) {
327 writel(0, pcie->base + PCIE_BAR_CTRL_OFF(i));
328 writel(0, pcie->base + PCIE_BAR_LO_OFF(i));
329 writel(0, pcie->base + PCIE_BAR_HI_OFF(i));
330 }
331
332 for (i = 0; i < 5; i++) {
333 writel(0, pcie->base + PCIE_WIN04_CTRL_OFF(i));
334 writel(0, pcie->base + PCIE_WIN04_BASE_OFF(i));
335 writel(0, pcie->base + PCIE_WIN04_REMAP_OFF(i));
336 }
337
338 writel(0, pcie->base + PCIE_WIN5_CTRL_OFF);
339 writel(0, pcie->base + PCIE_WIN5_BASE_OFF);
340 writel(0, pcie->base + PCIE_WIN5_REMAP_OFF);
341
342
343 size = 0;
344 for (i = 0; i < dram->num_cs; i++) {
345 const struct mbus_dram_window *cs = dram->cs + i;
346
347 writel(cs->base & 0xffff0000,
348 pcie->base + PCIE_WIN04_BASE_OFF(i));
349 writel(0, pcie->base + PCIE_WIN04_REMAP_OFF(i));
350 writel(((cs->size - 1) & 0xffff0000) |
351 (cs->mbus_attr << 8) |
352 (dram->mbus_dram_target_id << 4) | 1,
353 pcie->base + PCIE_WIN04_CTRL_OFF(i));
354
355 size += cs->size;
356 }
357
358
359 if ((size & (size - 1)) != 0)
360 size = 1 << fls(size);
361
362
363 writel(dram->cs[0].base | 0xc, pcie->base + PCIE_BAR_LO_OFF(1));
364 writel(0, pcie->base + PCIE_BAR_HI_OFF(1));
365 writel(((size - 1) & 0xffff0000) | 0x1,
366 pcie->base + PCIE_BAR_CTRL_OFF(1));
367}
368
369static int mvebu_pcie_probe(struct udevice *dev)
370{
371 struct mvebu_pcie *pcie = dev_get_plat(dev);
372 struct udevice *ctlr = pci_get_controller(dev);
373 struct pci_controller *hose = dev_get_uclass_priv(ctlr);
374 u32 reg;
375
376
377 reg = readl(pcie->base + PCIE_CTRL_OFF);
378 reg |= PCIE_CTRL_RC_MODE;
379 writel(reg, pcie->base + PCIE_CTRL_OFF);
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402 reg = readl(pcie->base + PCIE_DEV_REV_OFF);
403 reg &= ~0xffffff00;
404 reg |= (PCI_CLASS_BRIDGE_PCI << 8) << 8;
405 writel(reg, pcie->base + PCIE_DEV_REV_OFF);
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438 mvebu_pcie_set_local_bus_nr(pcie, 0);
439 mvebu_pcie_set_local_dev_nr(pcie, 1);
440
441 pcie->mem.start = (u32)mvebu_pcie_membase;
442 pcie->mem.end = pcie->mem.start + MBUS_PCI_MEM_SIZE - 1;
443 mvebu_pcie_membase += MBUS_PCI_MEM_SIZE;
444
445 if (mvebu_mbus_add_window_by_id(pcie->mem_target, pcie->mem_attr,
446 (phys_addr_t)pcie->mem.start,
447 MBUS_PCI_MEM_SIZE)) {
448 printf("PCIe unable to add mbus window for mem at %08x+%08x\n",
449 (u32)pcie->mem.start, MBUS_PCI_MEM_SIZE);
450 }
451
452 pcie->io.start = (u32)mvebu_pcie_iobase;
453 pcie->io.end = pcie->io.start + MBUS_PCI_IO_SIZE - 1;
454 mvebu_pcie_iobase += MBUS_PCI_IO_SIZE;
455
456 if (mvebu_mbus_add_window_by_id(pcie->io_target, pcie->io_attr,
457 (phys_addr_t)pcie->io.start,
458 MBUS_PCI_IO_SIZE)) {
459 printf("PCIe unable to add mbus window for IO at %08x+%08x\n",
460 (u32)pcie->io.start, MBUS_PCI_IO_SIZE);
461 }
462
463
464 mvebu_pcie_setup_wins(pcie);
465
466
467 pci_set_region(hose->regions + 0, pcie->mem.start,
468 pcie->mem.start, MBUS_PCI_MEM_SIZE, PCI_REGION_MEM);
469 pci_set_region(hose->regions + 1,
470 0, 0,
471 gd->ram_size,
472 PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
473 pci_set_region(hose->regions + 2, pcie->io.start,
474 pcie->io.start, MBUS_PCI_IO_SIZE, PCI_REGION_IO);
475 hose->region_count = 3;
476
477
478 writel(SOC_REGS_PHY_BASE, pcie->base + PCIE_BAR_LO_OFF(0));
479 writel(0, pcie->base + PCIE_BAR_HI_OFF(0));
480
481
482 pcie->cfgcache[(PCI_IO_BASE - 0x10) / 4] =
483 PCI_IO_RANGE_TYPE_32 | (PCI_IO_RANGE_TYPE_32 << 8);
484 pcie->cfgcache[(PCI_PREF_MEMORY_BASE - 0x10) / 4] =
485 PCI_PREF_RANGE_TYPE_64 | (PCI_PREF_RANGE_TYPE_64 << 16);
486
487 return 0;
488}
489
490static int mvebu_pcie_port_parse_dt(ofnode node, struct mvebu_pcie *pcie)
491{
492 const u32 *addr;
493 int len;
494
495 addr = ofnode_get_property(node, "assigned-addresses", &len);
496 if (!addr) {
497 pr_err("property \"assigned-addresses\" not found");
498 return -FDT_ERR_NOTFOUND;
499 }
500
501 pcie->base = (void *)(fdt32_to_cpu(addr[2]) + SOC_REGS_PHY_BASE);
502
503 return 0;
504}
505
506#define DT_FLAGS_TO_TYPE(flags) (((flags) >> 24) & 0x03)
507#define DT_TYPE_IO 0x1
508#define DT_TYPE_MEM32 0x2
509#define DT_CPUADDR_TO_TARGET(cpuaddr) (((cpuaddr) >> 56) & 0xFF)
510#define DT_CPUADDR_TO_ATTR(cpuaddr) (((cpuaddr) >> 48) & 0xFF)
511
512static int mvebu_get_tgt_attr(ofnode node, int devfn,
513 unsigned long type,
514 unsigned int *tgt,
515 unsigned int *attr)
516{
517 const int na = 3, ns = 2;
518 const __be32 *range;
519 int rlen, nranges, rangesz, pna, i;
520
521 *tgt = -1;
522 *attr = -1;
523
524 range = ofnode_get_property(node, "ranges", &rlen);
525 if (!range)
526 return -EINVAL;
527
528
529
530
531
532
533
534 pna = 2;
535 rangesz = pna + na + ns;
536 nranges = rlen / sizeof(__be32) / rangesz;
537
538 for (i = 0; i < nranges; i++, range += rangesz) {
539 u32 flags = of_read_number(range, 1);
540 u32 slot = of_read_number(range + 1, 1);
541 u64 cpuaddr = of_read_number(range + na, pna);
542 unsigned long rtype;
543
544 if (DT_FLAGS_TO_TYPE(flags) == DT_TYPE_IO)
545 rtype = IORESOURCE_IO;
546 else if (DT_FLAGS_TO_TYPE(flags) == DT_TYPE_MEM32)
547 rtype = IORESOURCE_MEM;
548 else
549 continue;
550
551
552
553
554
555
556 if (slot == PCI_DEV(devfn) && type == rtype) {
557 *tgt = DT_CPUADDR_TO_TARGET(cpuaddr);
558 *attr = DT_CPUADDR_TO_ATTR(cpuaddr);
559 return 0;
560 }
561 }
562
563 return -ENOENT;
564}
565
566static int mvebu_pcie_of_to_plat(struct udevice *dev)
567{
568 struct mvebu_pcie *pcie = dev_get_plat(dev);
569 int ret = 0;
570
571
572 if (ofnode_read_u32(dev_ofnode(dev), "marvell,pcie-port",
573 &pcie->port)) {
574 ret = -ENODEV;
575 goto err;
576 }
577
578 if (ofnode_read_u32(dev_ofnode(dev), "marvell,pcie-lane", &pcie->lane))
579 pcie->lane = 0;
580
581 sprintf(pcie->name, "pcie%d.%d", pcie->port, pcie->lane);
582
583
584 pcie->devfn = pci_get_devfn(dev);
585 if (pcie->devfn < 0) {
586 ret = -ENODEV;
587 goto err;
588 }
589
590 ret = mvebu_get_tgt_attr(dev_ofnode(dev->parent), pcie->devfn,
591 IORESOURCE_MEM,
592 &pcie->mem_target, &pcie->mem_attr);
593 if (ret < 0) {
594 printf("%s: cannot get tgt/attr for mem window\n", pcie->name);
595 goto err;
596 }
597
598 ret = mvebu_get_tgt_attr(dev_ofnode(dev->parent), pcie->devfn,
599 IORESOURCE_IO,
600 &pcie->io_target, &pcie->io_attr);
601 if (ret < 0) {
602 printf("%s: cannot get tgt/attr for IO window\n", pcie->name);
603 goto err;
604 }
605
606
607 ret = mvebu_pcie_port_parse_dt(dev_ofnode(dev), pcie);
608 if (ret < 0)
609 goto err;
610
611 return 0;
612
613err:
614 return ret;
615}
616
617static const struct dm_pci_ops mvebu_pcie_ops = {
618 .read_config = mvebu_pcie_read_config,
619 .write_config = mvebu_pcie_write_config,
620};
621
622static struct driver pcie_mvebu_drv = {
623 .name = "pcie_mvebu",
624 .id = UCLASS_PCI,
625 .ops = &mvebu_pcie_ops,
626 .probe = mvebu_pcie_probe,
627 .of_to_plat = mvebu_pcie_of_to_plat,
628 .plat_auto = sizeof(struct mvebu_pcie),
629};
630
631
632
633
634
635static int mvebu_pcie_bind(struct udevice *parent)
636{
637 struct mvebu_pcie *pcie;
638 struct uclass_driver *drv;
639 struct udevice *dev;
640 ofnode subnode;
641
642
643 drv = lists_uclass_lookup(UCLASS_PCI);
644 if (!drv) {
645 puts("Cannot find PCI driver\n");
646 return -ENOENT;
647 }
648
649 ofnode_for_each_subnode(subnode, dev_ofnode(parent)) {
650 if (!ofnode_is_available(subnode))
651 continue;
652
653 pcie = calloc(1, sizeof(*pcie));
654 if (!pcie)
655 return -ENOMEM;
656
657
658 device_bind(parent, &pcie_mvebu_drv, pcie->name, pcie, subnode,
659 &dev);
660 }
661
662 return 0;
663}
664
665static const struct udevice_id mvebu_pcie_ids[] = {
666 { .compatible = "marvell,armada-xp-pcie" },
667 { .compatible = "marvell,armada-370-pcie" },
668 { }
669};
670
671U_BOOT_DRIVER(pcie_mvebu_base) = {
672 .name = "pcie_mvebu_base",
673 .id = UCLASS_MISC,
674 .of_match = mvebu_pcie_ids,
675 .bind = mvebu_pcie_bind,
676};
677