Hi, On Fri, 3 May 2019 at 20:03, Z.q. Hou <zhiqiang....@nxp.com> wrote: > > From: Hou Zhiqiang <zhiqiang....@nxp.com> > > Add PCIe DM driver for Freescale PowerPC PCIe controllers. > > Signed-off-by: Hou Zhiqiang <zhiqiang....@nxp.com> > --- > drivers/pci/Kconfig | 7 + > drivers/pci/Makefile | 1 + > drivers/pci/pcie_fsl.c | 612 +++++++++++++++++++++++++++++++++++ > drivers/pci/pcie_fsl.h | 60 ++++ > drivers/pci/pcie_fsl_fixup.c | 40 +++ > 5 files changed, 720 insertions(+) > create mode 100644 drivers/pci/pcie_fsl.c > create mode 100644 drivers/pci/pcie_fsl.h > create mode 100644 drivers/pci/pcie_fsl_fixup.c > > diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig > index 1521885bde..36674db6c1 100644 > --- a/drivers/pci/Kconfig > +++ b/drivers/pci/Kconfig > @@ -60,6 +60,13 @@ config PCIE_DW_MVEBU > Armada-8K SoCs. The PCIe controller on Armada-8K is based on > DesignWare hardware. > > +config PCIE_FSL > + bool "FSL PowerPC PCIe support" > + depends on DM_PCI > + help > + Say Y here if you want to enable PCIe controller support on > + FSL PowerPC series SoCs.
Please add a bit more detail here. Which SoCs are supported? Which hardware features are supported, and which not supported? > + > config PCI_RCAR_GEN2 > bool "Renesas RCar Gen2 PCIe driver" > depends on DM_PCI > diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile > index 4923641895..d984848266 100644 > --- a/drivers/pci/Makefile > +++ b/drivers/pci/Makefile > @@ -30,6 +30,7 @@ obj-$(CONFIG_SH7780_PCI) +=pci_sh7780.o > obj-$(CONFIG_PCI_TEGRA) += pci_tegra.o > obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o > obj-$(CONFIG_PCIE_DW_MVEBU) += pcie_dw_mvebu.o > +obj-$(CONFIG_PCIE_FSL) += pcie_fsl.o pcie_fsl_fixup.o > obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o > obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape_fixup.o > obj-$(CONFIG_PCI_XILINX) += pcie_xilinx.o > diff --git a/drivers/pci/pcie_fsl.c b/drivers/pci/pcie_fsl.c > new file mode 100644 > index 0000000000..95973fd8d9 > --- /dev/null > +++ b/drivers/pci/pcie_fsl.c > @@ -0,0 +1,612 @@ > +// SPDX-License-Identifier: GPL-2.0+ OR X11 > +/* > + * Copyright 2019 NXP > + * Copyright 2007-2012 Freescale Semiconductor, Inc. > + * > + * PCIe DM U-Boot driver for Freescale PowerPC SoCs > + * Author: Hou Zhiqiang <zhiqiang....@nxp.com> > + */ > + > +#include <common.h> > +#include <malloc.h> > +#include <dm.h> > +#include <pci.h> > +#include <clk.h> > +#include <mapmem.h> > +#include <asm/io.h> > +#include <asm/fsl_serdes.h> > +#include "pcie_fsl.h" Please sort these properly: common clk dm malloc mapmem pci asm/fsl asm/io pcie_fsl > + > +LIST_HEAD(fsl_pcie_list); > + > +static inline int fsl_pcie_link_up(struct fsl_pcie *pcie); Why is this inline? Do you need the forward declaration? > + > +static int fsl_pcie_addr_valid(struct fsl_pcie *pcie, pci_dev_t bdf) > +{ > + struct udevice *bus = pcie->bus; > + > + if (!pcie->enabled) > + return -ENXIO; > + > + if (PCI_BUS(bdf) < bus->seq) > + return -EINVAL; > + > + if (PCI_BUS(bdf) > bus->seq && (!fsl_pcie_link_up(pcie) || > pcie->mode)) > + return -EINVAL; > + > + if (PCI_BUS(bdf) == bus->seq && (PCI_DEV(bdf) > 0 || PCI_FUNC(bdf) > > 0)) > + return -EINVAL; > + > + if (PCI_BUS(bdf) == (bus->seq + 1) && (PCI_DEV(bdf) > 0)) > + return -EINVAL; > + > + return 0; > +} > + > +static int fsl_pcie_read_config(struct udevice *bus, pci_dev_t bdf, > + uint offset, ulong *valuep, > + enum pci_size_t size) > +{ > + struct fsl_pcie *pcie = dev_get_priv(bus); > + ccsr_fsl_pci_t *regs = pcie->regs; > + u32 val; > + > + if (fsl_pcie_addr_valid(pcie, bdf)) { > + *valuep = pci_get_ff(size); > + return 0; > + } > + > + bdf = bdf - PCI_BDF(bus->seq, 0, 0); > + val = bdf | (offset & 0xfc) | ((offset & 0xf00) << 16) | 0x80000000; > + out_be32(®s->cfg_addr, val); > + > + sync(); > + > + switch (size) { > + case PCI_SIZE_8: > + *valuep = in_8((u8 *)®s->cfg_data + (offset & 3)); > + break; > + case PCI_SIZE_16: > + *valuep = in_le16((u16 *)((u8 *)®s->cfg_data + > + (offset & 2))); > + break; > + case PCI_SIZE_32: > + *valuep = in_le32(®s->cfg_data); > + break; > + } > + > + return 0; > +} > + > +static int fsl_pcie_write_config(struct udevice *bus, pci_dev_t bdf, > + uint offset, ulong value, > + enum pci_size_t size) > +{ > + struct fsl_pcie *pcie = dev_get_priv(bus); > + ccsr_fsl_pci_t *regs = pcie->regs; > + u32 val; > + u8 val_8; > + u16 val_16; > + u32 val_32; > + > + if (fsl_pcie_addr_valid(pcie, bdf)) > + return 0; > + > + bdf = bdf - PCI_BDF(bus->seq, 0, 0); > + val = bdf | (offset & 0xfc) | ((offset & 0xf00) << 16) | 0x80000000; > + out_be32(®s->cfg_addr, val); > + > + sync(); > + > + switch (size) { > + case PCI_SIZE_8: > + val_8 = value; > + out_8((u8 *)®s->cfg_data + (offset & 3), val_8); > + break; > + case PCI_SIZE_16: > + val_16 = value; > + out_le16((u16 *)((u8 *)®s->cfg_data + (offset & 2)), > val_16); > + break; > + case PCI_SIZE_32: > + val_32 = value; > + out_le32(®s->cfg_data, val_32); > + break; > + } > + > + return 0; > +} > + > +static int fsl_pcie_hose_read_config(struct fsl_pcie *pcie, uint offset, > + ulong *valuep, enum pci_size_t size) > +{ > + int ret; > + struct udevice *bus = pcie->bus; > + > + ret = fsl_pcie_read_config(bus, PCI_BDF(bus->seq, 0, 0), > + offset, valuep, size); > + > + return ret; > +} > + > +static int fsl_pcie_hose_write_config(struct fsl_pcie *pcie, uint offset, > + ulong value, enum pci_size_t size) > +{ > + struct udevice *bus = pcie->bus; > + > + return fsl_pcie_write_config(bus, PCI_BDF(bus->seq, 0, 0), > + offset, value, size); > +} > + > +static int fsl_pcie_hose_read_config_byte(struct fsl_pcie *pcie, uint offset, > + u8 *valuep) > +{ > + ulong val; > + int ret; > + > + ret = fsl_pcie_hose_read_config(pcie, offset, &val, PCI_SIZE_8); > + *valuep = val; > + > + return ret; > +} > + > +static int fsl_pcie_hose_read_config_word(struct fsl_pcie *pcie, uint offset, > + u16 *valuep) > +{ > + ulong val; > + int ret; > + > + ret = fsl_pcie_hose_read_config(pcie, offset, &val, PCI_SIZE_16); > + *valuep = val; > + > + return ret; > +} > + > +static int fsl_pcie_hose_read_config_dword(struct fsl_pcie *pcie, uint > offset, > + u32 *valuep) > +{ > + ulong val; > + int ret; > + > + ret = fsl_pcie_hose_read_config(pcie, offset, &val, PCI_SIZE_32); > + *valuep = val; > + > + return ret; > +} > + > +static int fsl_pcie_hose_write_config_byte(struct fsl_pcie *pcie, uint > offset, > + u8 value) > +{ > + return fsl_pcie_hose_write_config(pcie, offset, value, PCI_SIZE_8); > +} > + > +static int fsl_pcie_hose_write_config_word(struct fsl_pcie *pcie, uint > offset, > + u16 value) > +{ > + return fsl_pcie_hose_write_config(pcie, offset, value, PCI_SIZE_16); > +} > + > +static int fsl_pcie_hose_write_config_dword(struct fsl_pcie *pcie, uint > offset, > + u32 value) > +{ > + return fsl_pcie_hose_write_config(pcie, offset, value, PCI_SIZE_32); > +} > + > +static inline int fsl_pcie_link_up(struct fsl_pcie *pcie) > +{ > + ccsr_fsl_pci_t *regs = pcie->regs; > + u16 ltssm; > + > + if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) { > + ltssm = (in_be32(®s->pex_csr0) > + & PEX_CSR0_LTSSM_MASK) >> PEX_CSR0_LTSSM_SHIFT; > + return ltssm == LTSSM_L0_REV3; > + } > + > + fsl_pcie_hose_read_config_word(pcie, PCI_LTSSM, <ssm); > + > + return ltssm == LTSSM_L0; > +} > + > +static bool fsl_pcie_is_agent(struct fsl_pcie *pcie) > +{ > + u8 header_type; > + > + fsl_pcie_hose_read_config_byte(pcie, PCI_HEADER_TYPE, &header_type); > + > + return (header_type & 0x7f) == PCI_HEADER_TYPE_NORMAL; > +} > + > +static int fsl_pcie_setup_law(struct fsl_pcie *pcie) > +{ > + struct pci_region *io, *mem, *pref; > + > + pci_get_regions(pcie->bus, &io, &mem, &pref); > + > + if (mem) > + set_next_law(mem->phys_start, > + law_size_bits(mem->size), > + pcie->law_trgt_if); > + > + if (io) > + set_next_law(io->phys_start, > + law_size_bits(io->size), > + pcie->law_trgt_if); > + > + return 0; > +} > + > +static void fsl_pcie_config_ready(struct fsl_pcie *pcie) > +{ > + ccsr_fsl_pci_t *regs = pcie->regs; > + > + if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) { > + setbits_be32(®s->config, FSL_PCIE_V3_CFG_RDY); > + return; > + } > + > + fsl_pcie_hose_write_config_byte(pcie, FSL_PCIE_CFG_RDY, 0x1); > +} > + > +static int fsl_pcie_setup_outbound_win(struct fsl_pcie *pcie, int idx, > + int type, u64 phys, u64 bus_addr, > + pci_size_t size) > +{ > + ccsr_fsl_pci_t *regs = pcie->regs; > + pot_t *po = ®s->pot[idx]; > + u32 war, sz; > + > + if (idx < 0) > + return -EINVAL; > + > + out_be32(&po->powbar, phys >> 12); > + out_be32(&po->potar, bus_addr >> 12); > +#ifdef CONFIG_SYS_PCI_64BIT > + out_be32(&po->potear, bus_addr >> 44); > +#else > + out_be32(&po->potear, 0); > +#endif > + > + sz = (__ilog2_u64((u64)size) - 1); > + war = POWAR_EN | sz; > + > + if (type == PCI_REGION_IO) > + war |= POWAR_IO_READ | POWAR_IO_WRITE; > + else > + war |= POWAR_MEM_READ | POWAR_MEM_WRITE; > + > + out_be32(&po->powar, war); > + > + return 0; > +} > + > +static int fsl_pcie_setup_inbound_win(struct fsl_pcie *pcie, int idx, > + bool pf, u64 phys, u64 bus_addr, > + pci_size_t size) > +{ > + ccsr_fsl_pci_t *regs = pcie->regs; > + pit_t *pi = ®s->pit[idx]; > + u32 sz = (__ilog2_u64(size) - 1); > +#ifdef CONFIG_SYS_FSL_ERRATUM_A005434 This should be handled by the compatible string, not an #ifdef Please fix this globally. [...] > diff --git a/drivers/pci/pcie_fsl.h b/drivers/pci/pcie_fsl.h > new file mode 100644 > index 0000000000..ed089bfb71 > --- /dev/null > +++ b/drivers/pci/pcie_fsl.h > @@ -0,0 +1,60 @@ > +/* SPDX-License-Identifier: GPL-2.0+ */ > +/* > + * Copyright 2019 NXP > + * Copyright 2007-2012 Freescale Semiconductor, Inc. > + * > + * PCIe DM U-Boot driver for Freescale PowerPC SoCs > + * Author: Hou Zhiqiang <zhiqiang....@nxp.com> > + */ > + > +#ifndef _PCIE_FSL_H_ > +#define _PCIE_FSL_H_ > +#include <pci.h> > +#include <dm.h> > +#include <asm/fsl_pci.h> Please remove these includes. The C file has them alreadyy. > + > +#ifdef CONFIG_SYS_FSL_PCI_VER_3_X > +#define FSL_PCIE_CAP_ID 0x70 > +#else > +#define FSL_PCIE_CAP_ID 0x4c > +#endif > +/* PCIe Device Control Register */ > +#define PCI_DCR (FSL_PCIE_CAP_ID + 0x08) > +/* PCIe Device Status Register */ > +#define PCI_DSR (FSL_PCIE_CAP_ID + 0x0a) > +/* PCIe Link Control Register */ > +#define PCI_LCR (FSL_PCIE_CAP_ID + 0x10) > +/* PCIe Link Status Register */ > +#define PCI_LSR (FSL_PCIE_CAP_ID + 0x12) > + > +#ifndef CONFIG_SYS_PCI_MEMORY_BUS > +#define CONFIG_SYS_PCI_MEMORY_BUS 0 > +#endif > + > +#ifndef CONFIG_SYS_PCI_MEMORY_PHYS > +#define CONFIG_SYS_PCI_MEMORY_PHYS 0 > +#endif > + > +#if defined(CONFIG_SYS_PCI_64BIT) && !defined(CONFIG_SYS_PCI64_MEMORY_BUS) > +#define CONFIG_SYS_PCI64_MEMORY_BUS (64ull * 1024 * 1024 * 1024) > +#endif > + > +#define PEX_CSR0_LTSSM_MASK 0xFC > +#define PEX_CSR0_LTSSM_SHIFT 2 > +#define LTSSM_L0_REV3 0x11 > +#define LTSSM_L0 0x16 > + > +struct fsl_pcie { Need struct/member docs. > + int idx; > + struct udevice *bus; > + void __iomem *regs; > + u32 law_trgt_if; > + u32 block_rev; > + bool mode; > + bool enabled; > + struct list_head list; > +}; > + > +extern struct list_head fsl_pcie_list; > + > +#endif /* _PCIE_FSL_H_ */ > diff --git a/drivers/pci/pcie_fsl_fixup.c b/drivers/pci/pcie_fsl_fixup.c > new file mode 100644 > index 0000000000..c3cd1dc09a > --- /dev/null > +++ b/drivers/pci/pcie_fsl_fixup.c > @@ -0,0 +1,40 @@ > +// SPDX-License-Identifier: GPL-2.0+ OR X11 > +/* > + * Copyright 2019 NXP > + * Copyright 2007-2012 Freescale Semiconductor, Inc. > + * > + * PCIe Kernel DT fixup of DM U-Boot driver for Freescale PowerPC SoCs > + * Author: Hou Zhiqiang <zhiqiang....@nxp.com> > + */ > + > +#include <common.h> > +#ifdef CONFIG_OF_BOARD_SETUP Shouldn't need this. > +#include <linux/libfdt.h> > +#include <fdt_support.h> > +#include "pcie_fsl.h" > + > +static void ft_fsl_pcie_setup(void *blob, struct fsl_pcie *pcie) > +{ > + struct pci_controller *hose = dev_get_uclass_priv(pcie->bus); > + int off; > + > + off = fdt_node_offset_by_compat_reg(blob, FSL_PCIE_COMPAT, > + dev_read_addr(pcie->bus)); > + if (off < 0) > + return; Should return an error? > + > + if (!hose || !pcie->enabled) > + fdt_del_node(blob, off); > + else > + fdt_pci_dma_ranges(blob, off, hose); > +} > + > +/* Fixup Kernel DT for PCIe */ > +void pci_of_setup(void *blob, bd_t *bd) > +{ > + struct fsl_pcie *pcie; > + > + list_for_each_entry(pcie, &fsl_pcie_list, list) > + ft_fsl_pcie_setup(blob, pcie); > +} > +#endif > -- > 2.17.1 > Regards, Simon _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot