reset: rzg2l-usbphy-ctrl: Add new driver

Add a new driver to control the USB 2.0 PHY reset controller on the
Renesas RZ/G2L and related SoCs.

Signed-off-by: Paul Barker <paul.barker.ct@bp.renesas.com>
Reviewed-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
This commit is contained in:
Paul Barker 2025-03-11 20:57:43 +00:00 committed by Marek Vasut
parent 8bc3542384
commit b85fe01d7d
4 changed files with 140 additions and 0 deletions

View file

@ -235,4 +235,13 @@ config RESET_AT91
This enables the Reset Controller driver support for Microchip/Atmel
SoCs. Mainly used to expose assert/deassert methods to other drivers
that require it.
config RESET_RZG2L_USBPHY_CTRL
bool "Enable support for Renesas RZ/G2L USB 2.0 PHY control"
depends on DM_RESET
help
Enable support for controlling USB 2.0 PHY resets on the Renesas
RZ/G2L SoC. This is required for USB 2.0 functionality to work on this
SoC.
endmenu

View file

@ -33,3 +33,4 @@ obj-$(CONFIG_RESET_ZYNQMP) += reset-zynqmp.o
obj-$(CONFIG_RESET_DRA7) += reset-dra7.o
obj-$(CONFIG_RESET_AT91) += reset-at91.o
obj-$(CONFIG_$(PHASE_)RESET_JH7110) += reset-jh7110.o
obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o

View file

@ -0,0 +1,113 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2024 Renesas Electronics Corporation
*/
#include <asm/io.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <dm/lists.h>
#include <renesas/rzg2l-usbphy.h>
#include <reset-uclass.h>
#include <reset.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_MASK (RESET_PHYRST_1 | RESET_PHYRST_2)
#define NUM_PORTS 2
static int rzg2l_usbphy_ctrl_assert(struct reset_ctl *reset_ctl)
{
struct rzg2l_usbphy_ctrl_priv *priv = dev_get_priv(reset_ctl->dev);
u32 val;
val = readl(priv->regs + RESET);
val |= reset_ctl->id ? RESET_PHYRST_2 : RESET_PHYRST_1;
/* If both ports are in reset, we can also place the PLL into reset. */
if ((val & PHY_RESET_MASK) == PHY_RESET_MASK)
val |= RESET_PLLRESET;
writel(val, priv->regs + RESET);
return 0;
}
static int rzg2l_usbphy_ctrl_deassert(struct reset_ctl *reset_ctl)
{
struct rzg2l_usbphy_ctrl_priv *priv = dev_get_priv(reset_ctl->dev);
u32 val = reset_ctl->id ? RESET_PHYRST_2 : RESET_PHYRST_1;
/* If either port is out of reset, the PLL must also be out of reset. */
val |= RESET_PLLRESET;
clrbits_le32(priv->regs + RESET, val);
return 0;
}
static int rzg2l_usbphy_ctrl_of_xlate(struct reset_ctl *reset_ctl,
struct ofnode_phandle_args *args)
{
if (args->args[0] >= NUM_PORTS)
return -EINVAL;
reset_ctl->id = args->args[0];
return 0;
}
struct reset_ops rzg2l_usbphy_ctrl_ops = {
.rst_assert = rzg2l_usbphy_ctrl_assert,
.rst_deassert = rzg2l_usbphy_ctrl_deassert,
.of_xlate = rzg2l_usbphy_ctrl_of_xlate,
};
static int rzg2l_usbphy_ctrl_probe(struct udevice *dev)
{
struct rzg2l_usbphy_ctrl_priv *priv = dev_get_priv(dev);
struct reset_ctl rst;
int ret;
priv->regs = dev_read_addr(dev);
ret = reset_get_by_index(dev, 0, &rst);
if (ret < 0) {
dev_err(dev, "failed to get reset line: %d\n", ret);
return ret;
}
ret = reset_deassert(&rst);
if (ret < 0) {
dev_err(dev, "failed to de-assert reset line: %d\n", ret);
return ret;
}
/* put pll and phy into reset state */
setbits_le32(priv->regs + RESET,
RESET_SEL_PLLRESET | RESET_PLLRESET |
RESET_SEL_P1RESET | RESET_PHYRST_1 |
RESET_SEL_P2RESET | RESET_PHYRST_2);
return 0;
}
static const struct udevice_id rzg2l_usbphy_ctrl_ids[] = {
{ .compatible = "renesas,rzg2l-usbphy-ctrl", },
{ /* sentinel */ }
};
U_BOOT_DRIVER(rzg2l_usbphy_ctrl) = {
.name = "rzg2l_usbphy_ctrl",
.id = UCLASS_RESET,
.of_match = rzg2l_usbphy_ctrl_ids,
.probe = rzg2l_usbphy_ctrl_probe,
.ops = &rzg2l_usbphy_ctrl_ops,
.priv_auto = sizeof(struct rzg2l_usbphy_ctrl_priv),
};

View file

@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* RZ/G2L USB PHY common definitions
*
* Copyright (C) 2021-2023 Renesas Electronics Corp.
*/
#ifndef RENESAS_RZG2L_USBPHY_H
#define RENESAS_RZG2L_USBPHY_H
#include <fdtdec.h>
struct rzg2l_usbphy_ctrl_priv {
fdt_addr_t regs;
};
#endif /* RENESAS_RZG2L_USBPHY_H */