All of lore.kernel.org
 help / color / mirror / Atom feed
From: Horatiu Vultur <horatiu.vultur@microchip.com>
To: <p.zabel@pengutronix.de>, <robh+dt@kernel.org>
Cc: <devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	"Horatiu Vultur" <horatiu.vultur@microchip.com>
Subject: [PATCH 2/2] reset: lan966x: Add support for the phy reset on lan966x
Date: Tue, 19 Oct 2021 13:52:05 +0200	[thread overview]
Message-ID: <20211019115205.1516311-3-horatiu.vultur@microchip.com> (raw)
In-Reply-To: <20211019115205.1516311-1-horatiu.vultur@microchip.com>

This patch adds a driver to release the reset of the PHYs on lan966x.
There are 2 mdio buses on lan966x. One which is internal and has 2 PHYs
and one is external.
On the internal one it is required to release the HW reset of the phys
by writing specific register and while on the external one is required
to toggle a GPIO pin.

Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
 drivers/reset/Kconfig                       |  8 ++
 drivers/reset/Makefile                      |  1 +
 drivers/reset/reset-microchip-lan966x-phy.c | 93 +++++++++++++++++++++
 3 files changed, 102 insertions(+)
 create mode 100644 drivers/reset/reset-microchip-lan966x-phy.c

diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 36ce6c8bcf1e..94e1c0e7d343 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -122,6 +122,14 @@ config RESET_MCHP_SPARX5
 	help
 	  This driver supports switch core reset for the Microchip Sparx5 SoC.
 
+config RESET_MCHP_LAN966X_PHY
+	bool "Microchip lan966x phy reset driver"
+	depends on SOC_LAN966 || COMPILE_TEST
+	select MFD_SYSCON
+	help
+	  This driver supports the release of phy reset for the
+	  Microchip lan966x SoC.
+
 config RESET_MESON
 	tristate "Meson Reset Driver"
 	depends on ARCH_MESON || COMPILE_TEST
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 21d46d8869ff..2d7699aafb6c 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_RESET_K210) += reset-k210.o
 obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o
 obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
 obj-$(CONFIG_RESET_MCHP_SPARX5) += reset-microchip-sparx5.o
+obj-$(CONFIG_RESET_MCHP_LAN966X_PHY) += reset-microchip-lan966x-phy.o
 obj-$(CONFIG_RESET_MESON) += reset-meson.o
 obj-$(CONFIG_RESET_MESON_AUDIO_ARB) += reset-meson-audio-arb.o
 obj-$(CONFIG_RESET_NPCM) += reset-npcm.o
diff --git a/drivers/reset/reset-microchip-lan966x-phy.c b/drivers/reset/reset-microchip-lan966x-phy.c
new file mode 100644
index 000000000000..63dd6a7bc62f
--- /dev/null
+++ b/drivers/reset/reset-microchip-lan966x-phy.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0+
+#include <linux/gpio/consumer.h>
+#include <linux/of_device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+
+#define CUPHY_REG_OFF	0x10
+#define CUPHY_REG_BIT	0
+
+struct lan966x_phy_reset_context {
+	void __iomem *internal_phy_ctrl;
+	struct gpio_desc *external_phy_ctrl;
+	struct reset_controller_dev rcdev;
+};
+
+static int lan966x_phy_reset(struct reset_controller_dev *rcdev,
+			     unsigned long id)
+{
+	struct lan966x_phy_reset_context *ctx =
+		container_of(rcdev, struct lan966x_phy_reset_context, rcdev);
+	u32 val;
+
+	/* In case there are external PHYs toggle the GPIO to release the reset
+	 * of the PHYs
+	 */
+	if (ctx->external_phy_ctrl) {
+		gpiod_direction_output(ctx->external_phy_ctrl, 1);
+		gpiod_set_value(ctx->external_phy_ctrl, 0);
+		gpiod_set_value(ctx->external_phy_ctrl, 1);
+		gpiod_set_value(ctx->external_phy_ctrl, 0);
+	}
+
+	/* Release the reset of internal PHY */
+	val = readl(ctx->internal_phy_ctrl + CUPHY_REG_OFF);
+	val |= BIT(CUPHY_REG_BIT);
+	writel(val, ctx->internal_phy_ctrl + CUPHY_REG_OFF);
+
+	return 0;
+}
+
+static const struct reset_control_ops lan966x_phy_reset_ops = {
+	.reset = lan966x_phy_reset,
+};
+
+static int lan966x_phy_reset_probe(struct platform_device *pdev)
+{
+	struct device_node *dn = pdev->dev.of_node;
+	struct lan966x_phy_reset_context *ctx;
+
+	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+
+	ctx->internal_phy_ctrl = devm_platform_ioremap_resource_byname(pdev, "phy");
+	if (IS_ERR(ctx->internal_phy_ctrl))
+		return dev_err_probe(&pdev->dev, PTR_ERR(ctx->internal_phy_ctrl),
+				     "Could not get resource 0\n");
+
+	ctx->external_phy_ctrl = devm_gpiod_get_optional(&pdev->dev,
+							 "external-phy-reset",
+							 GPIOD_OUT_LOW);
+	if (IS_ERR(ctx->external_phy_ctrl))
+		return dev_err_probe(&pdev->dev, PTR_ERR(ctx->external_phy_ctrl),
+				     "Could not get reset GPIO\n");
+
+	ctx->rcdev.owner = THIS_MODULE;
+	ctx->rcdev.nr_resets = 1;
+	ctx->rcdev.ops = &lan966x_phy_reset_ops;
+	ctx->rcdev.of_node = dn;
+
+	return devm_reset_controller_register(&pdev->dev, &ctx->rcdev);
+}
+
+static const struct of_device_id lan966x_phy_reset_of_match[] = {
+	{ .compatible = "microchip,lan966x-phy-reset", },
+	{ }
+};
+
+static struct platform_driver lan966x_phy_reset_driver = {
+	.probe = lan966x_phy_reset_probe,
+	.driver = {
+		.name = "lan966x-phy-reset",
+		.of_match_table = lan966x_phy_reset_of_match,
+	},
+};
+
+static int __init lan966x_phy_reset_init(void)
+{
+	return platform_driver_register(&lan966x_phy_reset_driver);
+}
+postcore_initcall(lan966x_phy_reset_init);
-- 
2.33.0


      parent reply	other threads:[~2021-10-19 11:52 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-19 11:52 [PATCH 0/2] reset: lan996x: Add reset driver for lan966x phys Horatiu Vultur
2021-10-19 11:52 ` [PATCH 1/2] dt-bindings: reset: lan966x phy reset driver bindings Horatiu Vultur
2021-10-27  3:13   ` Rob Herring
2021-10-29 12:58     ` Horatiu Vultur
2022-03-13 16:00       ` Michael Walle
2021-10-19 11:52 ` Horatiu Vultur [this message]

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=20211019115205.1516311-3-horatiu.vultur@microchip.com \
    --to=horatiu.vultur@microchip.com \
    --cc=devicetree@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=p.zabel@pengutronix.de \
    --cc=robh+dt@kernel.org \
    /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.