Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

phy: renesas: rcar-gen3-usb2: Add support for RZ/T2H SoC

Add initial support for the Renesas RZ/T2H SoC to the R-Car Gen3 USB2 PHY
driver. The RZ/T2H SoC requires configuration of additional
hardware-specific bits for proper VBUS level control and OTG operation.

Introduce the `vblvl_ctrl` flag in the SoC-specific driver data to enable
handling of VBUS level selection logic using `VBCTRL.VBLVL` bits. This is
required for managing the VBUS status detection and drive logic based on
SoC-specific needs.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Link: https://lore.kernel.org/r/20250808215209.3692744-5-prabhakar.mahadev-lad.rj@bp.renesas.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Lad Prabhakar and committed by
Vinod Koul
b725741f 4b7aa47e

+75 -7
+75 -7
drivers/phy/renesas/phy-rcar-gen3-usb2.c
··· 9 9 * Copyright (C) 2014 Cogent Embedded, Inc. 10 10 */ 11 11 12 + #include <linux/bitfield.h> 13 + #include <linux/bits.h> 12 14 #include <linux/cleanup.h> 13 15 #include <linux/extcon-provider.h> 14 16 #include <linux/interrupt.h> ··· 71 69 #define USB2_COMMCTRL_OTG_PERI BIT(31) /* 1 = Peripheral mode */ 72 70 73 71 /* OBINTSTA and OBINTEN */ 72 + #define USB2_OBINTSTA_CLEAR GENMASK(31, 0) 74 73 #define USB2_OBINT_SESSVLDCHG BIT(12) 75 74 #define USB2_OBINT_IDDIGCHG BIT(11) 75 + #define USB2_OBINT_VBSTAINT BIT(3) 76 76 #define USB2_OBINT_IDCHG_EN BIT(0) /* RZ/G2L specific */ 77 77 78 78 /* VBCTRL */ 79 + #define USB2_VBCTRL_VBSTA_MASK GENMASK(31, 28) 80 + #define USB2_VBCTRL_VBSTA_DEFAULT 2 81 + #define USB2_VBCTRL_VBLVL_MASK GENMASK(23, 20) 82 + #define USB2_VBCTRL_VBLVL(m) FIELD_PREP_CONST(USB2_VBCTRL_VBLVL_MASK, (m)) 79 83 #define USB2_VBCTRL_OCCLREN BIT(16) 80 84 #define USB2_VBCTRL_DRVVBUSSEL BIT(8) 85 + #define USB2_VBCTRL_SIDDQREL BIT(2) 81 86 #define USB2_VBCTRL_VBOUT BIT(0) 82 87 83 88 /* LINECTRL1 */ ··· 97 88 /* ADPCTRL */ 98 89 #define USB2_ADPCTRL_OTGSESSVLD BIT(20) 99 90 #define USB2_ADPCTRL_IDDIG BIT(19) 91 + #define USB2_ADPCTRL_VBUSVALID BIT(18) 100 92 #define USB2_ADPCTRL_IDPULLUP BIT(5) /* 1 = ID sampling is enabled */ 101 93 #define USB2_ADPCTRL_DRVVBUS BIT(4) 102 94 ··· 148 138 bool no_adp_ctrl; 149 139 bool init_bus; 150 140 bool utmi_ctrl; 141 + bool vblvl_ctrl; 151 142 u32 obint_enable_bits; 152 143 }; 153 144 ··· 212 201 u32 val; 213 202 214 203 dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus); 215 - if (ch->phy_data->no_adp_ctrl) { 204 + if (ch->phy_data->no_adp_ctrl || ch->phy_data->vblvl_ctrl) { 216 205 if (ch->vbus) 217 206 regulator_hardware_enable(ch->vbus, vbus); 218 207 ··· 295 284 296 285 static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch) 297 286 { 287 + if (ch->phy_data->vblvl_ctrl) { 288 + bool vbus_valid; 289 + bool device; 290 + 291 + device = !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG); 292 + vbus_valid = !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_VBUSVALID); 293 + 294 + return !(device && !vbus_valid); 295 + } 296 + 298 297 if (!ch->uses_otg_pins) 299 298 return (ch->dr_mode == USB_DR_MODE_HOST) ? false : true; 300 299 ··· 440 419 writel(val, usb2_base + USB2_LINECTRL1); 441 420 442 421 if (!ch->phy_data->no_adp_ctrl) { 443 - val = readl(usb2_base + USB2_VBCTRL); 444 - val &= ~USB2_VBCTRL_OCCLREN; 445 - writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL); 446 - val = readl(usb2_base + USB2_ADPCTRL); 447 - writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL); 422 + if (ch->phy_data->vblvl_ctrl) { 423 + val = readl(usb2_base + USB2_VBCTRL); 424 + val = (val & ~USB2_VBCTRL_VBLVL_MASK) | USB2_VBCTRL_VBLVL(2); 425 + writel(val, usb2_base + USB2_VBCTRL); 426 + val = readl(usb2_base + USB2_ADPCTRL); 427 + writel(val | USB2_ADPCTRL_IDPULLUP | USB2_ADPCTRL_DRVVBUS, 428 + usb2_base + USB2_ADPCTRL); 429 + } else { 430 + val = readl(usb2_base + USB2_VBCTRL); 431 + val &= ~USB2_VBCTRL_OCCLREN; 432 + writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL); 433 + val = readl(usb2_base + USB2_ADPCTRL); 434 + writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL); 435 + } 448 436 } 449 437 mdelay(20); 450 438 ··· 461 431 writel(ch->phy_data->obint_enable_bits, usb2_base + USB2_OBINTEN); 462 432 463 433 rcar_gen3_device_recognition(ch); 434 + } 435 + 436 + static void rcar_gen3_configure_vblvl_ctrl(struct rcar_gen3_chan *ch) 437 + { 438 + void __iomem *usb2_base = ch->base; 439 + u32 val; 440 + 441 + if (!ch->phy_data->vblvl_ctrl) 442 + return; 443 + 444 + val = readl(usb2_base + USB2_VBCTRL); 445 + if ((val & USB2_VBCTRL_VBSTA_MASK) == 446 + FIELD_PREP_CONST(USB2_VBCTRL_VBSTA_MASK, USB2_VBCTRL_VBSTA_DEFAULT)) 447 + val &= ~USB2_VBCTRL_VBLVL_MASK; 448 + else 449 + val |= USB2_VBCTRL_VBLVL(USB2_VBCTRL_VBSTA_DEFAULT); 450 + writel(val, usb2_base + USB2_VBCTRL); 464 451 } 465 452 466 453 static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch) ··· 497 450 status = readl(usb2_base + USB2_OBINTSTA); 498 451 if (status & ch->phy_data->obint_enable_bits) { 499 452 dev_vdbg(dev, "%s: %08x\n", __func__, status); 500 - writel(ch->phy_data->obint_enable_bits, usb2_base + USB2_OBINTSTA); 453 + if (ch->phy_data->vblvl_ctrl) 454 + writel(USB2_OBINTSTA_CLEAR, usb2_base + USB2_OBINTSTA); 455 + else 456 + writel(ch->phy_data->obint_enable_bits, usb2_base + USB2_OBINTSTA); 501 457 rcar_gen3_device_recognition(ch); 458 + rcar_gen3_configure_vblvl_ctrl(ch); 502 459 ret = IRQ_HANDLED; 503 460 } 504 461 } ··· 534 483 /* Initialize otg part (only if we initialize a PHY with IRQs). */ 535 484 if (rphy->int_enable_bits) 536 485 rcar_gen3_init_otg(channel); 486 + 487 + if (channel->phy_data->vblvl_ctrl) { 488 + /* SIDDQ mode release */ 489 + writel(readl(usb2_base + USB2_VBCTRL) | USB2_VBCTRL_SIDDQREL, 490 + usb2_base + USB2_VBCTRL); 491 + udelay(250); 492 + } 537 493 538 494 if (channel->phy_data->utmi_ctrl) { 539 495 val = readl(usb2_base + USB2_REGEN_CG_CTRL) | USB2_REGEN_CG_CTRL_UPHY_WEN; ··· 671 613 .obint_enable_bits = USB2_OBINT_IDCHG_EN, 672 614 }; 673 615 616 + static const struct rcar_gen3_phy_drv_data rz_t2h_phy_usb2_data = { 617 + .phy_usb2_ops = &rcar_gen3_phy_usb2_ops, 618 + .vblvl_ctrl = true, 619 + .obint_enable_bits = USB2_OBINT_IDCHG_EN | USB2_OBINT_VBSTAINT, 620 + }; 621 + 674 622 static const struct rcar_gen3_phy_drv_data rz_v2h_phy_usb2_data = { 675 623 .phy_usb2_ops = &rcar_gen3_phy_usb2_ops, 676 624 .no_adp_ctrl = true, ··· 708 644 { 709 645 .compatible = "renesas,usb2-phy-r9a09g057", 710 646 .data = &rz_v2h_phy_usb2_data, 647 + }, 648 + { 649 + .compatible = "renesas,usb2-phy-r9a09g077", 650 + .data = &rz_t2h_phy_usb2_data, 711 651 }, 712 652 { 713 653 .compatible = "renesas,rzg2l-usb2-phy",