]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
phy: renesas: phy-rcar-gen3-usb2: Add USB2.0 PHY support for RZ/V2H(P)
authorLad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Mon, 14 Apr 2025 14:57:29 +0000 (15:57 +0100)
committerVinod Koul <vkoul@kernel.org>
Wed, 14 May 2025 11:14:59 +0000 (12:14 +0100)
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@bp.renesas.com>
Link: https://lore.kernel.org/r/20250414145729.343133-5-prabhakar.mahadev-lad.rj@bp.renesas.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/phy/renesas/phy-rcar-gen3-usb2.c

index 10d1a89558be18b092d8ca83c6143ff25ef04fee..867f43132b7a3a9514d4f6856a4a89f6181c1ab5 100644 (file)
 #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
 #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,