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