mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-16 09:54:35 +00:00
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:
parent
8bc3542384
commit
b85fe01d7d
4 changed files with 140 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
113
drivers/reset/reset-rzg2l-usbphy-ctrl.c
Normal file
113
drivers/reset/reset-rzg2l-usbphy-ctrl.c
Normal 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),
|
||||
};
|
17
include/renesas/rzg2l-usbphy.h
Normal file
17
include/renesas/rzg2l-usbphy.h
Normal 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 */
|
Loading…
Add table
Reference in a new issue