linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 0/7] Add endpoint driver for Rockchip PCIe controller
@ 2018-04-27  2:38 Shawn Lin
  2018-04-27  2:39 ` [PATCH v6 2/7] PCI: rockchip: Split out common function to parse DT Shawn Lin
                   ` (6 more replies)
  0 siblings, 7 replies; 12+ messages in thread
From: Shawn Lin @ 2018-04-27  2:38 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Bjorn Helgaas
  Cc: Heiko Stuebner, Rob Herring, devicetree, linux-rockchip,
	linux-pci, Shawn Lin


Hi Lorenzo,

This's the 6th try to upstream endpoint driver for Rockchip PCIe
controller. V6 is rebased by droping the rename change.

Thanks.


Changes in v6:
- rebase

Changes in v5:
- export symbol to fix error reported by Kbuild robot
- PCIE_ROCKCHIP depends on PCI

Changes in v4:
- remove empty line
- keep rockchip's order next to cadence and dwc, but
  we will try to resort it later when reconstructing
  the directories

Shawn Lin (7):
  PCI: rockchip: Separate common code from RC driver
  PCI: rockchip: Split out common function to parse DT
  PCI: rockchip: Split out common function to init controller
  dt-bindings: PCI: rockchip: Rename rockchip-pcie.txt to
    rockchip-pcie-host.txt
  PCI: rockchip: Add Endpoint controller driver for Rockchip PCIe
    controller
  dt-bindings: PCI: rockchip: Add DT bindings for Rockchip PCIe endpoint
    controller
  arm64: defconfig: update config for Rockchip PCIe

 .../devicetree/bindings/pci/rockchip-pcie-ep.txt   |   62 +
 .../{rockchip-pcie.txt => rockchip-pcie-host.txt}  |    0
 MAINTAINERS                                        |    4 +-
 arch/arm64/configs/defconfig                       |    3 +-
 drivers/pci/host/Kconfig                           |   19 +-
 drivers/pci/host/Makefile                          |    2 +
 drivers/pci/host/pcie-rockchip-ep.c                |  642 ++++++++
 drivers/pci/host/pcie-rockchip-host.c              | 1141 +++++++++++++
 drivers/pci/host/pcie-rockchip.c                   | 1683 +++-----------------
 drivers/pci/host/pcie-rockchip.h                   |  338 ++++
 10 files changed, 2406 insertions(+), 1488 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/rockchip-pcie-ep.txt
 rename Documentation/devicetree/bindings/pci/{rockchip-pcie.txt => rockchip-pcie-host.txt} (100%)
 create mode 100644 drivers/pci/host/pcie-rockchip-ep.c
 create mode 100644 drivers/pci/host/pcie-rockchip-host.c
 create mode 100644 drivers/pci/host/pcie-rockchip.h

-- 
1.9.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v6 2/7] PCI: rockchip: Split out common function to parse DT
  2018-04-27  2:38 [PATCH v6 0/7] Add endpoint driver for Rockchip PCIe controller Shawn Lin
@ 2018-04-27  2:39 ` Shawn Lin
  2018-04-30 14:51   ` Lorenzo Pieralisi
  2018-04-27  2:39 ` [PATCH v6 3/7] PCI: rockchip: Split out common function to init controller Shawn Lin
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: Shawn Lin @ 2018-04-27  2:39 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Bjorn Helgaas
  Cc: Heiko Stuebner, Rob Herring, devicetree, linux-rockchip,
	linux-pci, Shawn Lin

Most of the DT properties are used for both of host and
EP drivrs, so this patch spilt them out to new function,
rockchip_pcie_parse_dt in pcie-rockchip.c and rename the
original function to rockchip_pcie_parse_host_dt to avoid
confusion. No functional changed intended.

Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Tested-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---

Changes in v6: None
Changes in v5: None
Changes in v4: None

 drivers/pci/host/pcie-rockchip-host.c | 119 ++-----------------------------
 drivers/pci/host/pcie-rockchip.c      | 129 ++++++++++++++++++++++++++++++++++
 drivers/pci/host/pcie-rockchip.h      |   2 +
 3 files changed, 136 insertions(+), 114 deletions(-)

diff --git a/drivers/pci/host/pcie-rockchip-host.c b/drivers/pci/host/pcie-rockchip-host.c
index fae9ecc..cf97130 100644
--- a/drivers/pci/host/pcie-rockchip-host.c
+++ b/drivers/pci/host/pcie-rockchip-host.c
@@ -705,130 +705,20 @@ static int rockchip_pcie_setup_irq(struct rockchip_pcie *rockchip)
 }
 
 /**
- * rockchip_pcie_parse_dt - Parse Device Tree
+ * rockchip_pcie_parse_host_dt - Parse Device Tree
  * @rockchip: PCIe port information
  *
  * Return: '0' on success and error value on failure
  */
-static int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
+static int rockchip_pcie_parse_host_dt(struct rockchip_pcie *rockchip)
 {
 	struct device *dev = rockchip->dev;
-	struct platform_device *pdev = to_platform_device(dev);
-	struct device_node *node = dev->of_node;
-	struct resource *regs;
 	int err;
 
-	regs = platform_get_resource_byname(pdev,
-					    IORESOURCE_MEM,
-					    "axi-base");
-	rockchip->reg_base = devm_pci_remap_cfg_resource(dev, regs);
-	if (IS_ERR(rockchip->reg_base))
-		return PTR_ERR(rockchip->reg_base);
-
-	regs = platform_get_resource_byname(pdev,
-					    IORESOURCE_MEM,
-					    "apb-base");
-	rockchip->apb_base = devm_ioremap_resource(dev, regs);
-	if (IS_ERR(rockchip->apb_base))
-		return PTR_ERR(rockchip->apb_base);
-
-	err = rockchip_pcie_get_phys(rockchip);
+	err = rockchip_pcie_parse_dt(rockchip);
 	if (err)
 		return err;
 
-	rockchip->lanes = 1;
-	err = of_property_read_u32(node, "num-lanes", &rockchip->lanes);
-	if (!err && (rockchip->lanes == 0 ||
-		     rockchip->lanes == 3 ||
-		     rockchip->lanes > 4)) {
-		dev_warn(dev, "invalid num-lanes, default to use one lane\n");
-		rockchip->lanes = 1;
-	}
-
-	rockchip->link_gen = of_pci_get_max_link_speed(node);
-	if (rockchip->link_gen < 0 || rockchip->link_gen > 2)
-		rockchip->link_gen = 2;
-
-	rockchip->core_rst = devm_reset_control_get_exclusive(dev, "core");
-	if (IS_ERR(rockchip->core_rst)) {
-		if (PTR_ERR(rockchip->core_rst) != -EPROBE_DEFER)
-			dev_err(dev, "missing core reset property in node\n");
-		return PTR_ERR(rockchip->core_rst);
-	}
-
-	rockchip->mgmt_rst = devm_reset_control_get_exclusive(dev, "mgmt");
-	if (IS_ERR(rockchip->mgmt_rst)) {
-		if (PTR_ERR(rockchip->mgmt_rst) != -EPROBE_DEFER)
-			dev_err(dev, "missing mgmt reset property in node\n");
-		return PTR_ERR(rockchip->mgmt_rst);
-	}
-
-	rockchip->mgmt_sticky_rst = devm_reset_control_get_exclusive(dev,
-								     "mgmt-sticky");
-	if (IS_ERR(rockchip->mgmt_sticky_rst)) {
-		if (PTR_ERR(rockchip->mgmt_sticky_rst) != -EPROBE_DEFER)
-			dev_err(dev, "missing mgmt-sticky reset property in node\n");
-		return PTR_ERR(rockchip->mgmt_sticky_rst);
-	}
-
-	rockchip->pipe_rst = devm_reset_control_get_exclusive(dev, "pipe");
-	if (IS_ERR(rockchip->pipe_rst)) {
-		if (PTR_ERR(rockchip->pipe_rst) != -EPROBE_DEFER)
-			dev_err(dev, "missing pipe reset property in node\n");
-		return PTR_ERR(rockchip->pipe_rst);
-	}
-
-	rockchip->pm_rst = devm_reset_control_get_exclusive(dev, "pm");
-	if (IS_ERR(rockchip->pm_rst)) {
-		if (PTR_ERR(rockchip->pm_rst) != -EPROBE_DEFER)
-			dev_err(dev, "missing pm reset property in node\n");
-		return PTR_ERR(rockchip->pm_rst);
-	}
-
-	rockchip->pclk_rst = devm_reset_control_get_exclusive(dev, "pclk");
-	if (IS_ERR(rockchip->pclk_rst)) {
-		if (PTR_ERR(rockchip->pclk_rst) != -EPROBE_DEFER)
-			dev_err(dev, "missing pclk reset property in node\n");
-		return PTR_ERR(rockchip->pclk_rst);
-	}
-
-	rockchip->aclk_rst = devm_reset_control_get_exclusive(dev, "aclk");
-	if (IS_ERR(rockchip->aclk_rst)) {
-		if (PTR_ERR(rockchip->aclk_rst) != -EPROBE_DEFER)
-			dev_err(dev, "missing aclk reset property in node\n");
-		return PTR_ERR(rockchip->aclk_rst);
-	}
-
-	rockchip->ep_gpio = devm_gpiod_get(dev, "ep", GPIOD_OUT_HIGH);
-	if (IS_ERR(rockchip->ep_gpio)) {
-		dev_err(dev, "missing ep-gpios property in node\n");
-		return PTR_ERR(rockchip->ep_gpio);
-	}
-
-	rockchip->aclk_pcie = devm_clk_get(dev, "aclk");
-	if (IS_ERR(rockchip->aclk_pcie)) {
-		dev_err(dev, "aclk clock not found\n");
-		return PTR_ERR(rockchip->aclk_pcie);
-	}
-
-	rockchip->aclk_perf_pcie = devm_clk_get(dev, "aclk-perf");
-	if (IS_ERR(rockchip->aclk_perf_pcie)) {
-		dev_err(dev, "aclk_perf clock not found\n");
-		return PTR_ERR(rockchip->aclk_perf_pcie);
-	}
-
-	rockchip->hclk_pcie = devm_clk_get(dev, "hclk");
-	if (IS_ERR(rockchip->hclk_pcie)) {
-		dev_err(dev, "hclk clock not found\n");
-		return PTR_ERR(rockchip->hclk_pcie);
-	}
-
-	rockchip->clk_pcie_pm = devm_clk_get(dev, "pm");
-	if (IS_ERR(rockchip->clk_pcie_pm)) {
-		dev_err(dev, "pm clock not found\n");
-		return PTR_ERR(rockchip->clk_pcie_pm);
-	}
-
 	err = rockchip_pcie_setup_irq(rockchip);
 	if (err)
 		return err;
@@ -1195,8 +1085,9 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, rockchip);
 	rockchip->dev = dev;
+	rockchip->is_rc = true;
 
-	err = rockchip_pcie_parse_dt(rockchip);
+	err = rockchip_pcie_parse_host_dt(rockchip);
 	if (err)
 		return err;
 
diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c
index 3d46da9..bcc222b 100644
--- a/drivers/pci/host/pcie-rockchip.c
+++ b/drivers/pci/host/pcie-rockchip.c
@@ -12,10 +12,139 @@
  */
 
 #include <linux/clk.h>
+#include <linux/gpio/consumer.h>
+#include <linux/of_pci.h>
 #include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
 
 #include "pcie-rockchip.h"
 
+int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
+{
+	struct device *dev = rockchip->dev;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct device_node *node = dev->of_node;
+	struct resource *regs;
+	int err;
+
+	regs = platform_get_resource_byname(pdev,
+					    IORESOURCE_MEM,
+					    "axi-base");
+	rockchip->reg_base = devm_pci_remap_cfg_resource(dev, regs);
+	if (IS_ERR(rockchip->reg_base))
+		return PTR_ERR(rockchip->reg_base);
+
+	regs = platform_get_resource_byname(pdev,
+					    IORESOURCE_MEM,
+					    "apb-base");
+	rockchip->apb_base = devm_ioremap_resource(dev, regs);
+	if (IS_ERR(rockchip->apb_base))
+		return PTR_ERR(rockchip->apb_base);
+
+	err = rockchip_pcie_get_phys(rockchip);
+	if (err)
+		return err;
+
+	rockchip->lanes = 1;
+	err = of_property_read_u32(node, "num-lanes", &rockchip->lanes);
+	if (!err && (rockchip->lanes == 0 ||
+		     rockchip->lanes == 3 ||
+		     rockchip->lanes > 4)) {
+		dev_warn(dev, "invalid num-lanes, default to use one lane\n");
+		rockchip->lanes = 1;
+	}
+
+	rockchip->link_gen = of_pci_get_max_link_speed(node);
+	if (rockchip->link_gen < 0 || rockchip->link_gen > 2)
+		rockchip->link_gen = 2;
+
+	rockchip->core_rst = devm_reset_control_get_exclusive(dev, "core");
+	if (IS_ERR(rockchip->core_rst)) {
+		if (PTR_ERR(rockchip->core_rst) != -EPROBE_DEFER)
+			dev_err(dev, "missing core reset property in node\n");
+		return PTR_ERR(rockchip->core_rst);
+	}
+
+	rockchip->mgmt_rst = devm_reset_control_get_exclusive(dev, "mgmt");
+	if (IS_ERR(rockchip->mgmt_rst)) {
+		if (PTR_ERR(rockchip->mgmt_rst) != -EPROBE_DEFER)
+			dev_err(dev, "missing mgmt reset property in node\n");
+		return PTR_ERR(rockchip->mgmt_rst);
+	}
+
+	rockchip->mgmt_sticky_rst = devm_reset_control_get_exclusive(dev,
+								     "mgmt-sticky");
+	if (IS_ERR(rockchip->mgmt_sticky_rst)) {
+		if (PTR_ERR(rockchip->mgmt_sticky_rst) != -EPROBE_DEFER)
+			dev_err(dev, "missing mgmt-sticky reset property in node\n");
+		return PTR_ERR(rockchip->mgmt_sticky_rst);
+	}
+
+	rockchip->pipe_rst = devm_reset_control_get_exclusive(dev, "pipe");
+	if (IS_ERR(rockchip->pipe_rst)) {
+		if (PTR_ERR(rockchip->pipe_rst) != -EPROBE_DEFER)
+			dev_err(dev, "missing pipe reset property in node\n");
+		return PTR_ERR(rockchip->pipe_rst);
+	}
+
+	rockchip->pm_rst = devm_reset_control_get_exclusive(dev, "pm");
+	if (IS_ERR(rockchip->pm_rst)) {
+		if (PTR_ERR(rockchip->pm_rst) != -EPROBE_DEFER)
+			dev_err(dev, "missing pm reset property in node\n");
+		return PTR_ERR(rockchip->pm_rst);
+	}
+
+	rockchip->pclk_rst = devm_reset_control_get_exclusive(dev, "pclk");
+	if (IS_ERR(rockchip->pclk_rst)) {
+		if (PTR_ERR(rockchip->pclk_rst) != -EPROBE_DEFER)
+			dev_err(dev, "missing pclk reset property in node\n");
+		return PTR_ERR(rockchip->pclk_rst);
+	}
+
+	rockchip->aclk_rst = devm_reset_control_get_exclusive(dev, "aclk");
+	if (IS_ERR(rockchip->aclk_rst)) {
+		if (PTR_ERR(rockchip->aclk_rst) != -EPROBE_DEFER)
+			dev_err(dev, "missing aclk reset property in node\n");
+		return PTR_ERR(rockchip->aclk_rst);
+	}
+
+	if (rockchip->is_rc) {
+		rockchip->ep_gpio = devm_gpiod_get(dev, "ep", GPIOD_OUT_HIGH);
+		if (IS_ERR(rockchip->ep_gpio)) {
+			dev_err(dev, "missing ep-gpios property in node\n");
+			return PTR_ERR(rockchip->ep_gpio);
+		}
+	}
+
+	rockchip->aclk_pcie = devm_clk_get(dev, "aclk");
+	if (IS_ERR(rockchip->aclk_pcie)) {
+		dev_err(dev, "aclk clock not found\n");
+		return PTR_ERR(rockchip->aclk_pcie);
+	}
+
+	rockchip->aclk_perf_pcie = devm_clk_get(dev, "aclk-perf");
+	if (IS_ERR(rockchip->aclk_perf_pcie)) {
+		dev_err(dev, "aclk_perf clock not found\n");
+		return PTR_ERR(rockchip->aclk_perf_pcie);
+	}
+
+	rockchip->hclk_pcie = devm_clk_get(dev, "hclk");
+	if (IS_ERR(rockchip->hclk_pcie)) {
+		dev_err(dev, "hclk clock not found\n");
+		return PTR_ERR(rockchip->hclk_pcie);
+	}
+
+	rockchip->clk_pcie_pm = devm_clk_get(dev, "pm");
+	if (IS_ERR(rockchip->clk_pcie_pm)) {
+		dev_err(dev, "pm clock not found\n");
+		return PTR_ERR(rockchip->clk_pcie_pm);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rockchip_pcie_parse_dt);
+
 int rockchip_pcie_get_phys(struct rockchip_pcie *rockchip)
 {
 	struct device *dev = rockchip->dev;
diff --git a/drivers/pci/host/pcie-rockchip.h b/drivers/pci/host/pcie-rockchip.h
index d27941e..473e74f 100644
--- a/drivers/pci/host/pcie-rockchip.h
+++ b/drivers/pci/host/pcie-rockchip.h
@@ -222,6 +222,7 @@ struct rockchip_pcie {
 	u32     mem_size;
 	phys_addr_t msg_bus_addr;
 	phys_addr_t mem_bus_addr;
+	bool is_rc;
 };
 
 static u32 rockchip_pcie_read(struct rockchip_pcie *rockchip, u32 reg)
@@ -235,6 +236,7 @@ static void rockchip_pcie_write(struct rockchip_pcie *rockchip, u32 val,
 	writel(val, rockchip->apb_base + reg);
 }
 
+int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip);
 int rockchip_pcie_get_phys(struct rockchip_pcie *rockchip);
 void rockchip_pcie_deinit_phys(struct rockchip_pcie *rockchip);
 int rockchip_pcie_enable_clocks(struct rockchip_pcie *rockchip);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v6 3/7] PCI: rockchip: Split out common function to init controller
  2018-04-27  2:38 [PATCH v6 0/7] Add endpoint driver for Rockchip PCIe controller Shawn Lin
  2018-04-27  2:39 ` [PATCH v6 2/7] PCI: rockchip: Split out common function to parse DT Shawn Lin
