1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2018, The Linux Foundation. All rights reserved. 3 * 4 * Inspired by dwc3-of-simple.c 5 */ 6 7 #include <linux/io.h> 8 #include <linux/of.h> 9 #include <linux/clk.h> 10 #include <linux/irq.h> 11 #include <linux/of_clk.h> 12 #include <linux/module.h> 13 #include <linux/kernel.h> 14 #include <linux/extcon.h> 15 #include <linux/interconnect.h> 16 #include <linux/of_platform.h> 17 #include <linux/platform_device.h> 18 #include <linux/phy/phy.h> 19 #include <linux/usb/of.h> 20 #include <linux/reset.h> 21 #include <linux/iopoll.h> 22 #include <linux/usb/hcd.h> 23 #include <linux/usb.h> 24 #include "core.h" 25 26 /* USB QSCRATCH Hardware registers */ 27 #define QSCRATCH_HS_PHY_CTRL 0x10 28 #define UTMI_OTG_VBUS_VALID BIT(20) 29 #define SW_SESSVLD_SEL BIT(28) 30 31 #define QSCRATCH_SS_PHY_CTRL 0x30 32 #define LANE0_PWR_PRESENT BIT(24) 33 34 #define QSCRATCH_GENERAL_CFG 0x08 35 #define PIPE_UTMI_CLK_SEL BIT(0) 36 #define PIPE3_PHYSTATUS_SW BIT(3) 37 #define PIPE_UTMI_CLK_DIS BIT(8) 38 39 #define PWR_EVNT_IRQ_STAT_REG 0x58 40 #define PWR_EVNT_LPM_IN_L2_MASK BIT(4) 41 #define PWR_EVNT_LPM_OUT_L2_MASK BIT(5) 42 43 #define SDM845_QSCRATCH_BASE_OFFSET 0xf8800 44 #define SDM845_QSCRATCH_SIZE 0x400 45 #define SDM845_DWC3_CORE_SIZE 0xcd00 46 47 /* Interconnect path bandwidths in MBps */ 48 #define USB_MEMORY_AVG_HS_BW MBps_to_icc(240) 49 #define USB_MEMORY_PEAK_HS_BW MBps_to_icc(700) 50 #define USB_MEMORY_AVG_SS_BW MBps_to_icc(1000) 51 #define USB_MEMORY_PEAK_SS_BW MBps_to_icc(2500) 52 #define APPS_USB_AVG_BW 0 53 #define APPS_USB_PEAK_BW MBps_to_icc(40) 54 55 struct dwc3_qcom { 56 struct device *dev; 57 void __iomem *qscratch_base; 58 struct platform_device *dwc3; 59 struct clk **clks; 60 int num_clocks; 61 struct reset_control *resets; 62 63 int qusb2_phy_irq; 64 int dp_hs_phy_irq; 65 int dm_hs_phy_irq; 66 int ss_phy_irq; 67 enum usb_device_speed usb2_speed; 68 69 struct extcon_dev *edev; 70 struct extcon_dev *host_edev; 71 struct notifier_block vbus_nb; 72 struct notifier_block host_nb; 73 74 enum usb_dr_mode mode; 75 bool is_suspended; 76 bool pm_suspended; 77 struct icc_path *icc_path_ddr; 78 struct icc_path *icc_path_apps; 79 }; 80 81 static inline void dwc3_qcom_setbits(void __iomem *base, u32 offset, u32 val) 82 { 83 u32 reg; 84 85 reg = readl(base + offset); 86 reg |= val; 87 writel(reg, base + offset); 88 89 /* ensure that above write is through */ 90 readl(base + offset); 91 } 92 93 static inline void dwc3_qcom_clrbits(void __iomem *base, u32 offset, u32 val) 94 { 95 u32 reg; 96 97 reg = readl(base + offset); 98 reg &= ~val; 99 writel(reg, base + offset); 100 101 /* ensure that above write is through */ 102 readl(base + offset); 103 } 104 105 static void dwc3_qcom_vbus_override_enable(struct dwc3_qcom *qcom, bool enable) 106 { 107 if (enable) { 108 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_SS_PHY_CTRL, 109 LANE0_PWR_PRESENT); 110 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_HS_PHY_CTRL, 111 UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL); 112 } else { 113 dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_SS_PHY_CTRL, 114 LANE0_PWR_PRESENT); 115 dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_HS_PHY_CTRL, 116 UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL); 117 } 118 } 119 120 static int dwc3_qcom_vbus_notifier(struct notifier_block *nb, 121 unsigned long event, void *ptr) 122 { 123 struct dwc3_qcom *qcom = container_of(nb, struct dwc3_qcom, vbus_nb); 124 125 /* enable vbus override for device mode */ 126 dwc3_qcom_vbus_override_enable(qcom, event); 127 qcom->mode = event ? USB_DR_MODE_PERIPHERAL : USB_DR_MODE_HOST; 128 129 return NOTIFY_DONE; 130 } 131 132 static int dwc3_qcom_host_notifier(struct notifier_block *nb, 133 unsigned long event, void *ptr) 134 { 135 struct dwc3_qcom *qcom = container_of(nb, struct dwc3_qcom, host_nb); 136 137 /* disable vbus override in host mode */ 138 dwc3_qcom_vbus_override_enable(qcom, !event); 139 qcom->mode = event ? USB_DR_MODE_HOST : USB_DR_MODE_PERIPHERAL; 140 141 return NOTIFY_DONE; 142 } 143 144 static int dwc3_qcom_register_extcon(struct dwc3_qcom *qcom) 145 { 146 struct device *dev = qcom->dev; 147 struct extcon_dev *host_edev; 148 int ret; 149 150 if (!of_property_read_bool(dev->of_node, "extcon")) 151 return 0; 152 153 qcom->edev = extcon_get_edev_by_phandle(dev, 0); 154 if (IS_ERR(qcom->edev)) 155 return dev_err_probe(dev, PTR_ERR(qcom->edev), 156 "Failed to get extcon\n"); 157 158 qcom->vbus_nb.notifier_call = dwc3_qcom_vbus_notifier; 159 160 qcom->host_edev = extcon_get_edev_by_phandle(dev, 1); 161 if (IS_ERR(qcom->host_edev)) 162 qcom->host_edev = NULL; 163 164 ret = devm_extcon_register_notifier(dev, qcom->edev, EXTCON_USB, 165 &qcom->vbus_nb); 166 if (ret < 0) { 167 dev_err(dev, "VBUS notifier register failed\n"); 168 return ret; 169 } 170 171 if (qcom->host_edev) 172 host_edev = qcom->host_edev; 173 else 174 host_edev = qcom->edev; 175 176 qcom->host_nb.notifier_call = dwc3_qcom_host_notifier; 177 ret = devm_extcon_register_notifier(dev, host_edev, EXTCON_USB_HOST, 178 &qcom->host_nb); 179 if (ret < 0) { 180 dev_err(dev, "Host notifier register failed\n"); 181 return ret; 182 } 183 184 /* Update initial VBUS override based on extcon state */ 185 if (extcon_get_state(qcom->edev, EXTCON_USB) || 186 !extcon_get_state(host_edev, EXTCON_USB_HOST)) 187 dwc3_qcom_vbus_notifier(&qcom->vbus_nb, true, qcom->edev); 188 else 189 dwc3_qcom_vbus_notifier(&qcom->vbus_nb, false, qcom->edev); 190 191 return 0; 192 } 193 194 static int dwc3_qcom_interconnect_enable(struct dwc3_qcom *qcom) 195 { 196 int ret; 197 198 ret = icc_enable(qcom->icc_path_ddr); 199 if (ret) 200 return ret; 201 202 ret = icc_enable(qcom->icc_path_apps); 203 if (ret) 204 icc_disable(qcom->icc_path_ddr); 205 206 return ret; 207 } 208 209 static int dwc3_qcom_interconnect_disable(struct dwc3_qcom *qcom) 210 { 211 int ret; 212 213 ret = icc_disable(qcom->icc_path_ddr); 214 if (ret) 215 return ret; 216 217 ret = icc_disable(qcom->icc_path_apps); 218 if (ret) 219 icc_enable(qcom->icc_path_ddr); 220 221 return ret; 222 } 223 224 /** 225 * dwc3_qcom_interconnect_init() - Get interconnect path handles 226 * and set bandwidth. 227 * @qcom: Pointer to the concerned usb core. 228 * 229 */ 230 static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom) 231 { 232 enum usb_device_speed max_speed; 233 struct device *dev = qcom->dev; 234 int ret; 235 236 qcom->icc_path_ddr = of_icc_get(dev, "usb-ddr"); 237 if (IS_ERR(qcom->icc_path_ddr)) { 238 return dev_err_probe(dev, PTR_ERR(qcom->icc_path_ddr), 239 "failed to get usb-ddr path\n"); 240 } 241 242 qcom->icc_path_apps = of_icc_get(dev, "apps-usb"); 243 if (IS_ERR(qcom->icc_path_apps)) { 244 ret = dev_err_probe(dev, PTR_ERR(qcom->icc_path_apps), 245 "failed to get apps-usb path\n"); 246 goto put_path_ddr; 247 } 248 249 max_speed = usb_get_maximum_speed(&qcom->dwc3->dev); 250 if (max_speed >= USB_SPEED_SUPER || max_speed == USB_SPEED_UNKNOWN) { 251 ret = icc_set_bw(qcom->icc_path_ddr, 252 USB_MEMORY_AVG_SS_BW, USB_MEMORY_PEAK_SS_BW); 253 } else { 254 ret = icc_set_bw(qcom->icc_path_ddr, 255 USB_MEMORY_AVG_HS_BW, USB_MEMORY_PEAK_HS_BW); 256 } 257 if (ret) { 258 dev_err(dev, "failed to set bandwidth for usb-ddr path: %d\n", ret); 259 goto put_path_apps; 260 } 261 262 ret = icc_set_bw(qcom->icc_path_apps, APPS_USB_AVG_BW, APPS_USB_PEAK_BW); 263 if (ret) { 264 dev_err(dev, "failed to set bandwidth for apps-usb path: %d\n", ret); 265 goto put_path_apps; 266 } 267 268 return 0; 269 270 put_path_apps: 271 icc_put(qcom->icc_path_apps); 272 put_path_ddr: 273 icc_put(qcom->icc_path_ddr); 274 return ret; 275 } 276 277 /** 278 * dwc3_qcom_interconnect_exit() - Release interconnect path handles 279 * @qcom: Pointer to the concerned usb core. 280 * 281 * This function is used to release interconnect path handle. 282 */ 283 static void dwc3_qcom_interconnect_exit(struct dwc3_qcom *qcom) 284 { 285 icc_put(qcom->icc_path_ddr); 286 icc_put(qcom->icc_path_apps); 287 } 288 289 /* Only usable in contexts where the role can not change. */ 290 static bool dwc3_qcom_is_host(struct dwc3_qcom *qcom) 291 { 292 struct dwc3 *dwc; 293 294 /* 295 * FIXME: Fix this layering violation. 296 */ 297 dwc = platform_get_drvdata(qcom->dwc3); 298 299 /* Core driver may not have probed yet. */ 300 if (!dwc) 301 return false; 302 303 return dwc->xhci; 304 } 305 306 static enum usb_device_speed dwc3_qcom_read_usb2_speed(struct dwc3_qcom *qcom) 307 { 308 struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3); 309 struct usb_device *udev; 310 struct usb_hcd __maybe_unused *hcd; 311 312 /* 313 * FIXME: Fix this layering violation. 314 */ 315 hcd = platform_get_drvdata(dwc->xhci); 316 317 /* 318 * It is possible to query the speed of all children of 319 * USB2.0 root hub via usb_hub_for_each_child(). DWC3 code 320 * currently supports only 1 port per controller. So 321 * this is sufficient. 322 */ 323 #ifdef CONFIG_USB 324 udev = usb_hub_find_child(hcd->self.root_hub, 1); 325 #else 326 udev = NULL; 327 #endif 328 if (!udev) 329 return USB_SPEED_UNKNOWN; 330 331 return udev->speed; 332 } 333 334 static void dwc3_qcom_enable_wakeup_irq(int irq, unsigned int polarity) 335 { 336 if (!irq) 337 return; 338 339 if (polarity) 340 irq_set_irq_type(irq, polarity); 341 342 enable_irq(irq); 343 enable_irq_wake(irq); 344 } 345 346 static void dwc3_qcom_disable_wakeup_irq(int irq) 347 { 348 if (!irq) 349 return; 350 351 disable_irq_wake(irq); 352 disable_irq_nosync(irq); 353 } 354 355 static void dwc3_qcom_disable_interrupts(struct dwc3_qcom *qcom) 356 { 357 dwc3_qcom_disable_wakeup_irq(qcom->qusb2_phy_irq); 358 359 if (qcom->usb2_speed == USB_SPEED_LOW) { 360 dwc3_qcom_disable_wakeup_irq(qcom->dm_hs_phy_irq); 361 } else if ((qcom->usb2_speed == USB_SPEED_HIGH) || 362 (qcom->usb2_speed == USB_SPEED_FULL)) { 363 dwc3_qcom_disable_wakeup_irq(qcom->dp_hs_phy_irq); 364 } else { 365 dwc3_qcom_disable_wakeup_irq(qcom->dp_hs_phy_irq); 366 dwc3_qcom_disable_wakeup_irq(qcom->dm_hs_phy_irq); 367 } 368 369 dwc3_qcom_disable_wakeup_irq(qcom->ss_phy_irq); 370 } 371 372 static void dwc3_qcom_enable_interrupts(struct dwc3_qcom *qcom) 373 { 374 dwc3_qcom_enable_wakeup_irq(qcom->qusb2_phy_irq, 0); 375 376 /* 377 * Configure DP/DM line interrupts based on the USB2 device attached to 378 * the root hub port. When HS/FS device is connected, configure the DP line 379 * as falling edge to detect both disconnect and remote wakeup scenarios. When 380 * LS device is connected, configure DM line as falling edge to detect both 381 * disconnect and remote wakeup. When no device is connected, configure both 382 * DP and DM lines as rising edge to detect HS/HS/LS device connect scenario. 383 */ 384 385 if (qcom->usb2_speed == USB_SPEED_LOW) { 386 dwc3_qcom_enable_wakeup_irq(qcom->dm_hs_phy_irq, 387 IRQ_TYPE_EDGE_FALLING); 388 } else if ((qcom->usb2_speed == USB_SPEED_HIGH) || 389 (qcom->usb2_speed == USB_SPEED_FULL)) { 390 dwc3_qcom_enable_wakeup_irq(qcom->dp_hs_phy_irq, 391 IRQ_TYPE_EDGE_FALLING); 392 } else { 393 dwc3_qcom_enable_wakeup_irq(qcom->dp_hs_phy_irq, 394 IRQ_TYPE_EDGE_RISING); 395 dwc3_qcom_enable_wakeup_irq(qcom->dm_hs_phy_irq, 396 IRQ_TYPE_EDGE_RISING); 397 } 398 399 dwc3_qcom_enable_wakeup_irq(qcom->ss_phy_irq, 0); 400 } 401 402 static int dwc3_qcom_suspend(struct dwc3_qcom *qcom, bool wakeup) 403 { 404 u32 val; 405 int i, ret; 406 407 if (qcom->is_suspended) 408 return 0; 409 410 val = readl(qcom->qscratch_base + PWR_EVNT_IRQ_STAT_REG); 411 if (!(val & PWR_EVNT_LPM_IN_L2_MASK)) 412 dev_err(qcom->dev, "HS-PHY not in L2\n"); 413 414 for (i = qcom->num_clocks - 1; i >= 0; i--) 415 clk_disable_unprepare(qcom->clks[i]); 416 417 ret = dwc3_qcom_interconnect_disable(qcom); 418 if (ret) 419 dev_warn(qcom->dev, "failed to disable interconnect: %d\n", ret); 420 421 /* 422 * The role is stable during suspend as role switching is done from a 423 * freezable workqueue. 424 */ 425 if (dwc3_qcom_is_host(qcom) && wakeup) { 426 qcom->usb2_speed = dwc3_qcom_read_usb2_speed(qcom); 427 dwc3_qcom_enable_interrupts(qcom); 428 } 429 430 qcom->is_suspended = true; 431 432 return 0; 433 } 434 435 static int dwc3_qcom_resume(struct dwc3_qcom *qcom, bool wakeup) 436 { 437 int ret; 438 int i; 439 440 if (!qcom->is_suspended) 441 return 0; 442 443 if (dwc3_qcom_is_host(qcom) && wakeup) 444 dwc3_qcom_disable_interrupts(qcom); 445 446 for (i = 0; i < qcom->num_clocks; i++) { 447 ret = clk_prepare_enable(qcom->clks[i]); 448 if (ret < 0) { 449 while (--i >= 0) 450 clk_disable_unprepare(qcom->clks[i]); 451 return ret; 452 } 453 } 454 455 ret = dwc3_qcom_interconnect_enable(qcom); 456 if (ret) 457 dev_warn(qcom->dev, "failed to enable interconnect: %d\n", ret); 458 459 /* Clear existing events from PHY related to L2 in/out */ 460 dwc3_qcom_setbits(qcom->qscratch_base, PWR_EVNT_IRQ_STAT_REG, 461 PWR_EVNT_LPM_IN_L2_MASK | PWR_EVNT_LPM_OUT_L2_MASK); 462 463 qcom->is_suspended = false; 464 465 return 0; 466 } 467 468 static irqreturn_t qcom_dwc3_resume_irq(int irq, void *data) 469 { 470 struct dwc3_qcom *qcom = data; 471 struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3); 472 473 /* If pm_suspended then let pm_resume take care of resuming h/w */ 474 if (qcom->pm_suspended) 475 return IRQ_HANDLED; 476 477 /* 478 * This is safe as role switching is done from a freezable workqueue 479 * and the wakeup interrupts are disabled as part of resume. 480 */ 481 if (dwc3_qcom_is_host(qcom)) 482 pm_runtime_resume(&dwc->xhci->dev); 483 484 return IRQ_HANDLED; 485 } 486 487 static void dwc3_qcom_select_utmi_clk(struct dwc3_qcom *qcom) 488 { 489 /* Configure dwc3 to use UTMI clock as PIPE clock not present */ 490 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG, 491 PIPE_UTMI_CLK_DIS); 492 493 usleep_range(100, 1000); 494 495 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG, 496 PIPE_UTMI_CLK_SEL | PIPE3_PHYSTATUS_SW); 497 498 usleep_range(100, 1000); 499 500 dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG, 501 PIPE_UTMI_CLK_DIS); 502 } 503 504 static int dwc3_qcom_setup_irq(struct platform_device *pdev) 505 { 506 struct dwc3_qcom *qcom = platform_get_drvdata(pdev); 507 int irq; 508 int ret; 509 510 irq = platform_get_irq_byname_optional(pdev, "qusb2_phy"); 511 if (irq > 0) { 512 /* Keep wakeup interrupts disabled until suspend */ 513 ret = devm_request_threaded_irq(qcom->dev, irq, NULL, 514 qcom_dwc3_resume_irq, 515 IRQF_ONESHOT | IRQF_NO_AUTOEN, 516 "qcom_dwc3 QUSB2", qcom); 517 if (ret) { 518 dev_err(qcom->dev, "qusb2_phy_irq failed: %d\n", ret); 519 return ret; 520 } 521 qcom->qusb2_phy_irq = irq; 522 } 523 524 irq = platform_get_irq_byname_optional(pdev, "dp_hs_phy_irq"); 525 if (irq > 0) { 526 ret = devm_request_threaded_irq(qcom->dev, irq, NULL, 527 qcom_dwc3_resume_irq, 528 IRQF_ONESHOT | IRQF_NO_AUTOEN, 529 "qcom_dwc3 DP_HS", qcom); 530 if (ret) { 531 dev_err(qcom->dev, "dp_hs_phy_irq failed: %d\n", ret); 532 return ret; 533 } 534 qcom->dp_hs_phy_irq = irq; 535 } 536 537 irq = platform_get_irq_byname_optional(pdev, "dm_hs_phy_irq"); 538 if (irq > 0) { 539 ret = devm_request_threaded_irq(qcom->dev, irq, NULL, 540 qcom_dwc3_resume_irq, 541 IRQF_ONESHOT | IRQF_NO_AUTOEN, 542 "qcom_dwc3 DM_HS", qcom); 543 if (ret) { 544 dev_err(qcom->dev, "dm_hs_phy_irq failed: %d\n", ret); 545 return ret; 546 } 547 qcom->dm_hs_phy_irq = irq; 548 } 549 550 irq = platform_get_irq_byname_optional(pdev, "ss_phy_irq"); 551 if (irq > 0) { 552 ret = devm_request_threaded_irq(qcom->dev, irq, NULL, 553 qcom_dwc3_resume_irq, 554 IRQF_ONESHOT | IRQF_NO_AUTOEN, 555 "qcom_dwc3 SS", qcom); 556 if (ret) { 557 dev_err(qcom->dev, "ss_phy_irq failed: %d\n", ret); 558 return ret; 559 } 560 qcom->ss_phy_irq = irq; 561 } 562 563 return 0; 564 } 565 566 static int dwc3_qcom_clk_init(struct dwc3_qcom *qcom, int count) 567 { 568 struct device *dev = qcom->dev; 569 struct device_node *np = dev->of_node; 570 int i; 571 572 if (!np || !count) 573 return 0; 574 575 if (count < 0) 576 return count; 577 578 qcom->num_clocks = count; 579 580 qcom->clks = devm_kcalloc(dev, qcom->num_clocks, 581 sizeof(struct clk *), GFP_KERNEL); 582 if (!qcom->clks) 583 return -ENOMEM; 584 585 for (i = 0; i < qcom->num_clocks; i++) { 586 struct clk *clk; 587 int ret; 588 589 clk = of_clk_get(np, i); 590 if (IS_ERR(clk)) { 591 while (--i >= 0) 592 clk_put(qcom->clks[i]); 593 return PTR_ERR(clk); 594 } 595 596 ret = clk_prepare_enable(clk); 597 if (ret < 0) { 598 while (--i >= 0) { 599 clk_disable_unprepare(qcom->clks[i]); 600 clk_put(qcom->clks[i]); 601 } 602 clk_put(clk); 603 604 return ret; 605 } 606 607 qcom->clks[i] = clk; 608 } 609 610 return 0; 611 } 612 613 static int dwc3_qcom_of_register_core(struct platform_device *pdev) 614 { 615 struct dwc3_qcom *qcom = platform_get_drvdata(pdev); 616 struct device_node *np = pdev->dev.of_node, *dwc3_np; 617 struct device *dev = &pdev->dev; 618 int ret; 619 620 dwc3_np = of_get_compatible_child(np, "snps,dwc3"); 621 if (!dwc3_np) { 622 dev_err(dev, "failed to find dwc3 core child\n"); 623 return -ENODEV; 624 } 625 626 ret = of_platform_populate(np, NULL, NULL, dev); 627 if (ret) { 628 dev_err(dev, "failed to register dwc3 core - %d\n", ret); 629 goto node_put; 630 } 631 632 qcom->dwc3 = of_find_device_by_node(dwc3_np); 633 if (!qcom->dwc3) { 634 ret = -ENODEV; 635 dev_err(dev, "failed to get dwc3 platform device\n"); 636 of_platform_depopulate(dev); 637 } 638 639 node_put: 640 of_node_put(dwc3_np); 641 642 return ret; 643 } 644 645 static int dwc3_qcom_probe(struct platform_device *pdev) 646 { 647 struct device_node *np = pdev->dev.of_node; 648 struct device *dev = &pdev->dev; 649 struct dwc3_qcom *qcom; 650 struct resource *res; 651 int ret, i; 652 bool ignore_pipe_clk; 653 bool wakeup_source; 654 655 qcom = devm_kzalloc(&pdev->dev, sizeof(*qcom), GFP_KERNEL); 656 if (!qcom) 657 return -ENOMEM; 658 659 platform_set_drvdata(pdev, qcom); 660 qcom->dev = &pdev->dev; 661 662 qcom->resets = devm_reset_control_array_get_optional_exclusive(dev); 663 if (IS_ERR(qcom->resets)) { 664 return dev_err_probe(&pdev->dev, PTR_ERR(qcom->resets), 665 "failed to get resets\n"); 666 } 667 668 ret = reset_control_assert(qcom->resets); 669 if (ret) { 670 dev_err(&pdev->dev, "failed to assert resets, err=%d\n", ret); 671 return ret; 672 } 673 674 usleep_range(10, 1000); 675 676 ret = reset_control_deassert(qcom->resets); 677 if (ret) { 678 dev_err(&pdev->dev, "failed to deassert resets, err=%d\n", ret); 679 goto reset_assert; 680 } 681 682 ret = dwc3_qcom_clk_init(qcom, of_clk_get_parent_count(np)); 683 if (ret) { 684 dev_err_probe(dev, ret, "failed to get clocks\n"); 685 goto reset_assert; 686 } 687 688 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 689 690 qcom->qscratch_base = devm_ioremap_resource(dev, res); 691 if (IS_ERR(qcom->qscratch_base)) { 692 ret = PTR_ERR(qcom->qscratch_base); 693 goto clk_disable; 694 } 695 696 ret = dwc3_qcom_setup_irq(pdev); 697 if (ret) { 698 dev_err(dev, "failed to setup IRQs, err=%d\n", ret); 699 goto clk_disable; 700 } 701 702 /* 703 * Disable pipe_clk requirement if specified. Used when dwc3 704 * operates without SSPHY and only HS/FS/LS modes are supported. 705 */ 706 ignore_pipe_clk = device_property_read_bool(dev, 707 "qcom,select-utmi-as-pipe-clk"); 708 if (ignore_pipe_clk) 709 dwc3_qcom_select_utmi_clk(qcom); 710 711 ret = dwc3_qcom_of_register_core(pdev); 712 if (ret) { 713 dev_err(dev, "failed to register DWC3 Core, err=%d\n", ret); 714 goto clk_disable; 715 } 716 717 ret = dwc3_qcom_interconnect_init(qcom); 718 if (ret) 719 goto depopulate; 720 721 qcom->mode = usb_get_dr_mode(&qcom->dwc3->dev); 722 723 /* enable vbus override for device mode */ 724 if (qcom->mode != USB_DR_MODE_HOST) 725 dwc3_qcom_vbus_override_enable(qcom, true); 726 727 /* register extcon to override sw_vbus on Vbus change later */ 728 ret = dwc3_qcom_register_extcon(qcom); 729 if (ret) 730 goto interconnect_exit; 731 732 wakeup_source = of_property_read_bool(dev->of_node, "wakeup-source"); 733 device_init_wakeup(&pdev->dev, wakeup_source); 734 device_init_wakeup(&qcom->dwc3->dev, wakeup_source); 735 736 qcom->is_suspended = false; 737 pm_runtime_set_active(dev); 738 pm_runtime_enable(dev); 739 pm_runtime_forbid(dev); 740 741 return 0; 742 743 interconnect_exit: 744 dwc3_qcom_interconnect_exit(qcom); 745 depopulate: 746 of_platform_depopulate(&pdev->dev); 747 platform_device_put(qcom->dwc3); 748 clk_disable: 749 for (i = qcom->num_clocks - 1; i >= 0; i--) { 750 clk_disable_unprepare(qcom->clks[i]); 751 clk_put(qcom->clks[i]); 752 } 753 reset_assert: 754 reset_control_assert(qcom->resets); 755 756 return ret; 757 } 758 759 static void dwc3_qcom_remove(struct platform_device *pdev) 760 { 761 struct dwc3_qcom *qcom = platform_get_drvdata(pdev); 762 struct device *dev = &pdev->dev; 763 int i; 764 765 of_platform_depopulate(&pdev->dev); 766 platform_device_put(qcom->dwc3); 767 768 for (i = qcom->num_clocks - 1; i >= 0; i--) { 769 clk_disable_unprepare(qcom->clks[i]); 770 clk_put(qcom->clks[i]); 771 } 772 qcom->num_clocks = 0; 773 774 dwc3_qcom_interconnect_exit(qcom); 775 reset_control_assert(qcom->resets); 776 777 pm_runtime_allow(dev); 778 pm_runtime_disable(dev); 779 } 780 781 static int __maybe_unused dwc3_qcom_pm_suspend(struct device *dev) 782 { 783 struct dwc3_qcom *qcom = dev_get_drvdata(dev); 784 bool wakeup = device_may_wakeup(dev); 785 int ret; 786 787 ret = dwc3_qcom_suspend(qcom, wakeup); 788 if (ret) 789 return ret; 790 791 qcom->pm_suspended = true; 792 793 return 0; 794 } 795 796 static int __maybe_unused dwc3_qcom_pm_resume(struct device *dev) 797 { 798 struct dwc3_qcom *qcom = dev_get_drvdata(dev); 799 bool wakeup = device_may_wakeup(dev); 800 int ret; 801 802 ret = dwc3_qcom_resume(qcom, wakeup); 803 if (ret) 804 return ret; 805 806 qcom->pm_suspended = false; 807 808 return 0; 809 } 810 811 static int __maybe_unused dwc3_qcom_runtime_suspend(struct device *dev) 812 { 813 struct dwc3_qcom *qcom = dev_get_drvdata(dev); 814 815 return dwc3_qcom_suspend(qcom, true); 816 } 817 818 static int __maybe_unused dwc3_qcom_runtime_resume(struct device *dev) 819 { 820 struct dwc3_qcom *qcom = dev_get_drvdata(dev); 821 822 return dwc3_qcom_resume(qcom, true); 823 } 824 825 static const struct dev_pm_ops dwc3_qcom_dev_pm_ops = { 826 SET_SYSTEM_SLEEP_PM_OPS(dwc3_qcom_pm_suspend, dwc3_qcom_pm_resume) 827 SET_RUNTIME_PM_OPS(dwc3_qcom_runtime_suspend, dwc3_qcom_runtime_resume, 828 NULL) 829 }; 830 831 static const struct of_device_id dwc3_qcom_of_match[] = { 832 { .compatible = "qcom,dwc3" }, 833 { } 834 }; 835 MODULE_DEVICE_TABLE(of, dwc3_qcom_of_match); 836 837 static struct platform_driver dwc3_qcom_driver = { 838 .probe = dwc3_qcom_probe, 839 .remove_new = dwc3_qcom_remove, 840 .driver = { 841 .name = "dwc3-qcom", 842 .pm = &dwc3_qcom_dev_pm_ops, 843 .of_match_table = dwc3_qcom_of_match, 844 }, 845 }; 846 847 module_platform_driver(dwc3_qcom_driver); 848 849 MODULE_LICENSE("GPL v2"); 850 MODULE_DESCRIPTION("DesignWare DWC3 QCOM Glue Driver"); 851