1 // SPDX-License-Identifier: GPL-2.0+ OR X11
5 * PCIe DM U-Boot driver for Freescale PowerPC SoCs
6 * Author: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
14 #include <asm/fsl_pci.h>
15 #include <asm/fsl_serdes.h>
19 LIST_HEAD(fsl_pcie_list);
21 static int fsl_pcie_link_up(struct fsl_pcie *pcie);
23 static int fsl_pcie_addr_valid(struct fsl_pcie *pcie, pci_dev_t bdf)
25 struct udevice *bus = pcie->bus;
30 if (PCI_BUS(bdf) < bus->seq)
33 if (PCI_BUS(bdf) > bus->seq && (!fsl_pcie_link_up(pcie) || pcie->mode))
36 if (PCI_BUS(bdf) == bus->seq && (PCI_DEV(bdf) > 0 || PCI_FUNC(bdf) > 0))
39 if (PCI_BUS(bdf) == (bus->seq + 1) && (PCI_DEV(bdf) > 0))
45 static int fsl_pcie_read_config(struct udevice *bus, pci_dev_t bdf,
46 uint offset, ulong *valuep,
49 struct fsl_pcie *pcie = dev_get_priv(bus);
50 ccsr_fsl_pci_t *regs = pcie->regs;
53 if (fsl_pcie_addr_valid(pcie, bdf)) {
54 *valuep = pci_get_ff(size);
58 bdf = bdf - PCI_BDF(bus->seq, 0, 0);
59 val = bdf | (offset & 0xfc) | ((offset & 0xf00) << 16) | 0x80000000;
60 out_be32(®s->cfg_addr, val);
66 *valuep = in_8((u8 *)®s->cfg_data + (offset & 3));
69 *valuep = in_le16((u16 *)((u8 *)®s->cfg_data +
73 *valuep = in_le32(®s->cfg_data);
80 static int fsl_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
81 uint offset, ulong value,
84 struct fsl_pcie *pcie = dev_get_priv(bus);
85 ccsr_fsl_pci_t *regs = pcie->regs;
91 if (fsl_pcie_addr_valid(pcie, bdf))
94 bdf = bdf - PCI_BDF(bus->seq, 0, 0);
95 val = bdf | (offset & 0xfc) | ((offset & 0xf00) << 16) | 0x80000000;
96 out_be32(®s->cfg_addr, val);
103 out_8((u8 *)®s->cfg_data + (offset & 3), val_8);
107 out_le16((u16 *)((u8 *)®s->cfg_data + (offset & 2)), val_16);
111 out_le32(®s->cfg_data, val_32);
118 static int fsl_pcie_hose_read_config(struct fsl_pcie *pcie, uint offset,
119 ulong *valuep, enum pci_size_t size)
122 struct udevice *bus = pcie->bus;
124 ret = fsl_pcie_read_config(bus, PCI_BDF(bus->seq, 0, 0),
125 offset, valuep, size);
130 static int fsl_pcie_hose_write_config(struct fsl_pcie *pcie, uint offset,
131 ulong value, enum pci_size_t size)
133 struct udevice *bus = pcie->bus;
135 return fsl_pcie_write_config(bus, PCI_BDF(bus->seq, 0, 0),
136 offset, value, size);
139 static int fsl_pcie_hose_read_config_byte(struct fsl_pcie *pcie, uint offset,
145 ret = fsl_pcie_hose_read_config(pcie, offset, &val, PCI_SIZE_8);
151 static int fsl_pcie_hose_read_config_word(struct fsl_pcie *pcie, uint offset,
157 ret = fsl_pcie_hose_read_config(pcie, offset, &val, PCI_SIZE_16);
163 static int fsl_pcie_hose_read_config_dword(struct fsl_pcie *pcie, uint offset,
169 ret = fsl_pcie_hose_read_config(pcie, offset, &val, PCI_SIZE_32);
175 static int fsl_pcie_hose_write_config_byte(struct fsl_pcie *pcie, uint offset,
178 return fsl_pcie_hose_write_config(pcie, offset, value, PCI_SIZE_8);
181 static int fsl_pcie_hose_write_config_word(struct fsl_pcie *pcie, uint offset,
184 return fsl_pcie_hose_write_config(pcie, offset, value, PCI_SIZE_16);
187 static int fsl_pcie_hose_write_config_dword(struct fsl_pcie *pcie, uint offset,
190 return fsl_pcie_hose_write_config(pcie, offset, value, PCI_SIZE_32);
193 static int fsl_pcie_link_up(struct fsl_pcie *pcie)
195 ccsr_fsl_pci_t *regs = pcie->regs;
198 if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) {
199 ltssm = (in_be32(®s->pex_csr0)
200 & PEX_CSR0_LTSSM_MASK) >> PEX_CSR0_LTSSM_SHIFT;
201 return ltssm == LTSSM_L0_REV3;
204 fsl_pcie_hose_read_config_word(pcie, PCI_LTSSM, <ssm);
206 return ltssm == LTSSM_L0;
209 static bool fsl_pcie_is_agent(struct fsl_pcie *pcie)
213 fsl_pcie_hose_read_config_byte(pcie, PCI_HEADER_TYPE, &header_type);
215 return (header_type & 0x7f) == PCI_HEADER_TYPE_NORMAL;
218 static int fsl_pcie_setup_law(struct fsl_pcie *pcie)
220 struct pci_region *io, *mem, *pref;
222 pci_get_regions(pcie->bus, &io, &mem, &pref);
225 set_next_law(mem->phys_start,
226 law_size_bits(mem->size),
230 set_next_law(io->phys_start,
231 law_size_bits(io->size),
237 static void fsl_pcie_config_ready(struct fsl_pcie *pcie)
239 ccsr_fsl_pci_t *regs = pcie->regs;
241 if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) {
242 setbits_be32(®s->config, FSL_PCIE_V3_CFG_RDY);
246 fsl_pcie_hose_write_config_byte(pcie, FSL_PCIE_CFG_RDY, 0x1);
249 static int fsl_pcie_setup_outbound_win(struct fsl_pcie *pcie, int idx,
250 int type, u64 phys, u64 bus_addr,
253 ccsr_fsl_pci_t *regs = pcie->regs;
254 pot_t *po = ®s->pot[idx];
260 out_be32(&po->powbar, phys >> 12);
261 out_be32(&po->potar, bus_addr >> 12);
262 #ifdef CONFIG_SYS_PCI_64BIT
263 out_be32(&po->potear, bus_addr >> 44);
265 out_be32(&po->potear, 0);
268 sz = (__ilog2_u64((u64)size) - 1);
271 if (type == PCI_REGION_IO)
272 war |= POWAR_IO_READ | POWAR_IO_WRITE;
274 war |= POWAR_MEM_READ | POWAR_MEM_WRITE;
276 out_be32(&po->powar, war);
281 static int fsl_pcie_setup_inbound_win(struct fsl_pcie *pcie, int idx,
282 bool pf, u64 phys, u64 bus_addr,
285 ccsr_fsl_pci_t *regs = pcie->regs;
286 pit_t *pi = ®s->pit[idx];
287 u32 sz = (__ilog2_u64(size) - 1);
288 u32 flag = PIWAR_LOCAL;
293 out_be32(&pi->pitar, phys >> 12);
294 out_be32(&pi->piwbar, bus_addr >> 12);
296 #ifdef CONFIG_SYS_PCI_64BIT
297 out_be32(&pi->piwbear, bus_addr >> 44);
299 out_be32(&pi->piwbear, 0);
302 #ifdef CONFIG_SYS_FSL_ERRATUM_A005434
306 flag |= PIWAR_EN | PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP;
309 out_be32(&pi->piwar, flag | sz);
314 static int fsl_pcie_setup_outbound_wins(struct fsl_pcie *pcie)
316 struct pci_region *io, *mem, *pref;
317 int idx = 1; /* skip 0 */
319 pci_get_regions(pcie->bus, &io, &mem, &pref);
322 /* ATU : OUTBOUND : IO */
323 fsl_pcie_setup_outbound_win(pcie, idx++,
330 /* ATU : OUTBOUND : MEM */
331 fsl_pcie_setup_outbound_win(pcie, idx++,
339 static int fsl_pcie_setup_inbound_wins(struct fsl_pcie *pcie)
341 phys_addr_t phys_start = CONFIG_SYS_PCI_MEMORY_PHYS;
342 pci_addr_t bus_start = CONFIG_SYS_PCI_MEMORY_BUS;
343 u64 sz = min((u64)gd->ram_size, (1ull << 32));
347 if (pcie->block_rev >= PEX_IP_BLK_REV_2_2)
352 pci_sz = 1ull << __ilog2_u64(sz);
354 dev_dbg(pcie->bus, "R0 bus_start: %llx phys_start: %llx size: %llx\n",
355 (u64)bus_start, (u64)phys_start, (u64)sz);
357 /* if we aren't an exact power of two match, pci_sz is smaller
358 * round it up to the next power of two. We report the actual
359 * size to pci region tracking.
362 sz = 2ull << __ilog2_u64(sz);
364 fsl_pcie_setup_inbound_win(pcie, idx--, true,
365 CONFIG_SYS_PCI_MEMORY_PHYS,
366 CONFIG_SYS_PCI_MEMORY_BUS, sz);
367 #if defined(CONFIG_PHYS_64BIT) && defined(CONFIG_SYS_PCI_64BIT)
369 * On 64-bit capable systems, set up a mapping for all of DRAM
370 * in high pci address space.
372 pci_sz = 1ull << __ilog2_u64(gd->ram_size);
373 /* round up to the next largest power of two */
374 if (gd->ram_size > pci_sz)
375 pci_sz = 1ull << (__ilog2_u64(gd->ram_size) + 1);
377 dev_dbg(pcie->bus, "R64 bus_start: %llx phys_start: %llx size: %llx\n",
378 (u64)CONFIG_SYS_PCI64_MEMORY_BUS,
379 (u64)CONFIG_SYS_PCI_MEMORY_PHYS, (u64)pci_sz);
381 fsl_pcie_setup_inbound_win(pcie, idx--, true,
382 CONFIG_SYS_PCI_MEMORY_PHYS,
383 CONFIG_SYS_PCI64_MEMORY_BUS, pci_sz);
389 static int fsl_pcie_init_atmu(struct fsl_pcie *pcie)
391 fsl_pcie_setup_outbound_wins(pcie);
392 fsl_pcie_setup_inbound_wins(pcie);
397 static int fsl_pcie_init_port(struct fsl_pcie *pcie)
399 ccsr_fsl_pci_t *regs = pcie->regs;
403 fsl_pcie_init_atmu(pcie);
405 #ifdef CONFIG_FSL_PCIE_DISABLE_ASPM
407 fsl_pcie_hose_read_config_dword(pcie, PCI_LCR, &val_32);
409 fsl_pcie_hose_write_config_dword(pcie, PCI_LCR, val_32);
413 #ifdef CONFIG_FSL_PCIE_RESET
417 if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) {
418 /* assert PCIe reset */
419 setbits_be32(®s->pdb_stat, 0x08000000);
420 (void)in_be32(®s->pdb_stat);
422 /* clear PCIe reset */
423 clrbits_be32(®s->pdb_stat, 0x08000000);
425 for (i = 0; i < 100 && !fsl_pcie_link_up(pcie); i++)
428 fsl_pcie_hose_read_config_word(pcie, PCI_LTSSM, <ssm);
430 /* assert PCIe reset */
431 setbits_be32(®s->pdb_stat, 0x08000000);
432 (void)in_be32(®s->pdb_stat);
434 /* clear PCIe reset */
435 clrbits_be32(®s->pdb_stat, 0x08000000);
437 for (i = 0; i < 100 &&
438 !fsl_pcie_link_up(pcie); i++)
444 #ifdef CONFIG_SYS_P4080_ERRATUM_PCIE_A003
445 if (!fsl_pcie_link_up(pcie)) {
446 serdes_corenet_t *srds_regs;
448 srds_regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
449 val_32 = in_be32(&srds_regs->srdspccr0);
451 if ((val_32 >> 28) == 3) {
454 out_be32(&srds_regs->srdspccr0, 2 << 28);
455 setbits_be32(®s->pdb_stat, 0x08000000);
456 in_be32(®s->pdb_stat);
458 clrbits_be32(®s->pdb_stat, 0x08000000);
460 for (i = 0; i < 100 && !fsl_pcie_link_up(pcie); i++)
467 * The Read-Only Write Enable bit defaults to 1 instead of 0.
468 * Set to 0 to protect the read-only registers.
470 #ifdef CONFIG_SYS_FSL_ERRATUM_A007815
471 clrbits_be32(®s->dbi_ro_wr_en, 0x01);
475 * Enable All Error Interrupts except
476 * - Master abort (pci)
477 * - Master PERR (pci)
480 out_be32(®s->peer, ~0x20140);
482 /* set URR, FER, NFER (but not CER) */
483 fsl_pcie_hose_read_config_dword(pcie, PCI_DCR, &val_32);
485 fsl_pcie_hose_write_config_dword(pcie, PCI_DCR, val_32);
487 /* Clear all error indications */
488 out_be32(®s->pme_msg_det, 0xffffffff);
489 out_be32(®s->pme_msg_int_en, 0xffffffff);
490 out_be32(®s->pedr, 0xffffffff);
492 fsl_pcie_hose_read_config_word(pcie, PCI_DSR, &val_16);
494 fsl_pcie_hose_write_config_word(pcie, PCI_DSR, 0xffff);
496 fsl_pcie_hose_read_config_word(pcie, PCI_SEC_STATUS, &val_16);
498 fsl_pcie_hose_write_config_word(pcie, PCI_SEC_STATUS, 0xffff);
503 static int fsl_pcie_fixup_classcode(struct fsl_pcie *pcie)
505 ccsr_fsl_pci_t *regs = pcie->regs;
508 setbits_be32(®s->dbi_ro_wr_en, 0x01);
509 fsl_pcie_hose_read_config_dword(pcie, PCI_CLASS_REVISION, &val);
511 val |= PCI_CLASS_BRIDGE_PCI << 16;
512 fsl_pcie_hose_write_config_dword(pcie, PCI_CLASS_REVISION, val);
513 clrbits_be32(®s->dbi_ro_wr_en, 0x01);
518 static int fsl_pcie_init_rc(struct fsl_pcie *pcie)
520 return fsl_pcie_fixup_classcode(pcie);
523 static int fsl_pcie_init_ep(struct fsl_pcie *pcie)
525 fsl_pcie_config_ready(pcie);
530 static int fsl_pcie_probe(struct udevice *dev)
532 struct fsl_pcie *pcie = dev_get_priv(dev);
533 ccsr_fsl_pci_t *regs = pcie->regs;
537 pcie->block_rev = in_be32(®s->block_rev1);
539 list_add(&pcie->list, &fsl_pcie_list);
540 pcie->enabled = is_serdes_configured(PCIE1 + pcie->idx);
541 if (!pcie->enabled) {
542 printf("PCIe%d: %s disabled\n", pcie->idx, dev->name);
546 fsl_pcie_setup_law(pcie);
548 pcie->mode = fsl_pcie_is_agent(pcie);
550 fsl_pcie_init_port(pcie);
552 printf("PCIe%d: %s ", pcie->idx, dev->name);
556 fsl_pcie_init_ep(pcie);
558 printf("Root Complex");
559 fsl_pcie_init_rc(pcie);
562 if (!fsl_pcie_link_up(pcie)) {
563 printf(": %s\n", pcie->mode ? "undetermined link" : "no link");
567 fsl_pcie_hose_read_config_word(pcie, PCI_LSR, &val_16);
568 printf(": x%d gen%d\n", (val_16 & 0x3f0) >> 4, (val_16 & 0xf));
573 static int fsl_pcie_ofdata_to_platdata(struct udevice *dev)
575 struct fsl_pcie *pcie = dev_get_priv(dev);
578 pcie->regs = dev_remap_addr(dev);
580 pr_err("\"reg\" resource not found\n");
584 ret = dev_read_u32(dev, "law_trgt_if", &pcie->law_trgt_if);
586 pr_err("\"law_trgt_if\" not found\n");
590 pcie->idx = (dev_read_addr(dev) - 0xffe240000) / 0x10000;
595 static const struct dm_pci_ops fsl_pcie_ops = {
596 .read_config = fsl_pcie_read_config,
597 .write_config = fsl_pcie_write_config,
600 static const struct udevice_id fsl_pcie_ids[] = {
601 { .compatible = "fsl,pcie-t2080" },
605 U_BOOT_DRIVER(fsl_pcie) = {
608 .of_match = fsl_pcie_ids,
609 .ops = &fsl_pcie_ops,
610 .ofdata_to_platdata = fsl_pcie_ofdata_to_platdata,
611 .probe = fsl_pcie_probe,
612 .priv_auto_alloc_size = sizeof(struct fsl_pcie),