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.

at v6.19-rc7 259 lines 7.1 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Renesas RZ/G3E USB3.0 PHY driver 4 * 5 * Copyright (C) 2025 Renesas Electronics Corporation 6 */ 7 8#include <linux/bitfield.h> 9#include <linux/delay.h> 10#include <linux/io.h> 11#include <linux/iopoll.h> 12#include <linux/module.h> 13#include <linux/of.h> 14#include <linux/phy/phy.h> 15#include <linux/platform_device.h> 16#include <linux/pm_runtime.h> 17#include <linux/reset.h> 18 19#define USB3_TEST_RESET 0x0000 20#define USB3_TEST_UTMICTRL2 0x0b04 21#define USB3_TEST_PRMCTRL5_R 0x0c10 22#define USB3_TEST_PRMCTRL6_R 0x0c14 23 24#define USB3_TEST_RSTCTRL 0x1000 25#define USB3_TEST_CLKCTRL 0x1004 26#define USB3_TEST_RAMCTRL 0x100c 27#define USB3_TEST_CREGCTRL 0x1010 28#define USB3_TEST_LANECONFIG0 0x1030 29 30#define USB3_TEST_RESET_PORTRESET0_CTRL BIT(9) 31#define USB3_TEST_RESET_SIDDQ BIT(3) 32#define USB3_TEST_RESET_PHY_RESET BIT(2) 33#define USB3_TEST_RESET_PORTRESET0 BIT(1) 34#define USB3_TEST_RESET_RELEASE_OVERRIDE (0) 35 36#define USB3_TEST_UTMICTRL2_CTRL_MASK GENMASK(9, 8) 37#define USB3_TEST_UTMICTRL2_MODE_MASK GENMASK(1, 0) 38 39#define USB3_TEST_PRMCTRL5_R_TXPREEMPAMPTUNE0_MASK GENMASK(2, 1) 40 41#define USB3_TEST_PRMCTRL6_R_OTGTUNE0_MASK GENMASK(2, 0) 42 43#define USB3_TEST_RSTCTRL_HARDRESET_ODEN BIT(9) 44#define USB3_TEST_RSTCTRL_PIPERESET_ODEN BIT(8) 45#define USB3_TEST_RSTCTRL_HARDRESET BIT(1) 46#define USB3_TEST_RSTCTRL_PIPERESET BIT(0) 47#define USB3_TEST_RSTCTRL_ASSERT \ 48 (USB3_TEST_RSTCTRL_HARDRESET_ODEN | USB3_TEST_RSTCTRL_PIPERESET_ODEN | \ 49 USB3_TEST_RSTCTRL_HARDRESET | USB3_TEST_RSTCTRL_PIPERESET) 50#define USB3_TEST_RSTCTRL_RELEASE_HARDRESET \ 51 (USB3_TEST_RSTCTRL_HARDRESET_ODEN | USB3_TEST_RSTCTRL_PIPERESET_ODEN | \ 52 USB3_TEST_RSTCTRL_PIPERESET) 53#define USB3_TEST_RSTCTRL_DEASSERT \ 54 (USB3_TEST_RSTCTRL_HARDRESET_ODEN | USB3_TEST_RSTCTRL_PIPERESET_ODEN) 55#define USB3_TEST_RSTCTRL_RELEASE_OVERRIDE (0) 56 57#define USB3_TEST_CLKCTRL_MPLLA_SSC_EN BIT(2) 58 59#define USB3_TEST_RAMCTRL_SRAM_INIT_DONE BIT(2) 60#define USB3_TEST_RAMCTRL_SRAM_EXT_LD_DONE BIT(0) 61 62#define USB3_TEST_CREGCTRL_PARA_SEL BIT(8) 63 64#define USB3_TEST_LANECONFIG0_DEFAULT (0xd) 65 66struct rz_usb3 { 67 void __iomem *base; 68 struct reset_control *rstc; 69 bool skip_reinit; 70}; 71 72static void rzg3e_phy_usb2test_phy_init(void __iomem *base) 73{ 74 u32 val; 75 76 val = readl(base + USB3_TEST_UTMICTRL2); 77 val |= USB3_TEST_UTMICTRL2_CTRL_MASK | USB3_TEST_UTMICTRL2_MODE_MASK; 78 writel(val, base + USB3_TEST_UTMICTRL2); 79 80 val = readl(base + USB3_TEST_PRMCTRL5_R); 81 val &= ~USB3_TEST_PRMCTRL5_R_TXPREEMPAMPTUNE0_MASK; 82 val |= FIELD_PREP(USB3_TEST_PRMCTRL5_R_TXPREEMPAMPTUNE0_MASK, 2); 83 writel(val, base + USB3_TEST_PRMCTRL5_R); 84 85 val = readl(base + USB3_TEST_PRMCTRL6_R); 86 val &= ~USB3_TEST_PRMCTRL6_R_OTGTUNE0_MASK; 87 val |= FIELD_PREP(USB3_TEST_PRMCTRL6_R_OTGTUNE0_MASK, 7); 88 writel(val, base + USB3_TEST_PRMCTRL6_R); 89 90 val = readl(base + USB3_TEST_RESET); 91 val &= ~USB3_TEST_RESET_SIDDQ; 92 val |= USB3_TEST_RESET_PORTRESET0_CTRL | USB3_TEST_RESET_PHY_RESET | 93 USB3_TEST_RESET_PORTRESET0; 94 writel(val, base + USB3_TEST_RESET); 95 fsleep(10); 96 97 val &= ~(USB3_TEST_RESET_PHY_RESET | USB3_TEST_RESET_PORTRESET0); 98 writel(val, base + USB3_TEST_RESET); 99 fsleep(10); 100 101 val = readl(base + USB3_TEST_UTMICTRL2); 102 val &= ~USB3_TEST_UTMICTRL2_CTRL_MASK; 103 writel(val, base + USB3_TEST_UTMICTRL2); 104 105 writel(USB3_TEST_RESET_RELEASE_OVERRIDE, base + USB3_TEST_RESET); 106} 107 108static int rzg3e_phy_usb3test_phy_init(void __iomem *base) 109{ 110 int ret; 111 u32 val; 112 113 writel(USB3_TEST_CREGCTRL_PARA_SEL, base + USB3_TEST_CREGCTRL); 114 writel(USB3_TEST_RSTCTRL_ASSERT, base + USB3_TEST_RSTCTRL); 115 fsleep(20); 116 117 writel(USB3_TEST_CLKCTRL_MPLLA_SSC_EN, base + USB3_TEST_CLKCTRL); 118 writel(USB3_TEST_LANECONFIG0_DEFAULT, base + USB3_TEST_LANECONFIG0); 119 writel(USB3_TEST_RSTCTRL_RELEASE_HARDRESET, base + USB3_TEST_RSTCTRL); 120 121 ret = readl_poll_timeout_atomic(base + USB3_TEST_RAMCTRL, val, 122 val & USB3_TEST_RAMCTRL_SRAM_INIT_DONE, 1, 10000); 123 if (ret) 124 return ret; 125 126 writel(USB3_TEST_RSTCTRL_DEASSERT, base + USB3_TEST_RSTCTRL); 127 writel(USB3_TEST_RAMCTRL_SRAM_EXT_LD_DONE, base + USB3_TEST_RAMCTRL); 128 writel(USB3_TEST_RSTCTRL_RELEASE_OVERRIDE, base + USB3_TEST_RSTCTRL); 129 130 return 0; 131} 132 133static int rzg3e_phy_usb3_init_helper(void __iomem *base) 134{ 135 rzg3e_phy_usb2test_phy_init(base); 136 137 return rzg3e_phy_usb3test_phy_init(base); 138} 139 140static int rzg3e_phy_usb3_init(struct phy *p) 141{ 142 struct rz_usb3 *r = phy_get_drvdata(p); 143 int ret = 0; 144 145 if (!r->skip_reinit) 146 ret = rzg3e_phy_usb3_init_helper(r->base); 147 148 return ret; 149} 150 151static const struct phy_ops rzg3e_phy_usb3_ops = { 152 .init = rzg3e_phy_usb3_init, 153 .owner = THIS_MODULE, 154}; 155 156static int rzg3e_phy_usb3_probe(struct platform_device *pdev) 157{ 158 struct device *dev = &pdev->dev; 159 struct phy_provider *provider; 160 struct rz_usb3 *r; 161 struct phy *phy; 162 int ret; 163 164 r = devm_kzalloc(dev, sizeof(*r), GFP_KERNEL); 165 if (!r) 166 return -ENOMEM; 167 168 r->base = devm_platform_ioremap_resource(pdev, 0); 169 if (IS_ERR(r->base)) 170 return PTR_ERR(r->base); 171 172 r->rstc = devm_reset_control_get_shared_deasserted(dev, NULL); 173 if (IS_ERR(r->rstc)) 174 return dev_err_probe(dev, PTR_ERR(r->rstc), "failed to get deasserted reset\n"); 175 176 /* 177 * devm_phy_create() will call pm_runtime_enable(&phy->dev); 178 * And then, phy-core will manage runtime pm for this device. 179 */ 180 ret = devm_pm_runtime_enable(dev); 181 if (ret < 0) 182 return ret; 183 184 phy = devm_phy_create(dev, NULL, &rzg3e_phy_usb3_ops); 185 if (IS_ERR(phy)) 186 return dev_err_probe(dev, PTR_ERR(phy), "failed to create USB3 PHY\n"); 187 188 platform_set_drvdata(pdev, r); 189 phy_set_drvdata(phy, r); 190 191 provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 192 if (IS_ERR(provider)) 193 return dev_err_probe(dev, PTR_ERR(provider), "failed to register PHY provider\n"); 194 195 return 0; 196} 197 198static int rzg3e_phy_usb3_suspend(struct device *dev) 199{ 200 struct rz_usb3 *r = dev_get_drvdata(dev); 201 202 pm_runtime_put(dev); 203 reset_control_assert(r->rstc); 204 r->skip_reinit = false; 205 206 return 0; 207} 208 209static int rzg3e_phy_usb3_resume(struct device *dev) 210{ 211 struct rz_usb3 *r = dev_get_drvdata(dev); 212 int ret; 213 214 ret = reset_control_deassert(r->rstc); 215 if (ret) 216 return ret; 217 218 ret = pm_runtime_resume_and_get(dev); 219 if (ret) 220 goto reset_assert; 221 222 ret = rzg3e_phy_usb3_init_helper(r->base); 223 if (ret) 224 goto pm_put; 225 226 r->skip_reinit = true; 227 228 return 0; 229 230pm_put: 231 pm_runtime_put(dev); 232reset_assert: 233 reset_control_assert(r->rstc); 234 return ret; 235} 236 237static const struct dev_pm_ops rzg3e_phy_usb3_pm = { 238 NOIRQ_SYSTEM_SLEEP_PM_OPS(rzg3e_phy_usb3_suspend, rzg3e_phy_usb3_resume) 239}; 240 241static const struct of_device_id rzg3e_phy_usb3_match_table[] = { 242 { .compatible = "renesas,r9a09g047-usb3-phy" }, 243 { /* Sentinel */ } 244}; 245 246MODULE_DEVICE_TABLE(of, rzg3e_phy_usb3_match_table); 247static struct platform_driver rzg3e_phy_usb3_driver = { 248 .driver = { 249 .name = "phy_rzg3e_usb3", 250 .of_match_table = rzg3e_phy_usb3_match_table, 251 .pm = pm_sleep_ptr(&rzg3e_phy_usb3_pm), 252 }, 253 .probe = rzg3e_phy_usb3_probe, 254}; 255module_platform_driver(rzg3e_phy_usb3_driver); 256 257MODULE_LICENSE("GPL"); 258MODULE_DESCRIPTION("Renesas RZ/G3E USB3.0 PHY Driver"); 259MODULE_AUTHOR("biju.das.jz@bp.renesas.com>");