@ 2018-04-27  2:39 ` Shawn Lin
  2018-04-27  2:39 ` [PATCH v6 4/7] dt-bindings: PCI: rockchip: Rename rockchip-pcie.txt to rockchip-pcie-host.txt Shawn Lin
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Shawn Lin @ 2018-04-27  2:39 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Bjorn Helgaas
  Cc: Heiko Stuebner, Rob Herring, devicetree, linux-rockchip,
	linux-pci, Shawn Lin

Most of the operations are used for both of host and EP driver,
so this patch spilt them out to a new function, rockchip_pcie_init_port
in pcie-rockchip.c and rename the original function to
rockchip_pcie_host_init_port to avoid confusion. No functional
changed intended.

Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Tested-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---

Changes in v6: None
Changes in v5: None
Changes in v4: None

 drivers/pci/host/pcie-rockchip-host.c | 132 ++-----------------------------
 drivers/pci/host/pcie-rockchip.c      | 142 ++++++++++++++++++++++++++++++++++
 drivers/pci/host/pcie-rockchip.h      |   3 +
 3 files changed, 152 insertions(+), 125 deletions(-)

diff --git a/drivers/pci/host/pcie-rockchip-host.c b/drivers/pci/host/pcie-rockchip-host.c
index cf97130..388dbef 100644
--- a/drivers/pci/host/pcie-rockchip-host.c
+++ b/drivers/pci/host/pcie-rockchip-host.c
@@ -293,137 +293,20 @@ static void rockchip_pcie_set_power_limit(struct rockchip_pcie *rockchip)
 }
 
 /**
- * rockchip_pcie_init_port - Initialize hardware
+ * rockchip_pcie_host_init_port - Initialize hardware
  * @rockchip: PCIe port information
  */
-static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
+static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
 {
 	struct device *dev = rockchip->dev;
-	int err, i;
+	int err, i = MAX_LANE_NUM;
 	u32 status;
 
 	gpiod_set_value_cansleep(rockchip->ep_gpio, 0);
 
-	err = reset_control_assert(rockchip->aclk_rst);
-	if (err) {
-		dev_err(dev, "assert aclk_rst err %d\n", err);
-		return err;
-	}
-
-	err = reset_control_assert(rockchip->pclk_rst);
-	if (err) {
-		dev_err(dev, "assert pclk_rst err %d\n", err);
-		return err;
-	}
-
-	err = reset_control_assert(rockchip->pm_rst);
-	if (err) {
-		dev_err(dev, "assert pm_rst err %d\n", err);
+	err = rockchip_pcie_init_port(rockchip);
+	if (err)
 		return err;
-	}
-
-	for (i = 0; i < MAX_LANE_NUM; i++) {
-		err = phy_init(rockchip->phys[i]);
-		if (err) {
-			dev_err(dev, "init phy%d err %d\n", i, err);
-			goto err_exit_phy;
-		}
-	}
-
-	err = reset_control_assert(rockchip->core_rst);
-	if (err) {
-		dev_err(dev, "assert core_rst err %d\n", err);
-		goto err_exit_phy;
-	}
-
-	err = reset_control_assert(rockchip->mgmt_rst);
-	if (err) {
-		dev_err(dev, "assert mgmt_rst err %d\n", err);
-		goto err_exit_phy;
-	}
-
-	err = reset_control_assert(rockchip->mgmt_sticky_rst);
-	if (err) {
-		dev_err(dev, "assert mgmt_sticky_rst err %d\n", err);
-		goto err_exit_phy;
-	}
-
-	err = reset_control_assert(rockchip->pipe_rst);
-	if (err) {
-		dev_err(dev, "assert pipe_rst err %d\n", err);
-		goto err_exit_phy;
-	}
-
-	udelay(10);
-
-	err = reset_control_deassert(rockchip->pm_rst);
-	if (err) {
-		dev_err(dev, "deassert pm_rst err %d\n", err);
-		goto err_exit_phy;
-	}
-
-	err = reset_control_deassert(rockchip->aclk_rst);
-	if (err) {
-		dev_err(dev, "deassert aclk_rst err %d\n", err);
-		goto err_exit_phy;
-	}
-
-	err = reset_control_deassert(rockchip->pclk_rst);
-	if (err) {
-		dev_err(dev, "deassert pclk_rst err %d\n", err);
-		goto err_exit_phy;
-	}
-
-	if (rockchip->link_gen == 2)
-		rockchip_pcie_write(rockchip, PCIE_CLIENT_GEN_SEL_2,
-				    PCIE_CLIENT_CONFIG);
-	else
-		rockchip_pcie_write(rockchip, PCIE_CLIENT_GEN_SEL_1,
-				    PCIE_CLIENT_CONFIG);
-
-	rockchip_pcie_write(rockchip,
-			    PCIE_CLIENT_CONF_ENABLE |
-			    PCIE_CLIENT_LINK_TRAIN_ENABLE |
-			    PCIE_CLIENT_ARI_ENABLE |
-			    PCIE_CLIENT_CONF_LANE_NUM(rockchip->lanes) |
-			    PCIE_CLIENT_MODE_RC,
-			    PCIE_CLIENT_CONFIG);
-
-	for (i = 0; i < MAX_LANE_NUM; i++) {
-		err = phy_power_on(rockchip->phys[i]);
-		if (err) {
-			dev_err(dev, "power on phy%d err %d\n", i, err);
-			goto err_power_off_phy;
-		}
-	}
-
-	/*
-	 * Please don't reorder the deassert sequence of the following
-	 * four reset pins.
-	 */
-	err = reset_control_deassert(rockchip->mgmt_sticky_rst);
-	if (err) {
-		dev_err(dev, "deassert mgmt_sticky_rst err %d\n", err);
-		goto err_power_off_phy;
-	}
-
-	err = reset_control_deassert(rockchip->core_rst);
-	if (err) {
-		dev_err(dev, "deassert core_rst err %d\n", err);
-		goto err_power_off_phy;
-	}
-
-	err = reset_control_deassert(rockchip->mgmt_rst);
-	if (err) {
-		dev_err(dev, "deassert mgmt_rst err %d\n", err);
-		goto err_power_off_phy;
-	}
-
-	err = reset_control_deassert(rockchip->pipe_rst);
-	if (err) {
-		dev_err(dev, "deassert pipe_rst err %d\n", err);
-		goto err_power_off_phy;
-	}
 
 	/* Fix the transmitted FTS count desired to exit from L0s. */
 	status = rockchip_pcie_read(rockchip, PCIE_CORE_CTRL_PLC1);
@@ -517,7 +400,6 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
 	while (i--)
 		phy_power_off(rockchip->phys[i]);
 	i = MAX_LANE_NUM;
-err_exit_phy:
 	while (i--)
 		phy_exit(rockchip->phys[i]);
 	return err;
@@ -1036,7 +918,7 @@ static int __maybe_unused rockchip_pcie_resume_noirq(struct device *dev)
 	if (err)
 		goto err_disable_0v9;
 
-	err = rockchip_pcie_init_port(rockchip);
+	err = rockchip_pcie_host_init_port(rockchip);
 	if (err)
 		goto err_pcie_resume;
 
@@ -1101,7 +983,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
 		goto err_set_vpcie;
 	}
 
-	err = rockchip_pcie_init_port(rockchip);
+	err = rockchip_pcie_host_init_port(rockchip);
 	if (err)
 		goto err_vpcie;
 
diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c
index bcc222b..b27e975 100644
--- a/drivers/pci/host/pcie-rockchip.c
+++ b/drivers/pci/host/pcie-rockchip.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/delay.h>
 #include <linux/gpio/consumer.h>
 #include <linux/of_pci.h>
 #include <linux/phy/phy.h>
@@ -145,6 +146,147 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
 }
 EXPORT_SYMBOL_GPL(rockchip_pcie_parse_dt);
 
+int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
+{
+	struct device *dev = rockchip->dev;
+	int err, i;
+	u32 regs;
+
+	err = reset_control_assert(rockchip->aclk_rst);
+	if (err) {
+		dev_err(dev, "assert aclk_rst err %d\n", err);
+		return err;
+	}
+
+	err = reset_control_assert(rockchip->pclk_rst);
+	if (err) {
+		dev_err(dev, "assert pclk_rst err %d\n", err);
+		return err;
+	}
+
+	err = reset_control_assert(rockchip->pm_rst);
+	if (err) {
+		dev_err(dev, "assert pm_rst err %d\n", err);
+		return err;
+	}
+
+	for (i = 0; i < MAX_LANE_NUM; i++) {
+		err = phy_init(rockchip->phys[i]);
+		if (err) {
+			dev_err(dev, "init phy%d err %d\n", i, err);
+			goto err_exit_phy;
+		}
+	}
+
+	err = reset_control_assert(rockchip->core_rst);
+	if (err) {
+		dev_err(dev, "assert core_rst err %d\n", err);
+		goto err_exit_phy;
+	}
+
+	err = reset_control_assert(rockchip->mgmt_rst);
+	if (err) {
+		dev_err(dev, "assert mgmt_rst err %d\n", err);
+		goto err_exit_phy;
+	}
+
+	err = reset_control_assert(rockchip->mgmt_sticky_rst);
+	if (err) {
+		dev_err(dev, "assert mgmt_sticky_rst err %d\n", err);
+		goto err_exit_phy;
+	}
+
+	err = reset_control_assert(rockchip->pipe_rst);
+	if (err) {
+		dev_err(dev, "assert pipe_rst err %d\n", err);
+		goto err_exit_phy;
+	}
+
+	udelay(10);
+
+	err = reset_control_deassert(rockchip->pm_rst);
+	if (err) {
+		dev_err(dev, "deassert pm_rst err %d\n", err);
+		goto err_exit_phy;
+	}
+
+	err = reset_control_deassert(rockchip->aclk_rst);
+	if (err) {
+		dev_err(dev, "deassert aclk_rst err %d\n", err);
+		goto err_exit_phy;
+	}
+
+	err = reset_control_deassert(rockchip->pclk_rst);
+	if (err) {
+		dev_err(dev, "deassert pclk_rst err %d\n", err);
+		goto err_exit_phy;
+	}
+
+	if (rockchip->link_gen == 2)
+		rockchip_pcie_write(rockchip, PCIE_CLIENT_GEN_SEL_2,
+				    PCIE_CLIENT_CONFIG);
+	else
+		rockchip_pcie_write(rockchip, PCIE_CLIENT_GEN_SEL_1,
+				    PCIE_CLIENT_CONFIG);
+
+	regs = PCIE_CLIENT_LINK_TRAIN_ENABLE | PCIE_CLIENT_ARI_ENABLE |
+	       PCIE_CLIENT_CONF_LANE_NUM(rockchip->lanes);
+
+	if (rockchip->is_rc)
+		regs |= PCIE_CLIENT_CONF_ENABLE | PCIE_CLIENT_MODE_RC;
+	else
+		regs |= PCIE_CLIENT_CONF_DISABLE | PCIE_CLIENT_MODE_EP;
+
+	rockchip_pcie_write(rockchip, regs, PCIE_CLIENT_CONFIG);
+
+	for (i = 0; i < MAX_LANE_NUM; i++) {
+		err = phy_power_on(rockchip->phys[i]);
+		if (err) {
+			dev_err(dev, "power on phy%d err %d\n", i, err);
+			goto err_power_off_phy;
+		}
+	}
+
+	/*
+	 * Please don't reorder the deassert sequence of the following
+	 * four reset pins.
+	 */
+	err = reset_control_deassert(rockchip->mgmt_sticky_rst);
+	if (err) {
+		dev_err(dev, "deassert mgmt_sticky_rst err %d\n", err);
+		goto err_power_off_phy;
+	}
+
+	err = reset_control_deassert(rockchip->core_rst);
+	if (err) {
+		dev_err(dev, "deassert core_rst err %d\n", err);
+		goto err_power_off_phy;
+	}
+
+	err = reset_control_deassert(rockchip->mgmt_rst);
+	if (err) {
+		dev_err(dev, "deassert mgmt_rst err %d\n", err);
+		goto err_power_off_phy;
+	}
+
+	err = reset_control_deassert(rockchip->pipe_rst);
+	if (err) {
+		dev_err(dev, "deassert pipe_rst err %d\n", err);
+		goto err_power_off_phy;
+	}
+
+	return 0;
+err_power_off_phy:
+	while (i--)
+		phy_power_off(rockchip->phys[i]);
+	i = MAX_LANE_NUM;
+err_exit_phy:
+	while (i--)
+		phy_exit(rockchip->phys[i]);
+	return err;
+}
+EXPORT_SYMBOL_GPL(rockchip_pcie_init_port);
+
 int rockchip_pcie_get_phys(struct rockchip_pcie *rockchip)
 {
 	struct device *dev = rockchip->dev;
diff --git a/drivers/pci/host/pcie-rockchip.h b/drivers/pci/host/pcie-rockchip.h
index 473e74f..6f6e7ad 100644
--- a/drivers/pci/host/pcie-rockchip.h
+++ b/drivers/pci/host/pcie-rockchip.h
@@ -27,10 +27,12 @@
 #define PCIE_CLIENT_BASE		0x0
 #define PCIE_CLIENT_CONFIG		(PCIE_CLIENT_BASE + 0x00)
 #define   PCIE_CLIENT_CONF_ENABLE	  HIWORD_UPDATE_BIT(0x0001)
+#define   PCIE_CLIENT_CONF_DISABLE       HIWORD_UPDATE(0x0001, 0)
 #define   PCIE_CLIENT_LINK_TRAIN_ENABLE	  HIWORD_UPDATE_BIT(0x0002)
 #define   PCIE_CLIENT_ARI_ENABLE	  HIWORD_UPDATE_BIT(0x0008)
 #define   PCIE_CLIENT_CONF_LANE_NUM(x)	  HIWORD_UPDATE(0x0030, ENCODE_LANES(x))
 #define   PCIE_CLIENT_MODE_RC		  HIWORD_UPDATE_BIT(0x0040)
+#define   PCIE_CLIENT_MODE_EP            HIWORD_UPDATE(0x0040, 0)
 #define   PCIE_CLIENT_GEN_SEL_1		  HIWORD_UPDATE(0x0080, 0)
 #define   PCIE_CLIENT_GEN_SEL_2		  HIWORD_UPDATE_BIT(0x0080)
 #define PCIE_CLIENT_DEBUG_OUT_0		(PCIE_CLIENT_BASE + 0x3c)
@@ -237,6 +239,7 @@ static void rockchip_pcie_write(struct rockchip_pcie *rockchip, u32 val,
 }
 
 int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip);
