Re: [PATCH v3 3/6] pci: Add Rockchip PCIe controller driver

2020-05-10 Thread Suniel Mahesh
On Sat, May 9, 2020 at 10:26 PM Jagan Teki 
wrote:

> Add Rockchip PCIe controller driver for rk3399 platform.
>
> Driver support Gen1 by operating as a Root complex.
>
> Thanks to Patrick for initial work.
>
> Signed-off-by: Patrick Wildt 
> Signed-off-by: Jagan Teki 
> Reviewed-by: Kever Yang 
> ---
> Changes for v3:
> - none
>
>  drivers/pci/Kconfig |   8 +
>  drivers/pci/Makefile|   1 +
>  drivers/pci/pcie_rockchip.c | 467 
>  drivers/pci/pcie_rockchip.h |  79 ++
>  4 files changed, 555 insertions(+)
>  create mode 100644 drivers/pci/pcie_rockchip.c
>  create mode 100644 drivers/pci/pcie_rockchip.h
>
> diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
> index 437cd9a055..3dba84103b 100644
> --- a/drivers/pci/Kconfig
> +++ b/drivers/pci/Kconfig
> @@ -197,4 +197,12 @@ config PCIE_MEDIATEK
>   Say Y here if you want to enable Gen2 PCIe controller,
>   which could be found on MT7623 SoC family.
>
> +config PCIE_ROCKCHIP
> +   bool "Enable Rockchip PCIe driver"
> +   select DM_PCI
> +   default y if ROCKCHIP_RK3399
> +   help
> + Say Y here if you want to enable PCIe controller support on
> + Rockchip SoCs.
> +
>  endif
> diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
> index c051ecc9f3..493e9354dd 100644
> --- a/drivers/pci/Makefile
> +++ b/drivers/pci/Makefile
> @@ -43,3 +43,4 @@ obj-$(CONFIG_PCI_PHYTIUM) += pcie_phytium.o
>  obj-$(CONFIG_PCIE_INTEL_FPGA) += pcie_intel_fpga.o
>  obj-$(CONFIG_PCI_KEYSTONE) += pcie_dw_ti.o
>  obj-$(CONFIG_PCIE_MEDIATEK) += pcie_mediatek.o
> +obj-$(CONFIG_PCIE_ROCKCHIP) += pcie_rockchip.o
> diff --git a/drivers/pci/pcie_rockchip.c b/drivers/pci/pcie_rockchip.c
> new file mode 100644
> index 00..3f06f783ca
> --- /dev/null
> +++ b/drivers/pci/pcie_rockchip.c
> @@ -0,0 +1,467 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Rockchip AXI PCIe host controller driver
> + *
> + * Copyright (c) 2016 Rockchip, Inc.
> + * Copyright (c) 2020 Amarula Solutions(India)
> + * Copyright (c) 2020 Jagan Teki 
> + * Copyright (c) 2019 Patrick Wildt 
> + * Copyright (c) 2018 Mark Kettenis 
> + *
> + * Bits taken from Linux Rockchip PCIe host controller.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "pcie_rockchip.h"
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +static int rockchip_pcie_off_conf(pci_dev_t bdf, uint offset)
> +{
> +   unsigned int bus = PCI_BUS(bdf);
> +   unsigned int dev = PCI_DEV(bdf);
> +   unsigned int func = PCI_FUNC(bdf);
> +
> +   return (bus << 20) | (dev << 15) | (func << 12) | (offset & ~0x3);
> +}
> +
> +static int rockchip_pcie_rd_conf(const struct udevice *udev, pci_dev_t
> bdf,
> +uint offset, ulong *valuep,
> +enum pci_size_t size)
> +{
> +   struct rockchip_pcie *priv = dev_get_priv(udev);
> +   unsigned int bus = PCI_BUS(bdf);
> +   unsigned int dev = PCI_DEV(bdf);
> +   int where = rockchip_pcie_off_conf(bdf, offset);
> +   ulong value;
> +
> +   if (bus == priv->first_busno && dev == 0) {
> +   value = readl(priv->apb_base + PCIE_RC_NORMAL_BASE +
> where);
> +   *valuep = pci_conv_32_to_size(value, offset, size);
> +   return 0;
> +   }
> +
> +   if ((bus == priv->first_busno + 1) && dev == 0) {
> +   value = readl(priv->axi_base + where);
> +   *valuep = pci_conv_32_to_size(value, offset, size);
> +   return 0;
> +   }
> +
> +   *valuep = pci_get_ff(size);
> +
> +   return 0;
> +}
> +
> +static int rockchip_pcie_wr_conf(struct udevice *udev, pci_dev_t bdf,
> +uint offset, ulong value,
> +enum pci_size_t size)
> +{
> +   struct rockchip_pcie *priv = dev_get_priv(udev);
> +   unsigned int bus = PCI_BUS(bdf);
> +   unsigned int dev = PCI_DEV(bdf);
> +   int where = rockchip_pcie_off_conf(bdf, offset);
> +   ulong old;
> +
> +   if (bus == priv->first_busno && dev == 0) {
> +   old = readl(priv->apb_base + PCIE_RC_NORMAL_BASE + where);
> +   value = pci_conv_size_to_32(old, value, offset, size);
> +   writel(value, priv->apb_base + PCIE_RC_NORMAL_BASE +
> where);
> +   return 0;
> +   }
> +
> +   if ((bus == priv->first_busno + 1) && dev == 0) {
> +   old = readl(priv->axi_base + where);
> +   value = pci_conv_size_to_32(old, value, offset, size);
> +   writel(value, priv->axi_base + where);
> +   return 0;
> +   }
> +
> +   return 0;
> +}
> +
> +static int rockchip_pcie_atr_init(struct rockchip_pcie *priv)
> +{
> +   struct udevice *ctlr = pci_get_controller(priv->dev);
> +   struct 

[PATCH v3 3/6] pci: Add Rockchip PCIe controller driver

2020-05-09 Thread Jagan Teki
Add Rockchip PCIe controller driver for rk3399 platform.

Driver support Gen1 by operating as a Root complex.

Thanks to Patrick for initial work.

Signed-off-by: Patrick Wildt 
Signed-off-by: Jagan Teki 
Reviewed-by: Kever Yang 
---
Changes for v3:
- none

 drivers/pci/Kconfig |   8 +
 drivers/pci/Makefile|   1 +
 drivers/pci/pcie_rockchip.c | 467 
 drivers/pci/pcie_rockchip.h |  79 ++
 4 files changed, 555 insertions(+)
 create mode 100644 drivers/pci/pcie_rockchip.c
 create mode 100644 drivers/pci/pcie_rockchip.h

diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 437cd9a055..3dba84103b 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -197,4 +197,12 @@ config PCIE_MEDIATEK
  Say Y here if you want to enable Gen2 PCIe controller,
  which could be found on MT7623 SoC family.
 
+config PCIE_ROCKCHIP
+   bool "Enable Rockchip PCIe driver"
+   select DM_PCI
+   default y if ROCKCHIP_RK3399
+   help
+ Say Y here if you want to enable PCIe controller support on
+ Rockchip SoCs.
+
 endif
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index c051ecc9f3..493e9354dd 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -43,3 +43,4 @@ obj-$(CONFIG_PCI_PHYTIUM) += pcie_phytium.o
 obj-$(CONFIG_PCIE_INTEL_FPGA) += pcie_intel_fpga.o
 obj-$(CONFIG_PCI_KEYSTONE) += pcie_dw_ti.o
 obj-$(CONFIG_PCIE_MEDIATEK) += pcie_mediatek.o
+obj-$(CONFIG_PCIE_ROCKCHIP) += pcie_rockchip.o
diff --git a/drivers/pci/pcie_rockchip.c b/drivers/pci/pcie_rockchip.c
new file mode 100644
index 00..3f06f783ca
--- /dev/null
+++ b/drivers/pci/pcie_rockchip.c
@@ -0,0 +1,467 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Rockchip AXI PCIe host controller driver
+ *
+ * Copyright (c) 2016 Rockchip, Inc.
+ * Copyright (c) 2020 Amarula Solutions(India)
+ * Copyright (c) 2020 Jagan Teki 
+ * Copyright (c) 2019 Patrick Wildt 
+ * Copyright (c) 2018 Mark Kettenis 
+ *
+ * Bits taken from Linux Rockchip PCIe host controller.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pcie_rockchip.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int rockchip_pcie_off_conf(pci_dev_t bdf, uint offset)
+{
+   unsigned int bus = PCI_BUS(bdf);
+   unsigned int dev = PCI_DEV(bdf);
+   unsigned int func = PCI_FUNC(bdf);
+
+   return (bus << 20) | (dev << 15) | (func << 12) | (offset & ~0x3);
+}
+
+static int rockchip_pcie_rd_conf(const struct udevice *udev, pci_dev_t bdf,
+uint offset, ulong *valuep,
+enum pci_size_t size)
+{
+   struct rockchip_pcie *priv = dev_get_priv(udev);
+   unsigned int bus = PCI_BUS(bdf);
+   unsigned int dev = PCI_DEV(bdf);
+   int where = rockchip_pcie_off_conf(bdf, offset);
+   ulong value;
+
+   if (bus == priv->first_busno && dev == 0) {
+   value = readl(priv->apb_base + PCIE_RC_NORMAL_BASE + where);
+   *valuep = pci_conv_32_to_size(value, offset, size);
+   return 0;
+   }
+
+   if ((bus == priv->first_busno + 1) && dev == 0) {
+   value = readl(priv->axi_base + where);
+   *valuep = pci_conv_32_to_size(value, offset, size);
+   return 0;
+   }
+
+   *valuep = pci_get_ff(size);
+
+   return 0;
+}
+
+static int rockchip_pcie_wr_conf(struct udevice *udev, pci_dev_t bdf,
+uint offset, ulong value,
+enum pci_size_t size)
+{
+   struct rockchip_pcie *priv = dev_get_priv(udev);
+   unsigned int bus = PCI_BUS(bdf);
+   unsigned int dev = PCI_DEV(bdf);
+   int where = rockchip_pcie_off_conf(bdf, offset);
+   ulong old;
+
+   if (bus == priv->first_busno && dev == 0) {
+   old = readl(priv->apb_base + PCIE_RC_NORMAL_BASE + where);
+   value = pci_conv_size_to_32(old, value, offset, size);
+   writel(value, priv->apb_base + PCIE_RC_NORMAL_BASE + where);
+   return 0;
+   }
+
+   if ((bus == priv->first_busno + 1) && dev == 0) {
+   old = readl(priv->axi_base + where);
+   value = pci_conv_size_to_32(old, value, offset, size);
+   writel(value, priv->axi_base + where);
+   return 0;
+   }
+
+   return 0;
+}
+
+static int rockchip_pcie_atr_init(struct rockchip_pcie *priv)
+{
+   struct udevice *ctlr = pci_get_controller(priv->dev);
+   struct pci_controller *hose = dev_get_uclass_priv(ctlr);
+   u64 addr, size, offset;
+   u32 type;
+   int i, region;
+
+   /* Use region 0 to map PCI configuration space. */
+   writel(25 - 1, priv->apb_base + PCIE_ATR_OB_ADDR0(0));
+   writel(0, priv->apb_base + PCIE_ATR_OB_ADDR1(0));
+   writel(PCIE_ATR_HDR_CFG_TYPE0 | PCIE_ATR_HDR_RID,
+