1 // SPDX-License-Identifier: GPL-2.0+ OR X11
3 * Copyright 2018-2019 NXP
5 * PCIe Gen4 driver for NXP Layerscape SoCs
11 #include <asm/arch/fsl_serdes.h>
17 #include <linux/sizes.h>
19 #include "pcie_layerscape_gen4.h"
21 DECLARE_GLOBAL_DATA_PTR;
23 LIST_HEAD(ls_pcie_g4_list);
25 static u64 bar_size[4] = {
32 static int ls_pcie_g4_ltssm(struct ls_pcie_g4 *pcie)
36 state = pf_ctrl_readl(pcie, PCIE_LTSSM_STA) & LTSSM_STATE_MASK;
41 static int ls_pcie_g4_link_up(struct ls_pcie_g4 *pcie)
45 ltssm = ls_pcie_g4_ltssm(pcie);
46 if (ltssm != LTSSM_PCIE_L0)
52 static void ls_pcie_g4_ep_enable_cfg(struct ls_pcie_g4 *pcie)
54 ccsr_writel(pcie, GPEX_CFG_READY, PCIE_CONFIG_READY);
57 static void ls_pcie_g4_cfg_set_target(struct ls_pcie_g4 *pcie, u32 target)
59 ccsr_writel(pcie, PAB_AXI_AMAP_PEX_WIN_L(0), target);
60 ccsr_writel(pcie, PAB_AXI_AMAP_PEX_WIN_H(0), 0);
63 static int ls_pcie_g4_outbound_win_set(struct ls_pcie_g4 *pcie, int idx,
64 int type, u64 phys, u64 bus_addr,
70 if (idx >= PAB_WINS_NUM)
73 size_h = upper_32_bits(~(size - 1));
74 size_l = lower_32_bits(~(size - 1));
76 val = ccsr_readl(pcie, PAB_AXI_AMAP_CTRL(idx));
77 val &= ~((AXI_AMAP_CTRL_TYPE_MASK << AXI_AMAP_CTRL_TYPE_SHIFT) |
78 (AXI_AMAP_CTRL_SIZE_MASK << AXI_AMAP_CTRL_SIZE_SHIFT) |
80 val |= ((type & AXI_AMAP_CTRL_TYPE_MASK) << AXI_AMAP_CTRL_TYPE_SHIFT) |
81 ((size_l >> AXI_AMAP_CTRL_SIZE_SHIFT) <<
82 AXI_AMAP_CTRL_SIZE_SHIFT) | AXI_AMAP_CTRL_EN;
84 ccsr_writel(pcie, PAB_AXI_AMAP_CTRL(idx), val);
86 ccsr_writel(pcie, PAB_AXI_AMAP_AXI_WIN(idx), lower_32_bits(phys));
87 ccsr_writel(pcie, PAB_EXT_AXI_AMAP_AXI_WIN(idx), upper_32_bits(phys));
88 ccsr_writel(pcie, PAB_AXI_AMAP_PEX_WIN_L(idx), lower_32_bits(bus_addr));
89 ccsr_writel(pcie, PAB_AXI_AMAP_PEX_WIN_H(idx), upper_32_bits(bus_addr));
90 ccsr_writel(pcie, PAB_EXT_AXI_AMAP_SIZE(idx), size_h);
95 static int ls_pcie_g4_rc_inbound_win_set(struct ls_pcie_g4 *pcie, int idx,
96 int type, u64 phys, u64 bus_addr,
100 pci_size_t win_size = ~(size - 1);
102 val = ccsr_readl(pcie, PAB_PEX_AMAP_CTRL(idx));
104 val &= ~(PEX_AMAP_CTRL_TYPE_MASK << PEX_AMAP_CTRL_TYPE_SHIFT);
105 val &= ~(PEX_AMAP_CTRL_EN_MASK << PEX_AMAP_CTRL_EN_SHIFT);
106 val = (val | (type << PEX_AMAP_CTRL_TYPE_SHIFT));
107 val = (val | (1 << PEX_AMAP_CTRL_EN_SHIFT));
109 ccsr_writel(pcie, PAB_PEX_AMAP_CTRL(idx),
110 val | lower_32_bits(win_size));
112 ccsr_writel(pcie, PAB_EXT_PEX_AMAP_SIZE(idx), upper_32_bits(win_size));
113 ccsr_writel(pcie, PAB_PEX_AMAP_AXI_WIN(idx), lower_32_bits(phys));
114 ccsr_writel(pcie, PAB_EXT_PEX_AMAP_AXI_WIN(idx), upper_32_bits(phys));
115 ccsr_writel(pcie, PAB_PEX_AMAP_PEX_WIN_L(idx), lower_32_bits(bus_addr));
116 ccsr_writel(pcie, PAB_PEX_AMAP_PEX_WIN_H(idx), upper_32_bits(bus_addr));
121 static void ls_pcie_g4_dump_wins(struct ls_pcie_g4 *pcie, int wins)
125 for (i = 0; i < wins; i++) {
126 debug("APIO Win%d:\n", i);
127 debug("\tLOWER PHYS: 0x%08x\n",
128 ccsr_readl(pcie, PAB_AXI_AMAP_AXI_WIN(i)));
129 debug("\tUPPER PHYS: 0x%08x\n",
130 ccsr_readl(pcie, PAB_EXT_AXI_AMAP_AXI_WIN(i)));
131 debug("\tLOWER BUS: 0x%08x\n",
132 ccsr_readl(pcie, PAB_AXI_AMAP_PEX_WIN_L(i)));
133 debug("\tUPPER BUS: 0x%08x\n",
134 ccsr_readl(pcie, PAB_AXI_AMAP_PEX_WIN_H(i)));
135 debug("\tSIZE: 0x%08x\n",
136 ccsr_readl(pcie, PAB_AXI_AMAP_CTRL(i)) &
137 (AXI_AMAP_CTRL_SIZE_MASK << AXI_AMAP_CTRL_SIZE_SHIFT));
138 debug("\tEXT_SIZE: 0x%08x\n",
139 ccsr_readl(pcie, PAB_EXT_AXI_AMAP_SIZE(i)));
140 debug("\tPARAM: 0x%08x\n",
141 ccsr_readl(pcie, PAB_AXI_AMAP_PCI_HDR_PARAM(i)));
142 debug("\tCTRL: 0x%08x\n",
143 ccsr_readl(pcie, PAB_AXI_AMAP_CTRL(i)));
147 static void ls_pcie_g4_setup_wins(struct ls_pcie_g4 *pcie)
149 struct pci_region *io, *mem, *pref;
153 ls_pcie_g4_rc_inbound_win_set(pcie, 0, IB_TYPE_MEM_F, 0, 0, SIZE_1T);
155 /* OUTBOUND WIN 0: CFG */
156 ls_pcie_g4_outbound_win_set(pcie, 0, PAB_AXI_TYPE_CFG,
157 pcie->cfg_res.start, 0,
158 fdt_resource_size(&pcie->cfg_res));
160 pci_get_regions(pcie->bus, &io, &mem, &pref);
163 /* OUTBOUND WIN: IO */
164 ls_pcie_g4_outbound_win_set(pcie, idx++, PAB_AXI_TYPE_IO,
165 io->phys_start, io->bus_start,
169 /* OUTBOUND WIN: MEM */
170 ls_pcie_g4_outbound_win_set(pcie, idx++, PAB_AXI_TYPE_MEM,
171 mem->phys_start, mem->bus_start,
175 /* OUTBOUND WIN: perf MEM */
176 ls_pcie_g4_outbound_win_set(pcie, idx++, PAB_AXI_TYPE_MEM,
177 pref->phys_start, pref->bus_start,
180 ls_pcie_g4_dump_wins(pcie, idx);
183 /* Return 0 if the address is valid, -errno if not valid */
184 static int ls_pcie_g4_addr_valid(struct ls_pcie_g4 *pcie, pci_dev_t bdf)
186 struct udevice *bus = pcie->bus;
188 if (pcie->mode == PCI_HEADER_TYPE_NORMAL)
194 if (PCI_BUS(bdf) < bus->seq)
197 if ((PCI_BUS(bdf) > bus->seq) && (!ls_pcie_g4_link_up(pcie)))
200 if (PCI_BUS(bdf) <= (bus->seq + 1) && (PCI_DEV(bdf) > 0))
206 void *ls_pcie_g4_conf_address(struct ls_pcie_g4 *pcie, pci_dev_t bdf,
209 struct udevice *bus = pcie->bus;
212 if (PCI_BUS(bdf) == bus->seq) {
213 if (offset < INDIRECT_ADDR_BNDRY) {
214 ccsr_set_page(pcie, 0);
215 return pcie->ccsr + offset;
218 ccsr_set_page(pcie, OFFSET_TO_PAGE_IDX(offset));
219 return pcie->ccsr + OFFSET_TO_PAGE_ADDR(offset);
222 target = PAB_TARGET_BUS(PCI_BUS(bdf) - bus->seq) |
223 PAB_TARGET_DEV(PCI_DEV(bdf)) |
224 PAB_TARGET_FUNC(PCI_FUNC(bdf));
226 ls_pcie_g4_cfg_set_target(pcie, target);
228 return pcie->cfg + offset;
231 static int ls_pcie_g4_read_config(const struct udevice *bus, pci_dev_t bdf,
232 uint offset, ulong *valuep,
233 enum pci_size_t size)
235 struct ls_pcie_g4 *pcie = dev_get_priv(bus);
239 if (ls_pcie_g4_addr_valid(pcie, bdf)) {
240 *valuep = pci_get_ff(size);
244 address = ls_pcie_g4_conf_address(pcie, bdf, offset);
248 *valuep = readb(address);
251 *valuep = readw(address);
254 *valuep = readl(address);
264 static int ls_pcie_g4_write_config(struct udevice *bus, pci_dev_t bdf,
265 uint offset, ulong value,
266 enum pci_size_t size)
268 struct ls_pcie_g4 *pcie = dev_get_priv(bus);
271 if (ls_pcie_g4_addr_valid(pcie, bdf))
274 address = ls_pcie_g4_conf_address(pcie, bdf, offset);
278 writeb(value, address);
281 writew(value, address);
284 writel(value, address);
291 static void ls_pcie_g4_setup_ctrl(struct ls_pcie_g4 *pcie)
296 val = ccsr_readl(pcie, GPEX_CLASSCODE);
297 val &= ~(GPEX_CLASSCODE_MASK << GPEX_CLASSCODE_SHIFT);
298 val |= PCI_CLASS_BRIDGE_PCI << GPEX_CLASSCODE_SHIFT;
299 ccsr_writel(pcie, GPEX_CLASSCODE, val);
301 /* Enable APIO and Memory/IO/CFG Wins */
302 val = ccsr_readl(pcie, PAB_AXI_PIO_CTRL(0));
303 val |= APIO_EN | MEM_WIN_EN | IO_WIN_EN | CFG_WIN_EN;
304 ccsr_writel(pcie, PAB_AXI_PIO_CTRL(0), val);
306 ls_pcie_g4_setup_wins(pcie);
308 pcie->stream_id_cur = 0;
311 static void ls_pcie_g4_ep_inbound_win_set(struct ls_pcie_g4 *pcie, int pf,
316 /* PF BAR1 is for MSI-X and only need to enable */
318 ccsr_writel(pcie, PAB_PEX_BAR_AMAP(pf, bar), BAR_AMAP_EN);
322 val = upper_32_bits(phys);
323 ccsr_writel(pcie, PAB_EXT_PEX_BAR_AMAP(pf, bar), val);
324 val = lower_32_bits(phys) | BAR_AMAP_EN;
325 ccsr_writel(pcie, PAB_PEX_BAR_AMAP(pf, bar), val);
328 static void ls_pcie_g4_ep_setup_wins(struct ls_pcie_g4 *pcie, int pf)
334 if ((!pcie->sriov_support && pf > LS_G4_PF0) || pf > LS_G4_PF1)
337 phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + PCIE_BAR_SIZE * 4 * pf;
338 for (bar = 0; bar < PF_BAR_NUM; bar++) {
339 ls_pcie_g4_ep_inbound_win_set(pcie, pf, bar, phys);
340 phys += PCIE_BAR_SIZE;
343 /* OUTBOUND: map MEM */
344 ls_pcie_g4_outbound_win_set(pcie, pf, PAB_AXI_TYPE_MEM,
345 pcie->cfg_res.start +
346 CONFIG_SYS_PCI_MEMORY_SIZE * pf, 0x0,
347 CONFIG_SYS_PCI_MEMORY_SIZE);
349 val = ccsr_readl(pcie, PAB_AXI_AMAP_PCI_HDR_PARAM(pf));
350 val &= ~FUNC_NUM_PCIE_MASK;
352 ccsr_writel(pcie, PAB_AXI_AMAP_PCI_HDR_PARAM(pf), val);
355 static void ls_pcie_g4_ep_enable_bar(struct ls_pcie_g4 *pcie, int pf,
356 int bar, bool vf_bar, bool enable)
359 u32 bar_pos = BAR_POS(bar, pf, vf_bar);
361 val = ccsr_readl(pcie, GPEX_BAR_ENABLE);
365 val &= ~(1 << bar_pos);
366 ccsr_writel(pcie, GPEX_BAR_ENABLE, val);
369 static void ls_pcie_g4_ep_set_bar_size(struct ls_pcie_g4 *pcie, int pf,
370 int bar, bool vf_bar, u64 size)
372 u32 bar_pos = BAR_POS(bar, pf, vf_bar);
373 u32 mask_l = lower_32_bits(~(size - 1));
374 u32 mask_h = upper_32_bits(~(size - 1));
376 ccsr_writel(pcie, GPEX_BAR_SELECT, bar_pos);
377 ccsr_writel(pcie, GPEX_BAR_SIZE_LDW, mask_l);
378 ccsr_writel(pcie, GPEX_BAR_SIZE_UDW, mask_h);
381 static void ls_pcie_g4_ep_setup_bar(struct ls_pcie_g4 *pcie, int pf,
382 int bar, bool vf_bar, u64 size)
384 bool en = size ? true : false;
386 ls_pcie_g4_ep_enable_bar(pcie, pf, bar, vf_bar, en);
387 ls_pcie_g4_ep_set_bar_size(pcie, pf, bar, vf_bar, size);
390 static void ls_pcie_g4_ep_setup_bars(struct ls_pcie_g4 *pcie, int pf)
395 for (bar = 0; bar < PF_BAR_NUM; bar++)
396 ls_pcie_g4_ep_setup_bar(pcie, pf, bar, false, bar_size[bar]);
398 if (!pcie->sriov_support)
402 for (bar = 0; bar < VF_BAR_NUM; bar++)
403 ls_pcie_g4_ep_setup_bar(pcie, pf, bar, true, bar_size[bar]);
406 static void ls_pcie_g4_set_sriov(struct ls_pcie_g4 *pcie, int pf)
410 val = ccsr_readl(pcie, GPEX_SRIOV_INIT_VFS_TOTAL_VF(pf));
411 val &= ~(TTL_VF_MASK << TTL_VF_SHIFT);
412 val |= PCIE_VF_NUM << TTL_VF_SHIFT;
413 val &= ~(INI_VF_MASK << INI_VF_SHIFT);
414 val |= PCIE_VF_NUM << INI_VF_SHIFT;
415 ccsr_writel(pcie, GPEX_SRIOV_INIT_VFS_TOTAL_VF(pf), val);
417 val = ccsr_readl(pcie, PCIE_SRIOV_VF_OFFSET_STRIDE);
418 val += PCIE_VF_NUM * pf - pf;
419 ccsr_writel(pcie, GPEX_SRIOV_VF_OFFSET_STRIDE(pf), val);
422 static void ls_pcie_g4_setup_ep(struct ls_pcie_g4 *pcie)
428 /* Enable APIO and Memory Win */
429 val = ccsr_readl(pcie, PAB_AXI_PIO_CTRL(0));
430 val |= APIO_EN | MEM_WIN_EN;
431 ccsr_writel(pcie, PAB_AXI_PIO_CTRL(0), val);
433 sriov = ccsr_readl(pcie, PCIE_SRIOV_CAPABILITY);
434 if (PCI_EXT_CAP_ID(sriov) == PCI_EXT_CAP_ID_SRIOV)
435 pcie->sriov_support = 1;
437 pf = pcie->sriov_support ? PCIE_PF_NUM : 1;
439 for (i = 0; i < pf; i++) {
440 ls_pcie_g4_ep_setup_bars(pcie, i);
441 ls_pcie_g4_ep_setup_wins(pcie, i);
442 if (pcie->sriov_support)
443 ls_pcie_g4_set_sriov(pcie, i);
446 ls_pcie_g4_ep_enable_cfg(pcie);
447 ls_pcie_g4_dump_wins(pcie, pf);
450 static int ls_pcie_g4_probe(struct udevice *dev)
452 struct ls_pcie_g4 *pcie = dev_get_priv(dev);
453 const void *fdt = gd->fdt_blob;
454 int node = dev_of_offset(dev);
461 ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
462 "ccsr", &pcie->ccsr_res);
464 printf("ls-pcie-g4: resource \"ccsr\" not found\n");
468 pcie->idx = (pcie->ccsr_res.start - PCIE_SYS_BASE_ADDR) /
471 list_add(&pcie->list, &ls_pcie_g4_list);
473 pcie->enabled = is_serdes_configured(PCIE_SRDS_PRTCL(pcie->idx));
474 if (!pcie->enabled) {
475 printf("PCIe%d: %s disabled\n", pcie->idx, dev->name);
479 pcie->ccsr = map_physmem(pcie->ccsr_res.start,
480 fdt_resource_size(&pcie->ccsr_res),
483 ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
484 "config", &pcie->cfg_res);
486 printf("%s: resource \"config\" not found\n", dev->name);
490 pcie->cfg = map_physmem(pcie->cfg_res.start,
491 fdt_resource_size(&pcie->cfg_res),
494 ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
495 "lut", &pcie->lut_res);
497 printf("ls-pcie-g4: resource \"lut\" not found\n");
501 pcie->lut = map_physmem(pcie->lut_res.start,
502 fdt_resource_size(&pcie->lut_res),
505 ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
506 "pf_ctrl", &pcie->pf_ctrl_res);
508 printf("ls-pcie-g4: resource \"pf_ctrl\" not found\n");
512 pcie->pf_ctrl = map_physmem(pcie->pf_ctrl_res.start,
513 fdt_resource_size(&pcie->pf_ctrl_res),
516 pcie->big_endian = fdtdec_get_bool(fdt, node, "big-endian");
518 debug("%s ccsr:%lx, cfg:0x%lx, big-endian:%d\n",
519 dev->name, (unsigned long)pcie->ccsr, (unsigned long)pcie->cfg,
522 pcie->mode = readb(pcie->ccsr + PCI_HEADER_TYPE) & 0x7f;
524 if (pcie->mode == PCI_HEADER_TYPE_NORMAL) {
525 printf("PCIe%u: %s %s", pcie->idx, dev->name, "Endpoint");
526 ls_pcie_g4_setup_ep(pcie);
528 printf("PCIe%u: %s %s", pcie->idx, dev->name, "Root Complex");
529 ls_pcie_g4_setup_ctrl(pcie);
532 /* Enable Amba & PEX PIO */
533 val = ccsr_readl(pcie, PAB_CTRL);
534 val |= PAB_CTRL_APIO_EN | PAB_CTRL_PPIO_EN;
535 ccsr_writel(pcie, PAB_CTRL, val);
537 val = ccsr_readl(pcie, PAB_PEX_PIO_CTRL(0));
539 ccsr_writel(pcie, PAB_PEX_PIO_CTRL(0), val);
541 if (!ls_pcie_g4_link_up(pcie)) {
542 /* Let the user know there's no PCIe link */
543 printf(": no link\n");
547 /* Print the negotiated PCIe link width */
548 link_ctrl_sta = ccsr_readl(pcie, PCIE_LINK_CTRL_STA);
549 printf(": x%d gen%d\n",
550 (link_ctrl_sta >> PCIE_LINK_WIDTH_SHIFT & PCIE_LINK_WIDTH_MASK),
551 (link_ctrl_sta >> PCIE_LINK_SPEED_SHIFT) & PCIE_LINK_SPEED_MASK);
556 static const struct dm_pci_ops ls_pcie_g4_ops = {
557 .read_config = ls_pcie_g4_read_config,
558 .write_config = ls_pcie_g4_write_config,
561 static const struct udevice_id ls_pcie_g4_ids[] = {
562 { .compatible = "fsl,lx2160a-pcie" },
566 U_BOOT_DRIVER(pcie_layerscape_gen4) = {
567 .name = "pcie_layerscape_gen4",
569 .of_match = ls_pcie_g4_ids,
570 .ops = &ls_pcie_g4_ops,
571 .probe = ls_pcie_g4_probe,
572 .priv_auto_alloc_size = sizeof(struct ls_pcie_g4),