+int rockchip_pcie_init_port(struct rockchip_pcie *rockchip);
 int rockchip_pcie_get_phys(struct rockchip_pcie *rockchip);
 void rockchip_pcie_deinit_phys(struct rockchip_pcie *rockchip);
 int rockchip_pcie_enable_clocks(struct rockchip_pcie *rockchip);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v6 4/7] dt-bindings: PCI: rockchip: Rename rockchip-pcie.txt to rockchip-pcie-host.txt
  2018-04-27  2:38 [PATCH v6 0/7] Add endpoint driver for Rockchip PCIe controller Shawn Lin
  2018-04-27  2:39 ` [PATCH v6 2/7] PCI: rockchip: Split out common function to parse DT Shawn Lin
  2018-04-27  2:39 ` [PATCH v6 3/7] PCI: rockchip: Split out common function to init controller Shawn Lin
@ 2018-04-27  2:39 ` Shawn Lin
  2018-04-27  2:39 ` [PATCH v6 5/7] PCI: rockchip: Add Endpoint controller driver for Rockchip PCIe controller Shawn Lin
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Shawn Lin @ 2018-04-27  2:39 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Bjorn Helgaas
  Cc: Heiko Stuebner, Rob Herring, devicetree, linux-rockchip,
	linux-pci, Shawn Lin

Just make it more obvious that this documentation is referenced for
adding Rockchip PCIe controller as root complex mode.

Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---

Changes in v6: None
Changes in v5: None
Changes in v4: None

 .../devicetree/bindings/pci/{rockchip-pcie.txt => rockchip-pcie-host.txt} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename Documentation/devicetree/bindings/pci/{rockchip-pcie.txt => rockchip-pcie-host.txt} (100%)

diff --git a/Documentation/devicetree/bindings/pci/rockchip-pcie.txt b/Documentation/devicetree/bindings/pci/rockchip-pcie-host.txt
similarity index 100%
rename from Documentation/devicetree/bindings/pci/rockchip-pcie.txt
rename to Documentation/devicetree/bindings/pci/rockchip-pcie-host.txt
-- 
1.9.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v6 5/7] PCI: rockchip: Add Endpoint controller driver for Rockchip PCIe controller
  2018-04-27  2:38 [PATCH v6 0/7] Add endpoint driver for Rockchip PCIe controller Shawn Lin
                   ` (2 preceding siblings ...)
  2018-04-27  2:39 ` [PATCH v6 4/7] dt-bindings: PCI: rockchip: Rename rockchip-pcie.txt to rockchip-pcie-host.txt Shawn Lin
@ 2018-04-27  2:39 ` Shawn Lin
  2018-04-27  2:39 ` [PATCH v6 6/7] dt-bindings: PCI: rockchip: Add DT bindings for Rockchip PCIe endpoint controller Shawn Lin
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Shawn Lin @ 2018-04-27  2:39 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Bjorn Helgaas
  Cc: Heiko Stuebner, Rob Herring, devicetree, linux-rockchip,
	linux-pci, Shawn Lin

This patch adds support to the Rockchip PCIe controller in endpoint mode
which currently supports up to 32 regions, and each regions should at
least be 1MB per TRM.

Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---

Changes in v6: None
Changes in v5: None
Changes in v4: None

 drivers/pci/host/Kconfig            |  12 +
 drivers/pci/host/Makefile           |   1 +
 drivers/pci/host/pcie-rockchip-ep.c | 642 ++++++++++++++++++++++++++++++++++++
 drivers/pci/host/pcie-rockchip.c    |  25 +-
 drivers/pci/host/pcie-rockchip.h    |  88 +++++
 5 files changed, 759 insertions(+), 9 deletions(-)
 create mode 100644 drivers/pci/host/pcie-rockchip-ep.c

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index f2d8cab..0d8b21b 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -194,6 +194,18 @@ config PCIE_ROCKCHIP_HOST
 	  There is 1 internal PCIe port available to support GEN2 with
 	  4 slots.
 
+config PCIE_ROCKCHIP_EP
+	bool "Rockchip PCIe endpoint controller"
+	depends on ARCH_ROCKCHIP || COMPILE_TEST
+	depends on OF
+	depends on PCI_ENDPOINT
+	select MFD_SYSCON
+	select PCIE_ROCKCHIP
+	help
+	  Say Y here if you want to support Rockchip PCIe controller in
+	  endpoint mode on Rockchip SoC. There is 1 internal PCIe port
+	  available to support GEN2 with 4 slots.
+
 config PCIE_MEDIATEK
 	bool "MediaTek PCIe controller"
 	depends on (ARM || ARM64) && (ARCH_MEDIATEK || COMPILE_TEST)
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index f7d4522..11d21b0 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
 obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
 obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o
 obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o
+obj-$(CONFIG_PCIE_ROCKCHIP_EP) += pcie-rockchip-ep.o
 obj-$(CONFIG_PCIE_ROCKCHIP_HOST) += pcie-rockchip-host.o
 obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o
 obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
