1
2
3
4
5
6
7
8
9#include <common.h>
10#include <asm/arch/fsl_serdes.h>
11#include <pci.h>
12#include <asm/io.h>
13#include <errno.h>
14#include <malloc.h>
15#include <dm.h>
16#include <linux/sizes.h>
17
18#include "pcie_layerscape_gen4.h"
19
20DECLARE_GLOBAL_DATA_PTR;
21
22LIST_HEAD(ls_pcie_g4_list);
23
24static u64 bar_size[4] = {
25 PCIE_BAR0_SIZE,
26 PCIE_BAR1_SIZE,
27 PCIE_BAR2_SIZE,
28 PCIE_BAR4_SIZE
29};
30
31static int ls_pcie_g4_ltssm(struct ls_pcie_g4 *pcie)
32{
33 u32 state;
34
35 state = pf_ctrl_readl(pcie, PCIE_LTSSM_STA) & LTSSM_STATE_MASK;
36
37 return state;
38}
39
40static int ls_pcie_g4_link_up(struct ls_pcie_g4 *pcie)
41{
42 int ltssm;
43
44 ltssm = ls_pcie_g4_ltssm(pcie);
45 if (ltssm != LTSSM_PCIE_L0)
46 return 0;
47
48 return 1;
49}
50
51static void ls_pcie_g4_ep_enable_cfg(struct ls_pcie_g4 *pcie)
52{
53 ccsr_writel(pcie, GPEX_CFG_READY, PCIE_CONFIG_READY);
54}
55
56static void ls_pcie_g4_cfg_set_target(struct ls_pcie_g4 *pcie, u32 target)
57{
58 ccsr_writel(pcie, PAB_AXI_AMAP_PEX_WIN_L(0), target);
59 ccsr_writel(pcie, PAB_AXI_AMAP_PEX_WIN_H(0), 0);
60}
61
62static int ls_pcie_g4_outbound_win_set(struct ls_pcie_g4 *pcie, int idx,
63 int type, u64 phys, u64 bus_addr,
64 pci_size_t size)
65{
66 u32 val;
67 u32 size_h, size_l;
68
69 if (idx >= PAB_WINS_NUM)
70 return -EINVAL;
71
72 size_h = upper_32_bits(~(size - 1));
73 size_l = lower_32_bits(~(size - 1));
74
75 val = ccsr_readl(pcie, PAB_AXI_AMAP_CTRL(idx));
76 val &= ~((AXI_AMAP_CTRL_TYPE_MASK << AXI_AMAP_CTRL_TYPE_SHIFT) |
77 (AXI_AMAP_CTRL_SIZE_MASK << AXI_AMAP_CTRL_SIZE_SHIFT) |
78 AXI_AMAP_CTRL_EN);
79 val |= ((type & AXI_AMAP_CTRL_TYPE_MASK) << AXI_AMAP_CTRL_TYPE_SHIFT) |
80 ((size_l >> AXI_AMAP_CTRL_SIZE_SHIFT) <<
81 AXI_AMAP_CTRL_SIZE_SHIFT) | AXI_AMAP_CTRL_EN;
82
83 ccsr_writel(pcie, PAB_AXI_AMAP_CTRL(idx), val);
84
85 ccsr_writel(pcie, PAB_AXI_AMAP_AXI_WIN(idx), lower_32_bits(phys));
86 ccsr_writel(pcie, PAB_EXT_AXI_AMAP_AXI_WIN(idx), upper_32_bits(phys));
87 ccsr_writel(pcie, PAB_AXI_AMAP_PEX_WIN_L(idx), lower_32_bits(bus_addr));
88 ccsr_writel(pcie, PAB_AXI_AMAP_PEX_WIN_H(idx), upper_32_bits(bus_addr));
89 ccsr_writel(pcie, PAB_EXT_AXI_AMAP_SIZE(idx), size_h);
90
91 return 0;
92}
93
94static int ls_pcie_g4_rc_inbound_win_set(struct ls_pcie_g4 *pcie, int idx,
95 int type, u64 phys, u64 bus_addr,
96 pci_size_t size)
97{
98 u32 val;
99 pci_size_t win_size = ~(size - 1);
100
101 val = ccsr_readl(pcie, PAB_PEX_AMAP_CTRL(idx));
102
103 val &= ~(PEX_AMAP_CTRL_TYPE_MASK << PEX_AMAP_CTRL_TYPE_SHIFT);
104 val &= ~(PEX_AMAP_CTRL_EN_MASK << PEX_AMAP_CTRL_EN_SHIFT);
105 val = (val | (type << PEX_AMAP_CTRL_TYPE_SHIFT));
106 val = (val | (1 << PEX_AMAP_CTRL_EN_SHIFT));
107
108 ccsr_writel(pcie, PAB_PEX_AMAP_CTRL(idx),
109 val | lower_32_bits(win_size));
110
111 ccsr_writel(pcie, PAB_EXT_PEX_AMAP_SIZE(idx), upper_32_bits(win_size));
112 ccsr_writel(pcie, PAB_PEX_AMAP_AXI_WIN(idx), lower_32_bits(phys));
113 ccsr_writel(pcie, PAB_EXT_PEX_AMAP_AXI_WIN(idx), upper_32_bits(phys));
114 ccsr_writel(pcie, PAB_PEX_AMAP_PEX_WIN_L(idx), lower_32_bits(bus_addr));
115 ccsr_writel(pcie, PAB_PEX_AMAP_PEX_WIN_H(idx), upper_32_bits(bus_addr));
116
117 return 0;
118}
119
120static void ls_pcie_g4_dump_wins(struct ls_pcie_g4 *pcie, int wins)
121{
122 int i;
123
124 for (i = 0; i < wins; i++) {
125 debug("APIO Win%d:\n", i);
126 debug("\tLOWER PHYS: 0x%08x\n",
127 ccsr_readl(pcie, PAB_AXI_AMAP_AXI_WIN(i)));
128 debug("\tUPPER PHYS: 0x%08x\n",
129 ccsr_readl(pcie, PAB_EXT_AXI_AMAP_AXI_WIN(i)));
130 debug("\tLOWER BUS: 0x%08x\n",
131 ccsr_readl(pcie, PAB_AXI_AMAP_PEX_WIN_L(i)));
132 debug("\tUPPER BUS: 0x%08x\n",
133 ccsr_readl(pcie, PAB_AXI_AMAP_PEX_WIN_H(i)));
134 debug("\tSIZE: 0x%08x\n",
135 ccsr_readl(pcie, PAB_AXI_AMAP_CTRL(i)) &
136 (AXI_AMAP_CTRL_SIZE_MASK << AXI_AMAP_CTRL_SIZE_SHIFT));
137 debug("\tEXT_SIZE: 0x%08x\n",
138 ccsr_readl(pcie, PAB_EXT_AXI_AMAP_SIZE(i)));
139 debug("\tPARAM: 0x%08x\n",
140 ccsr_readl(pcie, PAB_AXI_AMAP_PCI_HDR_PARAM(i)));
141 debug("\tCTRL: 0x%08x\n",
142 ccsr_readl(pcie, PAB_AXI_AMAP_CTRL(i)));
143 }
144}
145
146static void ls_pcie_g4_setup_wins(struct ls_pcie_g4 *pcie)
147{
148 struct pci_region *io, *mem, *pref;
149 int idx = 1;
150
151
152 ls_pcie_g4_rc_inbound_win_set(pcie, 0, IB_TYPE_MEM_F, 0, 0, SIZE_1T);
153
154
155 ls_pcie_g4_outbound_win_set(pcie, 0, PAB_AXI_TYPE_CFG,
156 pcie->cfg_res.start, 0,
157 fdt_resource_size(&pcie->cfg_res));
158
159 pci_get_regions(pcie->bus, &io, &mem, &pref);
160
161 if (io)
162
163 ls_pcie_g4_outbound_win_set(pcie, idx++, PAB_AXI_TYPE_IO,
164 io->phys_start, io->bus_start,
165 io->size);
166
167 if (mem)
168
169 ls_pcie_g4_outbound_win_set(pcie, idx++, PAB_AXI_TYPE_MEM,
170 mem->phys_start, mem->bus_start,
171 mem->size);
172
173 if (pref)
174
175 ls_pcie_g4_outbound_win_set(pcie, idx++, PAB_AXI_TYPE_MEM,
176 pref->phys_start, pref->bus_start,
177 pref->size);
178
179 ls_pcie_g4_dump_wins(pcie, idx);
180}
181
182
183static int ls_pcie_g4_addr_valid(struct ls_pcie_g4 *pcie, pci_dev_t bdf)
184{
185 struct udevice *bus = pcie->bus;
186
187 if (pcie->mode == PCI_HEADER_TYPE_NORMAL)
188 return -ENODEV;
189
190 if (!pcie->enabled)
191 return -ENXIO;
192
193 if (PCI_BUS(bdf) < bus->seq)
194 return -EINVAL;
195
196 if ((PCI_BUS(bdf) > bus->seq) && (!ls_pcie_g4_link_up(pcie)))
197 return -EINVAL;
198
199 if (PCI_BUS(bdf) <= (bus->seq + 1) && (PCI_DEV(bdf) > 0))
200 return -EINVAL;
201
202 return 0;
203}
204
205void *ls_pcie_g4_conf_address(struct ls_pcie_g4 *pcie, pci_dev_t bdf,
206 int offset)
207{
208 struct udevice *bus = pcie->bus;
209 u32 target;
210
211 if (PCI_BUS(bdf) == bus->seq) {
212 if (offset < INDIRECT_ADDR_BNDRY) {
213 ccsr_set_page(pcie, 0);
214 return pcie->ccsr + offset;
215 }
216
217 ccsr_set_page(pcie, OFFSET_TO_PAGE_IDX(offset));
218 return pcie->ccsr + OFFSET_TO_PAGE_ADDR(offset);
219 }
220
221 target = PAB_TARGET_BUS(PCI_BUS(bdf) - bus->seq) |
222 PAB_TARGET_DEV(PCI_DEV(bdf)) |
223 PAB_TARGET_FUNC(PCI_FUNC(bdf));
224
225 ls_pcie_g4_cfg_set_target(pcie, target);
226
227 return pcie->cfg + offset;
228}
229
230static int ls_pcie_g4_read_config(struct udevice *bus, pci_dev_t bdf,
231 uint offset, ulong *valuep,
232 enum pci_size_t size)
233{
234 struct ls_pcie_g4 *pcie = dev_get_priv(bus);
235 void *address;
236 int ret = 0;
237
238 if (ls_pcie_g4_addr_valid(pcie, bdf)) {
239 *valuep = pci_get_ff(size);
240 return 0;
241 }
242
243 address = ls_pcie_g4_conf_address(pcie, bdf, offset);
244
245 switch (size) {
246 case PCI_SIZE_8:
247 *valuep = readb(address);
248 break;
249 case PCI_SIZE_16:
250 *valuep = readw(address);
251 break;
252 case PCI_SIZE_32:
253 *valuep = readl(address);
254 break;
255 default:
256 ret = -EINVAL;
257 break;
258 }
259
260 return ret;
261}
262
263static int ls_pcie_g4_write_config(struct udevice *bus, pci_dev_t bdf,
264 uint offset, ulong value,
265 enum pci_size_t size)
266{
267 struct ls_pcie_g4 *pcie = dev_get_priv(bus);
268 void *address;
269
270 if (ls_pcie_g4_addr_valid(pcie, bdf))
271 return 0;
272
273 address = ls_pcie_g4_conf_address(pcie, bdf, offset);
274
275 switch (size) {
276 case PCI_SIZE_8:
277 writeb(value, address);
278 return 0;
279 case PCI_SIZE_16:
280 writew(value, address);
281 return 0;
282 case PCI_SIZE_32:
283 writel(value, address);
284 return 0;
285 default:
286 return -EINVAL;
287 }
288}
289
290static void ls_pcie_g4_setup_ctrl(struct ls_pcie_g4 *pcie)
291{
292 u32 val;
293
294
295 val = ccsr_readl(pcie, GPEX_CLASSCODE);
296 val &= ~(GPEX_CLASSCODE_MASK << GPEX_CLASSCODE_SHIFT);
297 val |= PCI_CLASS_BRIDGE_PCI << GPEX_CLASSCODE_SHIFT;
298 ccsr_writel(pcie, GPEX_CLASSCODE, val);
299
300
301 val = ccsr_readl(pcie, PAB_AXI_PIO_CTRL(0));
302 val |= APIO_EN | MEM_WIN_EN | IO_WIN_EN | CFG_WIN_EN;
303 ccsr_writel(pcie, PAB_AXI_PIO_CTRL(0), val);
304
305 ls_pcie_g4_setup_wins(pcie);
306
307 pcie->stream_id_cur = 0;
308}
309
310static void ls_pcie_g4_ep_inbound_win_set(struct ls_pcie_g4 *pcie, int pf,
311 int bar, u64 phys)
312{
313 u32 val;
314
315
316 if (bar == 1) {
317 ccsr_writel(pcie, PAB_PEX_BAR_AMAP(pf, bar), BAR_AMAP_EN);
318 return;
319 }
320
321 val = upper_32_bits(phys);
322 ccsr_writel(pcie, PAB_EXT_PEX_BAR_AMAP(pf, bar), val);
323 val = lower_32_bits(phys) | BAR_AMAP_EN;
324 ccsr_writel(pcie, PAB_PEX_BAR_AMAP(pf, bar), val);
325}
326
327static void ls_pcie_g4_ep_setup_wins(struct ls_pcie_g4 *pcie, int pf)
328{
329 u64 phys;
330 int bar;
331 u32 val;
332
333 if ((!pcie->sriov_support && pf > LS_G4_PF0) || pf > LS_G4_PF1)
334 return;
335
336 phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + PCIE_BAR_SIZE * 4 * pf;
337 for (bar = 0; bar < PF_BAR_NUM; bar++) {
338 ls_pcie_g4_ep_inbound_win_set(pcie, pf, bar, phys);
339 phys += PCIE_BAR_SIZE;
340 }
341
342
343 ls_pcie_g4_outbound_win_set(pcie, pf, PAB_AXI_TYPE_MEM,
344 pcie->cfg_res.start +
345 CONFIG_SYS_PCI_MEMORY_SIZE * pf, 0x0,
346 CONFIG_SYS_PCI_MEMORY_SIZE);
347
348 val = ccsr_readl(pcie, PAB_AXI_AMAP_PCI_HDR_PARAM(pf));
349 val &= ~FUNC_NUM_PCIE_MASK;
350 val |= pf;
351 ccsr_writel(pcie, PAB_AXI_AMAP_PCI_HDR_PARAM(pf), val);
352}
353
354static void ls_pcie_g4_ep_enable_bar(struct ls_pcie_g4 *pcie, int pf,
355 int bar, bool vf_bar, bool enable)
356{
357 u32 val;
358 u32 bar_pos = BAR_POS(bar, pf, vf_bar);
359
360 val = ccsr_readl(pcie, GPEX_BAR_ENABLE);
361 if (enable)
362 val |= 1 << bar_pos;
363 else
364 val &= ~(1 << bar_pos);
365 ccsr_writel(pcie, GPEX_BAR_ENABLE, val);
366}
367
368static void ls_pcie_g4_ep_set_bar_size(struct ls_pcie_g4 *pcie, int pf,
369 int bar, bool vf_bar, u64 size)
370{
371 u32 bar_pos = BAR_POS(bar, pf, vf_bar);
372 u32 mask_l = lower_32_bits(~(size - 1));
373 u32 mask_h = upper_32_bits(~(size - 1));
374
375 ccsr_writel(pcie, GPEX_BAR_SELECT, bar_pos);
376 ccsr_writel(pcie, GPEX_BAR_SIZE_LDW, mask_l);
377 ccsr_writel(pcie, GPEX_BAR_SIZE_UDW, mask_h);
378}
379
380static void ls_pcie_g4_ep_setup_bar(struct ls_pcie_g4 *pcie, int pf,
381 int bar, bool vf_bar, u64 size)
382{
383 bool en = size ? true : false;
384
385 ls_pcie_g4_ep_enable_bar(pcie, pf, bar, vf_bar, en);
386 ls_pcie_g4_ep_set_bar_size(pcie, pf, bar, vf_bar, size);
387}
388
389static void ls_pcie_g4_ep_setup_bars(struct ls_pcie_g4 *pcie, int pf)
390{
391 int bar;
392
393
394 for (bar = 0; bar < PF_BAR_NUM; bar++)
395 ls_pcie_g4_ep_setup_bar(pcie, pf, bar, false, bar_size[bar]);
396
397 if (!pcie->sriov_support)
398 return;
399
400
401 for (bar = 0; bar < VF_BAR_NUM; bar++)
402 ls_pcie_g4_ep_setup_bar(pcie, pf, bar, true, bar_size[bar]);
403}
404
405static void ls_pcie_g4_set_sriov(struct ls_pcie_g4 *pcie, int pf)
406{
407 unsigned int val;
408
409 val = ccsr_readl(pcie, GPEX_SRIOV_INIT_VFS_TOTAL_VF(pf));
410 val &= ~(TTL_VF_MASK << TTL_VF_SHIFT);
411 val |= PCIE_VF_NUM << TTL_VF_SHIFT;
412 val &= ~(INI_VF_MASK << INI_VF_SHIFT);
413 val |= PCIE_VF_NUM << INI_VF_SHIFT;
414 ccsr_writel(pcie, GPEX_SRIOV_INIT_VFS_TOTAL_VF(pf), val);
415
416 val = ccsr_readl(pcie, PCIE_SRIOV_VF_OFFSET_STRIDE);
417 val += PCIE_VF_NUM * pf - pf;
418 ccsr_writel(pcie, GPEX_SRIOV_VF_OFFSET_STRIDE(pf), val);
419}
420
421static void ls_pcie_g4_setup_ep(struct ls_pcie_g4 *pcie)
422{
423 u32 pf, sriov;
424 u32 val;
425 int i;
426
427
428 val = ccsr_readl(pcie, PAB_AXI_PIO_CTRL(0));
429 val |= APIO_EN | MEM_WIN_EN;
430 ccsr_writel(pcie, PAB_AXI_PIO_CTRL(0), val);
431
432 sriov = ccsr_readl(pcie, PCIE_SRIOV_CAPABILITY);
433 if (PCI_EXT_CAP_ID(sriov) == PCI_EXT_CAP_ID_SRIOV)
434 pcie->sriov_support = 1;
435
436 pf = pcie->sriov_support ? PCIE_PF_NUM : 1;
437
438 for (i = 0; i < pf; i++) {
439 ls_pcie_g4_ep_setup_bars(pcie, i);
440 ls_pcie_g4_ep_setup_wins(pcie, i);
441 if (pcie->sriov_support)
442 ls_pcie_g4_set_sriov(pcie, i);
443 }
444
445 ls_pcie_g4_ep_enable_cfg(pcie);
446 ls_pcie_g4_dump_wins(pcie, pf);
447}
448
449static int ls_pcie_g4_probe(struct udevice *dev)
450{
451 struct ls_pcie_g4 *pcie = dev_get_priv(dev);
452 const void *fdt = gd->fdt_blob;
453 int node = dev_of_offset(dev);
454 u32 link_ctrl_sta;
455 u32 val;
456 int ret;
457
458 pcie->bus = dev;
459
460 ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
461 "ccsr", &pcie->ccsr_res);
462 if (ret) {
463 printf("ls-pcie-g4: resource \"ccsr\" not found\n");
464 return ret;
465 }
466
467 pcie->idx = (pcie->ccsr_res.start - PCIE_SYS_BASE_ADDR) /
468 PCIE_CCSR_SIZE;
469
470 list_add(&pcie->list, &ls_pcie_g4_list);
471
472 pcie->enabled = is_serdes_configured(PCIE_SRDS_PRTCL(pcie->idx));
473 if (!pcie->enabled) {
474 printf("PCIe%d: %s disabled\n", pcie->idx, dev->name);
475 return 0;
476 }
477
478 pcie->ccsr = map_physmem(pcie->ccsr_res.start,
479 fdt_resource_size(&pcie->ccsr_res),
480 MAP_NOCACHE);
481
482 ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
483 "config", &pcie->cfg_res);
484 if (ret) {
485 printf("%s: resource \"config\" not found\n", dev->name);
486 return ret;
487 }
488
489 pcie->cfg = map_physmem(pcie->cfg_res.start,
490 fdt_resource_size(&pcie->cfg_res),
491 MAP_NOCACHE);
492
493 ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
494 "lut", &pcie->lut_res);
495 if (ret) {
496 printf("ls-pcie-g4: resource \"lut\" not found\n");
497 return ret;
498 }
499
500 pcie->lut = map_physmem(pcie->lut_res.start,
501 fdt_resource_size(&pcie->lut_res),
502 MAP_NOCACHE);
503
504 ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
505 "pf_ctrl", &pcie->pf_ctrl_res);
506 if (ret) {
507 printf("ls-pcie-g4: resource \"pf_ctrl\" not found\n");
508 return ret;
509 }
510
511 pcie->pf_ctrl = map_physmem(pcie->pf_ctrl_res.start,
512 fdt_resource_size(&pcie->pf_ctrl_res),
513 MAP_NOCACHE);
514
515 pcie->big_endian = fdtdec_get_bool(fdt, node, "big-endian");
516
517 debug("%s ccsr:%lx, cfg:0x%lx, big-endian:%d\n",
518 dev->name, (unsigned long)pcie->ccsr, (unsigned long)pcie->cfg,
519 pcie->big_endian);
520
521 pcie->mode = readb(pcie->ccsr + PCI_HEADER_TYPE) & 0x7f;
522
523 if (pcie->mode == PCI_HEADER_TYPE_NORMAL) {
524 printf("PCIe%u: %s %s", pcie->idx, dev->name, "Endpoint");
525 ls_pcie_g4_setup_ep(pcie);
526 } else {
527 printf("PCIe%u: %s %s", pcie->idx, dev->name, "Root Complex");
528 ls_pcie_g4_setup_ctrl(pcie);
529 }
530
531
532 val = ccsr_readl(pcie, PAB_CTRL);
533 val |= PAB_CTRL_APIO_EN | PAB_CTRL_PPIO_EN;
534 ccsr_writel(pcie, PAB_CTRL, val);
535
536 val = ccsr_readl(pcie, PAB_PEX_PIO_CTRL(0));
537 val |= PPIO_EN;
538 ccsr_writel(pcie, PAB_PEX_PIO_CTRL(0), val);
539
540 if (!ls_pcie_g4_link_up(pcie)) {
541
542 printf(": no link\n");
543 return 0;
544 }
545
546
547 link_ctrl_sta = ccsr_readl(pcie, PCIE_LINK_CTRL_STA);
548 printf(": x%d gen%d\n",
549 (link_ctrl_sta >> PCIE_LINK_WIDTH_SHIFT & PCIE_LINK_WIDTH_MASK),
550 (link_ctrl_sta >> PCIE_LINK_SPEED_SHIFT) & PCIE_LINK_SPEED_MASK);
551
552 return 0;
553}
554
555static const struct dm_pci_ops ls_pcie_g4_ops = {
556 .read_config = ls_pcie_g4_read_config,
557 .write_config = ls_pcie_g4_write_config,
558};
559
560static const struct udevice_id ls_pcie_g4_ids[] = {
561 { .compatible = "fsl,lx2160a-pcie" },
562 { }
563};
564
565U_BOOT_DRIVER(pcie_layerscape_gen4) = {
566 .name = "pcie_layerscape_gen4",
567 .id = UCLASS_PCI,
568 .of_match = ls_pcie_g4_ids,
569 .ops = &ls_pcie_g4_ops,
570 .probe = ls_pcie_g4_probe,
571 .priv_auto_alloc_size = sizeof(struct ls_pcie_g4),
572};
573