[PATCH] pci: pcie-rcar: add regulators support

From: Meng Li
Date: Tue Oct 19 2021 - 06:00:03 EST


From: Andrey Gusakov <andrey.gusakov@xxxxxxxxxxxxxxxxxx>

Add PCIe regulators for KingFisher board.

Signed-off-by: Meng Li <Meng.Li@xxxxxxxxxxxxx>
---
arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 47 +++++++++++++++++
drivers/pci/controller/pcie-rcar-host.c | 64 ++++++++++++++++++++++++
2 files changed, 111 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
index 8986a7e6e099..82e463c32a37 100644
--- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
@@ -50,6 +50,25 @@
startup-delay-us = <70000>;
enable-active-high;
};
+
+ mpcie_3v3: regulator-mpcie_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "mPCIe 3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio_exp_77 14 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ mpcie_1v8: regulator-mpcie_1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "mPCIe 1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&gpio_exp_77 15 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <200000>;
+ enable-active-high;
+ };
};

&can0 {
@@ -241,6 +260,31 @@
interrupt-controller;
interrupt-parent = <&gpio5>;
interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+
+ mpcie_wake {
+ gpio-hog;
+ gpios = <0 GPIO_ACTIVE_HIGH>;
+ output-low;
+ line-name = "mPCIe WAKE#";
+ };
+ mpcie_wdisable {
+ gpio-hog;
+ gpios = <1 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "mPCIe W_DISABLE";
+ };
+ mpcie_clreq {
+ gpio-hog;
+ gpios = <2 GPIO_ACTIVE_HIGH>;
+ input;
+ line-name = "mPCIe CLKREQ#";
+ };
+ mpcie_ovc {
+ gpio-hog;
+ gpios = <3 GPIO_ACTIVE_HIGH>;
+ input;
+ line-name = "mPCIe OVC";
+ };
};
};

@@ -259,6 +303,9 @@

&pciec1 {
status = "okay";
+
+ pcie3v3-supply = <&mpcie_3v3>;
+ pcie1v8-supply = <&mpcie_1v8>;
};

&pfc {
diff --git a/drivers/pci/controller/pcie-rcar-host.c b/drivers/pci/controller/pcie-rcar-host.c
index cdc0963f154e..bf1e4007876e 100644
--- a/drivers/pci/controller/pcie-rcar-host.c
+++ b/drivers/pci/controller/pcie-rcar-host.c
@@ -14,6 +14,7 @@
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
+#include <linux/regulator/consumer.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
@@ -54,6 +55,8 @@ struct rcar_pcie_host {
struct rcar_pcie pcie;
struct phy *phy;
struct clk *bus_clk;
+ struct regulator *pcie3v3; /* 3.3V power supply */
+ struct regulator *pcie1v8; /* 1.8V power supply */
struct rcar_msi msi;
int (*phy_init_fn)(struct rcar_pcie_host *host);
};
@@ -893,6 +896,36 @@ static const struct of_device_id rcar_pcie_of_match[] = {
{},
};

+static int rcar_pcie_set_vpcie(struct rcar_pcie_host *host)
+{
+ struct device *dev = host->pcie.dev;
+ int err;
+
+ if (!IS_ERR(host->pcie3v3)) {
+ err = regulator_enable(host->pcie3v3);
+ if (err) {
+ dev_err(dev, "fail to enable vpcie3v3 regulator\n");
+ goto err_out;
+ }
+ }
+
+ if (!IS_ERR(host->pcie1v8)) {
+ err = regulator_enable(host->pcie1v8);
+ if (err) {
+ dev_err(dev, "fail to enable vpcie1v8 regulator\n");
+ goto err_disable_3v3;
+ }
+ }
+
+ return 0;
+
+err_disable_3v3:
+ if (!IS_ERR(host->pcie3v3))
+ regulator_disable(host->pcie3v3);
+err_out:
+ return err;
+}
+
static int rcar_pcie_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -911,6 +944,31 @@ static int rcar_pcie_probe(struct platform_device *pdev)
pcie->dev = dev;
platform_set_drvdata(pdev, host);

+ host->pcie3v3 = devm_regulator_get_optional(dev, "pcie3v3");
+ if (IS_ERR(host->pcie3v3)) {
+ if (PTR_ERR(host->pcie3v3) == -EPROBE_DEFER) {
+ pci_free_host_bridge(bridge);
+ return -EPROBE_DEFER;
+ }
+ dev_info(dev, "no pcie3v3 regulator found\n");
+ }
+
+ host->pcie1v8 = devm_regulator_get_optional(dev, "pcie1v8");
+ if (IS_ERR(host->pcie1v8)) {
+ if (PTR_ERR(host->pcie1v8) == -EPROBE_DEFER) {
+ pci_free_host_bridge(bridge);
+ return -EPROBE_DEFER;
+ }
+ dev_info(dev, "no pcie1v8 regulator found\n");
+ }
+
+ err = rcar_pcie_set_vpcie(host);
+ if (err) {
+ dev_err(dev, "failed to set pcie regulators\n");
+ pci_free_host_bridge(bridge);
+ return err;
+ }
+
pm_runtime_enable(pcie->dev);
err = pm_runtime_get_sync(pcie->dev);
if (err < 0) {
@@ -985,6 +1043,12 @@ static int rcar_pcie_probe(struct platform_device *pdev)
irq_dispose_mapping(host->msi.irq1);

err_pm_put:
+ if(!IS_ERR(host->pcie3v3))
+ if (regulator_is_enabled(host->pcie3v3))
+ regulator_disable(host->pcie3v3);
+ if(!IS_ERR(host->pcie1v8))
+ if (regulator_is_enabled(host->pcie1v8))
+ regulator_disable(host->pcie1v8);
pm_runtime_put(dev);
pm_runtime_disable(dev);

--
2.17.1