diff --git a/drivers/pci/host/pcie-rockchip-ep.c b/drivers/pci/host/pcie-rockchip-ep.c
new file mode 100644
index 0000000..fc267a4
--- /dev/null
+++ b/drivers/pci/host/pcie-rockchip-ep.c
@@ -0,0 +1,642 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Rockchip AXI PCIe endpoint controller driver
+ *
+ * Copyright (c) 2018 Rockchip, Inc.
+ *
+ * Author: Shawn Lin <shawn.lin@rock-chips.com>
+ *         Simon Xue <xxm@rock-chips.com>
+ */
+
+#include <linux/configfs.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/pci-epc.h>
+#include <linux/platform_device.h>
+#include <linux/pci-epf.h>
+#include <linux/sizes.h>
+
+#include "pcie-rockchip.h"
+
+/**
+ * struct rockchip_pcie_ep - private data for PCIe endpoint controller driver
+ * @rockchip: Rockchip PCIe controller
+ * @max_regions: maximum number of regions supported by hardware
+ * @ob_region_map: bitmask of mapped outbound regions
+ * @ob_addr: base addresses in the AXI bus where the outbound regions start
+ * @irq_phys_addr: base address on the AXI bus where the MSI/legacy IRQ
+ *		   dedicated outbound regions is mapped.
+ * @irq_cpu_addr: base address in the CPU space where a write access triggers
+ *		  the sending of a memory write (MSI) / normal message (legacy
+ *		  IRQ) TLP through the PCIe bus.
+ * @irq_pci_addr: used to save the current mapping of the MSI/legacy IRQ
+ *		  dedicated outbound region.
+ * @irq_pci_fn: the latest PCI function that has updated the mapping of
+ *		the MSI/legacy IRQ dedicated outbound region.
+ * @irq_pending: bitmask of asserted legacy IRQs.
+ */
+struct rockchip_pcie_ep {
+	struct rockchip_pcie	rockchip;
+	struct pci_epc		*epc;
+	u32			max_regions;
+	unsigned long		ob_region_map;
+	phys_addr_t		*ob_addr;
+	phys_addr_t		irq_phys_addr;
+	void __iomem		*irq_cpu_addr;
+	u64			irq_pci_addr;
+	u8			irq_pci_fn;
+	u8			irq_pending;
+};
+
+static void rockchip_pcie_clear_ep_ob_atu(struct rockchip_pcie *rockchip,
+					  u32 region)
+{
+	rockchip_pcie_write(rockchip, 0,
+			    ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0(region));
+	rockchip_pcie_write(rockchip, 0,
+			    ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR1(region));
+	rockchip_pcie_write(rockchip, 0,
+			    ROCKCHIP_PCIE_AT_OB_REGION_DESC0(region));
+	rockchip_pcie_write(rockchip, 0,
+			    ROCKCHIP_PCIE_AT_OB_REGION_DESC1(region));
+	rockchip_pcie_write(rockchip, 0,
+			    ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR0(region));
+	rockchip_pcie_write(rockchip, 0,
+			    ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR1(region));
+}
+
+static void rockchip_pcie_prog_ep_ob_atu(struct rockchip_pcie *rockchip, u8 fn,
+					 u32 r, u32 type, u64 cpu_addr,
+					 u64 pci_addr, size_t size)
+{
+	u64 sz = 1ULL << fls64(size - 1);
+	int num_pass_bits = ilog2(sz);
+	u32 addr0, addr1, desc0, desc1;
+	bool is_nor_msg = (type == AXI_WRAPPER_NOR_MSG);
+
+	/* The minimal region size is 1MB */
+	if (num_pass_bits < 8)
+		num_pass_bits = 8;
+
+	cpu_addr -= rockchip->mem_res->start;
+	addr0 = ((is_nor_msg ? 0x10 : (num_pass_bits - 1)) &
+		PCIE_CORE_OB_REGION_ADDR0_NUM_BITS) |
+		(lower_32_bits(cpu_addr) & PCIE_CORE_OB_REGION_ADDR0_LO_ADDR);
+	addr1 = upper_32_bits(is_nor_msg ? cpu_addr : pci_addr);
+	desc0 = ROCKCHIP_PCIE_AT_OB_REGION_DESC0_DEVFN(fn) | type;
+	desc1 = 0;
+
+	if (is_nor_msg) {
+		rockchip_pcie_write(rockchip, 0,
+				    ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0(r));
+		rockchip_pcie_write(rockchip, 0,
+				    ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR1(r));
+		rockchip_pcie_write(rockchip, desc0,
+				    ROCKCHIP_PCIE_AT_OB_REGION_DESC0(r));
+		rockchip_pcie_write(rockchip, desc1,
+				    ROCKCHIP_PCIE_AT_OB_REGION_DESC1(r));
+	} else {
+		/* PCI bus address region */
+		rockchip_pcie_write(rockchip, addr0,
+				    ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0(r));
+		rockchip_pcie_write(rockchip, addr1,
+				    ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR1(r));
+		rockchip_pcie_write(rockchip, desc0,
+				    ROCKCHIP_PCIE_AT_OB_REGION_DESC0(r));
+		rockchip_pcie_write(rockchip, desc1,
+				    ROCKCHIP_PCIE_AT_OB_REGION_DESC1(r));
+
+		addr0 =
+		    ((num_pass_bits - 1) & PCIE_CORE_OB_REGION_ADDR0_NUM_BITS) |
+		    (lower_32_bits(cpu_addr) &
+		     PCIE_CORE_OB_REGION_ADDR0_LO_ADDR);
+		addr1 = upper_32_bits(cpu_addr);
+	}
+
+	/* CPU bus address region */
+	rockchip_pcie_write(rockchip, addr0,
+			    ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR0(r));
+	rockchip_pcie_write(rockchip, addr1,
+			    ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR1(r));
+}
+
+static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
+					 struct pci_epf_header *hdr)
+{
+	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
+	struct rockchip_pcie *rockchip = &ep->rockchip;
+
+	/* All functions share the same vendor ID with function 0 */
+	if (fn == 0) {
+		u32 vid_regs = (hdr->vendorid & GENMASK(15, 0)) |
+			       (hdr->subsys_vendor_id & GENMASK(31, 16)) << 16;
+
+		rockchip_pcie_write(rockchip, vid_regs,
+				    PCIE_CORE_CONFIG_VENDOR);
+	}
+
+	rockchip_pcie_write(rockchip, hdr->deviceid << 16,
+			    ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + PCI_VENDOR_ID);
+
+	rockchip_pcie_write(rockchip,
+			    hdr->revid |
+			    hdr->progif_code << 8 |
+			    hdr->subclass_code << 16 |
+			    hdr->baseclass_code << 24,
+			    ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + PCI_REVISION_ID);
+	rockchip_pcie_write(rockchip, hdr->cache_line_size,
+			    ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
+			    PCI_CACHE_LINE_SIZE);
+	rockchip_pcie_write(rockchip, hdr->subsys_id << 16,
+			    ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
+			    PCI_SUBSYSTEM_VENDOR_ID);
+	rockchip_pcie_write(rockchip, hdr->interrupt_pin << 8,
+			    ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
+			    PCI_INTERRUPT_LINE);
+
+	return 0;
+}
+
+static int rockchip_pcie_ep_set_bar(struct pci_epc *epc, u8 fn,
+				    struct pci_epf_bar *epf_bar)
+{
+	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
+	struct rockchip_pcie *rockchip = &ep->rockchip;
+	dma_addr_t bar_phys = epf_bar->phys_addr;
+	enum pci_barno bar = epf_bar->barno;
+	int flags = epf_bar->flags;
+	u32 addr0, addr1, reg, cfg, b, aperture, ctrl;
+	u64 sz;
+
+	/* BAR size is 2^(aperture + 7) */
+	sz = max_t(size_t, epf_bar->size, MIN_EP_APERTURE);
+
+	/*
+	 * roundup_pow_of_two() returns an unsigned long, which is not suited
+	 * for 64bit values.
+	 */
+	sz = 1ULL << fls64(sz - 1);
+	aperture = ilog2(sz) - 7; /* 128B -> 0, 256B -> 1, 512B -> 2, ... */
+
+	if ((flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
+		ctrl = ROCKCHIP_PCIE_CORE_BAR_CFG_CTRL_IO_32BITS;
+	} else {
+		bool is_prefetch = !!(flags & PCI_BASE_ADDRESS_MEM_PREFETCH);
+		bool is_64bits = sz > SZ_2G;
+
+		if (is_64bits && (bar & 1))
+			return -EINVAL;
+
+		if (is_64bits && is_prefetch)
+			ctrl =
+			    ROCKCHIP_PCIE_CORE_BAR_CFG_CTRL_PREFETCH_MEM_64BITS;
+		else if (is_prefetch)
+			ctrl =
+			    ROCKCHIP_PCIE_CORE_BAR_CFG_CTRL_PREFETCH_MEM_32BITS;
+		else if (is_64bits)
+			ctrl = ROCKCHIP_PCIE_CORE_BAR_CFG_CTRL_MEM_64BITS;
+		else
+			ctrl = ROCKCHIP_PCIE_CORE_BAR_CFG_CTRL_MEM_32BITS;
+	}
+
+	if (bar < BAR_4) {
+		reg = ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG0(fn);
+		b = bar;
+	} else {
+		reg = ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG1(fn);
+		b = bar - BAR_4;
+	}
+
+	addr0 = lower_32_bits(bar_phys);
+	addr1 = upper_32_bits(bar_phys);
+
+	cfg = rockchip_pcie_read(rockchip, reg);
+	cfg &= ~(ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
+		 ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
+	cfg |= (ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG_BAR_APERTURE(b, aperture) |
+		ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl));
+
+	rockchip_pcie_write(rockchip, cfg, reg);
+	rockchip_pcie_write(rockchip, addr0,
+			    ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar));
+	rockchip_pcie_write(rockchip, addr1,
+			    ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar));
+
+	return 0;
+}
+
+static void rockchip_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
+				       struct pci_epf_bar *epf_bar)
+{
+	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
+	struct rockchip_pcie *rockchip = &ep->rockchip;
+	u32 reg, cfg, b, ctrl;
+	enum pci_barno bar = epf_bar->barno;
+
+	if (bar < BAR_4) {
+		reg = ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG0(fn);
+		b = bar;
+	} else {
+		reg = ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG1(fn);
+		b = bar - BAR_4;
+	}
+
+	ctrl = ROCKCHIP_PCIE_CORE_BAR_CFG_CTRL_DISABLED;
+	cfg = rockchip_pcie_read(rockchip, reg);
+	cfg &= ~(ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
+		 ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
+	cfg |= ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl);
+
+	rockchip_pcie_write(rockchip, cfg, reg);
+	rockchip_pcie_write(rockchip, 0x0,
+			    ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar));
+	rockchip_pcie_write(rockchip, 0x0,
+			    ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar));
+}
+
+static int rockchip_pcie_ep_map_addr(struct pci_epc *epc, u8 fn,
+				     phys_addr_t addr, u64 pci_addr,
+				     size_t size)
+{
+	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
+	struct rockchip_pcie *pcie = &ep->rockchip;
+	u32 r;
+
+	r = find_first_zero_bit(&ep->ob_region_map,
+				sizeof(ep->ob_region_map) * BITS_PER_LONG);
+	/*
+	 * Region 0 is reserved for configuration space and shouldn't
+	 * be used elsewhere per TRM, so leave it out.
+	 */
+	if (r >= ep->max_regions - 1) {
+		dev_err(&epc->dev, "no free outbound region\n");
+		return -EINVAL;
+	}
+
+	rockchip_pcie_prog_ep_ob_atu(pcie, fn, r, AXI_WRAPPER_MEM_WRITE, addr,
+				     pci_addr, size);
+
+	set_bit(r, &ep->ob_region_map);
+	ep->ob_addr[r] = addr;
+
+	return 0;
+}
+
+static void rockchip_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn,
+					phys_addr_t addr)
+{
+	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
+	struct rockchip_pcie *rockchip = &ep->rockchip;
+	u32 r;
+
+	for (r = 0; r < ep->max_regions - 1; r++)
+		if (ep->ob_addr[r] == addr)
+			break;
+
+	/*
+	 * Region 0 is reserved for configuration space and shouldn't
+	 * be used elsewhere per TRM, so leave it out.
+	 */
+	if (r == ep->max_regions - 1)
+		return;
+
+	rockchip_pcie_clear_ep_ob_atu(rockchip, r);
+
+	ep->ob_addr[r] = 0;
+	clear_bit(r, &ep->ob_region_map);
+}
+
+static int rockchip_pcie_ep_set_msi(struct pci_epc *epc, u8 fn,
+				    u8 multi_msg_cap)
+{
+	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
+	struct rockchip_pcie *rockchip = &ep->rockchip;
+	u16 flags;
+
+	flags = rockchip_pcie_read(rockchip,
+				   ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
+				   ROCKCHIP_PCIE_EP_MSI_CTRL_REG);
+	flags &= ~ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_MASK;
+	flags |=
+	   ((multi_msg_cap << 1) <<  ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_OFFSET) |
+	   PCI_MSI_FLAGS_64BIT;
+	flags &= ~ROCKCHIP_PCIE_EP_MSI_CTRL_MASK_MSI_CAP;
+	rockchip_pcie_write(rockchip, flags,
+			    ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
+			    ROCKCHIP_PCIE_EP_MSI_CTRL_REG);
+	return 0;
+}
+
+static int rockchip_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
+{
+	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
+	struct rockchip_pcie *rockchip = &ep->rockchip;
+	u16 flags;
+
+	flags = rockchip_pcie_read(rockchip,
+				   ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
+				   ROCKCHIP_PCIE_EP_MSI_CTRL_REG);
+	if (!(flags & ROCKCHIP_PCIE_EP_MSI_CTRL_ME))
+		return -EINVAL;
+
+	return ((flags & ROCKCHIP_PCIE_EP_MSI_CTRL_MME_MASK) >>
+			ROCKCHIP_PCIE_EP_MSI_CTRL_MME_OFFSET);
+}
+
+static void rockchip_pcie_ep_assert_intx(struct rockchip_pcie_ep *ep, u8 fn,
+					 u8 intx, bool is_asserted)
+{
+	struct rockchip_pcie *rockchip = &ep->rockchip;
+	u32 r = ep->max_regions - 1;
+	u32 offset;
+	u16 status;
+	u8 msg_code;
+
+	if (unlikely(ep->irq_pci_addr != ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR ||
+		     ep->irq_pci_fn != fn)) {
+		rockchip_pcie_prog_ep_ob_atu(rockchip, fn, r,
+					     AXI_WRAPPER_NOR_MSG,
+					     ep->irq_phys_addr, 0, 0);
+		ep->irq_pci_addr = ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR;
+		ep->irq_pci_fn = fn;
+	}
+
+	intx &= 3;
+	if (is_asserted) {
+		ep->irq_pending |= BIT(intx);
+		msg_code = ROCKCHIP_PCIE_MSG_CODE_ASSERT_INTA + intx;
+	} else {
+		ep->irq_pending &= ~BIT(intx);
+		msg_code = ROCKCHIP_PCIE_MSG_CODE_DEASSERT_INTA + intx;
+	}
+
+	status = rockchip_pcie_read(rockchip,
+				    ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
+				    ROCKCHIP_PCIE_EP_CMD_STATUS);
+	status &= ROCKCHIP_PCIE_EP_CMD_STATUS_IS;
+
+	if ((status != 0) ^ (ep->irq_pending != 0)) {
+		status ^= ROCKCHIP_PCIE_EP_CMD_STATUS_IS;
+		rockchip_pcie_write(rockchip, status,
+				    ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
+				    ROCKCHIP_PCIE_EP_CMD_STATUS);
+	}
+
+	offset =
+	   ROCKCHIP_PCIE_MSG_ROUTING(ROCKCHIP_PCIE_MSG_ROUTING_LOCAL_INTX) |
+	   ROCKCHIP_PCIE_MSG_CODE(msg_code) | ROCKCHIP_PCIE_MSG_NO_DATA;
+	writel(0, ep->irq_cpu_addr + offset);
+}
+
+static int rockchip_pcie_ep_send_legacy_irq(struct rockchip_pcie_ep *ep, u8 fn,
+					    u8 intx)
+{
+	u16 cmd;
+
+	cmd = rockchip_pcie_read(&ep->rockchip,
+				 ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
+				 ROCKCHIP_PCIE_EP_CMD_STATUS);
+
+	if (cmd & PCI_COMMAND_INTX_DISABLE)
+		return -EINVAL;
+
+	/*
+	 * Should add some delay between toggling INTx per TRM vaguely saying
+	 * it depends on some cycles of the AHB bus clock to function it. So
+	 * add sufficient 1ms here.
+	 */
+	rockchip_pcie_ep_assert_intx(ep, fn, intx, true);
+	mdelay(1);
+	rockchip_pcie_ep_assert_intx(ep, fn, intx, false);
+	return 0;
+}
+
+static int rockchip_pcie_ep_send_msi_irq(struct rockchip_pcie_ep *ep, u8 fn,
+					 u8 interrupt_num)
+{
+	struct rockchip_pcie *rockchip = &ep->rockchip;
+	u16 flags, mme, data, data_mask;
+	u8 msi_count;
+	u64 pci_addr, pci_addr_mask = 0xff;
+
+	/* Check MSI enable bit */
+	flags = rockchip_pcie_read(&ep->rockchip,
+				   ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
+				   ROCKCHIP_PCIE_EP_MSI_CTRL_REG);
+	if (!(flags & ROCKCHIP_PCIE_EP_MSI_CTRL_ME))
+		return -EINVAL;
+
+	/* Get MSI numbers from MME */
+	mme = ((flags & ROCKCHIP_PCIE_EP_MSI_CTRL_MME_MASK) >>
+			ROCKCHIP_PCIE_EP_MSI_CTRL_MME_OFFSET);
+	msi_count = 1 << mme;
+	if (!interrupt_num || interrupt_num > msi_count)
+		return -EINVAL;
+
+	/* Set MSI private data */
+	data_mask = msi_count - 1;
+	data = rockchip_pcie_read(rockchip,
+				  ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
+				  ROCKCHIP_PCIE_EP_MSI_CTRL_REG +
+				  PCI_MSI_DATA_64);
+	data = (data & ~data_mask) | ((interrupt_num - 1) & data_mask);
+
+	/* Get MSI PCI address */
+	pci_addr = rockchip_pcie_read(rockchip,
+				      ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
+				      ROCKCHIP_PCIE_EP_MSI_CTRL_REG +
+				      PCI_MSI_ADDRESS_HI);
+	pci_addr <<= 32;
+	pci_addr |= rockchip_pcie_read(rockchip,
+				       ROCKCHIP_PCIE_EP_FUNC_BASE(fn) +
+				       ROCKCHIP_PCIE_EP_MSI_CTRL_REG +
+				       PCI_MSI_ADDRESS_LO);
+	pci_addr &= GENMASK_ULL(63, 2);
+
+	/* Set the outbound region if needed. */
+	if (unlikely(ep->irq_pci_addr != (pci_addr & ~pci_addr_mask) ||
+		     ep->irq_pci_fn != fn)) {
+		rockchip_pcie_prog_ep_ob_atu(rockchip, fn, ep->max_regions - 1,
+					     AXI_WRAPPER_MEM_WRITE,
+					     ep->irq_phys_addr,
+					     pci_addr & ~pci_addr_mask,
+					     pci_addr_mask + 1);
+		ep->irq_pci_addr = (pci_addr & ~pci_addr_mask);
+		ep->irq_pci_fn = fn;
+	}
+
+	writew(data, ep->irq_cpu_addr + (pci_addr & pci_addr_mask));
+	return 0;
+}
+
+static int rockchip_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
+				      enum pci_epc_irq_type type,
+				      u8 interrupt_num)
+{
+	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
+
+	switch (type) {
+	case PCI_EPC_IRQ_LEGACY:
+		return rockchip_pcie_ep_send_legacy_irq(ep, fn, 0);
+	case PCI_EPC_IRQ_MSI:
+		return rockchip_pcie_ep_send_msi_irq(ep, fn, interrupt_num);
+	default:
+		return -EINVAL;
+	}
+}
+
+static int rockchip_pcie_ep_start(struct pci_epc *epc)
+{
+	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
+	struct rockchip_pcie *rockchip = &ep->rockchip;
+	struct pci_epf *epf;
+	u32 cfg;
+
+	cfg = BIT(0);
+	list_for_each_entry(epf, &epc->pci_epf, list)
+		cfg |= BIT(epf->func_no);
+
+	rockchip_pcie_write(rockchip, cfg, PCIE_CORE_PHY_FUNC_CFG);
+
+	list_for_each_entry(epf, &epc->pci_epf, list)
+		pci_epf_linkup(epf);
+
+	return 0;
+}
+
+static const struct pci_epc_ops rockchip_pcie_epc_ops = {
+	.write_header	= rockchip_pcie_ep_write_header,
+	.set_bar	= rockchip_pcie_ep_set_bar,
+	.clear_bar	= rockchip_pcie_ep_clear_bar,
+	.map_addr	= rockchip_pcie_ep_map_addr,
+	.unmap_addr	= rockchip_pcie_ep_unmap_addr,
+	.set_msi	= rockchip_pcie_ep_set_msi,
+	.get_msi	= rockchip_pcie_ep_get_msi,
+	.raise_irq	= rockchip_pcie_ep_raise_irq,
+	.start		= rockchip_pcie_ep_start,
+};
+
+static int rockchip_pcie_parse_ep_dt(struct rockchip_pcie *rockchip,
+				     struct rockchip_pcie_ep *ep)
+{
+	struct device *dev = rockchip->dev;
+	int err;
+
+	err = rockchip_pcie_parse_dt(rockchip);
+	if (err)
+		return err;
+
+	err = rockchip_pcie_get_phys(rockchip);
+	if (err)
+		return err;
+
+	err = of_property_read_u32(dev->of_node,
+				   "rockchip,max-outbound-regions",
+				   &ep->max_regions);
+	if (err < 0 || ep->max_regions > MAX_REGION_LIMIT)
+		ep->max_regions = MAX_REGION_LIMIT;
+
+	err = of_property_read_u8(dev->of_node, "max-functions",
+				  &ep->epc->max_functions);
+	if (err < 0)
+		ep->epc->max_functions = 1;
+
+	return 0;
+}
+
+static const struct of_device_id rockchip_pcie_ep_of_match[] = {
+	{ .compatible = "rockchip,rk3399-pcie-ep"},
+	{},
+};
+
+static int rockchip_pcie_ep_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct rockchip_pcie_ep *ep;
+	struct rockchip_pcie *rockchip;
+	struct pci_epc *epc;
+	size_t max_regions;
+	int err;
+
+	ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL);
+	if (!ep)
+		return -ENOMEM;
+
+	rockchip = &ep->rockchip;
+	rockchip->is_rc = false;
+	rockchip->dev = dev;
+
+	epc = devm_pci_epc_create(dev, &rockchip_pcie_epc_ops);
+	if (IS_ERR(epc)) {
+		dev_err(dev, "failed to create epc device\n");
+		return PTR_ERR(epc);
+	}
+
+	ep->epc = epc;
+	epc_set_drvdata(epc, ep);
+
+	err = rockchip_pcie_parse_ep_dt(rockchip, ep);
+	if (err)
+		return err;
+
+	err = rockchip_pcie_enable_clocks(rockchip);
+	if (err)
+		return err;
+
+	err = rockchip_pcie_init_port(rockchip);
+	if (err)
+		goto err_disable_clocks;
+
+	/* Establish the link automatically */
+	rockchip_pcie_write(rockchip, PCIE_CLIENT_LINK_TRAIN_ENABLE,
+			    PCIE_CLIENT_CONFIG);
+
+	max_regions = ep->max_regions;
+	ep->ob_addr = devm_kzalloc(dev, max_regions * sizeof(*ep->ob_addr),
+				   GFP_KERNEL);
+
+	if (!ep->ob_addr) {
+		err = -ENOMEM;
+		goto err_uninit_port;
+	}
+
+	/* Only enable function 0 by default */
+	rockchip_pcie_write(rockchip, BIT(0), PCIE_CORE_PHY_FUNC_CFG);
+
+	err = pci_epc_mem_init(epc, rockchip->mem_res->start,
+			       resource_size(rockchip->mem_res));
+	if (err < 0) {
+		dev_err(dev, "failed to initialize the memory space\n");
+		goto err_uninit_port;
+	}
+
+	ep->irq_cpu_addr = pci_epc_mem_alloc_addr(epc, &ep->irq_phys_addr,
+						  SZ_128K);
+	if (!ep->irq_cpu_addr) {
+		dev_err(dev, "failed to reserve memory space for MSI\n");
+		err = -ENOMEM;
+		goto err_epc_mem_exit;
+	}
+
+	ep->irq_pci_addr = ROCKCHIP_PCIE_EP_DUMMY_IRQ_ADDR;
+
+	return 0;
+err_epc_mem_exit:
+	pci_epc_mem_exit(epc);
+err_uninit_port:
+	rockchip_pcie_deinit_phys(rockchip);
+err_disable_clocks:
+	rockchip_pcie_disable_clocks(rockchip);
+	return err;
+}
+
+static struct platform_driver rockchip_pcie_ep_driver = {
+	.driver = {
+		.name = "rockchip-pcie-ep",
+		.of_match_table = rockchip_pcie_ep_of_match,
+	},
+	.probe = rockchip_pcie_ep_probe,
+};
+
+builtin_platform_driver(rockchip_pcie_ep_driver);
diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c
index b27e975..eb3f2c5 100644
--- a/drivers/pci/host/pcie-rockchip.c
+++ b/drivers/pci/host/pcie-rockchip.c
@@ -29,15 +29,22 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
 	struct resource *regs;
 	int err;
 
-	regs = platform_get_resource_byname(pdev,
-					    IORESOURCE_MEM,
-					    "axi-base");
-	rockchip->reg_base = devm_pci_remap_cfg_resource(dev, regs);
-	if (IS_ERR(rockchip->reg_base))
-		return PTR_ERR(rockchip->reg_base);
-
-	regs = platform_get_resource_byname(pdev,
-					    IORESOURCE_MEM,
+	if (rockchip->is_rc) {
+		regs = platform_get_resource_byname(pdev,
+						    IORESOURCE_MEM,
+						    "axi-base");
+		rockchip->reg_base = devm_pci_remap_cfg_resource(dev, regs);
+		if (IS_ERR(rockchip->reg_base))
+			return PTR_ERR(rockchip->reg_base);
+	} else {
+		rockchip->mem_res =
+			platform_get_resource_byname(pdev, IORESOURCE_MEM,
+						     "mem-base");
+		if (!rockchip->mem_res)
+			return -EINVAL;
+	}
+
+	regs = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 					    "apb-base");
 	rockchip->apb_base = devm_ioremap_resource(dev, regs);
 	if (IS_ERR(rockchip->apb_base))
