Re: [PATCH v5 1/3] starfive: pci: Add StarFive JH7110 pcie driver

2023-04-23 Thread Pali Rohár
On Sunday 23 April 2023 18:58:57 Minda Chen wrote:
> From: Mason Huo 
> 
> Add pcie driver for StarFive JH7110, Also add PLDA
> PCIe controller common driver functions.
> 
> Several devices are tested:
> a) M.2 NVMe SSD
> b) Realtek 8169 Ethernet adapter.
> 
> Signed-off-by: Mason Huo 
> Signed-off-by: Minda Chen 

Acked-by: Pali Rohár 

> ---
>  drivers/pci/Kconfig|  13 ++
>  drivers/pci/Makefile   |   2 +
>  drivers/pci/pcie_plda_common.c | 116 +++
>  drivers/pci/pcie_plda_common.h | 118 +++
>  drivers/pci/pcie_starfive_jh7110.c | 317 +
>  5 files changed, 566 insertions(+)
>  create mode 100644 drivers/pci/pcie_plda_common.c
>  create mode 100644 drivers/pci/pcie_plda_common.h
>  create mode 100644 drivers/pci/pcie_starfive_jh7110.c
> 
> diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
> index ef328d2652..f2c5f0be63 100644
> --- a/drivers/pci/Kconfig
> +++ b/drivers/pci/Kconfig
> @@ -374,4 +374,17 @@ config PCIE_UNIPHIER
> Say Y here if you want to enable PCIe controller support on
> UniPhier SoCs.
>  
> +config PCIE_PLDA_COMMON
> + bool
> +
> +config PCIE_STARFIVE_JH7110
> + bool "Enable Starfive JH7110 PCIe driver"
> + select PCIE_PLDA_COMMON
> + imply STARFIVE_JH7110
> + imply CLK_JH7110
> + imply RESET_JH7110
> + help
> +   Say Y here if you want to enable PLDA XpressRich PCIe controller
> +   support on StarFive JH7110 SoC.
> +
>  endif
> diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
> index 49506e7ba5..5a6974f013 100644
> --- a/drivers/pci/Makefile
> +++ b/drivers/pci/Makefile
> @@ -49,3 +49,5 @@ obj-$(CONFIG_PCI_OCTEONTX) += pci_octeontx.o
>  obj-$(CONFIG_PCIE_OCTEON) += pcie_octeon.o
>  obj-$(CONFIG_PCIE_DW_SIFIVE) += pcie_dw_sifive.o
>  obj-$(CONFIG_PCIE_UNIPHIER) += pcie_uniphier.o
> +obj-$(CONFIG_PCIE_PLDA_COMMON) += pcie_plda_common.o
> +obj-$(CONFIG_PCIE_STARFIVE_JH7110) += pcie_starfive_jh7110.o
> diff --git a/drivers/pci/pcie_plda_common.c b/drivers/pci/pcie_plda_common.c
> new file mode 100644
> index 00..005b92616a
> --- /dev/null
> +++ b/drivers/pci/pcie_plda_common.c
> @@ -0,0 +1,116 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * PLDA XpressRich PCIe host controller common functions.
> + *
> + * Copyright (C) 2023 StarFive Technology Co., Ltd.
> + *
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include "pcie_plda_common.h"
> +
> +static bool plda_pcie_addr_valid(struct pcie_plda *plda, pci_dev_t bdf)
> +{
> + /*
> +  * Single device limitation.
> +  * PCIe controller contain HW issue that secondary bus of
> +  * host bridge emumerate duplicate devices.
> +  * Only can access device 0 in secondary bus.
> +  */
> + if (PCI_BUS(bdf) == plda->sec_busno && PCI_DEV(bdf) > 0)
> + return false;
> +
> + return true;
> +}
> +
> +static int plda_pcie_conf_address(const struct udevice *udev, pci_dev_t bdf,
> +   uint offset, void **paddr)
> +{
> + struct pcie_plda *priv = dev_get_priv(udev);
> + int where = PCIE_ECAM_OFFSET(PCI_BUS(bdf), PCI_DEV(bdf),
> +  PCI_FUNC(bdf), offset);
> +
> + if (!plda_pcie_addr_valid(priv, bdf))
> + return -ENODEV;
> +
> + *paddr = (void *)(priv->cfg_base + where);
> + return 0;
> +}
> +
> +int plda_pcie_config_read(const struct udevice *udev, pci_dev_t bdf,
> +   uint offset, ulong *valuep,
> +   enum pci_size_t size)
> +{
> + return pci_generic_mmap_read_config(udev, plda_pcie_conf_address,
> + bdf, offset, valuep, size);
> +}
> +
> +int plda_pcie_config_write(struct udevice *udev, pci_dev_t bdf,
> +uint offset, ulong value,
> +enum pci_size_t size)
> +{
> + struct pcie_plda *priv = dev_get_priv(udev);
> + int ret;
> +
> + ret = pci_generic_mmap_write_config(udev, plda_pcie_conf_address,
> + bdf, offset, value, size);
> +
> + /* record secondary bus number */
> + if (!ret && PCI_BUS(bdf) == dev_seq(udev) &&
> + PCI_DEV(bdf) == 0 && PCI_FUNC(bdf) == 0 &&
> + (offset == PCI_SECONDARY_BUS ||
> + (offset == PCI_PRIMARY_BUS && size != PCI_SIZE_8))) {
> + priv->sec_busno =
> + ((offset == PCI_PRIMARY_BUS) ? (value >> 8) : value) & 
> 0xff;
> + debug("Secondary bus number was changed to %d\n",
> +   priv->sec_busno);
> + }
> + return ret;
> +}
> +
> +int plda_pcie_set_atr_entry(struct pcie_plda *plda, phys_addr_t src_addr,
> + phys_addr_t trsl_addr, phys_size_t window_size,
> + int trsl_param)
> +{
> + void __iomem *base =
> + 

[PATCH v5 1/3] starfive: pci: Add StarFive JH7110 pcie driver

2023-04-23 Thread Minda Chen
From: Mason Huo 

Add pcie driver for StarFive JH7110, Also add PLDA
PCIe controller common driver functions.

Several devices are tested:
a) M.2 NVMe SSD
b) Realtek 8169 Ethernet adapter.

