[PATCH 4/4] phy: renesas: phy-rcar-gen3-usb2: Add USB2.0 PHY support for RZ/V2H(P)

From: Prabhakar
Date: Mon Apr 14 2025 - 11:04:54 EST


From: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx>

Add USB2.0 PHY support for RZ/V2H(P) SoC.

On the RZ/V2H(P) SoC we need to configure the UTMI to a specific value
as compared to other SoCs (which doesn't need configuring it).

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx>
---
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 30 ++++++++++++++++++++++++
1 file changed, 30 insertions(+)

diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 10d1a89558be..867f43132b7a 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -28,8 +28,10 @@
#define USB2_INT_ENABLE 0x000
#define USB2_AHB_BUS_CTR 0x008
#define USB2_USBCTR 0x00c
+#define USB2_REGEN_CG_CTRL 0x104 /* RZ/V2H(P) only */
#define USB2_SPD_RSM_TIMSET 0x10c
#define USB2_OC_TIMSET 0x110
+#define USB2_UTMI_CTRL 0x118 /* RZ/V2H(P) only */
#define USB2_COMMCTRL 0x600
#define USB2_OBINTSTA 0x604
#define USB2_OBINTEN 0x608
@@ -50,12 +52,18 @@
#define USB2_USBCTR_DIRPD BIT(2)
#define USB2_USBCTR_PLL_RST BIT(1)

+/* REGEN_CG_CTRL*/
+#define USB2_REGEN_CG_CTRL_UPHY_WEN BIT(0)
+
/* SPD_RSM_TIMSET */
#define USB2_SPD_RSM_TIMSET_INIT 0x014e029b

/* OC_TIMSET */
#define USB2_OC_TIMSET_INIT 0x000209ab

+/* UTMI_CTRL */
+#define USB2_UTMI_CTRL_INIT 0x8000018f
+
/* COMMCTRL */
#define USB2_COMMCTRL_OTG_PERI BIT(31) /* 1 = Peripheral mode */

@@ -127,12 +135,14 @@ struct rcar_gen3_chan {
bool is_otg_channel;
bool uses_otg_pins;
bool soc_no_adp_ctrl;
+ bool utmi_ctrl;
};

struct rcar_gen3_phy_drv_data {
const struct phy_ops *phy_usb2_ops;
bool no_adp_ctrl;
bool init_bus;
+ bool utmi_ctrl;
};

/*
@@ -472,6 +482,14 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)
rphy->otg_initialized = true;
}

+ if (channel->utmi_ctrl) {
+ val = readl(usb2_base + USB2_REGEN_CG_CTRL) | USB2_REGEN_CG_CTRL_UPHY_WEN;
+ writel(val, usb2_base + USB2_REGEN_CG_CTRL);
+
+ writel(USB2_UTMI_CTRL_INIT, usb2_base + USB2_UTMI_CTRL);
+ writel(val & ~USB2_REGEN_CG_CTRL_UPHY_WEN, usb2_base + USB2_REGEN_CG_CTRL);
+ }
+
rphy->initialized = true;

return 0;
@@ -589,6 +607,12 @@ static const struct rcar_gen3_phy_drv_data rz_g3s_phy_usb2_data = {
.init_bus = true,
};

+static const struct rcar_gen3_phy_drv_data rz_v2h_phy_usb2_data = {
+ .phy_usb2_ops = &rcar_gen3_phy_usb2_ops,
+ .no_adp_ctrl = true,
+ .utmi_ctrl = true,
+};
+
static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = {
{
.compatible = "renesas,usb2-phy-r8a77470",
@@ -610,6 +634,10 @@ static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = {
.compatible = "renesas,usb2-phy-r9a08g045",
.data = &rz_g3s_phy_usb2_data,
},
+ {
+ .compatible = "renesas,usb2-phy-r9a09g057",
+ .data = &rz_v2h_phy_usb2_data,
+ },
{
.compatible = "renesas,rzg2l-usb2-phy",
.data = &rz_g2l_phy_usb2_data,
@@ -763,6 +791,8 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
if (phy_data->no_adp_ctrl)
channel->obint_enable_bits = USB2_OBINT_IDCHG_EN;

+ channel->utmi_ctrl = phy_data->utmi_ctrl;
+
mutex_init(&channel->lock);
for (i = 0; i < NUM_OF_PHYS; i++) {
channel->rphys[i].phy = devm_phy_create(dev, NULL,
--
2.49.0