diff --git a/drivers/pci/host/pcie-rockchip.h b/drivers/pci/host/pcie-rockchip.h
index 6f6e7ad..8e87a05 100644
--- a/drivers/pci/host/pcie-rockchip.h
+++ b/drivers/pci/host/pcie-rockchip.h
@@ -23,6 +23,8 @@
 
 #define ENCODE_LANES(x)			((((x) >> 1) & 3) << 4)
 #define MAX_LANE_NUM			4
+#define MAX_REGION_LIMIT		32
+#define MIN_EP_APERTURE			28
 
 #define PCIE_CLIENT_BASE		0x0
 #define PCIE_CLIENT_CONFIG		(PCIE_CLIENT_BASE + 0x00)
@@ -109,7 +111,14 @@
 #define   PCIE_CORE_INT_MMVC			BIT(19)
 #define PCIE_CORE_CONFIG_VENDOR		(PCIE_CORE_CTRL_MGMT_BASE + 0x44)
 #define PCIE_CORE_INT_MASK		(PCIE_CORE_CTRL_MGMT_BASE + 0x210)
+#define PCIE_CORE_PHY_FUNC_CFG		(PCIE_CORE_CTRL_MGMT_BASE + 0x2c0)
 #define PCIE_RC_BAR_CONF		(PCIE_CORE_CTRL_MGMT_BASE + 0x300)
+#define ROCKCHIP_PCIE_CORE_BAR_CFG_CTRL_DISABLED		0x0
+#define ROCKCHIP_PCIE_CORE_BAR_CFG_CTRL_IO_32BITS		0x1
+#define ROCKCHIP_PCIE_CORE_BAR_CFG_CTRL_MEM_32BITS		0x4
+#define ROCKCHIP_PCIE_CORE_BAR_CFG_CTRL_PREFETCH_MEM_32BITS	0x5
+#define ROCKCHIP_PCIE_CORE_BAR_CFG_CTRL_MEM_64BITS		0x6
+#define ROCKCHIP_PCIE_CORE_BAR_CFG_CTRL_PREFETCH_MEM_64BITS	0x7
 
 #define PCIE_CORE_INT \
 		(PCIE_CORE_INT_PRFPE | PCIE_CORE_INT_CRFPE | \
@@ -120,6 +129,7 @@
 		 PCIE_CORE_INT_CT | PCIE_CORE_INT_UTC | \
 		 PCIE_CORE_INT_MMVC)
 
+#define PCIE_RC_RP_ATS_BASE		0x400000
 #define PCIE_RC_CONFIG_NORMAL_BASE	0x800000
 #define PCIE_RC_CONFIG_BASE		0xa00000
 #define PCIE_RC_CONFIG_RID_CCR		(PCIE_RC_CONFIG_BASE + 0x08)
@@ -188,6 +198,83 @@
 #define RC_REGION_0_TYPE_MASK			GENMASK(3, 0)
 #define MAX_AXI_WRAPPER_REGION_NUM		33
 
+#define ROCKCHIP_PCIE_MSG_ROUTING_TO_RC		0x0
+#define ROCKCHIP_PCIE_MSG_ROUTING_VIA_ADDR		0x1
+#define ROCKCHIP_PCIE_MSG_ROUTING_VIA_ID		0x2
+#define ROCKCHIP_PCIE_MSG_ROUTING_BROADCAST		0x3
+#define ROCKCHIP_PCIE_MSG_ROUTING_LOCAL_INTX		0x4
+#define ROCKCHIP_PCIE_MSG_ROUTING_PME_ACK		0x5
+#define ROCKCHIP_PCIE_MSG_CODE_ASSERT_INTA		0x20
+#define ROCKCHIP_PCIE_MSG_CODE_ASSERT_INTB		0x21
+#define ROCKCHIP_PCIE_MSG_CODE_ASSERT_INTC		0x22
+#define ROCKCHIP_PCIE_MSG_CODE_ASSERT_INTD		0x23
+#define ROCKCHIP_PCIE_MSG_CODE_DEASSERT_INTA		0x24
+#define ROCKCHIP_PCIE_MSG_CODE_DEASSERT_INTB		0x25
+#define ROCKCHIP_PCIE_MSG_CODE_DEASSERT_INTC		0x26
+#define ROCKCHIP_PCIE_MSG_CODE_DEASSERT_INTD		0x27
+#define ROCKCHIP_PCIE_MSG_ROUTING_MASK			GENMASK(7, 5)
+#define ROCKCHIP_PCIE_MSG_ROUTING(route) \
+	(((route) << 5) & ROCKCHIP_PCIE_MSG_ROUTING_MASK)
+#define ROCKCHIP_PCIE_MSG_CODE_MASK			GENMASK(15, 8)
+#define ROCKCHIP_PCIE_MSG_CODE(code) \
+	(((code) << 8) & ROCKCHIP_PCIE_MSG_CODE_MASK)
+#define ROCKCHIP_PCIE_MSG_NO_DATA			BIT(16)
+
+#define ROCKCHIP_PCIE_EP_CMD_STATUS			0x4
+#define   ROCKCHIP_PCIE_EP_CMD_STATUS_IS		BIT(19)
+#define ROCKCHIP_PCIE_EP_MSI_CTRL_REG			0x90
+#define   ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_OFFSET		17
+#define   ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_MASK		GENMASK(19, 17)
+#define   ROCKCHIP_PCIE_EP_MSI_CTRL_MME_OFFSET		20
+#define   ROCKCHIP_PCIE_EP_MSI_CTRL_MME_MASK		GENMASK(22, 20)
+#define   ROCKCHIP_PCIE_EP_MSI_CTRL_ME				BIT(16)
+#define   ROCKCHIP_PCIE_EP_MSI_CTRL_MASK_MSI_CAP	BIT(24)
+#define ROCKCHIP_PCIE_EP_DUMMY_IRQ_ADDR				0x1
+#define ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR		0x3
+#define ROCKCHIP_PCIE_EP_FUNC_BASE(fn)	(((fn) << 12) & GENMASK(19, 12))
+#define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar) \
+	(PCIE_RC_RP_ATS_BASE + 0x0840 + (fn) * 0x0040 + (bar) * 0x0008)
+#define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar) \
+	(PCIE_RC_RP_ATS_BASE + 0x0844 + (fn) * 0x0040 + (bar) * 0x0008)
+#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0(r) \
+	(PCIE_RC_RP_ATS_BASE + 0x0000 + ((r) & 0x1f) * 0x0020)
+#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN_MASK	GENMASK(19, 12)
+#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN(devfn) \
+	(((devfn) << 12) & \
+		 ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN_MASK)
+#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_BUS_MASK	GENMASK(27, 20)
+#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_BUS(bus) \
+		(((bus) << 20) & ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR0_BUS_MASK)
+#define ROCKCHIP_PCIE_AT_OB_REGION_PCI_ADDR1(r) \
+		(PCIE_RC_RP_ATS_BASE + 0x0004 + ((r) & 0x1f) * 0x0020)
+#define ROCKCHIP_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID	BIT(23)
+#define ROCKCHIP_PCIE_AT_OB_REGION_DESC0_DEVFN_MASK	GENMASK(31, 24)
+#define ROCKCHIP_PCIE_AT_OB_REGION_DESC0_DEVFN(devfn) \
+		(((devfn) << 24) & ROCKCHIP_PCIE_AT_OB_REGION_DESC0_DEVFN_MASK)
+#define ROCKCHIP_PCIE_AT_OB_REGION_DESC0(r) \
+		(PCIE_RC_RP_ATS_BASE + 0x0008 + ((r) & 0x1f) * 0x0020)
+#define ROCKCHIP_PCIE_AT_OB_REGION_DESC1(r)	\
+		(PCIE_RC_RP_ATS_BASE + 0x000c + ((r) & 0x1f) * 0x0020)
+#define ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR0(r) \
+		(PCIE_RC_RP_ATS_BASE + 0x0018 + ((r) & 0x1f) * 0x0020)
+#define ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR1(r) \
+		(PCIE_RC_RP_ATS_BASE + 0x001c + ((r) & 0x1f) * 0x0020)
+
+#define ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG0(fn) \
+		(PCIE_CORE_CTRL_MGMT_BASE + 0x0240 + (fn) * 0x0008)
+#define ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG1(fn) \
+		(PCIE_CORE_CTRL_MGMT_BASE + 0x0244 + (fn) * 0x0008)
+#define ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) \
+		(GENMASK(4, 0) << ((b) * 8))
+#define ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG_BAR_APERTURE(b, a) \
+		(((a) << ((b) * 8)) & \
+		 ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b))
+#define ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b) \
+		(GENMASK(7, 5) << ((b) * 8))
+#define ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG_BAR_CTRL(b, c) \
+		(((c) << ((b) * 8 + 5)) & \
+		 ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b))
+
 struct rockchip_pcie {
 	void	__iomem *reg_base;		/* DT axi-base */
 	void	__iomem *apb_base;		/* DT apb-base */
@@ -225,6 +312,7 @@ struct rockchip_pcie {
 	phys_addr_t msg_bus_addr;
 	phys_addr_t mem_bus_addr;
 	bool is_rc;
+	struct resource *mem_res;
 };
 
 static u32 rockchip_pcie_read(struct rockchip_pcie *rockchip, u32 reg)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v6 6/7] dt-bindings: PCI: rockchip: Add DT bindings for Rockchip PCIe endpoint controller
  2018-04-27  2:38 [PATCH v6 0/7] Add endpoint driver for Rockchip PCIe controller Shawn Lin
                   ` (3 preceding siblings ...)
  2018-04-27  2:39 ` [PATCH v6 5/7] PCI: rockchip: Add Endpoint controller driver for Rockchip PCIe controller Shawn Lin
@ 2018-04-27  2:39 ` Shawn Lin
  2018-04-27  2:40 ` [PATCH v6 7/7] arm64: defconfig: update config for Rockchip PCIe Shawn Lin
  2018-05-08 11:52 ` [PATCH v6 0/7] Add endpoint driver for Rockchip PCIe controller Lorenzo Pieralisi
  6 siblings, 0 replies; 12+ messages in thread
From: Shawn Lin @ 2018-04-27  2:39 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Bjorn Helgaas
  Cc: Heiko Stuebner, Rob Herring, devicetree, linux-rockchip,
	linux-pci, Shawn Lin

This patch documents the DT bindings for the Rockchip PCIe controller
when configured in endpoint mode.

Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---

Changes in v6: None
Changes in v5: None
Changes in v4: None

 .../devicetree/bindings/pci/rockchip-pcie-ep.txt   | 62 ++++++++++++++++++++++
 1 file changed, 62 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/rockchip-pcie-ep.txt

diff --git a/Documentation/devicetree/bindings/pci/rockchip-pcie-ep.txt b/Documentation/devicetree/bindings/pci/rockchip-pcie-ep.txt
new file mode 100644
index 0000000..77846730
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/rockchip-pcie-ep.txt
@@ -0,0 +1,62 @@
+* Rockchip AXI PCIe Endpoint Controller DT description
+
+Required properties:
+- compatible: Should contain "rockchip,rk3399-pcie-ep"
+- reg: Two register ranges as listed in the reg-names property
+- reg-names: Must include the following names
+	- "apb-base"
+	- "mem-base"
+- clocks: Must contain an entry for each entry in clock-names.
+		See ../clocks/clock-bindings.txt for details.
+- clock-names: Must include the following entries:
+	- "aclk"
+	- "aclk-perf"
+	- "hclk"
+	- "pm"
+- resets: Must contain seven entries for each entry in reset-names.
+	   See ../reset/reset.txt for details.
+- reset-names: Must include the following names
+	- "core"
+	- "mgmt"
+	- "mgmt-sticky"
+	- "pipe"
+	- "pm"
+	- "aclk"
+	- "pclk"
+- pinctrl-names : The pin control state names
+- pinctrl-0: The "default" pinctrl state
+- phys: Must contain an phandle to a PHY for each entry in phy-names.
+- phy-names: Must include 4 entries for all 4 lanes even if some of
+  them won't be used for your cases. Entries are of the form "pcie-phy-N":
+  where N ranges from 0 to 3.
+  (see example below and you MUST also refer to ../phy/rockchip-pcie-phy.txt
+  for changing the #phy-cells of phy node to support it)
+- rockchip,max-outbound-regions: Maximum number of outbound regions
+
+Optional Property:
+- num-lanes: number of lanes to use
+- max-functions: Maximum number of functions that can be configured (default 1).
+
+pcie0-ep: pcie@f8000000 {
+	compatible = "rockchip,rk3399-pcie-ep";
+	#address-cells = <3>;
+	#size-cells = <2>;
+	rockchip,max-outbound-regions = <16>;
+	clocks = <&cru ACLK_PCIE>, <&cru ACLK_PERF_PCIE>,
+		 <&cru PCLK_PCIE>, <&cru SCLK_PCIE_PM>;
+	clock-names = "aclk", "aclk-perf",
+		      "hclk", "pm";
+	max-functions = /bits/ 8 <8>;
+	num-lanes = <4>;
+	reg = <0x0 0xfd000000 0x0 0x1000000>, <0x0 0x80000000 0x0 0x20000>;
+	reg-names = "apb-base", "mem-base";
+	resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>,
+		 <&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE> ,
+		 <&cru SRST_PCIE_PM>, <&cru SRST_P_PCIE>, <&cru SRST_A_PCIE>;
+	reset-names = "core", "mgmt", "mgmt-sticky", "pipe",
+		      "pm", "pclk", "aclk";
+	phys = <&pcie_phy 0>, <&pcie_phy 1>, <&pcie_phy 2>, <&pcie_phy 3>;
+	phy-names = "pcie-phy-0", "pcie-phy-1", "pcie-phy-2", "pcie-phy-3";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie_clkreq>;
+};
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v6 7/7] arm64: defconfig: update config for Rockchip PCIe
  2018-04-27  2:38 [PATCH v6 0/7] Add endpoint driver for Rockchip PCIe controller Shawn Lin
                   ` (4 preceding siblings ...)
  2018-04-27  2:39 ` [PATCH v6 6/7] dt-bindings: PCI: rockchip: Add DT bindings for Rockchip PCIe endpoint controller Shawn Lin
@ 2018-04-27  2:40 ` Shawn Lin
  2018-05-08 11:52 ` [PATCH v6 0/7] Add endpoint driver for Rockchip PCIe controller Lorenzo Pieralisi
  6 siblings, 0 replies; 12+ messages in thread
From: Shawn Lin @ 2018-04-27  2:40 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Bjorn Helgaas
  Cc: devicetree, Heiko Stuebner, linux-pci, Shawn Lin, linux-rockchip,
	Rob Herring, linux-arm-kernel

Now Rockchip PCIe drivers could support both of host mode
and endponint mode, so we rename the config name. This patch
updates defconfig to refect the fact that we want to build
Rockchip PCIe controller driver into a module as before.

Cc: linux-arm-kernel@lists.infradead.org
Cc: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>

---

Changes in v6: None
Changes in v5: None
Changes in v4: None

 arch/arm64/configs/defconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 0d8ae1d..5cf70af 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -79,7 +79,8 @@ CONFIG_PCIE_ARMADA_8K=y
 CONFIG_PCI_AARDVARK=y
 CONFIG_PCI_TEGRA=y
 CONFIG_PCIE_RCAR=y
-CONFIG_PCIE_ROCKCHIP=m
+CONFIG_PCIE_ROCKCHIP=y
+CONFIG_PCIE_ROCKCHIP_HOST=m
 CONFIG_PCI_HOST_GENERIC=y
 CONFIG_PCI_XGENE=y
 CONFIG_PCI_HOST_THUNDER_PEM=y
-- 
1.9.1



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v6 2/7] PCI: rockchip: Split out common function to parse DT
  2018-04-27  2:39 ` [PATCH v6 2/7] PCI: rockchip: Split out common function to parse DT Shawn Lin
