mtu3_plat.c (13428B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2016 MediaTek Inc. 4 * 5 * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> 6 */ 7 8#include <linux/dma-mapping.h> 9#include <linux/iopoll.h> 10#include <linux/kernel.h> 11#include <linux/module.h> 12#include <linux/of_address.h> 13#include <linux/of_irq.h> 14#include <linux/platform_device.h> 15#include <linux/pm_wakeirq.h> 16 17#include "mtu3.h" 18#include "mtu3_dr.h" 19#include "mtu3_debug.h" 20 21/* u2-port0 should be powered on and enabled; */ 22int ssusb_check_clocks(struct ssusb_mtk *ssusb, u32 ex_clks) 23{ 24 void __iomem *ibase = ssusb->ippc_base; 25 u32 value, check_val; 26 int ret; 27 28 check_val = ex_clks | SSUSB_SYS125_RST_B_STS | SSUSB_SYSPLL_STABLE | 29 SSUSB_REF_RST_B_STS; 30 31 ret = readl_poll_timeout(ibase + U3D_SSUSB_IP_PW_STS1, value, 32 (check_val == (value & check_val)), 100, 20000); 33 if (ret) { 34 dev_err(ssusb->dev, "clks of sts1 are not stable!\n"); 35 return ret; 36 } 37 38 ret = readl_poll_timeout(ibase + U3D_SSUSB_IP_PW_STS2, value, 39 (value & SSUSB_U2_MAC_SYS_RST_B_STS), 100, 10000); 40 if (ret) { 41 dev_err(ssusb->dev, "mac2 clock is not stable\n"); 42 return ret; 43 } 44 45 return 0; 46} 47 48static int wait_for_ip_sleep(struct ssusb_mtk *ssusb) 49{ 50 bool sleep_check = true; 51 u32 value; 52 int ret; 53 54 if (!ssusb->is_host) 55 sleep_check = ssusb_gadget_ip_sleep_check(ssusb); 56 57 if (!sleep_check) 58 return 0; 59 60 /* wait for ip enter sleep mode */ 61 ret = readl_poll_timeout(ssusb->ippc_base + U3D_SSUSB_IP_PW_STS1, value, 62 (value & SSUSB_IP_SLEEP_STS), 100, 100000); 63 if (ret) { 64 dev_err(ssusb->dev, "ip sleep failed!!!\n"); 65 ret = -EBUSY; 66 } else { 67 /* workaround: avoid wrong wakeup signal latch for some soc */ 68 usleep_range(100, 200); 69 } 70 71 return ret; 72} 73 74static int ssusb_phy_init(struct ssusb_mtk *ssusb) 75{ 76 int i; 77 int ret; 78 79 for (i = 0; i < ssusb->num_phys; i++) { 80 ret = phy_init(ssusb->phys[i]); 81 if (ret) 82 goto exit_phy; 83 } 84 return 0; 85 86exit_phy: 87 for (; i > 0; i--) 88 phy_exit(ssusb->phys[i - 1]); 89 90 return ret; 91} 92 93static int ssusb_phy_exit(struct ssusb_mtk *ssusb) 94{ 95 int i; 96 97 for (i = 0; i < ssusb->num_phys; i++) 98 phy_exit(ssusb->phys[i]); 99 100 return 0; 101} 102 103static int ssusb_phy_power_on(struct ssusb_mtk *ssusb) 104{ 105 int i; 106 int ret; 107 108 for (i = 0; i < ssusb->num_phys; i++) { 109 ret = phy_power_on(ssusb->phys[i]); 110 if (ret) 111 goto power_off_phy; 112 } 113 return 0; 114 115power_off_phy: 116 for (; i > 0; i--) 117 phy_power_off(ssusb->phys[i - 1]); 118 119 return ret; 120} 121 122static void ssusb_phy_power_off(struct ssusb_mtk *ssusb) 123{ 124 unsigned int i; 125 126 for (i = 0; i < ssusb->num_phys; i++) 127 phy_power_off(ssusb->phys[i]); 128} 129 130static int ssusb_rscs_init(struct ssusb_mtk *ssusb) 131{ 132 int ret = 0; 133 134 ret = regulator_enable(ssusb->vusb33); 135 if (ret) { 136 dev_err(ssusb->dev, "failed to enable vusb33\n"); 137 goto vusb33_err; 138 } 139 140 ret = clk_bulk_prepare_enable(BULK_CLKS_CNT, ssusb->clks); 141 if (ret) 142 goto clks_err; 143 144 ret = ssusb_phy_init(ssusb); 145 if (ret) { 146 dev_err(ssusb->dev, "failed to init phy\n"); 147 goto phy_init_err; 148 } 149 150 ret = ssusb_phy_power_on(ssusb); 151 if (ret) { 152 dev_err(ssusb->dev, "failed to power on phy\n"); 153 goto phy_err; 154 } 155 156 return 0; 157 158phy_err: 159 ssusb_phy_exit(ssusb); 160phy_init_err: 161 clk_bulk_disable_unprepare(BULK_CLKS_CNT, ssusb->clks); 162clks_err: 163 regulator_disable(ssusb->vusb33); 164vusb33_err: 165 return ret; 166} 167 168static void ssusb_rscs_exit(struct ssusb_mtk *ssusb) 169{ 170 clk_bulk_disable_unprepare(BULK_CLKS_CNT, ssusb->clks); 171 regulator_disable(ssusb->vusb33); 172 ssusb_phy_power_off(ssusb); 173 ssusb_phy_exit(ssusb); 174} 175 176static void ssusb_ip_sw_reset(struct ssusb_mtk *ssusb) 177{ 178 /* reset whole ip (xhci & u3d) */ 179 mtu3_setbits(ssusb->ippc_base, U3D_SSUSB_IP_PW_CTRL0, SSUSB_IP_SW_RST); 180 udelay(1); 181 mtu3_clrbits(ssusb->ippc_base, U3D_SSUSB_IP_PW_CTRL0, SSUSB_IP_SW_RST); 182 183 /* 184 * device ip may be powered on in firmware/BROM stage before entering 185 * kernel stage; 186 * power down device ip, otherwise ip-sleep will fail when working as 187 * host only mode 188 */ 189 mtu3_setbits(ssusb->ippc_base, U3D_SSUSB_IP_PW_CTRL2, SSUSB_IP_DEV_PDN); 190} 191 192static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb) 193{ 194 struct device_node *node = pdev->dev.of_node; 195 struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; 196 struct clk_bulk_data *clks = ssusb->clks; 197 struct device *dev = &pdev->dev; 198 int i; 199 int ret; 200 201 ssusb->vusb33 = devm_regulator_get(dev, "vusb33"); 202 if (IS_ERR(ssusb->vusb33)) { 203 dev_err(dev, "failed to get vusb33\n"); 204 return PTR_ERR(ssusb->vusb33); 205 } 206 207 clks[0].id = "sys_ck"; 208 clks[1].id = "ref_ck"; 209 clks[2].id = "mcu_ck"; 210 clks[3].id = "dma_ck"; 211 ret = devm_clk_bulk_get_optional(dev, BULK_CLKS_CNT, clks); 212 if (ret) 213 return ret; 214 215 ssusb->num_phys = of_count_phandle_with_args(node, 216 "phys", "#phy-cells"); 217 if (ssusb->num_phys > 0) { 218 ssusb->phys = devm_kcalloc(dev, ssusb->num_phys, 219 sizeof(*ssusb->phys), GFP_KERNEL); 220 if (!ssusb->phys) 221 return -ENOMEM; 222 } else { 223 ssusb->num_phys = 0; 224 } 225 226 for (i = 0; i < ssusb->num_phys; i++) { 227 ssusb->phys[i] = devm_of_phy_get_by_index(dev, node, i); 228 if (IS_ERR(ssusb->phys[i])) { 229 dev_err(dev, "failed to get phy-%d\n", i); 230 return PTR_ERR(ssusb->phys[i]); 231 } 232 } 233 234 ssusb->ippc_base = devm_platform_ioremap_resource_byname(pdev, "ippc"); 235 if (IS_ERR(ssusb->ippc_base)) 236 return PTR_ERR(ssusb->ippc_base); 237 238 ssusb->wakeup_irq = platform_get_irq_byname_optional(pdev, "wakeup"); 239 if (ssusb->wakeup_irq == -EPROBE_DEFER) 240 return ssusb->wakeup_irq; 241 242 ssusb->dr_mode = usb_get_dr_mode(dev); 243 if (ssusb->dr_mode == USB_DR_MODE_UNKNOWN) 244 ssusb->dr_mode = USB_DR_MODE_OTG; 245 246 if (ssusb->dr_mode == USB_DR_MODE_PERIPHERAL) 247 goto out; 248 249 /* if host role is supported */ 250 ret = ssusb_wakeup_of_property_parse(ssusb, node); 251 if (ret) { 252 dev_err(dev, "failed to parse uwk property\n"); 253 return ret; 254 } 255 256 /* optional property, ignore the error if it does not exist */ 257 of_property_read_u32(node, "mediatek,u3p-dis-msk", 258 &ssusb->u3p_dis_msk); 259 of_property_read_u32(node, "mediatek,u2p-dis-msk", 260 &ssusb->u2p_dis_msk); 261 262 otg_sx->vbus = devm_regulator_get(dev, "vbus"); 263 if (IS_ERR(otg_sx->vbus)) { 264 dev_err(dev, "failed to get vbus\n"); 265 return PTR_ERR(otg_sx->vbus); 266 } 267 268 if (ssusb->dr_mode == USB_DR_MODE_HOST) 269 goto out; 270 271 /* if dual-role mode is supported */ 272 otg_sx->is_u3_drd = of_property_read_bool(node, "mediatek,usb3-drd"); 273 otg_sx->manual_drd_enabled = 274 of_property_read_bool(node, "enable-manual-drd"); 275 otg_sx->role_sw_used = of_property_read_bool(node, "usb-role-switch"); 276 277 /* can't disable port0 when use dual-role mode */ 278 ssusb->u2p_dis_msk &= ~0x1; 279 280 if (otg_sx->role_sw_used || otg_sx->manual_drd_enabled) 281 goto out; 282 283 if (of_property_read_bool(node, "extcon")) { 284 otg_sx->edev = extcon_get_edev_by_phandle(ssusb->dev, 0); 285 if (IS_ERR(otg_sx->edev)) { 286 return dev_err_probe(dev, PTR_ERR(otg_sx->edev), 287 "couldn't get extcon device\n"); 288 } 289 } 290 291out: 292 dev_info(dev, "dr_mode: %d, is_u3_dr: %d, drd: %s\n", 293 ssusb->dr_mode, otg_sx->is_u3_drd, 294 otg_sx->manual_drd_enabled ? "manual" : "auto"); 295 dev_info(dev, "u2p_dis_msk: %x, u3p_dis_msk: %x\n", 296 ssusb->u2p_dis_msk, ssusb->u3p_dis_msk); 297 298 return 0; 299} 300 301static int mtu3_probe(struct platform_device *pdev) 302{ 303 struct device_node *node = pdev->dev.of_node; 304 struct device *dev = &pdev->dev; 305 struct ssusb_mtk *ssusb; 306 int ret = -ENOMEM; 307 308 /* all elements are set to ZERO as default value */ 309 ssusb = devm_kzalloc(dev, sizeof(*ssusb), GFP_KERNEL); 310 if (!ssusb) 311 return -ENOMEM; 312 313 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); 314 if (ret) { 315 dev_err(dev, "No suitable DMA config available\n"); 316 return -ENOTSUPP; 317 } 318 319 platform_set_drvdata(pdev, ssusb); 320 ssusb->dev = dev; 321 322 ret = get_ssusb_rscs(pdev, ssusb); 323 if (ret) 324 return ret; 325 326 ssusb_debugfs_create_root(ssusb); 327 328 /* enable power domain */ 329 pm_runtime_set_active(dev); 330 pm_runtime_use_autosuspend(dev); 331 pm_runtime_set_autosuspend_delay(dev, 4000); 332 pm_runtime_enable(dev); 333 pm_runtime_get_sync(dev); 334 335 ret = ssusb_rscs_init(ssusb); 336 if (ret) 337 goto comm_init_err; 338 339 if (ssusb->wakeup_irq > 0) { 340 ret = dev_pm_set_dedicated_wake_irq_reverse(dev, ssusb->wakeup_irq); 341 if (ret) { 342 dev_err(dev, "failed to set wakeup irq %d\n", ssusb->wakeup_irq); 343 goto comm_exit; 344 } 345 dev_info(dev, "wakeup irq %d\n", ssusb->wakeup_irq); 346 } 347 348 ssusb_ip_sw_reset(ssusb); 349 350 if (IS_ENABLED(CONFIG_USB_MTU3_HOST)) 351 ssusb->dr_mode = USB_DR_MODE_HOST; 352 else if (IS_ENABLED(CONFIG_USB_MTU3_GADGET)) 353 ssusb->dr_mode = USB_DR_MODE_PERIPHERAL; 354 355 /* default as host */ 356 ssusb->is_host = !(ssusb->dr_mode == USB_DR_MODE_PERIPHERAL); 357 358 switch (ssusb->dr_mode) { 359 case USB_DR_MODE_PERIPHERAL: 360 ret = ssusb_gadget_init(ssusb); 361 if (ret) { 362 dev_err(dev, "failed to initialize gadget\n"); 363 goto comm_exit; 364 } 365 break; 366 case USB_DR_MODE_HOST: 367 ret = ssusb_host_init(ssusb, node); 368 if (ret) { 369 dev_err(dev, "failed to initialize host\n"); 370 goto comm_exit; 371 } 372 break; 373 case USB_DR_MODE_OTG: 374 ret = ssusb_gadget_init(ssusb); 375 if (ret) { 376 dev_err(dev, "failed to initialize gadget\n"); 377 goto comm_exit; 378 } 379 380 ret = ssusb_host_init(ssusb, node); 381 if (ret) { 382 dev_err(dev, "failed to initialize host\n"); 383 goto gadget_exit; 384 } 385 386 ret = ssusb_otg_switch_init(ssusb); 387 if (ret) { 388 dev_err(dev, "failed to initialize switch\n"); 389 goto host_exit; 390 } 391 break; 392 default: 393 dev_err(dev, "unsupported mode: %d\n", ssusb->dr_mode); 394 ret = -EINVAL; 395 goto comm_exit; 396 } 397 398 device_enable_async_suspend(dev); 399 pm_runtime_mark_last_busy(dev); 400 pm_runtime_put_autosuspend(dev); 401 pm_runtime_forbid(dev); 402 403 return 0; 404 405host_exit: 406 ssusb_host_exit(ssusb); 407gadget_exit: 408 ssusb_gadget_exit(ssusb); 409comm_exit: 410 ssusb_rscs_exit(ssusb); 411comm_init_err: 412 pm_runtime_put_noidle(dev); 413 pm_runtime_disable(dev); 414 ssusb_debugfs_remove_root(ssusb); 415 416 return ret; 417} 418 419static int mtu3_remove(struct platform_device *pdev) 420{ 421 struct ssusb_mtk *ssusb = platform_get_drvdata(pdev); 422 423 pm_runtime_get_sync(&pdev->dev); 424 425 switch (ssusb->dr_mode) { 426 case USB_DR_MODE_PERIPHERAL: 427 ssusb_gadget_exit(ssusb); 428 break; 429 case USB_DR_MODE_HOST: 430 ssusb_host_exit(ssusb); 431 break; 432 case USB_DR_MODE_OTG: 433 ssusb_otg_switch_exit(ssusb); 434 ssusb_gadget_exit(ssusb); 435 ssusb_host_exit(ssusb); 436 break; 437 default: 438 return -EINVAL; 439 } 440 441 ssusb_rscs_exit(ssusb); 442 ssusb_debugfs_remove_root(ssusb); 443 pm_runtime_disable(&pdev->dev); 444 pm_runtime_put_noidle(&pdev->dev); 445 pm_runtime_set_suspended(&pdev->dev); 446 447 return 0; 448} 449 450static int resume_ip_and_ports(struct ssusb_mtk *ssusb, pm_message_t msg) 451{ 452 switch (ssusb->dr_mode) { 453 case USB_DR_MODE_PERIPHERAL: 454 ssusb_gadget_resume(ssusb, msg); 455 break; 456 case USB_DR_MODE_HOST: 457 ssusb_host_resume(ssusb, false); 458 break; 459 case USB_DR_MODE_OTG: 460 ssusb_host_resume(ssusb, !ssusb->is_host); 461 if (!ssusb->is_host) 462 ssusb_gadget_resume(ssusb, msg); 463 464 break; 465 default: 466 return -EINVAL; 467 } 468 469 return 0; 470} 471 472static int mtu3_suspend_common(struct device *dev, pm_message_t msg) 473{ 474 struct ssusb_mtk *ssusb = dev_get_drvdata(dev); 475 int ret = 0; 476 477 dev_dbg(dev, "%s\n", __func__); 478 479 switch (ssusb->dr_mode) { 480 case USB_DR_MODE_PERIPHERAL: 481 ret = ssusb_gadget_suspend(ssusb, msg); 482 if (ret) 483 goto err; 484 485 break; 486 case USB_DR_MODE_HOST: 487 ssusb_host_suspend(ssusb); 488 break; 489 case USB_DR_MODE_OTG: 490 if (!ssusb->is_host) { 491 ret = ssusb_gadget_suspend(ssusb, msg); 492 if (ret) 493 goto err; 494 } 495 ssusb_host_suspend(ssusb); 496 break; 497 default: 498 return -EINVAL; 499 } 500 501 ret = wait_for_ip_sleep(ssusb); 502 if (ret) 503 goto sleep_err; 504 505 ssusb_phy_power_off(ssusb); 506 clk_bulk_disable_unprepare(BULK_CLKS_CNT, ssusb->clks); 507 ssusb_wakeup_set(ssusb, true); 508 return 0; 509 510sleep_err: 511 resume_ip_and_ports(ssusb, msg); 512err: 513 return ret; 514} 515 516static int mtu3_resume_common(struct device *dev, pm_message_t msg) 517{ 518 struct ssusb_mtk *ssusb = dev_get_drvdata(dev); 519 int ret; 520 521 dev_dbg(dev, "%s\n", __func__); 522 523 ssusb_wakeup_set(ssusb, false); 524 ret = clk_bulk_prepare_enable(BULK_CLKS_CNT, ssusb->clks); 525 if (ret) 526 goto clks_err; 527 528 ret = ssusb_phy_power_on(ssusb); 529 if (ret) 530 goto phy_err; 531 532 return resume_ip_and_ports(ssusb, msg); 533 534phy_err: 535 clk_bulk_disable_unprepare(BULK_CLKS_CNT, ssusb->clks); 536clks_err: 537 return ret; 538} 539 540static int __maybe_unused mtu3_suspend(struct device *dev) 541{ 542 return mtu3_suspend_common(dev, PMSG_SUSPEND); 543} 544 545static int __maybe_unused mtu3_resume(struct device *dev) 546{ 547 return mtu3_resume_common(dev, PMSG_SUSPEND); 548} 549 550static int __maybe_unused mtu3_runtime_suspend(struct device *dev) 551{ 552 if (!device_may_wakeup(dev)) 553 return 0; 554 555 return mtu3_suspend_common(dev, PMSG_AUTO_SUSPEND); 556} 557 558static int __maybe_unused mtu3_runtime_resume(struct device *dev) 559{ 560 if (!device_may_wakeup(dev)) 561 return 0; 562 563 return mtu3_resume_common(dev, PMSG_AUTO_SUSPEND); 564} 565 566static const struct dev_pm_ops mtu3_pm_ops = { 567 SET_SYSTEM_SLEEP_PM_OPS(mtu3_suspend, mtu3_resume) 568 SET_RUNTIME_PM_OPS(mtu3_runtime_suspend, 569 mtu3_runtime_resume, NULL) 570}; 571 572#define DEV_PM_OPS (IS_ENABLED(CONFIG_PM) ? &mtu3_pm_ops : NULL) 573 574static const struct of_device_id mtu3_of_match[] = { 575 {.compatible = "mediatek,mt8173-mtu3",}, 576 {.compatible = "mediatek,mtu3",}, 577 {}, 578}; 579MODULE_DEVICE_TABLE(of, mtu3_of_match); 580 581static struct platform_driver mtu3_driver = { 582 .probe = mtu3_probe, 583 .remove = mtu3_remove, 584 .driver = { 585 .name = MTU3_DRIVER_NAME, 586 .pm = DEV_PM_OPS, 587 .of_match_table = mtu3_of_match, 588 }, 589}; 590module_platform_driver(mtu3_driver); 591 592MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>"); 593MODULE_LICENSE("GPL v2"); 594MODULE_DESCRIPTION("MediaTek USB3 DRD Controller Driver");