Message ID | 20191014092939.3858271-1-hs@denx.de |
---|---|
State | Accepted |
Commit | b61cbbdcabbd56da83eed401b813766e2ef994dc |
Delegated to: | Priyanka Jain |
Headers | show |
Series | [U-Boot,v2] pci: add DM based mpc85xx driver | expand |
>-----Original Message----- >From: U-Boot <u-boot-bounces@lists.denx.de> On Behalf Of Heiko Schocher >Sent: Monday, October 14, 2019 3:00 PM >To: u-boot@lists.denx.de >Cc: Heinrich Schuchardt <xypron.glpk@gmx.de>; Z.q. Hou ><zhiqiang.hou@nxp.com>; Michal Simek <michal.simek@xilinx.com>; Ryder >Lee <ryder.lee@mediatek.com>; Stefan Roese <sr@denx.de> >Subject: [U-Boot] [PATCH v2] pci: add DM based mpc85xx driver > >add DM based PCI Configuration space access support for MPC85xx PCI >Bridge. This driver is based on arch/powerpc/cpu/mpc85xx/pci.c > >In the old driver there is a fix for a hw issue on the TARGET_MPC8555CDS and >TARGET_MPC8541CDS boards. As I have no such hardware I did not port this >part. > >Signed-off-by: Heiko Schocher <hs@denx.de> > >--- >Travis build, see: >https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Ftravis- >ci.org%2Fhsdenx%2Fu-boot- >test%2Fbuilds%2F597452473&data=02%7C01%7Cpriyanka.jain%40nxp.co >m%7Cec182e150f6a4dd75f6408d750891bbc%7C686ea1d3bc2b4c6fa92cd99c5c >301635%7C0%7C0%7C637066422116723776&sdata=h3jdy9SofUyvjzm5Jdy >NTnWqphxOLRnzEkxYBguxYrw%3D&reserved=0 > >Changes in v2: >- added in commit message that this driver is based on > arch/powerpc/cpu/mpc85xx/pci.c >- add note, that I did not port the fix for hw issue on > TARGET_MPC8555CDS and TARGET_MPC8541CDS boards >- set LAWs in this driver not in board code > as suggested by Zhiqiang > > MAINTAINERS | 5 ++ > drivers/pci/Kconfig | 7 ++ > drivers/pci/Makefile | 1 + > drivers/pci/pci_mpc85xx.c | 158 >++++++++++++++++++++++++++++++++++++++ > 4 files changed, 171 insertions(+) > create mode 100644 drivers/pci/pci_mpc85xx.c > >diff --git a/MAINTAINERS b/MAINTAINERS >index 2ef2976855..c9cd817b59 100644 >--- a/MAINTAINERS >+++ b/MAINTAINERS >@@ -692,6 +692,11 @@ S: Maintained > F: drivers/pci_endpoint/ > F: include/pci_ep.h > >+PCI MPC85xx >+M: Heiko Schocher <hs@denx.de> >+S: Maintained >+F: drivers/pci/pci_mpc85xx.c >+ > POWER > M: Jaehoon Chung <jh80.chung@samsung.com> > S: Maintained >diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index >19e7b50046..71aab85ed3 100644 >--- a/drivers/pci/Kconfig >+++ b/drivers/pci/Kconfig >@@ -68,6 +68,13 @@ config PCIE_FSL > PowerPC MPC85xx, MPC86xx, B series, P series and T series SoCs. > This driver does not support SRIO_PCIE_BOOT feature. > >+config PCI_MPC85XX >+ bool "MPC85XX PowerPC PCI support" >+ depends on DM_PCI >+ help >+ Say Y here if you want to enable PCI controller support on FSL >+ PowerPC MPC85xx SoC. >+ > 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 >b1d3dc8610..856ac71a1c 100644 >--- a/drivers/pci/Makefile >+++ b/drivers/pci/Makefile >@@ -19,6 +19,7 @@ obj-$(CONFIG_PCIE_ECAM_GENERIC) += >pcie_ecam_generic.o > obj-$(CONFIG_FSL_PCI_INIT) += fsl_pci_init.o > obj-$(CONFIG_PCI_INDIRECT_BRIDGE) += pci_indirect.o > obj-$(CONFIG_PCI_GT64120) += pci_gt64120.o >+obj-$(CONFIG_PCI_MPC85XX) += pci_mpc85xx.o > obj-$(CONFIG_PCI_MSC01) += pci_msc01.o > obj-$(CONFIG_PCIE_IMX) += pcie_imx.o > obj-$(CONFIG_FTPCI100) += pci_ftpci100.o diff --git >a/drivers/pci/pci_mpc85xx.c b/drivers/pci/pci_mpc85xx.c new file mode >100644 index 0000000000..e58ab60ee0 >--- /dev/null >+++ b/drivers/pci/pci_mpc85xx.c >@@ -0,0 +1,158 @@ >+// SPDX-License-Identifier: GPL-2.0 >+/* >+ * (C) Copyright 2019 >+ * Heiko Schocher, DENX Software Engineering, hs@denx.de. >+ * >+ */ >+#include <common.h> >+#include <asm/cpm_85xx.h> >+#include <pci.h> >+#include <dm.h> >+#include <asm/fsl_law.h> >+ >+struct mpc85xx_pci_priv { >+ void __iomem *cfg_addr; >+ void __iomem *cfg_data; >+}; >+ >+static int mpc85xx_pci_dm_read_config(struct udevice *dev, pci_dev_t bdf, >+ uint offset, ulong *value, >+ enum pci_size_t size) >+{ >+ struct mpc85xx_pci_priv *priv = dev_get_priv(dev); >+ u32 addr; >+ >+ addr = bdf | (offset & 0xfc) | ((offset & 0xf00) << 16) | 0x80000000; >+ out_be32(priv->cfg_addr, addr); >+ sync(); >+ *value = pci_conv_32_to_size(in_le32(priv->cfg_data), offset, size); >+ >+ return 0; >+} >+ >+static int mpc85xx_pci_dm_write_config(struct udevice *dev, pci_dev_t bdf, >+ uint offset, ulong value, >+ enum pci_size_t size) >+{ >+ struct mpc85xx_pci_priv *priv = dev_get_priv(dev); >+ u32 addr; >+ >+ addr = bdf | (offset & 0xfc) | ((offset & 0xf00) << 16) | 0x80000000; >+ out_be32(priv->cfg_addr, addr); >+ sync(); >+ out_le32(priv->cfg_data, pci_conv_size_to_32(0, value, offset, size)); >+ >+ return 0; >+} >+ >+static int >+mpc85xx_pci_dm_setup_laws(struct pci_region *io, struct pci_region *mem, >+ struct pci_region *pre) >+{ >+ /* >+ * Unfortunately we have defines for this addresse, >+ * as we have to setup the TLB, and at this stage >+ * we have no access to DT ... may we check here >+ * if the value in the define is the same ? >+ */ >+ if (mem) >+ set_next_law(mem->phys_start, law_size_bits(mem->size), >+ LAW_TRGT_IF_PCI); >+ if (io) >+ set_next_law(io->phys_start, law_size_bits(io->size), >+ LAW_TRGT_IF_PCI); >+ if (pre) >+ set_next_law(pre->phys_start, law_size_bits(pre->size), >+ LAW_TRGT_IF_PCI); >+ >+ return 0; >+} >+ >+static int mpc85xx_pci_dm_probe(struct udevice *dev) { >+ struct mpc85xx_pci_priv *priv = dev_get_priv(dev); >+ struct pci_region *io; >+ struct pci_region *mem; >+ struct pci_region *pre; >+ int count; >+ ccsr_pcix_t *pcix; >+ >+ count = pci_get_regions(dev, &io, &mem, &pre); >+ if (count != 2) { >+ printf("%s: wrong count of regions %d only 2 allowed\n", >+ __func__, count); >+ return -EINVAL; >+ } >+ >+ mpc85xx_pci_dm_setup_laws(io, mem, pre); >+ >+ pcix = priv->cfg_addr; >+ /* BAR 1: memory */ >+ out_be32(&pcix->potar1, (mem->bus_start >> 12) & 0x000fffff); >+ out_be32(&pcix->potear1, 0); >+ out_be32(&pcix->powbar1, (mem->phys_start >> 12) & 0x000fffff); >+ out_be32(&pcix->powbear1, 0); >+ out_be32(&pcix->powar1, (POWAR_EN | POWAR_MEM_READ | >+ POWAR_MEM_WRITE | (__ilog2(mem->size) - 1))); >+ >+ /* BAR 1: IO */ >+ out_be32(&pcix->potar2, (io->bus_start >> 12) & 0x000fffff); >+ out_be32(&pcix->potear2, 0); >+ out_be32(&pcix->powbar2, (io->phys_start >> 12) & 0x000fffff); >+ out_be32(&pcix->powbear2, 0); >+ out_be32(&pcix->powar2, (POWAR_EN | POWAR_IO_READ | >+ POWAR_IO_WRITE | (__ilog2(io->size) - 1))); >+ >+ out_be32(&pcix->pitar1, 0); >+ out_be32(&pcix->piwbar1, 0); >+ out_be32(&pcix->piwar1, (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL | >+ PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | >PIWAR_MEM_2G)); >+ >+ out_be32(&pcix->powar3, 0); >+ out_be32(&pcix->powar4, 0); >+ out_be32(&pcix->piwar2, 0); >+ out_be32(&pcix->piwar3, 0); >+ >+ return 0; >+} >+ >+static int mpc85xx_pci_dm_remove(struct udevice *dev) { >+ return 0; >+} >+ >+static int mpc85xx_pci_ofdata_to_platdata(struct udevice *dev) { >+ struct mpc85xx_pci_priv *priv = dev_get_priv(dev); >+ fdt_addr_t addr; >+ >+ addr = devfdt_get_addr_index(dev, 0); >+ if (addr == FDT_ADDR_T_NONE) >+ return -EINVAL; >+ priv->cfg_addr = (void __iomem *)addr; >+ addr += 4; >+ priv->cfg_data = (void __iomem *)addr; >+ >+ return 0; >+} >+ >+static const struct dm_pci_ops mpc85xx_pci_ops = { >+ .read_config = mpc85xx_pci_dm_read_config, >+ .write_config = mpc85xx_pci_dm_write_config, >+}; >+ >+static const struct udevice_id mpc85xx_pci_ids[] = { >+ { .compatible = "fsl,mpc8540-pci" }, >+ { } >+}; >+ >+U_BOOT_DRIVER(mpc85xx_pci) = { >+ .name = "mpc85xx_pci", >+ .id = UCLASS_PCI, >+ .of_match = mpc85xx_pci_ids, >+ .ops = &mpc85xx_pci_ops, >+ .probe = mpc85xx_pci_dm_probe, >+ .remove = mpc85xx_pci_dm_remove, >+ .ofdata_to_platdata = mpc85xx_pci_ofdata_to_platdata, >+ .priv_auto_alloc_size = sizeof(struct mpc85xx_pci_priv), >+}; >-- >2.21.0 > >_______________________________________________ >U-Boot mailing list >U-Boot@lists.denx.de >https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.de >nx.de%2Flistinfo%2Fu- >boot&data=02%7C01%7Cpriyanka.jain%40nxp.com%7Cec182e150f6a4dd >75f6408d750891bbc%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C6 >37066422116723776&sdata=uSVBiA5dF7j1dXC0NvsvNTVL3ZhaX2qEydW5 >%2FGWkSDM%3D&reserved=0 Applied to mpc85xx master, awaiting upstream. Thanks priyankajain
diff --git a/MAINTAINERS b/MAINTAINERS index 2ef2976855..c9cd817b59 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -692,6 +692,11 @@ S: Maintained F: drivers/pci_endpoint/ F: include/pci_ep.h +PCI MPC85xx +M: Heiko Schocher <hs@denx.de> +S: Maintained +F: drivers/pci/pci_mpc85xx.c + POWER M: Jaehoon Chung <jh80.chung@samsung.com> S: Maintained diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 19e7b50046..71aab85ed3 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -68,6 +68,13 @@ config PCIE_FSL PowerPC MPC85xx, MPC86xx, B series, P series and T series SoCs. This driver does not support SRIO_PCIE_BOOT feature. +config PCI_MPC85XX + bool "MPC85XX PowerPC PCI support" + depends on DM_PCI + help + Say Y here if you want to enable PCI controller support on FSL + PowerPC MPC85xx SoC. + 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 b1d3dc8610..856ac71a1c 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_PCIE_ECAM_GENERIC) += pcie_ecam_generic.o obj-$(CONFIG_FSL_PCI_INIT) += fsl_pci_init.o obj-$(CONFIG_PCI_INDIRECT_BRIDGE) += pci_indirect.o obj-$(CONFIG_PCI_GT64120) += pci_gt64120.o +obj-$(CONFIG_PCI_MPC85XX) += pci_mpc85xx.o obj-$(CONFIG_PCI_MSC01) += pci_msc01.o obj-$(CONFIG_PCIE_IMX) += pcie_imx.o obj-$(CONFIG_FTPCI100) += pci_ftpci100.o diff --git a/drivers/pci/pci_mpc85xx.c b/drivers/pci/pci_mpc85xx.c new file mode 100644 index 0000000000..e58ab60ee0 --- /dev/null +++ b/drivers/pci/pci_mpc85xx.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * (C) Copyright 2019 + * Heiko Schocher, DENX Software Engineering, hs@denx.de. + * + */ +#include <common.h> +#include <asm/cpm_85xx.h> +#include <pci.h> +#include <dm.h> +#include <asm/fsl_law.h> + +struct mpc85xx_pci_priv { + void __iomem *cfg_addr; + void __iomem *cfg_data; +}; + +static int mpc85xx_pci_dm_read_config(struct udevice *dev, pci_dev_t bdf, + uint offset, ulong *value, + enum pci_size_t size) +{ + struct mpc85xx_pci_priv *priv = dev_get_priv(dev); + u32 addr; + + addr = bdf | (offset & 0xfc) | ((offset & 0xf00) << 16) | 0x80000000; + out_be32(priv->cfg_addr, addr); + sync(); + *value = pci_conv_32_to_size(in_le32(priv->cfg_data), offset, size); + + return 0; +} + +static int mpc85xx_pci_dm_write_config(struct udevice *dev, pci_dev_t bdf, + uint offset, ulong value, + enum pci_size_t size) +{ + struct mpc85xx_pci_priv *priv = dev_get_priv(dev); + u32 addr; + + addr = bdf | (offset & 0xfc) | ((offset & 0xf00) << 16) | 0x80000000; + out_be32(priv->cfg_addr, addr); + sync(); + out_le32(priv->cfg_data, pci_conv_size_to_32(0, value, offset, size)); + + return 0; +} + +static int +mpc85xx_pci_dm_setup_laws(struct pci_region *io, struct pci_region *mem, + struct pci_region *pre) +{ + /* + * Unfortunately we have defines for this addresse, + * as we have to setup the TLB, and at this stage + * we have no access to DT ... may we check here + * if the value in the define is the same ? + */ + if (mem) + set_next_law(mem->phys_start, law_size_bits(mem->size), + LAW_TRGT_IF_PCI); + if (io) + set_next_law(io->phys_start, law_size_bits(io->size), + LAW_TRGT_IF_PCI); + if (pre) + set_next_law(pre->phys_start, law_size_bits(pre->size), + LAW_TRGT_IF_PCI); + + return 0; +} + +static int mpc85xx_pci_dm_probe(struct udevice *dev) +{ + struct mpc85xx_pci_priv *priv = dev_get_priv(dev); + struct pci_region *io; + struct pci_region *mem; + struct pci_region *pre; + int count; + ccsr_pcix_t *pcix; + + count = pci_get_regions(dev, &io, &mem, &pre); + if (count != 2) { + printf("%s: wrong count of regions %d only 2 allowed\n", + __func__, count); + return -EINVAL; + } + + mpc85xx_pci_dm_setup_laws(io, mem, pre); + + pcix = priv->cfg_addr; + /* BAR 1: memory */ + out_be32(&pcix->potar1, (mem->bus_start >> 12) & 0x000fffff); + out_be32(&pcix->potear1, 0); + out_be32(&pcix->powbar1, (mem->phys_start >> 12) & 0x000fffff); + out_be32(&pcix->powbear1, 0); + out_be32(&pcix->powar1, (POWAR_EN | POWAR_MEM_READ | + POWAR_MEM_WRITE | (__ilog2(mem->size) - 1))); + + /* BAR 1: IO */ + out_be32(&pcix->potar2, (io->bus_start >> 12) & 0x000fffff); + out_be32(&pcix->potear2, 0); + out_be32(&pcix->powbar2, (io->phys_start >> 12) & 0x000fffff); + out_be32(&pcix->powbear2, 0); + out_be32(&pcix->powar2, (POWAR_EN | POWAR_IO_READ | + POWAR_IO_WRITE | (__ilog2(io->size) - 1))); + + out_be32(&pcix->pitar1, 0); + out_be32(&pcix->piwbar1, 0); + out_be32(&pcix->piwar1, (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL | + PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_MEM_2G)); + + out_be32(&pcix->powar3, 0); + out_be32(&pcix->powar4, 0); + out_be32(&pcix->piwar2, 0); + out_be32(&pcix->piwar3, 0); + + return 0; +} + +static int mpc85xx_pci_dm_remove(struct udevice *dev) +{ + return 0; +} + +static int mpc85xx_pci_ofdata_to_platdata(struct udevice *dev) +{ + struct mpc85xx_pci_priv *priv = dev_get_priv(dev); + fdt_addr_t addr; + + addr = devfdt_get_addr_index(dev, 0); + if (addr == FDT_ADDR_T_NONE) + return -EINVAL; + priv->cfg_addr = (void __iomem *)addr; + addr += 4; + priv->cfg_data = (void __iomem *)addr; + + return 0; +} + +static const struct dm_pci_ops mpc85xx_pci_ops = { + .read_config = mpc85xx_pci_dm_read_config, + .write_config = mpc85xx_pci_dm_write_config, +}; + +static const struct udevice_id mpc85xx_pci_ids[] = { + { .compatible = "fsl,mpc8540-pci" }, + { } +}; + +U_BOOT_DRIVER(mpc85xx_pci) = { + .name = "mpc85xx_pci", + .id = UCLASS_PCI, + .of_match = mpc85xx_pci_ids, + .ops = &mpc85xx_pci_ops, + .probe = mpc85xx_pci_dm_probe, + .remove = mpc85xx_pci_dm_remove, + .ofdata_to_platdata = mpc85xx_pci_ofdata_to_platdata, + .priv_auto_alloc_size = sizeof(struct mpc85xx_pci_priv), +};
add DM based PCI Configuration space access support for MPC85xx PCI Bridge. This driver is based on arch/powerpc/cpu/mpc85xx/pci.c In the old driver there is a fix for a hw issue on the TARGET_MPC8555CDS and TARGET_MPC8541CDS boards. As I have no such hardware I did not port this part. Signed-off-by: Heiko Schocher <hs@denx.de> --- Travis build, see: https://travis-ci.org/hsdenx/u-boot-test/builds/597452473 Changes in v2: - added in commit message that this driver is based on arch/powerpc/cpu/mpc85xx/pci.c - add note, that I did not port the fix for hw issue on TARGET_MPC8555CDS and TARGET_MPC8541CDS boards - set LAWs in this driver not in board code as suggested by Zhiqiang MAINTAINERS | 5 ++ drivers/pci/Kconfig | 7 ++ drivers/pci/Makefile | 1 + drivers/pci/pci_mpc85xx.c | 158 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 171 insertions(+) create mode 100644 drivers/pci/pci_mpc85xx.c