[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250521140943.3830195-9-claudiu.beznea.uj@bp.renesas.com>
Date: Wed, 21 May 2025 17:09:39 +0300
From: Claudiu <claudiu.beznea@...on.dev>
To: vkoul@...nel.org,
kishon@...nel.org,
robh@...nel.org,
krzk+dt@...nel.org,
conor+dt@...nel.org,
p.zabel@...gutronix.de,
geert+renesas@...der.be,
magnus.damm@...il.com,
yoshihiro.shimoda.uh@...esas.com,
kees@...nel.org,
gustavoars@...nel.org,
biju.das.jz@...renesas.com
Cc: claudiu.beznea@...on.dev,
linux-phy@...ts.infradead.org,
devicetree@...r.kernel.org,
linux-kernel@...r.kernel.org,
linux-renesas-soc@...r.kernel.org,
linux-hardening@...r.kernel.org,
john.madieu.xa@...renesas.com,
Claudiu Beznea <claudiu.beznea.uj@...renesas.com>
Subject: [PATCH v3 08/12] reset: rzg2l-usbphy-ctrl: Add support for USB PWRRDY signal
From: Claudiu Beznea <claudiu.beznea.uj@...renesas.com>
On the Renesas RZ/G3S SoC, the USB PHY block has an input signal called
PWRRDY. This signal is managed by the system controller and must be
de-asserted after powering on the area where USB PHY resides and asserted
before powering it off.
On power-on the USB PWRRDY signal need to be de-asserted before enabling
clock and switching the module to normal state (though MSTOP support). The
power-on configuration sequence must be:
1/ PWRRDY=0
2/ CLK_ON=1
3/ MSTOP=0
On power-off the configuration sequence should be:
1/ MSTOP=1
2/ CLK_ON=0
3/ PWRRDY=1
The CLK_ON and MSTOP functionalities are controlled by clock drivers.
After long discussions with the internal HW team, it has been confirmed
that the HW connection b/w USB PHY block, the USB channels, the system
controller, clock, MSTOP, PWRRDY signal is as follows:
┌──────────────────────────────┐
│ │◄── CPG_CLKON_USB.CLK0_ON
│ USB CH0 │
┌──────────────────────────┐ │┌───────────────────────────┐ │◄── CPG_CLKON_USB.CLK2_ON
│ ┌────────┐ ││host controller registers │ │
│ │ │ ││function controller registers│
│ │ PHY0 │◄──┤└───────────────────────────┘ │
│ USB PHY │ │ └────────────▲─────────────────┘
│ └────────┘ │
│ │ CPG_BUS_PERI_COM_MSTOP.MSTOP{6, 5}_ON
│┌──────────────┐ ┌────────┐
││USHPHY control│ │ │
││ registers │ │ PHY1 │ ┌──────────────────────────────┐
│└──────────────┘ │ │◄──┤ USB CH1 │
│ └────────┘ │┌───────────────────────────┐ │◄── CPG_CLKON_USB.CLK1_ON
└─▲───────▲─────────▲──────┘ ││ host controller registers │ │
│ │ │ │└───────────────────────────┘ │
│ │ │ └────────────▲─────────────────┘
│ │ │ │
│ │ │ CPG_BUS_PERI_COM_MSTOP.MSTOP7_ON
│PWRRDY │ │
│ │ CPG_CLK_ON_USB.CLK3_ON
│ │
│ CPG_BUS_PERI_COM_MSTOP.MSTOP4_ON
│
┌────┐
│SYSC│
└────┘
where:
- CPG_CLKON_USB.CLK.CLKX_ON is the register bit controlling the clock X
of different USB blocks, X in {0, 1, 2, 3}
- CPG_BUS_PERI_COM_MSTOP.MSTOPX_ON is the register bit controlling the
MSTOP of different USB blocks, X in {4, 5, 6, 7}
- USB PHY is the USB PHY block exposing 2 ports, port0 and port1, used
by the USB CH0, USB CH1
- SYSC is the system controller block controlling the PWRRDY signal
- USB CHx are individual USB block with host and function capabilities
(USB CH0 have both host and function capabilities, USB CH1 has only
host capabilities)
The USBPHY control registers are controlled though the
reset-rzg2l-usbphy-ctrl driver. The USB PHY ports are controlled by
phy_rcar_gen3_usb2 (drivers/phy/renesas/phy-rcar-gen3-usb2.c file). The
USB PHY ports requests resets from the reset-rzg2l-usbphy-ctrl driver.
The connection b/w the system controller and the USB PHY drivers is
implemented through the renesas,sysc-signals device tree property. This
property specifies the register offset and the bitmask required to control
the signal. The system controller exports the syscon regmap, and the
read/write access to the memory area of the PWRRDY signal is
reference-counted, as the same system controller signal is provided to
the PHY driver and the reset-rzg2l-usbphy-ctrl.
This approach was chosen to avoid any violation of the configuration
sequence b/w PWRRDY, CLK_ON and MSTOP bits specified above.
Add support for PWRRDY in reset-rzg2l-usbphy-ctrl driver.
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@...renesas.com>
---
Changes in v3:
- none; this patch is new
drivers/reset/reset-rzg2l-usbphy-ctrl.c | 42 +++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
index 8a7f167e405e..016aae883b2e 100644
--- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c
+++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
@@ -13,6 +13,7 @@
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/reset-controller.h>
+#include <linux/soc/renesas/rz-sysc.h>
#define RESET 0x000
#define VBENCTL 0x03c
@@ -35,6 +36,7 @@ struct rzg2l_usbphy_ctrl_priv {
struct reset_control *rstc;
void __iomem *base;
struct platform_device *vdev;
+ struct rz_sysc_signal_map *pwrrdy;
spinlock_t lock;
};
@@ -91,6 +93,8 @@ static int rzg2l_usbphy_ctrl_status(struct reset_controller_dev *rcdev,
return !!(readl(priv->base + RESET) & port_mask);
}
+#define RZG2L_USBPHY_CTRL_PWRRDY 1
+
static const struct of_device_id rzg2l_usbphy_ctrl_match_table[] = {
{ .compatible = "renesas,rzg2l-usbphy-ctrl" },
{ /* Sentinel */ }
@@ -110,6 +114,40 @@ static const struct regmap_config rzg2l_usb_regconf = {
.max_register = 1,
};
+static void rzg2l_usbphy_ctrl_set_pwrrdy(struct rzg2l_usbphy_ctrl_priv *priv,
+ bool power_on)
+{
+ struct rz_sysc_signal_map *pwrrdy = priv->pwrrdy;
+
+ regmap_update_bits(pwrrdy->regmap, pwrrdy->offset, pwrrdy->mask, !power_on);
+}
+
+static void rzg2l_usbphy_ctrl_pwrrdy_off(void *data)
+{
+ rzg2l_usbphy_ctrl_set_pwrrdy(data, false);
+}
+
+static int rzg2l_usbphy_ctrl_pwrrdy_init(struct device *dev,
+ struct rzg2l_usbphy_ctrl_priv *priv)
+{
+ struct rz_sysc_signal_map *pwrrdy;
+ const int *data;
+
+ data = device_get_match_data(dev);
+ if (data != (int *)RZG2L_USBPHY_CTRL_PWRRDY)
+ return 0;
+
+ pwrrdy = rz_sysc_get_signal_map(dev);
+ if (IS_ERR(pwrrdy))
+ return PTR_ERR(pwrrdy);
+
+ priv->pwrrdy = pwrrdy;
+
+ rzg2l_usbphy_ctrl_set_pwrrdy(priv, true);
+
+ return devm_add_action_or_reset(dev, rzg2l_usbphy_ctrl_pwrrdy_off, priv);
+}
+
static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -132,6 +170,10 @@ static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev)
if (IS_ERR(regmap))
return PTR_ERR(regmap);
+ error = rzg2l_usbphy_ctrl_pwrrdy_init(dev, priv);
+ if (error)
+ return error;
+
priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
if (IS_ERR(priv->rstc))
return dev_err_probe(dev, PTR_ERR(priv->rstc),
--
2.43.0
Powered by blists - more mailing lists