Signed-off-by: Mason Huo 
Signed-off-by: Minda Chen 
---
 drivers/pci/Kconfig|  13 ++
 drivers/pci/Makefile   |   2 +
 drivers/pci/pcie_plda_common.c | 116 +++
 drivers/pci/pcie_plda_common.h | 118 +++
 drivers/pci/pcie_starfive_jh7110.c | 317 +
 5 files changed, 566 insertions(+)
 create mode 100644 drivers/pci/pcie_plda_common.c
 create mode 100644 drivers/pci/pcie_plda_common.h
 create mode 100644 drivers/pci/pcie_starfive_jh7110.c

diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index ef328d2652..f2c5f0be63 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -374,4 +374,17 @@ config PCIE_UNIPHIER
  Say Y here if you want to enable PCIe controller support on
  UniPhier SoCs.
 
+config PCIE_PLDA_COMMON
+   bool
+
+config PCIE_STARFIVE_JH7110
+   bool "Enable Starfive JH7110 PCIe driver"
+   select PCIE_PLDA_COMMON
+   imply STARFIVE_JH7110
+   imply CLK_JH7110
+   imply RESET_JH7110
+   help
+ Say Y here if you want to enable PLDA XpressRich PCIe controller
+ support on StarFive JH7110 SoC.
+
 endif
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 49506e7ba5..5a6974f013 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -49,3 +49,5 @@ obj-$(CONFIG_PCI_OCTEONTX) += pci_octeontx.o
 obj-$(CONFIG_PCIE_OCTEON) += pcie_octeon.o
 obj-$(CONFIG_PCIE_DW_SIFIVE) += pcie_dw_sifive.o
 obj-$(CONFIG_PCIE_UNIPHIER) += pcie_uniphier.o
+obj-$(CONFIG_PCIE_PLDA_COMMON) += pcie_plda_common.o
+obj-$(CONFIG_PCIE_STARFIVE_JH7110) += pcie_starfive_jh7110.o
diff --git a/drivers/pci/pcie_plda_common.c b/drivers/pci/pcie_plda_common.c
new file mode 100644
index 00..005b92616a
--- /dev/null
+++ b/drivers/pci/pcie_plda_common.c
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * PLDA XpressRich PCIe host controller common functions.
+ *
+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "pcie_plda_common.h"
+
+static bool plda_pcie_addr_valid(struct pcie_plda *plda, pci_dev_t bdf)
+{
+   /*
+* Single device limitation.
+* PCIe controller contain HW issue that secondary bus of
+* host bridge emumerate duplicate devices.
+* Only can access device 0 in secondary bus.
+*/
+   if (PCI_BUS(bdf) == plda->sec_busno && PCI_DEV(bdf) > 0)
+   return false;
+
+   return true;
+}
+
+static int plda_pcie_conf_address(const struct udevice *udev, pci_dev_t bdf,
+ uint offset, void **paddr)
+{
+   struct pcie_plda *priv = dev_get_priv(udev);
+   int where = PCIE_ECAM_OFFSET(PCI_BUS(bdf), PCI_DEV(bdf),
+PCI_FUNC(bdf), offset);
+
+   if (!plda_pcie_addr_valid(priv, bdf))
+   return -ENODEV;
+
+   *paddr = (void *)(priv->cfg_base + where);
+   return 0;
+}
+
+int plda_pcie_config_read(const struct udevice *udev, pci_dev_t bdf,
+ uint offset, ulong *valuep,
+ enum pci_size_t size)
+{
+   return pci_generic_mmap_read_config(udev, plda_pcie_conf_address,
+   bdf, offset, valuep, size);
+}
+
+int plda_pcie_config_write(struct udevice *udev, pci_dev_t bdf,
+  uint offset, ulong value,
+  enum pci_size_t size)
+{
+   struct pcie_plda *priv = dev_get_priv(udev);
+   int ret;
+
+   ret = pci_generic_mmap_write_config(udev, plda_pcie_conf_address,
+   bdf, offset, value, size);
+
+   /* record secondary bus number */
+   if (!ret && PCI_BUS(bdf) == dev_seq(udev) &&
+   PCI_DEV(bdf) == 0 && PCI_FUNC(bdf) == 0 &&
+   (offset == PCI_SECONDARY_BUS ||
+   (offset == PCI_PRIMARY_BUS && size != PCI_SIZE_8))) {
+   priv->sec_busno =
+   ((offset == PCI_PRIMARY_BUS) ? (value >> 8) : value) & 
0xff;
+   debug("Secondary bus number was changed to %d\n",
+ priv->sec_busno);
+   }
+   return ret;
+}
+
+int plda_pcie_set_atr_entry(struct pcie_plda *plda, phys_addr_t src_addr,
+   phys_addr_t trsl_addr, phys_size_t window_size,
+   int trsl_param)
+{
+   void __iomem *base =
+   plda->reg_base + XR3PCI_ATR_AXI4_SLV0;
+
+   /* Support AXI4 Slave 0 Address Translation Tables 0-7. */
+   if (plda->atr_table_num >= XR3PCI_ATR_MAX_TABLE_NUM) {
+   dev_err(plda->dev, "ATR table number %d exceeds max num\n",
+