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

phy: renesas: phy-rcar-gen3-usb2: Add USB2.0 PHY support for RZ/G2L

This patch adds USB2.0 PHY support for RZ/G2L SoC.

We need to use a different compatible string due to some differences
with R-Car Gen3 USB2.0 PHY. It uses line ctrl register for OTG_ID
pin changes and different OTG-BC interrupt bit for device recognition.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> # on R-Car
Link: https://lore.kernel.org/r/20210727185527.19907-4-biju.das.jz@bp.renesas.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Biju Das and committed by
Vinod Koul
b0512a6e 5711af41

+73 -24
+73 -24
drivers/phy/renesas/phy-rcar-gen3-usb2.c
··· 64 64 /* VBCTRL */ 65 65 #define USB2_VBCTRL_OCCLREN BIT(16) 66 66 #define USB2_VBCTRL_DRVVBUSSEL BIT(8) 67 + #define USB2_VBCTRL_VBOUT BIT(0) 67 68 68 69 /* LINECTRL1 */ 69 70 #define USB2_LINECTRL1_DPRPD_EN BIT(19) ··· 78 77 #define USB2_ADPCTRL_IDDIG BIT(19) 79 78 #define USB2_ADPCTRL_IDPULLUP BIT(5) /* 1 = ID sampling is enabled */ 80 79 #define USB2_ADPCTRL_DRVVBUS BIT(4) 80 + 81 + /* RZ/G2L specific */ 82 + #define USB2_OBINT_IDCHG_EN BIT(0) 83 + #define USB2_LINECTRL1_USB2_IDMON BIT(0) 81 84 82 85 #define NUM_OF_PHYS 4 83 86 enum rcar_gen3_phy_index { ··· 117 112 struct mutex lock; /* protects rphys[...].powered */ 118 113 enum usb_dr_mode dr_mode; 119 114 int irq; 115 + u32 obint_enable_bits; 120 116 bool extcon_host; 121 117 bool is_otg_channel; 122 118 bool uses_otg_pins; 119 + bool soc_no_adp_ctrl; 120 + }; 121 + 122 + struct rcar_gen3_phy_drv_data { 123 + const struct phy_ops *phy_usb2_ops; 124 + bool no_adp_ctrl; 123 125 }; 124 126 125 127 /* ··· 184 172 static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus) 185 173 { 186 174 void __iomem *usb2_base = ch->base; 187 - u32 val = readl(usb2_base + USB2_ADPCTRL); 175 + u32 vbus_ctrl_reg = USB2_ADPCTRL; 176 + u32 vbus_ctrl_val = USB2_ADPCTRL_DRVVBUS; 177 + u32 val; 188 178 189 179 dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus); 180 + if (ch->soc_no_adp_ctrl) { 181 + vbus_ctrl_reg = USB2_VBCTRL; 182 + vbus_ctrl_val = USB2_VBCTRL_VBOUT; 183 + } 184 + 185 + val = readl(usb2_base + vbus_ctrl_reg); 190 186 if (vbus) 191 - val |= USB2_ADPCTRL_DRVVBUS; 187 + val |= vbus_ctrl_val; 192 188 else 193 - val &= ~USB2_ADPCTRL_DRVVBUS; 194 - writel(val, usb2_base + USB2_ADPCTRL); 189 + val &= ~vbus_ctrl_val; 190 + writel(val, usb2_base + vbus_ctrl_reg); 195 191 } 196 192 197 193 static void rcar_gen3_control_otg_irq(struct rcar_gen3_chan *ch, int enable) ··· 208 188 u32 val = readl(usb2_base + USB2_OBINTEN); 209 189 210 190 if (ch->uses_otg_pins && enable) 211 - val |= USB2_OBINT_BITS; 191 + val |= ch->obint_enable_bits; 212 192 else 213 - val &= ~USB2_OBINT_BITS; 193 + val &= ~ch->obint_enable_bits; 214 194 writel(val, usb2_base + USB2_OBINTEN); 215 195 } 216 196 ··· 271 251 { 272 252 if (!ch->uses_otg_pins) 273 253 return (ch->dr_mode == USB_DR_MODE_HOST) ? false : true; 254 + 255 + if (ch->soc_no_adp_ctrl) 256 + return !!(readl(ch->base + USB2_LINECTRL1) & USB2_LINECTRL1_USB2_IDMON); 274 257 275 258 return !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG); 276 259 } ··· 399 376 USB2_LINECTRL1_DMRPD_EN | USB2_LINECTRL1_DM_RPD; 400 377 writel(val, usb2_base + USB2_LINECTRL1); 401 378 402 - val = readl(usb2_base + USB2_VBCTRL); 403 - val &= ~USB2_VBCTRL_OCCLREN; 404 - writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL); 405 - val = readl(usb2_base + USB2_ADPCTRL); 406 - writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL); 407 - 379 + if (!ch->soc_no_adp_ctrl) { 380 + val = readl(usb2_base + USB2_VBCTRL); 381 + val &= ~USB2_VBCTRL_OCCLREN; 382 + writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL); 383 + val = readl(usb2_base + USB2_ADPCTRL); 384 + writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL); 385 + } 408 386 msleep(20); 409 387 410 388 writel(0xffffffff, usb2_base + USB2_OBINTSTA); 411 - writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTEN); 389 + writel(ch->obint_enable_bits, usb2_base + USB2_OBINTEN); 412 390 413 391 rcar_gen3_device_recognition(ch); 414 392 } ··· 421 397 u32 status = readl(usb2_base + USB2_OBINTSTA); 422 398 irqreturn_t ret = IRQ_NONE; 423 399 424 - if (status & USB2_OBINT_BITS) { 400 + if (status & ch->obint_enable_bits) { 425 401 dev_vdbg(ch->dev, "%s: %08x\n", __func__, status); 426 - writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA); 402 + writel(ch->obint_enable_bits, usb2_base + USB2_OBINTSTA); 427 403 rcar_gen3_device_recognition(ch); 428 404 ret = IRQ_HANDLED; 429 405 } ··· 559 535 .owner = THIS_MODULE, 560 536 }; 561 537 538 + static const struct rcar_gen3_phy_drv_data rcar_gen3_phy_usb2_data = { 539 + .phy_usb2_ops = &rcar_gen3_phy_usb2_ops, 540 + .no_adp_ctrl = false, 541 + }; 542 + 543 + static const struct rcar_gen3_phy_drv_data rz_g1c_phy_usb2_data = { 544 + .phy_usb2_ops = &rz_g1c_phy_usb2_ops, 545 + .no_adp_ctrl = false, 546 + }; 547 + 548 + static const struct rcar_gen3_phy_drv_data rz_g2l_phy_usb2_data = { 549 + .phy_usb2_ops = &rcar_gen3_phy_usb2_ops, 550 + .no_adp_ctrl = true, 551 + }; 552 + 562 553 static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = { 563 554 { 564 555 .compatible = "renesas,usb2-phy-r8a77470", 565 - .data = &rz_g1c_phy_usb2_ops, 556 + .data = &rz_g1c_phy_usb2_data, 566 557 }, 567 558 { 568 559 .compatible = "renesas,usb2-phy-r8a7795", 569 - .data = &rcar_gen3_phy_usb2_ops, 560 + .data = &rcar_gen3_phy_usb2_data, 570 561 }, 571 562 { 572 563 .compatible = "renesas,usb2-phy-r8a7796", 573 - .data = &rcar_gen3_phy_usb2_ops, 564 + .data = &rcar_gen3_phy_usb2_data, 574 565 }, 575 566 { 576 567 .compatible = "renesas,usb2-phy-r8a77965", 577 - .data = &rcar_gen3_phy_usb2_ops, 568 + .data = &rcar_gen3_phy_usb2_data, 569 + }, 570 + { 571 + .compatible = "renesas,rzg2l-usb2-phy", 572 + .data = &rz_g2l_phy_usb2_data, 578 573 }, 579 574 { 580 575 .compatible = "renesas,rcar-gen3-usb2-phy", 581 - .data = &rcar_gen3_phy_usb2_ops, 576 + .data = &rcar_gen3_phy_usb2_data, 582 577 }, 583 578 { /* sentinel */ }, 584 579 }; ··· 651 608 652 609 static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) 653 610 { 611 + const struct rcar_gen3_phy_drv_data *phy_data; 654 612 struct device *dev = &pdev->dev; 655 613 struct rcar_gen3_chan *channel; 656 614 struct phy_provider *provider; 657 - const struct phy_ops *phy_usb2_ops; 658 615 int ret = 0, i; 659 616 660 617 if (!dev->of_node) { ··· 670 627 if (IS_ERR(channel->base)) 671 628 return PTR_ERR(channel->base); 672 629 630 + channel->obint_enable_bits = USB2_OBINT_BITS; 673 631 /* get irq number here and request_irq for OTG in phy_init */ 674 632 channel->irq = platform_get_irq_optional(pdev, 0); 675 633 channel->dr_mode = rcar_gen3_get_dr_mode(dev->of_node); ··· 697 653 * And then, phy-core will manage runtime pm for this device. 698 654 */ 699 655 pm_runtime_enable(dev); 700 - phy_usb2_ops = of_device_get_match_data(dev); 701 - if (!phy_usb2_ops) { 656 + 657 + phy_data = of_device_get_match_data(dev); 658 + if (!phy_data) { 702 659 ret = -EINVAL; 703 660 goto error; 704 661 } 705 662 663 + channel->soc_no_adp_ctrl = phy_data->no_adp_ctrl; 664 + if (phy_data->no_adp_ctrl) 665 + channel->obint_enable_bits = USB2_OBINT_IDCHG_EN; 666 + 706 667 mutex_init(&channel->lock); 707 668 for (i = 0; i < NUM_OF_PHYS; i++) { 708 669 channel->rphys[i].phy = devm_phy_create(dev, NULL, 709 - phy_usb2_ops); 670 + phy_data->phy_usb2_ops); 710 671 if (IS_ERR(channel->rphys[i].phy)) { 711 672 dev_err(dev, "Failed to create USB2 PHY\n"); 712 673 ret = PTR_ERR(channel->rphys[i].phy);