All of lore.kernel.org
 help / color / mirror / Atom feed
From: Biju Das <biju.das.jz@bp.renesas.com>
To: Philipp Zabel <p.zabel@pengutronix.de>
Cc: Biju Das <biju.das.jz@bp.renesas.com>,
	Geert Uytterhoeven <geert+renesas@glider.be>,
	Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>,
	Chris Paterson <Chris.Paterson2@renesas.com>,
	Biju Das <biju.das@bp.renesas.com>,
	Prabhakar Mahadev Lad <prabhakar.mahadev-lad.rj@bp.renesas.com>,
	linux-renesas-soc@vger.kernel.org
Subject: [PATCH v4 04/10] reset: renesas: Add RZ/G2L usbphy control driver
Date: Mon, 19 Jul 2021 13:19:32 +0100	[thread overview]
Message-ID: <20210719121938.6532-5-biju.das.jz@bp.renesas.com> (raw)
In-Reply-To: <20210719121938.6532-1-biju.das.jz@bp.renesas.com>

Add support for RZ/G2L USBPHY Control driver. It mainly controls
reset and power down of the USB/PHY.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
v3->v4:
 * Incorporated the changes suggested by Philipp
 * removed *dev pointer, replaced the magic number 0xff
 * started using of_reset_simple_xlate
 * Added spinlock for read-modify-writes
 v3:
  * New driver. As per Rob's suggestion, Modelled IP as a reset driver,
    since it mainly controls reset and power down of the PHY.
---
 drivers/reset/Kconfig                   |   7 +
 drivers/reset/Makefile                  |   1 +
 drivers/reset/reset-rzg2l-usbphy-ctrl.c | 175 ++++++++++++++++++++++++
 3 files changed, 183 insertions(+)
 create mode 100644 drivers/reset/reset-rzg2l-usbphy-ctrl.c

diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 328f70f633eb..ed65ea66987b 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -181,6 +181,13 @@ config RESET_RASPBERRYPI
 	  interfacing with RPi4's co-processor and model these firmware
 	  initialization routines as reset lines.
 
+config RESET_RZG2L_USBPHY_CTRL
+	tristate "Renesas RZ/G2L USBPHY control driver"
+	depends on ARCH_R9A07G044 || COMPILE_TEST
+	help
+	  Support for USBPHY Control found on RZ/G2L family. It mainly
+	  controls reset and power down of the USB/PHY.
+
 config RESET_SCMI
 	tristate "Reset driver controlled via ARM SCMI interface"
 	depends on ARM_SCMI_PROTOCOL || COMPILE_TEST
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index ea8b8d9ca565..21d46d8869ff 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_RESET_PISTACHIO) += reset-pistachio.o
 obj-$(CONFIG_RESET_QCOM_AOSS) += reset-qcom-aoss.o
 obj-$(CONFIG_RESET_QCOM_PDC) += reset-qcom-pdc.o
 obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o
+obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o
 obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
 obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
 obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
