1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Rockchip usb PHY driver 4 * 5 * Copyright (C) 2014 Yunzhi Li <lyz@rock-chips.com> 6 * Copyright (C) 2014 ROCKCHIP, Inc. 7 */ 8 9 #include <linux/clk.h> 10 #include <linux/clk-provider.h> 11 #include <linux/io.h> 12 #include <linux/kernel.h> 13 #include <linux/module.h> 14 #include <linux/mutex.h> 15 #include <linux/of.h> 16 #include <linux/phy/phy.h> 17 #include <linux/platform_device.h> 18 #include <linux/property.h> 19 #include <linux/regulator/consumer.h> 20 #include <linux/reset.h> 21 #include <linux/regmap.h> 22 #include <linux/mfd/syscon.h> 23 #include <linux/delay.h> 24 25 static int enable_usb_uart; 26 27 #define HIWORD_UPDATE(val, mask) \ 28 ((val) | (mask) << 16) 29 30 #define UOC_CON0 0x00 31 #define UOC_CON0_SIDDQ BIT(13) 32 #define UOC_CON0_DISABLE BIT(4) 33 #define UOC_CON0_COMMON_ON_N BIT(0) 34 35 #define UOC_CON2 0x08 36 #define UOC_CON2_SOFT_CON_SEL BIT(2) 37 38 #define UOC_CON3 0x0c 39 /* bits present on rk3188 and rk3288 phys */ 40 #define UOC_CON3_UTMI_TERMSEL_FULLSPEED BIT(5) 41 #define UOC_CON3_UTMI_XCVRSEELCT_FSTRANSC (1 << 3) 42 #define UOC_CON3_UTMI_XCVRSEELCT_MASK (3 << 3) 43 #define UOC_CON3_UTMI_OPMODE_NODRIVING (1 << 1) 44 #define UOC_CON3_UTMI_OPMODE_MASK (3 << 1) 45 #define UOC_CON3_UTMI_SUSPENDN BIT(0) 46 47 struct rockchip_usb_phys { 48 int reg; 49 const char *pll_name; 50 }; 51 52 struct rockchip_usb_phy_base; 53 struct rockchip_usb_phy_pdata { 54 struct rockchip_usb_phys *phys; 55 int (*init_usb_uart)(struct regmap *grf, 56 const struct rockchip_usb_phy_pdata *pdata); 57 int usb_uart_phy; 58 }; 59 60 struct rockchip_usb_phy_base { 61 struct device *dev; 62 struct regmap *reg_base; 63 const struct rockchip_usb_phy_pdata *pdata; 64 }; 65 66 struct rockchip_usb_phy { 67 struct rockchip_usb_phy_base *base; 68 struct device_node *np; 69 unsigned int reg_offset; 70 struct clk *clk; 71 struct clk *clk480m; 72 struct clk_hw clk480m_hw; 73 struct phy *phy; 74 bool uart_enabled; 75 struct reset_control *reset; 76 struct regulator *vbus; 77 }; 78 79 static int rockchip_usb_phy_power(struct rockchip_usb_phy *phy, 80 bool siddq) 81 { 82 u32 val = HIWORD_UPDATE(siddq ? UOC_CON0_SIDDQ : 0, UOC_CON0_SIDDQ); 83 84 return regmap_write(phy->base->reg_base, phy->reg_offset, val); 85 } 86 87 static unsigned long rockchip_usb_phy480m_recalc_rate(struct clk_hw *hw, 88 unsigned long parent_rate) 89 { 90 return 480000000; 91 } 92 93 static void rockchip_usb_phy480m_disable(struct clk_hw *hw) 94 { 95 struct rockchip_usb_phy *phy = container_of(hw, 96 struct rockchip_usb_phy, 97 clk480m_hw); 98 99 if (phy->vbus) 100 regulator_disable(phy->vbus); 101 102 /* Power down usb phy analog blocks by set siddq 1 */ 103 rockchip_usb_phy_power(phy, 1); 104 } 105 106 static int rockchip_usb_phy480m_enable(struct clk_hw *hw) 107 { 108 struct rockchip_usb_phy *phy = container_of(hw, 109 struct rockchip_usb_phy, 110 clk480m_hw); 111 112 /* Power up usb phy analog blocks by set siddq 0 */ 113 return rockchip_usb_phy_power(phy, 0); 114 } 115 116 static int rockchip_usb_phy480m_is_enabled(struct clk_hw *hw) 117 { 118 struct rockchip_usb_phy *phy = container_of(hw, 119 struct rockchip_usb_phy, 120 clk480m_hw); 121 int ret; 122 u32 val; 123 124 ret = regmap_read(phy->base->reg_base, phy->reg_offset, &val); 125 if (ret < 0) 126 return ret; 127 128 return (val & UOC_CON0_SIDDQ) ? 0 : 1; 129 } 130 131 static const struct clk_ops rockchip_usb_phy480m_ops = { 132 .enable = rockchip_usb_phy480m_enable, 133 .disable = rockchip_usb_phy480m_disable, 134 .is_enabled = rockchip_usb_phy480m_is_enabled, 135 .recalc_rate = rockchip_usb_phy480m_recalc_rate, 136 }; 137 138 static int rockchip_usb_phy_power_off(struct phy *_phy) 139 { 140 struct rockchip_usb_phy *phy = phy_get_drvdata(_phy); 141 142 if (phy->uart_enabled) 143 return -EBUSY; 144 145 clk_disable_unprepare(phy->clk480m); 146 147 return 0; 148 } 149 150 static int rockchip_usb_phy_power_on(struct phy *_phy) 151 { 152 struct rockchip_usb_phy *phy = phy_get_drvdata(_phy); 153 154 if (phy->uart_enabled) 155 return -EBUSY; 156 157 if (phy->vbus) { 158 int ret; 159 160 ret = regulator_enable(phy->vbus); 161 if (ret) 162 return ret; 163 } 164 165 return clk_prepare_enable(phy->clk480m); 166 } 167 168 static int rockchip_usb_phy_reset(struct phy *_phy) 169 { 170 struct rockchip_usb_phy *phy = phy_get_drvdata(_phy); 171 172 if (phy->reset) { 173 reset_control_assert(phy->reset); 174 udelay(10); 175 reset_control_deassert(phy->reset); 176 } 177 178 return 0; 179 } 180 181 static const struct phy_ops ops = { 182 .power_on = rockchip_usb_phy_power_on, 183 .power_off = rockchip_usb_phy_power_off, 184 .reset = rockchip_usb_phy_reset, 185 .owner = THIS_MODULE, 186 }; 187 188 static void rockchip_usb_phy_action(void *data) 189 { 190 struct rockchip_usb_phy *rk_phy = data; 191 192 if (!rk_phy->uart_enabled) { 193 of_clk_del_provider(rk_phy->np); 194 clk_unregister(rk_phy->clk480m); 195 } 196 197 if (rk_phy->clk) 198 clk_put(rk_phy->clk); 199 } 200 201 static int rockchip_usb_phy_init(struct rockchip_usb_phy_base *base, 202 struct device_node *child) 203 { 204 struct rockchip_usb_phy *rk_phy; 205 unsigned int reg_offset; 206 const char *clk_name; 207 struct clk_init_data init; 208 int err, i; 209 210 rk_phy = devm_kzalloc(base->dev, sizeof(*rk_phy), GFP_KERNEL); 211 if (!rk_phy) 212 return -ENOMEM; 213 214 rk_phy->base = base; 215 rk_phy->np = child; 216 217 if (of_property_read_u32(child, "reg", ®_offset)) { 218 dev_err(base->dev, "missing reg property in node %pOFn\n", 219 child); 220 return -EINVAL; 221 } 222 223 rk_phy->reset = of_reset_control_get(child, "phy-reset"); 224 if (IS_ERR(rk_phy->reset)) 225 rk_phy->reset = NULL; 226 227 rk_phy->reg_offset = reg_offset; 228 229 rk_phy->clk = of_clk_get_by_name(child, "phyclk"); 230 if (IS_ERR(rk_phy->clk)) 231 rk_phy->clk = NULL; 232 233 i = 0; 234 init.name = NULL; 235 while (base->pdata->phys[i].reg) { 236 if (base->pdata->phys[i].reg == reg_offset) { 237 init.name = base->pdata->phys[i].pll_name; 238 break; 239 } 240 i++; 241 } 242 243 if (!init.name) { 244 dev_err(base->dev, "phy data not found\n"); 245 return -EINVAL; 246 } 247 248 if (enable_usb_uart && base->pdata->usb_uart_phy == i) { 249 dev_dbg(base->dev, "phy%d used as uart output\n", i); 250 rk_phy->uart_enabled = true; 251 } else { 252 if (rk_phy->clk) { 253 clk_name = __clk_get_name(rk_phy->clk); 254 init.flags = 0; 255 init.parent_names = &clk_name; 256 init.num_parents = 1; 257 } else { 258 init.flags = 0; 259 init.parent_names = NULL; 260 init.num_parents = 0; 261 } 262 263 init.ops = &rockchip_usb_phy480m_ops; 264 rk_phy->clk480m_hw.init = &init; 265 266 rk_phy->clk480m = clk_register(base->dev, &rk_phy->clk480m_hw); 267 if (IS_ERR(rk_phy->clk480m)) { 268 err = PTR_ERR(rk_phy->clk480m); 269 goto err_clk; 270 } 271 272 err = of_clk_add_provider(child, of_clk_src_simple_get, 273 rk_phy->clk480m); 274 if (err < 0) 275 goto err_clk_prov; 276 } 277 278 err = devm_add_action_or_reset(base->dev, rockchip_usb_phy_action, 279 rk_phy); 280 if (err) 281 return err; 282 283 rk_phy->phy = devm_phy_create(base->dev, child, &ops); 284 if (IS_ERR(rk_phy->phy)) { 285 dev_err(base->dev, "failed to create PHY\n"); 286 return PTR_ERR(rk_phy->phy); 287 } 288 phy_set_drvdata(rk_phy->phy, rk_phy); 289 290 rk_phy->vbus = devm_regulator_get_optional(&rk_phy->phy->dev, "vbus"); 291 if (IS_ERR(rk_phy->vbus)) { 292 if (PTR_ERR(rk_phy->vbus) == -EPROBE_DEFER) 293 return PTR_ERR(rk_phy->vbus); 294 rk_phy->vbus = NULL; 295 } 296 297 /* 298 * When acting as uart-pipe, just keep clock on otherwise 299 * only power up usb phy when it use, so disable it when init 300 */ 301 if (rk_phy->uart_enabled) 302 return clk_prepare_enable(rk_phy->clk); 303 else 304 return rockchip_usb_phy_power(rk_phy, 1); 305 306 err_clk_prov: 307 if (!rk_phy->uart_enabled) 308 clk_unregister(rk_phy->clk480m); 309 err_clk: 310 if (rk_phy->clk) 311 clk_put(rk_phy->clk); 312 return err; 313 } 314 315 static const struct rockchip_usb_phy_pdata rk3066a_pdata = { 316 .phys = (struct rockchip_usb_phys[]){ 317 { .reg = 0x17c, .pll_name = "sclk_otgphy0_480m" }, 318 { .reg = 0x188, .pll_name = "sclk_otgphy1_480m" }, 319 { /* sentinel */ } 320 }, 321 }; 322 323 static int __init rockchip_init_usb_uart_common(struct regmap *grf, 324 const struct rockchip_usb_phy_pdata *pdata) 325 { 326 int regoffs = pdata->phys[pdata->usb_uart_phy].reg; 327 int ret; 328 u32 val; 329 330 /* 331 * COMMON_ON and DISABLE settings are described in the TRM, 332 * but were not present in the original code. 333 * Also disable the analog phy components to save power. 334 */ 335 val = HIWORD_UPDATE(UOC_CON0_COMMON_ON_N 336 | UOC_CON0_DISABLE 337 | UOC_CON0_SIDDQ, 338 UOC_CON0_COMMON_ON_N 339 | UOC_CON0_DISABLE 340 | UOC_CON0_SIDDQ); 341 ret = regmap_write(grf, regoffs + UOC_CON0, val); 342 if (ret) 343 return ret; 344 345 val = HIWORD_UPDATE(UOC_CON2_SOFT_CON_SEL, 346 UOC_CON2_SOFT_CON_SEL); 347 ret = regmap_write(grf, regoffs + UOC_CON2, val); 348 if (ret) 349 return ret; 350 351 val = HIWORD_UPDATE(UOC_CON3_UTMI_OPMODE_NODRIVING 352 | UOC_CON3_UTMI_XCVRSEELCT_FSTRANSC 353 | UOC_CON3_UTMI_TERMSEL_FULLSPEED, 354 UOC_CON3_UTMI_SUSPENDN 355 | UOC_CON3_UTMI_OPMODE_MASK 356 | UOC_CON3_UTMI_XCVRSEELCT_MASK 357 | UOC_CON3_UTMI_TERMSEL_FULLSPEED); 358 ret = regmap_write(grf, UOC_CON3, val); 359 if (ret) 360 return ret; 361 362 return 0; 363 } 364 365 #define RK3188_UOC0_CON0 0x10c 366 #define RK3188_UOC0_CON0_BYPASSSEL BIT(9) 367 #define RK3188_UOC0_CON0_BYPASSDMEN BIT(8) 368 369 /* 370 * Enable the bypass of uart2 data through the otg usb phy. 371 * See description of rk3288-variant for details. 372 */ 373 static int __init rk3188_init_usb_uart(struct regmap *grf, 374 const struct rockchip_usb_phy_pdata *pdata) 375 { 376 u32 val; 377 int ret; 378 379 ret = rockchip_init_usb_uart_common(grf, pdata); 380 if (ret) 381 return ret; 382 383 val = HIWORD_UPDATE(RK3188_UOC0_CON0_BYPASSSEL 384 | RK3188_UOC0_CON0_BYPASSDMEN, 385 RK3188_UOC0_CON0_BYPASSSEL 386 | RK3188_UOC0_CON0_BYPASSDMEN); 387 ret = regmap_write(grf, RK3188_UOC0_CON0, val); 388 if (ret) 389 return ret; 390 391 return 0; 392 } 393 394 static const struct rockchip_usb_phy_pdata rk3188_pdata = { 395 .phys = (struct rockchip_usb_phys[]){ 396 { .reg = 0x10c, .pll_name = "sclk_otgphy0_480m" }, 397 { .reg = 0x11c, .pll_name = "sclk_otgphy1_480m" }, 398 { /* sentinel */ } 399 }, 400 .init_usb_uart = rk3188_init_usb_uart, 401 .usb_uart_phy = 0, 402 }; 403 404 #define RK3288_UOC0_CON3 0x32c 405 #define RK3288_UOC0_CON3_BYPASSDMEN BIT(6) 406 #define RK3288_UOC0_CON3_BYPASSSEL BIT(7) 407 408 /* 409 * Enable the bypass of uart2 data through the otg usb phy. 410 * Original description in the TRM. 411 * 1. Disable the OTG block by setting OTGDISABLE0 to 1’b1. 412 * 2. Disable the pull-up resistance on the D+ line by setting 413 * OPMODE0[1:0] to 2’b01. 414 * 3. To ensure that the XO, Bias, and PLL blocks are powered down in Suspend 415 * mode, set COMMONONN to 1’b1. 416 * 4. Place the USB PHY in Suspend mode by setting SUSPENDM0 to 1’b0. 417 * 5. Set BYPASSSEL0 to 1’b1. 418 * 6. To transmit data, controls BYPASSDMEN0, and BYPASSDMDATA0. 419 * To receive data, monitor FSVPLUS0. 420 * 421 * The actual code in the vendor kernel does some things differently. 422 */ 423 static int __init rk3288_init_usb_uart(struct regmap *grf, 424 const struct rockchip_usb_phy_pdata *pdata) 425 { 426 u32 val; 427 int ret; 428 429 ret = rockchip_init_usb_uart_common(grf, pdata); 430 if (ret) 431 return ret; 432 433 val = HIWORD_UPDATE(RK3288_UOC0_CON3_BYPASSSEL 434 | RK3288_UOC0_CON3_BYPASSDMEN, 435 RK3288_UOC0_CON3_BYPASSSEL 436 | RK3288_UOC0_CON3_BYPASSDMEN); 437 ret = regmap_write(grf, RK3288_UOC0_CON3, val); 438 if (ret) 439 return ret; 440 441 return 0; 442 } 443 444 static const struct rockchip_usb_phy_pdata rk3288_pdata = { 445 .phys = (struct rockchip_usb_phys[]){ 446 { .reg = 0x320, .pll_name = "sclk_otgphy0_480m" }, 447 { .reg = 0x334, .pll_name = "sclk_otgphy1_480m" }, 448 { .reg = 0x348, .pll_name = "sclk_otgphy2_480m" }, 449 { /* sentinel */ } 450 }, 451 .init_usb_uart = rk3288_init_usb_uart, 452 .usb_uart_phy = 0, 453 }; 454 455 static int rockchip_usb_phy_probe(struct platform_device *pdev) 456 { 457 struct device *dev = &pdev->dev; 458 struct rockchip_usb_phy_base *phy_base; 459 struct phy_provider *phy_provider; 460 struct device_node *child; 461 int err; 462 463 phy_base = devm_kzalloc(dev, sizeof(*phy_base), GFP_KERNEL); 464 if (!phy_base) 465 return -ENOMEM; 466 467 phy_base->pdata = device_get_match_data(dev); 468 if (!phy_base->pdata) { 469 dev_err(dev, "missing phy data\n"); 470 return -EINVAL; 471 } 472 473 phy_base->dev = dev; 474 phy_base->reg_base = ERR_PTR(-ENODEV); 475 if (dev->parent && dev->parent->of_node) 476 phy_base->reg_base = syscon_node_to_regmap( 477 dev->parent->of_node); 478 if (IS_ERR(phy_base->reg_base)) 479 phy_base->reg_base = syscon_regmap_lookup_by_phandle( 480 dev->of_node, "rockchip,grf"); 481 if (IS_ERR(phy_base->reg_base)) { 482 dev_err(&pdev->dev, "Missing rockchip,grf property\n"); 483 return PTR_ERR(phy_base->reg_base); 484 } 485 486 for_each_available_child_of_node(dev->of_node, child) { 487 err = rockchip_usb_phy_init(phy_base, child); 488 if (err) { 489 of_node_put(child); 490 return err; 491 } 492 } 493 494 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 495 return PTR_ERR_OR_ZERO(phy_provider); 496 } 497 498 static const struct of_device_id rockchip_usb_phy_dt_ids[] = { 499 { .compatible = "rockchip,rk3066a-usb-phy", .data = &rk3066a_pdata }, 500 { .compatible = "rockchip,rk3188-usb-phy", .data = &rk3188_pdata }, 501 { .compatible = "rockchip,rk3288-usb-phy", .data = &rk3288_pdata }, 502 {} 503 }; 504 505 MODULE_DEVICE_TABLE(of, rockchip_usb_phy_dt_ids); 506 507 static struct platform_driver rockchip_usb_driver = { 508 .probe = rockchip_usb_phy_probe, 509 .driver = { 510 .name = "rockchip-usb-phy", 511 .of_match_table = rockchip_usb_phy_dt_ids, 512 }, 513 }; 514 515 module_platform_driver(rockchip_usb_driver); 516 517 #ifndef MODULE 518 static int __init rockchip_init_usb_uart(void) 519 { 520 const struct of_device_id *match; 521 const struct rockchip_usb_phy_pdata *data; 522 struct device_node *np; 523 struct regmap *grf; 524 int ret; 525 526 if (!enable_usb_uart) 527 return 0; 528 529 np = of_find_matching_node_and_match(NULL, rockchip_usb_phy_dt_ids, 530 &match); 531 if (!np) { 532 pr_err("%s: failed to find usbphy node\n", __func__); 533 return -ENOTSUPP; 534 } 535 536 pr_debug("%s: using settings for %s\n", __func__, match->compatible); 537 data = match->data; 538 539 if (!data->init_usb_uart) { 540 pr_err("%s: usb-uart not available on %s\n", 541 __func__, match->compatible); 542 return -ENOTSUPP; 543 } 544 545 grf = ERR_PTR(-ENODEV); 546 if (np->parent) 547 grf = syscon_node_to_regmap(np->parent); 548 if (IS_ERR(grf)) 549 grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); 550 if (IS_ERR(grf)) { 551 pr_err("%s: Missing rockchip,grf property, %lu\n", 552 __func__, PTR_ERR(grf)); 553 return PTR_ERR(grf); 554 } 555 556 ret = data->init_usb_uart(grf, data); 557 if (ret) { 558 pr_err("%s: could not init usb_uart, %d\n", __func__, ret); 559 enable_usb_uart = 0; 560 return ret; 561 } 562 563 return 0; 564 } 565 early_initcall(rockchip_init_usb_uart); 566 567 static int __init rockchip_usb_uart(char *buf) 568 { 569 enable_usb_uart = true; 570 return 0; 571 } 572 early_param("rockchip.usb_uart", rockchip_usb_uart); 573 #endif 574 575 MODULE_AUTHOR("Yunzhi Li <lyz@rock-chips.com>"); 576 MODULE_DESCRIPTION("Rockchip USB 2.0 PHY driver"); 577 MODULE_LICENSE("GPL v2"); 578