@ 2018-04-30 14:51   ` Lorenzo Pieralisi
  2018-05-02  0:57     ` Shawn Lin
  0 siblings, 1 reply; 12+ messages in thread
From: Lorenzo Pieralisi @ 2018-04-30 14:51 UTC (permalink / raw)
  To: Shawn Lin
  Cc: Bjorn Helgaas, Heiko Stuebner, Rob Herring, devicetree,
	linux-rockchip, linux-pci

On Fri, Apr 27, 2018 at 10:39:11AM +0800, Shawn Lin wrote:
> Most of the DT properties are used for both of host and
> EP drivrs, so this patch spilt them out to new function,
> rockchip_pcie_parse_dt in pcie-rockchip.c and rename the
> original function to rockchip_pcie_parse_host_dt to avoid
> confusion. No functional changed intended.

If you read this commit log again you would notice that there
are typos and the formatting is non-compliant with:

https://marc.info/?l=linux-pci&m=150905742808166&w=2

I am fine with updating commit logs myself, that's not a problem, but I
wanted to make clear that you can easily spot these issues for future
postings too ;-)

Lorenzo

> Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
> Tested-by: Jeffy Chen <jeffy.chen@rock-chips.com>
> ---
> 
> Changes in v6: None
> Changes in v5: None
> Changes in v4: None
> 
>  drivers/pci/host/pcie-rockchip-host.c | 119 ++-----------------------------
>  drivers/pci/host/pcie-rockchip.c      | 129 ++++++++++++++++++++++++++++++++++
>  drivers/pci/host/pcie-rockchip.h      |   2 +
>  3 files changed, 136 insertions(+), 114 deletions(-)
> 
> diff --git a/drivers/pci/host/pcie-rockchip-host.c b/drivers/pci/host/pcie-rockchip-host.c
> index fae9ecc..cf97130 100644
> --- a/drivers/pci/host/pcie-rockchip-host.c
> +++ b/drivers/pci/host/pcie-rockchip-host.c
> @@ -705,130 +705,20 @@ static int rockchip_pcie_setup_irq(struct rockchip_pcie *rockchip)
>  }
>  
>  /**
> - * rockchip_pcie_parse_dt - Parse Device Tree
> + * rockchip_pcie_parse_host_dt - Parse Device Tree
>   * @rockchip: PCIe port information
>   *
>   * Return: '0' on success and error value on failure
>   */
> -static int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
> +static int rockchip_pcie_parse_host_dt(struct rockchip_pcie *rockchip)
>  {
>  	struct device *dev = rockchip->dev;
> -	struct platform_device *pdev = to_platform_device(dev);
> -	struct device_node *node = dev->of_node;
> -	struct resource *regs;
>  	int err;
>  
> -	regs = platform_get_resource_byname(pdev,
> -					    IORESOURCE_MEM,
> -					    "axi-base");
> -	rockchip->reg_base = devm_pci_remap_cfg_resource(dev, regs);
> -	if (IS_ERR(rockchip->reg_base))
> -		return PTR_ERR(rockchip->reg_base);
> -
> -	regs = platform_get_resource_byname(pdev,
> -					    IORESOURCE_MEM,
> -					    "apb-base");
> -	rockchip->apb_base = devm_ioremap_resource(dev, regs);
> -	if (IS_ERR(rockchip->apb_base))
> -		return PTR_ERR(rockchip->apb_base);
> -
> -	err = rockchip_pcie_get_phys(rockchip);
> +	err = rockchip_pcie_parse_dt(rockchip);
>  	if (err)
>  		return err;
>  
> -	rockchip->lanes = 1;
> -	err = of_property_read_u32(node, "num-lanes", &rockchip->lanes);
> -	if (!err && (rockchip->lanes == 0 ||
> -		     rockchip->lanes == 3 ||
> -		     rockchip->lanes > 4)) {
> -		dev_warn(dev, "invalid num-lanes, default to use one lane\n");
> -		rockchip->lanes = 1;
> -	}
> -
> -	rockchip->link_gen = of_pci_get_max_link_speed(node);
> -	if (rockchip->link_gen < 0 || rockchip->link_gen > 2)
> -		rockchip->link_gen = 2;
> -
> -	rockchip->core_rst = devm_reset_control_get_exclusive(dev, "core");
> -	if (IS_ERR(rockchip->core_rst)) {
> -		if (PTR_ERR(rockchip->core_rst) != -EPROBE_DEFER)
> -			dev_err(dev, "missing core reset property in node\n");
> -		return PTR_ERR(rockchip->core_rst);
> -	}
> -
> -	rockchip->mgmt_rst = devm_reset_control_get_exclusive(dev, "mgmt");
> -	if (IS_ERR(rockchip->mgmt_rst)) {
> -		if (PTR_ERR(rockchip->mgmt_rst) != -EPROBE_DEFER)
> -			dev_err(dev, "missing mgmt reset property in node\n");
> -		return PTR_ERR(rockchip->mgmt_rst);
> -	}
> -
> -	rockchip->mgmt_sticky_rst = devm_reset_control_get_exclusive(dev,
> -								     "mgmt-sticky");
> -	if (IS_ERR(rockchip->mgmt_sticky_rst)) {
> -		if (PTR_ERR(rockchip->mgmt_sticky_rst) != -EPROBE_DEFER)
> -			dev_err(dev, "missing mgmt-sticky reset property in node\n");
> -		return PTR_ERR(rockchip->mgmt_sticky_rst);
> -	}
> -
> -	rockchip->pipe_rst = devm_reset_control_get_exclusive(dev, "pipe");
> -	if (IS_ERR(rockchip->pipe_rst)) {
> -		if (PTR_ERR(rockchip->pipe_rst) != -EPROBE_DEFER)
> -			dev_err(dev, "missing pipe reset property in node\n");
> -		return PTR_ERR(rockchip->pipe_rst);
> -	}
> -
> -	rockchip->pm_rst = devm_reset_control_get_exclusive(dev, "pm");
> -	if (IS_ERR(rockchip->pm_rst)) {
> -		if (PTR_ERR(rockchip->pm_rst) != -EPROBE_DEFER)
> -			dev_err(dev, "missing pm reset property in node\n");
> -		return PTR_ERR(rockchip->pm_rst);
> -	}
> -
> -	rockchip->pclk_rst = devm_reset_control_get_exclusive(dev, "pclk");
> -	if (IS_ERR(rockchip->pclk_rst)) {
> -		if (PTR_ERR(rockchip->pclk_rst) != -EPROBE_DEFER)
> -			dev_err(dev, "missing pclk reset property in node\n");
> -		return PTR_ERR(rockchip->pclk_rst);
> -	}
> -
> -	rockchip->aclk_rst = devm_reset_control_get_exclusive(dev, "aclk");
> -	if (IS_ERR(rockchip->aclk_rst)) {
> -		if (PTR_ERR(rockchip->aclk_rst) != -EPROBE_DEFER)
> -			dev_err(dev, "missing aclk reset property in node\n");
> -		return PTR_ERR(rockchip->aclk_rst);
> -	}
> -
> -	rockchip->ep_gpio = devm_gpiod_get(dev, "ep", GPIOD_OUT_HIGH);
> -	if (IS_ERR(rockchip->ep_gpio)) {
> -		dev_err(dev, "missing ep-gpios property in node\n");
> -		return PTR_ERR(rockchip->ep_gpio);
> -	}
> -
> -	rockchip->aclk_pcie = devm_clk_get(dev, "aclk");
> -	if (IS_ERR(rockchip->aclk_pcie)) {
> -		dev_err(dev, "aclk clock not found\n");
> -		return PTR_ERR(rockchip->aclk_pcie);
> -	}
> -
> -	rockchip->aclk_perf_pcie = devm_clk_get(dev, "aclk-perf");
> -	if (IS_ERR(rockchip->aclk_perf_pcie)) {
> -		dev_err(dev, "aclk_perf clock not found\n");
> -		return PTR_ERR(rockchip->aclk_perf_pcie);
> -	}
> -
> -	rockchip->hclk_pcie = devm_clk_get(dev, "hclk");
> -	if (IS_ERR(rockchip->hclk_pcie)) {
> -		dev_err(dev, "hclk clock not found\n");
> -		return PTR_ERR(rockchip->hclk_pcie);
> -	}
> -
> -	rockchip->clk_pcie_pm = devm_clk_get(dev, "pm");
> -	if (IS_ERR(rockchip->clk_pcie_pm)) {
> -		dev_err(dev, "pm clock not found\n");
> -		return PTR_ERR(rockchip->clk_pcie_pm);
> -	}
> -
>  	err = rockchip_pcie_setup_irq(rockchip);
>  	if (err)
>  		return err;
> @@ -1195,8 +1085,9 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
>  
>  	platform_set_drvdata(pdev, rockchip);
>  	rockchip->dev = dev;
> +	rockchip->is_rc = true;
>  
> -	err = rockchip_pcie_parse_dt(rockchip);
> +	err = rockchip_pcie_parse_host_dt(rockchip);
>  	if (err)
>  		return err;
>  
> diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c
> index 3d46da9..bcc222b 100644
> --- a/drivers/pci/host/pcie-rockchip.c
> +++ b/drivers/pci/host/pcie-rockchip.c
> @@ -12,10 +12,139 @@
>   */
>  
>  #include <linux/clk.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/of_pci.h>
>  #include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/reset.h>
>  
>  #include "pcie-rockchip.h"
>  
> +int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
> +{
> +	struct device *dev = rockchip->dev;
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct device_node *node = dev->of_node;
> +	struct resource *regs;
> +	int err;
> +
> +	regs = platform_get_resource_byname(pdev,
> +					    IORESOURCE_MEM,
> +					    "axi-base");
> +	rockchip->reg_base = devm_pci_remap_cfg_resource(dev, regs);
> +	if (IS_ERR(rockchip->reg_base))
> +		return PTR_ERR(rockchip->reg_base);
> +
> +	regs = platform_get_resource_byname(pdev,
> +					    IORESOURCE_MEM,
> +					    "apb-base");
> +	rockchip->apb_base = devm_ioremap_resource(dev, regs);
> +	if (IS_ERR(rockchip->apb_base))
> +		return PTR_ERR(rockchip->apb_base);
> +
> +	err = rockchip_pcie_get_phys(rockchip);
> +	if (err)
> +		return err;
> +
> +	rockchip->lanes = 1;
> +	err = of_property_read_u32(node, "num-lanes", &rockchip->lanes);
> +	if (!err && (rockchip->lanes == 0 ||
> +		     rockchip->lanes == 3 ||
> +		     rockchip->lanes > 4)) {
> +		dev_warn(dev, "invalid num-lanes, default to use one lane\n");
> +		rockchip->lanes = 1;
> +	}
> +
> +	rockchip->link_gen = of_pci_get_max_link_speed(node);
> +	if (rockchip->link_gen < 0 || rockchip->link_gen > 2)
> +		rockchip->link_gen = 2;
> +
> +	rockchip->core_rst = devm_reset_control_get_exclusive(dev, "core");
> +	if (IS_ERR(rockchip->core_rst)) {
> +		if (PTR_ERR(rockchip->core_rst) != -EPROBE_DEFER)
> +			dev_err(dev, "missing core reset property in node\n");
> +		return PTR_ERR(rockchip->core_rst);
> +	}
> +
> +	rockchip->mgmt_rst = devm_reset_control_get_exclusive(dev, "mgmt");
> +	if (IS_ERR(rockchip->mgmt_rst)) {
> +		if (PTR_ERR(rockchip->mgmt_rst) != -EPROBE_DEFER)
> +			dev_err(dev, "missing mgmt reset property in node\n");
> +		return PTR_ERR(rockchip->mgmt_rst);
> +	}
> +
> +	rockchip->mgmt_sticky_rst = devm_reset_control_get_exclusive(dev,
> +								     "mgmt-sticky");
> +	if (IS_ERR(rockchip->mgmt_sticky_rst)) {
> +		if (PTR_ERR(rockchip->mgmt_sticky_rst) != -EPROBE_DEFER)
> +			dev_err(dev, "missing mgmt-sticky reset property in node\n");
> +		return PTR_ERR(rockchip->mgmt_sticky_rst);
> +	}
> +
> +	rockchip->pipe_rst = devm_reset_control_get_exclusive(dev, "pipe");
> +	if (IS_ERR(rockchip->pipe_rst)) {
> +		if (PTR_ERR(rockchip->pipe_rst) != -EPROBE_DEFER)
> +			dev_err(dev, "missing pipe reset property in node\n");
> +		return PTR_ERR(rockchip->pipe_rst);
> +	}
> +
> +	rockchip->pm_rst = devm_reset_control_get_exclusive(dev, "pm");
> +	if (IS_ERR(rockchip->pm_rst)) {
> +		if (PTR_ERR(rockchip->pm_rst) != -EPROBE_DEFER)
> +			dev_err(dev, "missing pm reset property in node\n");
> +		return PTR_ERR(rockchip->pm_rst);
> +	}
> +
> +	rockchip->pclk_rst = devm_reset_control_get_exclusive(dev, "pclk");
> +	if (IS_ERR(rockchip->pclk_rst)) {
> +		if (PTR_ERR(rockchip->pclk_rst) != -EPROBE_DEFER)
> +			dev_err(dev, "missing pclk reset property in node\n");
> +		return PTR_ERR(rockchip->pclk_rst);
> +	}
> +
> +	rockchip->aclk_rst = devm_reset_control_get_exclusive(dev, "aclk");
> +	if (IS_ERR(rockchip->aclk_rst)) {
> +		if (PTR_ERR(rockchip->aclk_rst) != -EPROBE_DEFER)
> +			dev_err(dev, "missing aclk reset property in node\n");
> +		return PTR_ERR(rockchip->aclk_rst);
> +	}
> +
> +	if (rockchip->is_rc) {
> +		rockchip->ep_gpio = devm_gpiod_get(dev, "ep", GPIOD_OUT_HIGH);
> +		if (IS_ERR(rockchip->ep_gpio)) {
> +			dev_err(dev, "missing ep-gpios property in node\n");
> +			return PTR_ERR(rockchip->ep_gpio);
> +		}
> +	}
> +
> +	rockchip->aclk_pcie = devm_clk_get(dev, "aclk");
> +	if (IS_ERR(rockchip->aclk_pcie)) {
> +		dev_err(dev, "aclk clock not found\n");
> +		return PTR_ERR(rockchip->aclk_pcie);
> +	}
> +
> +	rockchip->aclk_perf_pcie = devm_clk_get(dev, "aclk-perf");
> +	if (IS_ERR(rockchip->aclk_perf_pcie)) {
> +		dev_err(dev, "aclk_perf clock not found\n");
> +		return PTR_ERR(rockchip->aclk_perf_pcie);
> +	}
> +
> +	rockchip->hclk_pcie = devm_clk_get(dev, "hclk");
> +	if (IS_ERR(rockchip->hclk_pcie)) {
> +		dev_err(dev, "hclk clock not found\n");
> +		return PTR_ERR(rockchip->hclk_pcie);
> +	}
> +
> +	rockchip->clk_pcie_pm = devm_clk_get(dev, "pm");
> +	if (IS_ERR(rockchip->clk_pcie_pm)) {
> +		dev_err(dev, "pm clock not found\n");
> +		return PTR_ERR(rockchip->clk_pcie_pm);
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(rockchip_pcie_parse_dt);
> +
>  int rockchip_pcie_get_phys(struct rockchip_pcie *rockchip)
>  {
>  	struct device *dev = rockchip->dev;
> diff --git a/drivers/pci/host/pcie-rockchip.h b/drivers/pci/host/pcie-rockchip.h
> index d27941e..473e74f 100644
> --- a/drivers/pci/host/pcie-rockchip.h
> +++ b/drivers/pci/host/pcie-rockchip.h
> @@ -222,6 +222,7 @@ struct rockchip_pcie {
>  	u32     mem_size;
>  	phys_addr_t msg_bus_addr;
>  	phys_addr_t mem_bus_addr;
> +	bool is_rc;
>  };
>  
>  static u32 rockchip_pcie_read(struct rockchip_pcie *rockchip, u32 reg)
> @@ -235,6 +236,7 @@ static void rockchip_pcie_write(struct rockchip_pcie *rockchip, u32 val,
>  	writel(val, rockchip->apb_base + reg);
>  }
>  
> +int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip);
>  int rockchip_pcie_get_phys(struct rockchip_pcie *rockchip);
>  void rockchip_pcie_deinit_phys(struct rockchip_pcie *rockchip);
>  int rockchip_pcie_enable_clocks(struct rockchip_pcie *rockchip);
> -- 
> 1.9.1
> 
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v6 2/7] PCI: rockchip: Split out common function to parse DT
  2018-04-30 14:51   ` Lorenzo Pieralisi
@ 2018-05-02  0:57     ` Shawn Lin
  0 siblings, 0 replies; 12+ messages in thread
From: Shawn Lin @ 2018-05-02  0:57 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: shawn.lin, Bjorn Helgaas, Heiko Stuebner, Rob Herring,
	devicetree, linux-rockchip, linux-pci

Hi Lorenzo,

On 2018/4/30 22:51, Lorenzo Pieralisi wrote:
> On Fri, Apr 27, 2018 at 10:39:11AM +0800, Shawn Lin wrote:
>> Most of the DT properties are used for both of host and
>> EP drivrs, so this patch spilt them out to new function,
>> rockchip_pcie_parse_dt in pcie-rockchip.c and rename the
>> original function to rockchip_pcie_parse_host_dt to avoid
>> confusion. No functional changed intended.
> 
> If you read this commit log again you would notice that there
> are typos and the formatting is non-compliant with:
> 
> https://marc.info/?l=linux-pci&m=150905742808166&w=2
> 
> I am fine with updating commit logs myself, that's not a problem, but I
> wanted to make clear that you can easily spot these issues for future
> postings too ;-)
> 

My bad. Will be more careful for future postings. :)