new file mode 100644
index 000000000000..e0704fd2b533
--- /dev/null
+++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
@@ -0,0 +1,175 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas RZ/G2L USBPHY control driver
+ *
+ * Copyright (C) 2021 Renesas Electronics Corporation
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <linux/reset-controller.h>
+
+#define RESET			0x000
+
+#define RESET_SEL_PLLRESET	BIT(12)
+#define RESET_PLLRESET		BIT(8)
+
+#define RESET_SEL_P2RESET	BIT(5)
+#define RESET_SEL_P1RESET	BIT(4)
+#define RESET_PHYRST_2		BIT(1)
+#define RESET_PHYRST_1		BIT(0)
+
+#define PHY_RESET_PORT2		(RESET_SEL_P2RESET | RESET_PHYRST_2)
+#define PHY_RESET_PORT1		(RESET_SEL_P1RESET | RESET_PHYRST_1)
+
+#define NUM_PORTS		2
+
+struct rzg2l_usbphy_ctrl_priv {
+	struct reset_controller_dev rcdev;
+	struct reset_control *rstc;
+	void __iomem *base;
+
+	spinlock_t lock;
+};
+
+#define rcdev_to_priv(x)	container_of(x, struct rzg2l_usbphy_ctrl_priv, rcdev)
+
+static int rzg2l_usbphy_ctrl_assert(struct reset_controller_dev *rcdev,
+				    unsigned long id)
+{
+	struct rzg2l_usbphy_ctrl_priv *priv = rcdev_to_priv(rcdev);
+	u32 port_mask = PHY_RESET_PORT1 | PHY_RESET_PORT2;
+	void __iomem *base = priv->base;
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	val = readl(base + RESET);
+	val |= id ? PHY_RESET_PORT2 : PHY_RESET_PORT1;
+	if (port_mask == (val & port_mask))
+		val |= RESET_PLLRESET;
+	writel(val, base + RESET);
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+}
+
+static int rzg2l_usbphy_ctrl_deassert(struct reset_controller_dev *rcdev,
+				      unsigned long id)
+{
+	struct rzg2l_usbphy_ctrl_priv *priv = rcdev_to_priv(rcdev);
+	void __iomem *base = priv->base;
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	val = readl(base + RESET);
+
+	val |= RESET_SEL_PLLRESET;
+	val &= ~(RESET_PLLRESET | (id ? PHY_RESET_PORT2 : PHY_RESET_PORT1));
+	writel(val, base + RESET);
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+}
+
+static int rzg2l_usbphy_ctrl_status(struct reset_controller_dev *rcdev,
+				    unsigned long id)
+{
+	struct rzg2l_usbphy_ctrl_priv *priv = rcdev_to_priv(rcdev);
+	u32 port_mask;
+
+	port_mask = id ? PHY_RESET_PORT2 : PHY_RESET_PORT1;
+
+	return !!(readl(priv->base + RESET) & port_mask);
+}
+
+static const struct of_device_id rzg2l_usbphy_ctrl_match_table[] = {
+	{ .compatible = "renesas,rzg2l-usbphy-ctrl" },
+	{ /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, rzg2l_usbphy_ctrl_match_table);
+
+static const struct reset_control_ops rzg2l_usbphy_ctrl_reset_ops = {
+	.assert = rzg2l_usbphy_ctrl_assert,
+	.deassert = rzg2l_usbphy_ctrl_deassert,
+	.status = rzg2l_usbphy_ctrl_status,
+};
+
+static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct rzg2l_usbphy_ctrl_priv *priv;
+	unsigned long flags;
+	int error;
+	u32 val;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+	if (IS_ERR(priv->rstc))
+		return dev_err_probe(dev, PTR_ERR(priv->rstc),
+				     "failed to get reset\n");
+
+	reset_control_deassert(priv->rstc);
+
+	priv->rcdev.ops = &rzg2l_usbphy_ctrl_reset_ops;
+	priv->rcdev.of_reset_n_cells = 1;
+	priv->rcdev.nr_resets = NUM_PORTS;
+	priv->rcdev.of_node = dev->of_node;
+	priv->rcdev.dev = dev;
+
+	error = devm_reset_controller_register(dev, &priv->rcdev);
+	if (error)
+		return error;
+
+	spin_lock_init(&priv->lock);
+	dev_set_drvdata(dev, priv);
+
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_resume_and_get(&pdev->dev);
+
+	/* put pll and phy into reset state */
+	spin_lock_irqsave(&priv->lock, flags);
+	val = readl(priv->base + RESET);
+	val |= RESET_SEL_PLLRESET | RESET_PLLRESET | PHY_RESET_PORT2 | PHY_RESET_PORT1;
+	writel(val, priv->base + RESET);
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+}
+
+static int rzg2l_usbphy_ctrl_remove(struct platform_device *pdev)
+{
+	struct rzg2l_usbphy_ctrl_priv *priv = dev_get_drvdata(&pdev->dev);
+
+	pm_runtime_put(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+	reset_control_assert(priv->rstc);
+
+	return 0;
+}
+
+static struct platform_driver rzg2l_usbphy_ctrl_driver = {
+	.driver = {
+		.name		= "rzg2l_usbphy_ctrl",
+		.of_match_table	= rzg2l_usbphy_ctrl_match_table,
+	},
+	.probe	= rzg2l_usbphy_ctrl_probe,
+	.remove	= rzg2l_usbphy_ctrl_remove,
+};
+module_platform_driver(rzg2l_usbphy_ctrl_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Renesas RZ/G2L USBPHY Control");
+MODULE_AUTHOR("biju.das.jz@bp.renesas.com>");
-- 
2.17.1


  parent reply	other threads:[~2021-07-19 12:19 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20210719121938.6532-1-biju.das.jz@bp.renesas.com>
2021-07-19 12:19 ` [PATCH v4 01/10] dt-bindings: usb: generic-ohci: Document dr_mode property Biju Das
2021-07-19 12:19 ` [PATCH v4 02/10] dt-bindings: usb: generic-ehci: " Biju Das
2021-07-19 12:19 ` [PATCH v4 03/10] dt-bindings: reset: Document RZ/G2L USBPHY Control bindings Biju Das
2021-07-19 15:27   ` Rob Herring
2021-07-20 11:26     ` Biju Das
2021-07-20 16:36       ` Rob Herring
2021-07-20 16:56         ` Biju Das
2021-07-26 22:26   ` Rob Herring
2021-07-19 12:19 ` Biju Das [this message]
2021-07-27  7:55   ` [PATCH v4 04/10] reset: renesas: Add RZ/G2L usbphy control driver Biju Das
2021-07-27 13:37     ` Philipp Zabel
2021-07-27 13:53       ` Biju Das
2021-07-27 13:58         ` Philipp Zabel
2021-07-19 12:19 ` [PATCH v4 05/10] arm64: configs: defconfig: Enable RZ/G2L USBPHY " Biju Das
2021-07-19 12:19   ` Biju Das
2021-07-19 12:19 ` [PATCH v4 06/10] dt-bindings: phy: renesas,usb2-phy: Document RZ/G2L phy bindings Biju Das
2021-07-19 12:19   ` [PATCH v4 06/10] dt-bindings: phy: renesas, usb2-phy: " Biju Das
2021-07-26 22:28   ` [PATCH v4 06/10] dt-bindings: phy: renesas,usb2-phy: " Rob Herring
2021-07-26 22:28     ` Rob Herring
2021-07-27 14:58     ` Biju Das
2021-07-27 14:58       ` Biju Das
2021-07-19 12:19 ` [PATCH v4 07/10] phy: renesas: phy-rcar-gen3-usb2: Add OTG support for RZ/G2L Biju Das
2021-07-19 12:19   ` Biju Das
2021-07-19 12:19 ` [PATCH v4 08/10] arm64: dts: renesas: r9a07g044: Add USB2.0 phy and host support Biju Das
2021-07-19 12:19 ` [PATCH v4 09/10] dt-bindings: usb: renesas,usbhs: Document RZ/G2L bindings Biju Das
2021-07-26 22:30   ` Rob Herring
2021-07-27 14:59     ` Biju Das
2021-07-19 12:19 ` [PATCH v4 10/10] arm64: dts: renesas: r9a07g044: Add USB2.0 device support Biju Das

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210719121938.6532-5-biju.das.jz@bp.renesas.com \
    --to=biju.das.jz@bp.renesas.com \
    --cc=Chris.Paterson2@renesas.com \
    --cc=biju.das@bp.renesas.com \
    --cc=geert+renesas@glider.be \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=p.zabel@pengutronix.de \
    --cc=prabhakar.mahadev-lad.rj@bp.renesas.com \
    --cc=yoshihiro.shimoda.uh@renesas.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.