> Lorenzo
> 
>> Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
>> Tested-by: Jeffy Chen <jeffy.chen@rock-chips.com>
>> ---
>>
>> Changes in v6: None
>> Changes in v5: None
>> Changes in v4: None
>>
>>   drivers/pci/host/pcie-rockchip-host.c | 119 ++-----------------------------
>>   drivers/pci/host/pcie-rockchip.c      | 129 ++++++++++++++++++++++++++++++++++
>>   drivers/pci/host/pcie-rockchip.h      |   2 +
>>   3 files changed, 136 insertions(+), 114 deletions(-)
>>
>> diff --git a/drivers/pci/host/pcie-rockchip-host.c b/drivers/pci/host/pcie-rockchip-host.c
>> index fae9ecc..cf97130 100644
>> --- a/drivers/pci/host/pcie-rockchip-host.c
>> +++ b/drivers/pci/host/pcie-rockchip-host.c
>> @@ -705,130 +705,20 @@ static int rockchip_pcie_setup_irq(struct rockchip_pcie *rockchip)
>>   }
>>   
>>   /**
>> - * rockchip_pcie_parse_dt - Parse Device Tree
>> + * rockchip_pcie_parse_host_dt - Parse Device Tree
>>    * @rockchip: PCIe port information
>>    *
>>    * Return: '0' on success and error value on failure
>>    */
>> -static int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
>> +static int rockchip_pcie_parse_host_dt(struct rockchip_pcie *rockchip)
>>   {
>>   	struct device *dev = rockchip->dev;
>> -	struct platform_device *pdev = to_platform_device(dev);
>> -	struct device_node *node = dev->of_node;
>> -	struct resource *regs;
>>   	int err;
>>   
>> -	regs = platform_get_resource_byname(pdev,
>> -					    IORESOURCE_MEM,
>> -					    "axi-base");
>> -	rockchip->reg_base = devm_pci_remap_cfg_resource(dev, regs);
>> -	if (IS_ERR(rockchip->reg_base))
>> -		return PTR_ERR(rockchip->reg_base);
>> -
>> -	regs = platform_get_resource_byname(pdev,
>> -					    IORESOURCE_MEM,
>> -					    "apb-base");
>> -	rockchip->apb_base = devm_ioremap_resource(dev, regs);
>> -	if (IS_ERR(rockchip->apb_base))
>> -		return PTR_ERR(rockchip->apb_base);
>> -
>> -	err = rockchip_pcie_get_phys(rockchip);
>> +	err = rockchip_pcie_parse_dt(rockchip);
>>   	if (err)
>>   		return err;
>>   
>> -	rockchip->lanes = 1;
>> -	err = of_property_read_u32(node, "num-lanes", &rockchip->lanes);
>> -	if (!err && (rockchip->lanes == 0 ||
>> -		     rockchip->lanes == 3 ||
>> -		     rockchip->lanes > 4)) {
>> -		dev_warn(dev, "invalid num-lanes, default to use one lane\n");
>> -		rockchip->lanes = 1;
>> -	}
>> -
>> -	rockchip->link_gen = of_pci_get_max_link_speed(node);
>> -	if (rockchip->link_gen < 0 || rockchip->link_gen > 2)
>> -		rockchip->link_gen = 2;
>> -
>> -	rockchip->core_rst = devm_reset_control_get_exclusive(dev, "core");
>> -	if (IS_ERR(rockchip->core_rst)) {
>> -		if (PTR_ERR(rockchip->core_rst) != -EPROBE_DEFER)
>> -			dev_err(dev, "missing core reset property in node\n");
>> -		return PTR_ERR(rockchip->core_rst);
>> -	}
>> -
>> -	rockchip->mgmt_rst = devm_reset_control_get_exclusive(dev, "mgmt");
>> -	if (IS_ERR(rockchip->mgmt_rst)) {
>> -		if (PTR_ERR(rockchip->mgmt_rst) != -EPROBE_DEFER)
>> -			dev_err(dev, "missing mgmt reset property in node\n");
>> -		return PTR_ERR(rockchip->mgmt_rst);
>> -	}
>> -
>> -	rockchip->mgmt_sticky_rst = devm_reset_control_get_exclusive(dev,
>> -								     "mgmt-sticky");
>> -	if (IS_ERR(rockchip->mgmt_sticky_rst)) {
>> -		if (PTR_ERR(rockchip->mgmt_sticky_rst) != -EPROBE_DEFER)
>> -			dev_err(dev, "missing mgmt-sticky reset property in node\n");
>> -		return PTR_ERR(rockchip->mgmt_sticky_rst);
>> -	}
>> -
>> -	rockchip->pipe_rst = devm_reset_control_get_exclusive(dev, "pipe");
>> -	if (IS_ERR(rockchip->pipe_rst)) {
>> -		if (PTR_ERR(rockchip->pipe_rst) != -EPROBE_DEFER)
>> -			dev_err(dev, "missing pipe reset property in node\n");
>> -		return PTR_ERR(rockchip->pipe_rst);
>> -	}
>> -
>> -	rockchip->pm_rst = devm_reset_control_get_exclusive(dev, "pm");
>> -	if (IS_ERR(rockchip->pm_rst)) {
>> -		if (PTR_ERR(rockchip->pm_rst) != -EPROBE_DEFER)
>> -			dev_err(dev, "missing pm reset property in node\n");
>> -		return PTR_ERR(rockchip->pm_rst);
>> -	}
>> -
>> -	rockchip->pclk_rst = devm_reset_control_get_exclusive(dev, "pclk");
>> -	if (IS_ERR(rockchip->pclk_rst)) {
>> -		if (PTR_ERR(rockchip->pclk_rst) != -EPROBE_DEFER)
>> -			dev_err(dev, "missing pclk reset property in node\n");
>> -		return PTR_ERR(rockchip->pclk_rst);
>> -	}
>> -
>> -	rockchip->aclk_rst = devm_reset_control_get_exclusive(dev, "aclk");
>> -	if (IS_ERR(rockchip->aclk_rst)) {
>> -		if (PTR_ERR(rockchip->aclk_rst) != -EPROBE_DEFER)
>> -			dev_err(dev, "missing aclk reset property in node\n");
>> -		return PTR_ERR(rockchip->aclk_rst);
>> -	}
>> -
>> -	rockchip->ep_gpio = devm_gpiod_get(dev, "ep", GPIOD_OUT_HIGH);
>> -	if (IS_ERR(rockchip->ep_gpio)) {
>> -		dev_err(dev, "missing ep-gpios property in node\n");
>> -		return PTR_ERR(rockchip->ep_gpio);
>> -	}
>> -
>> -	rockchip->aclk_pcie = devm_clk_get(dev, "aclk");
>> -	if (IS_ERR(rockchip->aclk_pcie)) {
>> -		dev_err(dev, "aclk clock not found\n");
>> -		return PTR_ERR(rockchip->aclk_pcie);
>> -	}
>> -
>> -	rockchip->aclk_perf_pcie = devm_clk_get(dev, "aclk-perf");
>> -	if (IS_ERR(rockchip->aclk_perf_pcie)) {
>> -		dev_err(dev, "aclk_perf clock not found\n");
>> -		return PTR_ERR(rockchip->aclk_perf_pcie);
>> -	}
>> -
>> -	rockchip->hclk_pcie = devm_clk_get(dev, "hclk");
>> -	if (IS_ERR(rockchip->hclk_pcie)) {
>> -		dev_err(dev, "hclk clock not found\n");
>> -		return PTR_ERR(rockchip->hclk_pcie);
>> -	}
>> -
>> -	rockchip->clk_pcie_pm = devm_clk_get(dev, "pm");
>> -	if (IS_ERR(rockchip->clk_pcie_pm)) {
>> -		dev_err(dev, "pm clock not found\n");
>> -		return PTR_ERR(rockchip->clk_pcie_pm);
>> -	}
>> -
>>   	err = rockchip_pcie_setup_irq(rockchip);
>>   	if (err)
>>   		return err;
>> @@ -1195,8 +1085,9 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
>>   
>>   	platform_set_drvdata(pdev, rockchip);
>>   	rockchip->dev = dev;
>> +	rockchip->is_rc = true;
>>   
>> -	err = rockchip_pcie_parse_dt(rockchip);
>> +	err = rockchip_pcie_parse_host_dt(rockchip);
>>   	if (err)
>>   		return err;
>>   
>> diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c
>> index 3d46da9..bcc222b 100644
>> --- a/drivers/pci/host/pcie-rockchip.c
>> +++ b/drivers/pci/host/pcie-rockchip.c
>> @@ -12,10 +12,139 @@
>>    */
>>   
>>   #include <linux/clk.h>
>> +#include <linux/gpio/consumer.h>
>> +#include <linux/of_pci.h>
>>   #include <linux/phy/phy.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/reset.h>
>>   
>>   #include "pcie-rockchip.h"
>>   
>> +int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
>> +{
>> +	struct device *dev = rockchip->dev;
>> +	struct platform_device *pdev = to_platform_device(dev);
>> +	struct device_node *node = dev->of_node;
>> +	struct resource *regs;
>> +	int err;
>> +
>> +	regs = platform_get_resource_byname(pdev,
>> +					    IORESOURCE_MEM,
>> +					    "axi-base");
>> +	rockchip->reg_base = devm_pci_remap_cfg_resource(dev, regs);
>> +	if (IS_ERR(rockchip->reg_base))
>> +		return PTR_ERR(rockchip->reg_base);
>> +
>> +	regs = platform_get_resource_byname(pdev,
>> +					    IORESOURCE_MEM,
>> +					    "apb-base");
>> +	rockchip->apb_base = devm_ioremap_resource(dev, regs);
>> +	if (IS_ERR(rockchip->apb_base))
>> +		return PTR_ERR(rockchip->apb_base);
>> +
>> +	err = rockchip_pcie_get_phys(rockchip);
>> +	if (err)
>> +		return err;
>> +
>> +	rockchip->lanes = 1;
>> +	err = of_property_read_u32(node, "num-lanes", &rockchip->lanes);
>> +	if (!err && (rockchip->lanes == 0 ||
>> +		     rockchip->lanes == 3 ||
>> +		     rockchip->lanes > 4)) {
>> +		dev_warn(dev, "invalid num-lanes, default to use one lane\n");
>> +		rockchip->lanes = 1;
>> +	}
>> +
>> +	rockchip->link_gen = of_pci_get_max_link_speed(node);
>> +	if (rockchip->link_gen < 0 || rockchip->link_gen > 2)
>> +		rockchip->link_gen = 2;
>> +
>> +	rockchip->core_rst = devm_reset_control_get_exclusive(dev, "core");
>> +	if (IS_ERR(rockchip->core_rst)) {
>> +		if (PTR_ERR(rockchip->core_rst) != -EPROBE_DEFER)
>> +			dev_err(dev, "missing core reset property in node\n");
>> +		return PTR_ERR(rockchip->core_rst);
>> +	}
>> +
>> +	rockchip->mgmt_rst = devm_reset_control_get_exclusive(dev, "mgmt");
>> +	if (IS_ERR(rockchip->mgmt_rst)) {
>> +		if (PTR_ERR(rockchip->mgmt_rst) != -EPROBE_DEFER)
>> +			dev_err(dev, "missing mgmt reset property in node\n");
>> +		return PTR_ERR(rockchip->mgmt_rst);
>> +	}
>> +
>> +	rockchip->mgmt_sticky_rst = devm_reset_control_get_exclusive(dev,
>> +								     "mgmt-sticky");
>> +	if (IS_ERR(rockchip->mgmt_sticky_rst)) {
>> +		if (PTR_ERR(rockchip->mgmt_sticky_rst) != -EPROBE_DEFER)
>> +			dev_err(dev, "missing mgmt-sticky reset property in node\n");
>> +		return PTR_ERR(rockchip->mgmt_sticky_rst);
>> +	}
>> +
>> +	rockchip->pipe_rst = devm_reset_control_get_exclusive(dev, "pipe");
>> +	if (IS_ERR(rockchip->pipe_rst)) {
>> +		if (PTR_ERR(rockchip->pipe_rst) != -EPROBE_DEFER)
>> +			dev_err(dev, "missing pipe reset property in node\n");
>> +		return PTR_ERR(rockchip->pipe_rst);
>> +	}
>> +
>> +	rockchip->pm_rst = devm_reset_control_get_exclusive(dev, "pm");
>> +	if (IS_ERR(rockchip->pm_rst)) {
>> +		if (PTR_ERR(rockchip->pm_rst) != -EPROBE_DEFER)
>> +			dev_err(dev, "missing pm reset property in node\n");
>> +		return PTR_ERR(rockchip->pm_rst);
>> +	}
>> +
>> +	rockchip->pclk_rst = devm_reset_control_get_exclusive(dev, "pclk");
>> +	if (IS_ERR(rockchip->pclk_rst)) {
>> +		if (PTR_ERR(rockchip->pclk_rst) != -EPROBE_DEFER)
>> +			dev_err(dev, "missing pclk reset property in node\n");
>> +		return PTR_ERR(rockchip->pclk_rst);
>> +	}
>> +
>> +	rockchip->aclk_rst = devm_reset_control_get_exclusive(dev, "aclk");
>> +	if (IS_ERR(rockchip->aclk_rst)) {
>> +		if (PTR_ERR(rockchip->aclk_rst) != -EPROBE_DEFER)
>> +			dev_err(dev, "missing aclk reset property in node\n");
>> +		return PTR_ERR(rockchip->aclk_rst);
>> +	}
>> +
>> +	if (rockchip->is_rc) {
>> +		rockchip->ep_gpio = devm_gpiod_get(dev, "ep", GPIOD_OUT_HIGH);
>> +		if (IS_ERR(rockchip->ep_gpio)) {
>> +			dev_err(dev, "missing ep-gpios property in node\n");
>> +			return PTR_ERR(rockchip->ep_gpio);
>> +		}
>> +	}
>> +
>> +	rockchip->aclk_pcie = devm_clk_get(dev, "aclk");
>> +	if (IS_ERR(rockchip->aclk_pcie)) {
>> +		dev_err(dev, "aclk clock not found\n");
>> +		return PTR_ERR(rockchip->aclk_pcie);
>> +	}
>> +
>> +	rockchip->aclk_perf_pcie = devm_clk_get(dev, "aclk-perf");
>> +	if (IS_ERR(rockchip->aclk_perf_pcie)) {
>> +		dev_err(dev, "aclk_perf clock not found\n");
>> +		return PTR_ERR(rockchip->aclk_perf_pcie);
>> +	}
>> +
>> +	rockchip->hclk_pcie = devm_clk_get(dev, "hclk");
>> +	if (IS_ERR(rockchip->hclk_pcie)) {
>> +		dev_err(dev, "hclk clock not found\n");
>> +		return PTR_ERR(rockchip->hclk_pcie);
>> +	}
>> +
>> +	rockchip->clk_pcie_pm = devm_clk_get(dev, "pm");
>> +	if (IS_ERR(rockchip->clk_pcie_pm)) {
>> +		dev_err(dev, "pm clock not found\n");
>> +		return PTR_ERR(rockchip->clk_pcie_pm);
>> +	}
>> +
>> +	return 0;
>> +}
>> +EXPORT_SYMBOL_GPL(rockchip_pcie_parse_dt);
>> +
>>   int rockchip_pcie_get_phys(struct rockchip_pcie *rockchip)
>>   {
>>   	struct device *dev = rockchip->dev;
>> diff --git a/drivers/pci/host/pcie-rockchip.h b/drivers/pci/host/pcie-rockchip.h
>> index d27941e..473e74f 100644
>> --- a/drivers/pci/host/pcie-rockchip.h
>> +++ b/drivers/pci/host/pcie-rockchip.h
>> @@ -222,6 +222,7 @@ struct rockchip_pcie {
>>   	u32     mem_size;
>>   	phys_addr_t msg_bus_addr;
>>   	phys_addr_t mem_bus_addr;
>> +	bool is_rc;
>>   };
>>   
>>   static u32 rockchip_pcie_read(struct rockchip_pcie *rockchip, u32 reg)
>> @@ -235,6 +236,7 @@ static void rockchip_pcie_write(struct rockchip_pcie *rockchip, u32 val,
>>   	writel(val, rockchip->apb_base + reg);
>>   }
>>   
>> +int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip);
>>   int rockchip_pcie_get_phys(struct rockchip_pcie *rockchip);
>>   void rockchip_pcie_deinit_phys(struct rockchip_pcie *rockchip);
>>   int rockchip_pcie_enable_clocks(struct rockchip_pcie *rockchip);
>> -- 
>> 1.9.1
>>
>>
> 
> 
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v6 0/7] Add endpoint driver for Rockchip PCIe controller
  2018-04-27  2:38 [PATCH v6 0/7] Add endpoint driver for Rockchip PCIe controller Shawn Lin
                   ` (5 preceding siblings ...)
  2018-04-27  2:40 ` [PATCH v6 7/7] arm64: defconfig: update config for Rockchip PCIe Shawn Lin
@ 2018-05-08 11:52 ` Lorenzo Pieralisi
  2018-05-08 14:28   ` Shawn Lin
  6 siblings, 1 reply; 12+ messages in thread
From: Lorenzo Pieralisi @ 2018-05-08 11:52 UTC (permalink / raw)
  To: Shawn Lin
  Cc: Bjorn Helgaas, Heiko Stuebner, Rob Herring, devicetree,
	linux-rockchip, linux-pci

Hi Shawn,

On Fri, Apr 27, 2018 at 10:38:17AM +0800, Shawn Lin wrote:
> 
> Hi Lorenzo,
> 
> This's the 6th try to upstream endpoint driver for Rockchip PCIe
> controller. V6 is rebased by droping the rename change.
> 
> Thanks.
> 
> 
> Changes in v6:
> - rebase
> 
> Changes in v5:
> - export symbol to fix error reported by Kbuild robot
> - PCIE_ROCKCHIP depends on PCI
> 
> Changes in v4:
> - remove empty line
> - keep rockchip's order next to cadence and dwc, but
>   we will try to resort it later when reconstructing
>   the directories
> 
> Shawn Lin (7):
>   PCI: rockchip: Separate common code from RC driver

There seems to be no patch (1) on linux-pci list, not sure what
happened, mind resending the whole series possibly with
commit logs updated as discussed ?

Thanks,
Lorenzo

>   PCI: rockchip: Split out common function to parse DT
>   PCI: rockchip: Split out common function to init controller
>   dt-bindings: PCI: rockchip: Rename rockchip-pcie.txt to
>     rockchip-pcie-host.txt
>   PCI: rockchip: Add Endpoint controller driver for Rockchip PCIe
>     controller
>   dt-bindings: PCI: rockchip: Add DT bindings for Rockchip PCIe endpoint
>     controller
>   arm64: defconfig: update config for Rockchip PCIe
> 
>  .../devicetree/bindings/pci/rockchip-pcie-ep.txt   |   62 +
>  .../{rockchip-pcie.txt => rockchip-pcie-host.txt}  |    0
>  MAINTAINERS                                        |    4 +-
>  arch/arm64/configs/defconfig                       |    3 +-
>  drivers/pci/host/Kconfig                           |   19 +-
>  drivers/pci/host/Makefile                          |    2 +
>  drivers/pci/host/pcie-rockchip-ep.c                |  642 ++++++++
>  drivers/pci/host/pcie-rockchip-host.c              | 1141 +++++++++++++
>  drivers/pci/host/pcie-rockchip.c                   | 1683 +++-----------------
>  drivers/pci/host/pcie-rockchip.h                   |  338 ++++
>  10 files changed, 2406 insertions(+), 1488 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/pci/rockchip-pcie-ep.txt
>  rename Documentation/devicetree/bindings/pci/{rockchip-pcie.txt => rockchip-pcie-host.txt} (100%)
>  create mode 100644 drivers/pci/host/pcie-rockchip-ep.c
>  create mode 100644 drivers/pci/host/pcie-rockchip-host.c
>  create mode 100644 drivers/pci/host/pcie-rockchip.h
> 
> -- 
> 1.9.1
> 
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v6 0/7] Add endpoint driver for Rockchip PCIe controller
  2018-05-08 11:52 ` [PATCH v6 0/7] Add endpoint driver for Rockchip PCIe controller Lorenzo Pieralisi
@ 2018-05-08 14:28   ` Shawn Lin
  2018-05-09  1:42     ` Shawn Lin
  0 siblings, 1 reply; 12+ messages in thread
From: Shawn Lin @ 2018-05-08 14:28 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: shawn.lin, Bjorn Helgaas, Heiko Stuebner, Rob Herring,
	devicetree, linux-rockchip, linux-pci

Hi Lorenzo,

On 2018/5/8 19:52, Lorenzo Pieralisi wrote:
> Hi Shawn,
> 
> On Fri, Apr 27, 2018 at 10:38:17AM +0800, Shawn Lin wrote:
>>
>> Hi Lorenzo,
>>
>> This's the 6th try to upstream endpoint driver for Rockchip PCIe
>> controller. V6 is rebased by droping the rename change.
>>
>> Thanks.
>>
>>
>> Changes in v6:
>> - rebase
>>
>> Changes in v5:
>> - export symbol to fix error reported by Kbuild robot
>> - PCIE_ROCKCHIP depends on PCI
>>
>> Changes in v4:
>> - remove empty line
>> - keep rockchip's order next to cadence and dwc, but
>>    we will try to resort it later when reconstructing
>>    the directories
>>
>> Shawn Lin (7):
>>    PCI: rockchip: Separate common code from RC driver
> 
> There seems to be no patch (1) on linux-pci list, not sure what
> happened, mind resending the whole series possibly with
> commit logs updated as discussed ?

Sure! Will send v7 for updating commit logs.

> 
> Thanks,
> Lorenzo
> 
>>    PCI: rockchip: Split out common function to parse DT
>>    PCI: rockchip: Split out common function to init controller
>>    dt-bindings: PCI: rockchip: Rename rockchip-pcie.txt to
>>      rockchip-pcie-host.txt
>>    PCI: rockchip: Add Endpoint controller driver for Rockchip PCIe
>>      controller
>>    dt-bindings: PCI: rockchip: Add DT bindings for Rockchip PCIe endpoint
>>      controller
>>    arm64: defconfig: update config for Rockchip PCIe
>>
>>   .../devicetree/bindings/pci/rockchip-pcie-ep.txt   |   62 +
>>   .../{rockchip-pcie.txt => rockchip-pcie-host.txt}  |    0
>>   MAINTAINERS                                        |    4 +-
>>   arch/arm64/configs/defconfig                       |    3 +-
>>   drivers/pci/host/Kconfig                           |   19 +-
>>   drivers/pci/host/Makefile                          |    2 +
>>   drivers/pci/host/pcie-rockchip-ep.c                |  642 ++++++++
>>   drivers/pci/host/pcie-rockchip-host.c              | 1141 +++++++++++++
>>   drivers/pci/host/pcie-rockchip.c                   | 1683 +++-----------------
>>   drivers/pci/host/pcie-rockchip.h                   |  338 ++++
>>   10 files changed, 2406 insertions(+), 1488 deletions(-)
>>   create mode 100644 Documentation/devicetree/bindings/pci/rockchip-pcie-ep.txt
>>   rename Documentation/devicetree/bindings/pci/{rockchip-pcie.txt => rockchip-pcie-host.txt} (100%)
>>   create mode 100644 drivers/pci/host/pcie-rockchip-ep.c
>>   create mode 100644 drivers/pci/host/pcie-rockchip-host.c
>>   create mode 100644 drivers/pci/host/pcie-rockchip.h
>>
>> -- 
>> 1.9.1
>>
>>
> 
> 
> 


-- 
Best Regards
Shawn Lin

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v6 0/7] Add endpoint driver for Rockchip PCIe controller
  2018-05-08 14:28   ` Shawn Lin
@ 2018-05-09  1:42     ` Shawn Lin
  0 siblings, 0 replies; 12+ messages in thread
From: Shawn Lin @ 2018-05-09  1:42 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: shawn.lin, Bjorn Helgaas, Heiko Stuebner, Rob Herring,
	devicetree, linux-rockchip, linux-pci

Hi Lorenzo,

On 2018/5/8 22:28, Shawn Lin wrote:
> Hi Lorenzo,
> 
> On 2018/5/8 19:52, Lorenzo Pieralisi wrote:
>> Hi Shawn,
>>
>> On Fri, Apr 27, 2018 at 10:38:17AM +0800, Shawn Lin wrote:
>>>
>>> Hi Lorenzo,
>>>
>>> This's the 6th try to upstream endpoint driver for Rockchip PCIe
>>> controller. V6 is rebased by droping the rename change.
>>>
>>> Thanks.
>>>
>>>
>>> Changes in v6:
>>> - rebase
>>>
>>> Changes in v5:
>>> - export symbol to fix error reported by Kbuild robot
>>> - PCIE_ROCKCHIP depends on PCI
>>>
>>> Changes in v4:
>>> - remove empty line
>>> - keep rockchip's order next to cadence and dwc, but
>>>    we will try to resort it later when reconstructing
>>>    the directories
>>>
>>> Shawn Lin (7):
>>>    PCI: rockchip: Separate common code from RC driver
>>
>> There seems to be no patch (1) on linux-pci list, not sure what
>> happened, mind resending the whole series possibly with
>> commit logs updated as discussed ?
> 
> Sure! Will send v7 for updating commit logs.
> 

I send v7 and check the series in linux-pci[1], but patch (1) is still
missing, but I could find it actually hit the linux-rockchip[2]. I
guess it was spammed by linux-pci and probably due to the size, 100K,
which is larger than the throttle setting of patchwork for linux-pci.
How should I move forward with that? :)


4.0K 0000-cover-letter.patch
100K 0001-PCI-rockchip-Separate-common-code-from-RC-driver.patch
12K 0002-PCI-rockchip-Split-out-rockchip_pcie_parse_dt-to-par.patch
12K 0003-PCI-rockchip-Split-out-common-function-to-init-contr.patch
4.0K 0004-dt-bindings-PCI-rockchip-Rename-rockchip-pcie.txt-to.patch
28K 0005-PCI-rockchip-Add-EP-driver-for-Rockchip-PCIe-control.patch
4.0K 0006-dt-bindings-PCI-rockchip-Add-DT-bindings-for-Rockchi.patch
4.0K 0007-arm64-defconfig-update-config-for-Rockchip-PCIe.patch


[1]: https://patchwork.kernel.org/project/linux-pci/list/
[2]: https://patchwork.kernel.org/patch/10387915/

>>
>> Thanks,
>> Lorenzo
>>
>>>    PCI: rockchip: Split out common function to parse DT
>>>    PCI: rockchip: Split out common function to init controller
>>>    dt-bindings: PCI: rockchip: Rename rockchip-pcie.txt to
>>>      rockchip-pcie-host.txt
>>>    PCI: rockchip: Add Endpoint controller driver for Rockchip PCIe
>>>      controller
>>>    dt-bindings: PCI: rockchip: Add DT bindings for Rockchip PCIe 
>>> endpoint
>>>      controller
>>>    arm64: defconfig: update config for Rockchip PCIe
>>>
>>>   .../devicetree/bindings/pci/rockchip-pcie-ep.txt   |   62 +
>>>   .../{rockchip-pcie.txt => rockchip-pcie-host.txt}  |    0
>>>   MAINTAINERS                                        |    4 +-
>>>   arch/arm64/configs/defconfig                       |    3 +-
>>>   drivers/pci/host/Kconfig                           |   19 +-
>>>   drivers/pci/host/Makefile                          |    2 +
>>>   drivers/pci/host/pcie-rockchip-ep.c                |  642 ++++++++
>>>   drivers/pci/host/pcie-rockchip-host.c              | 1141 
>>> +++++++++++++
>>>   drivers/pci/host/pcie-rockchip.c                   | 1683 
>>> +++-----------------
>>>   drivers/pci/host/pcie-rockchip.h                   |  338 ++++
>>>   10 files changed, 2406 insertions(+), 1488 deletions(-)
>>>   create mode 100644 
>>> Documentation/devicetree/bindings/pci/rockchip-pcie-ep.txt
>>>   rename Documentation/devicetree/bindings/pci/{rockchip-pcie.txt => 
>>> rockchip-pcie-host.txt} (100%)
>>>   create mode 100644 drivers/pci/host/pcie-rockchip-ep.c
>>>   create mode 100644 drivers/pci/host/pcie-rockchip-host.c
>>>   create mode 100644 drivers/pci/host/pcie-rockchip.h
>>>
>>> -- 
>>> 1.9.1
>>>
>>>
>>
>>
>>
> 
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2018-05-09  1:42 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-27  2:38 [PATCH v6 0/7] Add endpoint driver for Rockchip PCIe controller Shawn Lin
2018-04-27  2:39 ` [PATCH v6 2/7] PCI: rockchip: Split out common function to parse DT Shawn Lin
2018-04-30 14:51   ` Lorenzo Pieralisi
2018-05-02  0:57     ` Shawn Lin
2018-04-27  2:39 ` [PATCH v6 3/7] PCI: rockchip: Split out common function to init controller Shawn Lin
2018-04-27  2:39 ` [PATCH v6 4/7] dt-bindings: PCI: rockchip: Rename rockchip-pcie.txt to rockchip-pcie-host.txt Shawn Lin
2018-04-27  2:39 ` [PATCH v6 5/7] PCI: rockchip: Add Endpoint controller driver for Rockchip PCIe controller Shawn Lin
2018-04-27  2:39 ` [PATCH v6 6/7] dt-bindings: PCI: rockchip: Add DT bindings for Rockchip PCIe endpoint controller Shawn Lin
2018-04-27  2:40 ` [PATCH v6 7/7] arm64: defconfig: update config for Rockchip PCIe Shawn Lin
2018-05-08 11:52 ` [PATCH v6 0/7] Add endpoint driver for Rockchip PCIe controller Lorenzo Pieralisi
2018-05-08 14:28   ` Shawn Lin
2018-05-09  1:42     ` Shawn Lin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).