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/acpi.h> 8#include <linux/io.h> 9#include <linux/of.h> 10#include <linux/clk.h> 11#include <linux/irq.h> 12#include <linux/of_clk.h> 13#include <linux/module.h> 14#include <linux/kernel.h> 15#include <linux/extcon.h> 16#include <linux/interconnect.h> 17#include <linux/of_platform.h> 18#include <linux/platform_device.h> 19#include <linux/phy/phy.h> 20#include <linux/usb/of.h> 21#include <linux/reset.h> 22#include <linux/iopoll.h> 23 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 55struct dwc3_acpi_pdata { 56 u32 qscratch_base_offset; 57 u32 qscratch_base_size; 58 u32 dwc3_core_base_size; 59 int hs_phy_irq_index; 60 int dp_hs_phy_irq_index; 61 int dm_hs_phy_irq_index; 62 int ss_phy_irq_index; 63 bool is_urs; 64}; 65 66struct dwc3_qcom { 67 struct device *dev; 68 void __iomem *qscratch_base; 69 struct platform_device *dwc3; 70 struct platform_device *urs_usb; 71 struct clk **clks; 72 int num_clocks; 73 struct reset_control *resets; 74 75 int hs_phy_irq; 76 int dp_hs_phy_irq; 77 int dm_hs_phy_irq; 78 int ss_phy_irq; 79 80 struct extcon_dev *edev; 81 struct extcon_dev *host_edev; 82 struct notifier_block vbus_nb; 83 struct notifier_block host_nb; 84 85 const struct dwc3_acpi_pdata *acpi_pdata; 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 94static inline void dwc3_qcom_setbits(void __iomem *base, u32 offset, u32 val) 95{ 96 u32 reg; 97 98 reg = readl(base + offset); 99 reg |= val; 100 writel(reg, base + offset); 101 102 /* ensure that above write is through */ 103 readl(base + offset); 104} 105 106static inline void dwc3_qcom_clrbits(void __iomem *base, u32 offset, u32 val) 107{ 108 u32 reg; 109 110 reg = readl(base + offset); 111 reg &= ~val; 112 writel(reg, base + offset); 113 114 /* ensure that above write is through */ 115 readl(base + offset); 116} 117 118static void dwc3_qcom_vbus_override_enable(struct dwc3_qcom *qcom, bool enable) 119{ 120 if (enable) { 121 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_SS_PHY_CTRL, 122 LANE0_PWR_PRESENT); 123 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_HS_PHY_CTRL, 124 UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL); 125 } else { 126 dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_SS_PHY_CTRL, 127 LANE0_PWR_PRESENT); 128 dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_HS_PHY_CTRL, 129 UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL); 130 } 131} 132 133static int dwc3_qcom_vbus_notifier(struct notifier_block *nb, 134 unsigned long event, void *ptr) 135{ 136 struct dwc3_qcom *qcom = container_of(nb, struct dwc3_qcom, vbus_nb); 137 138 /* enable vbus override for device mode */ 139 dwc3_qcom_vbus_override_enable(qcom, event); 140 qcom->mode = event ? USB_DR_MODE_PERIPHERAL : USB_DR_MODE_HOST; 141 142 return NOTIFY_DONE; 143} 144 145static int dwc3_qcom_host_notifier(struct notifier_block *nb, 146 unsigned long event, void *ptr) 147{ 148 struct dwc3_qcom *qcom = container_of(nb, struct dwc3_qcom, host_nb); 149 150 /* disable vbus override in host mode */ 151 dwc3_qcom_vbus_override_enable(qcom, !event); 152 qcom->mode = event ? USB_DR_MODE_HOST : USB_DR_MODE_PERIPHERAL; 153 154 return NOTIFY_DONE; 155} 156 157static int dwc3_qcom_register_extcon(struct dwc3_qcom *qcom) 158{ 159 struct device *dev = qcom->dev; 160 struct extcon_dev *host_edev; 161 int ret; 162 163 if (!of_property_read_bool(dev->of_node, "extcon")) 164 return 0; 165 166 qcom->edev = extcon_get_edev_by_phandle(dev, 0); 167 if (IS_ERR(qcom->edev)) 168 return PTR_ERR(qcom->edev); 169 170 qcom->vbus_nb.notifier_call = dwc3_qcom_vbus_notifier; 171 172 qcom->host_edev = extcon_get_edev_by_phandle(dev, 1); 173 if (IS_ERR(qcom->host_edev)) 174 qcom->host_edev = NULL; 175 176 ret = devm_extcon_register_notifier(dev, qcom->edev, EXTCON_USB, 177 &qcom->vbus_nb); 178 if (ret < 0) { 179 dev_err(dev, "VBUS notifier register failed\n"); 180 return ret; 181 } 182 183 if (qcom->host_edev) 184 host_edev = qcom->host_edev; 185 else 186 host_edev = qcom->edev; 187 188 qcom->host_nb.notifier_call = dwc3_qcom_host_notifier; 189 ret = devm_extcon_register_notifier(dev, host_edev, EXTCON_USB_HOST, 190 &qcom->host_nb); 191 if (ret < 0) { 192 dev_err(dev, "Host notifier register failed\n"); 193 return ret; 194 } 195 196 /* Update initial VBUS override based on extcon state */ 197 if (extcon_get_state(qcom->edev, EXTCON_USB) || 198 !extcon_get_state(host_edev, EXTCON_USB_HOST)) 199 dwc3_qcom_vbus_notifier(&qcom->vbus_nb, true, qcom->edev); 200 else 201 dwc3_qcom_vbus_notifier(&qcom->vbus_nb, false, qcom->edev); 202 203 return 0; 204} 205 206static int dwc3_qcom_interconnect_enable(struct dwc3_qcom *qcom) 207{ 208 int ret; 209 210 ret = icc_enable(qcom->icc_path_ddr); 211 if (ret) 212 return ret; 213 214 ret = icc_enable(qcom->icc_path_apps); 215 if (ret) 216 icc_disable(qcom->icc_path_ddr); 217 218 return ret; 219} 220 221static int dwc3_qcom_interconnect_disable(struct dwc3_qcom *qcom) 222{ 223 int ret; 224 225 ret = icc_disable(qcom->icc_path_ddr); 226 if (ret) 227 return ret; 228 229 ret = icc_disable(qcom->icc_path_apps); 230 if (ret) 231 icc_enable(qcom->icc_path_ddr); 232 233 return ret; 234} 235 236/** 237 * dwc3_qcom_interconnect_init() - Get interconnect path handles 238 * and set bandwidhth. 239 * @qcom: Pointer to the concerned usb core. 240 * 241 */ 242static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom) 243{ 244 struct device *dev = qcom->dev; 245 int ret; 246 247 if (has_acpi_companion(dev)) 248 return 0; 249 250 qcom->icc_path_ddr = of_icc_get(dev, "usb-ddr"); 251 if (IS_ERR(qcom->icc_path_ddr)) { 252 dev_err(dev, "failed to get usb-ddr path: %ld\n", 253 PTR_ERR(qcom->icc_path_ddr)); 254 return PTR_ERR(qcom->icc_path_ddr); 255 } 256 257 qcom->icc_path_apps = of_icc_get(dev, "apps-usb"); 258 if (IS_ERR(qcom->icc_path_apps)) { 259 dev_err(dev, "failed to get apps-usb path: %ld\n", 260 PTR_ERR(qcom->icc_path_apps)); 261 ret = PTR_ERR(qcom->icc_path_apps); 262 goto put_path_ddr; 263 } 264 265 if (usb_get_maximum_speed(&qcom->dwc3->dev) >= USB_SPEED_SUPER || 266 usb_get_maximum_speed(&qcom->dwc3->dev) == USB_SPEED_UNKNOWN) 267 ret = icc_set_bw(qcom->icc_path_ddr, 268 USB_MEMORY_AVG_SS_BW, USB_MEMORY_PEAK_SS_BW); 269 else 270 ret = icc_set_bw(qcom->icc_path_ddr, 271 USB_MEMORY_AVG_HS_BW, USB_MEMORY_PEAK_HS_BW); 272 273 if (ret) { 274 dev_err(dev, "failed to set bandwidth for usb-ddr path: %d\n", ret); 275 goto put_path_apps; 276 } 277 278 ret = icc_set_bw(qcom->icc_path_apps, 279 APPS_USB_AVG_BW, APPS_USB_PEAK_BW); 280 if (ret) { 281 dev_err(dev, "failed to set bandwidth for apps-usb path: %d\n", ret); 282 goto put_path_apps; 283 } 284 285 return 0; 286 287put_path_apps: 288 icc_put(qcom->icc_path_apps); 289put_path_ddr: 290 icc_put(qcom->icc_path_ddr); 291 return ret; 292} 293 294/** 295 * dwc3_qcom_interconnect_exit() - Release interconnect path handles 296 * @qcom: Pointer to the concerned usb core. 297 * 298 * This function is used to release interconnect path handle. 299 */ 300static void dwc3_qcom_interconnect_exit(struct dwc3_qcom *qcom) 301{ 302 icc_put(qcom->icc_path_ddr); 303 icc_put(qcom->icc_path_apps); 304} 305 306/* Only usable in contexts where the role can not change. */ 307static bool dwc3_qcom_is_host(struct dwc3_qcom *qcom) 308{ 309 struct dwc3 *dwc; 310 311 /* 312 * FIXME: Fix this layering violation. 313 */ 314 dwc = platform_get_drvdata(qcom->dwc3); 315 316 /* Core driver may not have probed yet. */ 317 if (!dwc) 318 return false; 319 320 return dwc->xhci; 321} 322 323static void dwc3_qcom_disable_interrupts(struct dwc3_qcom *qcom) 324{ 325 if (qcom->hs_phy_irq) { 326 disable_irq_wake(qcom->hs_phy_irq); 327 disable_irq_nosync(qcom->hs_phy_irq); 328 } 329 330 if (qcom->dp_hs_phy_irq) { 331 disable_irq_wake(qcom->dp_hs_phy_irq); 332 disable_irq_nosync(qcom->dp_hs_phy_irq); 333 } 334 335 if (qcom->dm_hs_phy_irq) { 336 disable_irq_wake(qcom->dm_hs_phy_irq); 337 disable_irq_nosync(qcom->dm_hs_phy_irq); 338 } 339 340 if (qcom->ss_phy_irq) { 341 disable_irq_wake(qcom->ss_phy_irq); 342 disable_irq_nosync(qcom->ss_phy_irq); 343 } 344} 345 346static void dwc3_qcom_enable_interrupts(struct dwc3_qcom *qcom) 347{ 348 if (qcom->hs_phy_irq) { 349 enable_irq(qcom->hs_phy_irq); 350 enable_irq_wake(qcom->hs_phy_irq); 351 } 352 353 if (qcom->dp_hs_phy_irq) { 354 enable_irq(qcom->dp_hs_phy_irq); 355 enable_irq_wake(qcom->dp_hs_phy_irq); 356 } 357 358 if (qcom->dm_hs_phy_irq) { 359 enable_irq(qcom->dm_hs_phy_irq); 360 enable_irq_wake(qcom->dm_hs_phy_irq); 361 } 362 363 if (qcom->ss_phy_irq) { 364 enable_irq(qcom->ss_phy_irq); 365 enable_irq_wake(qcom->ss_phy_irq); 366 } 367} 368 369static int dwc3_qcom_suspend(struct dwc3_qcom *qcom) 370{ 371 u32 val; 372 int i, ret; 373 374 if (qcom->is_suspended) 375 return 0; 376 377 val = readl(qcom->qscratch_base + PWR_EVNT_IRQ_STAT_REG); 378 if (!(val & PWR_EVNT_LPM_IN_L2_MASK)) 379 dev_err(qcom->dev, "HS-PHY not in L2\n"); 380 381 for (i = qcom->num_clocks - 1; i >= 0; i--) 382 clk_disable_unprepare(qcom->clks[i]); 383 384 ret = dwc3_qcom_interconnect_disable(qcom); 385 if (ret) 386 dev_warn(qcom->dev, "failed to disable interconnect: %d\n", ret); 387 388 if (device_may_wakeup(qcom->dev)) 389 dwc3_qcom_enable_interrupts(qcom); 390 391 qcom->is_suspended = true; 392 393 return 0; 394} 395 396static int dwc3_qcom_resume(struct dwc3_qcom *qcom) 397{ 398 int ret; 399 int i; 400 401 if (!qcom->is_suspended) 402 return 0; 403 404 if (device_may_wakeup(qcom->dev)) 405 dwc3_qcom_disable_interrupts(qcom); 406 407 for (i = 0; i < qcom->num_clocks; i++) { 408 ret = clk_prepare_enable(qcom->clks[i]); 409 if (ret < 0) { 410 while (--i >= 0) 411 clk_disable_unprepare(qcom->clks[i]); 412 return ret; 413 } 414 } 415 416 ret = dwc3_qcom_interconnect_enable(qcom); 417 if (ret) 418 dev_warn(qcom->dev, "failed to enable interconnect: %d\n", ret); 419 420 /* Clear existing events from PHY related to L2 in/out */ 421 dwc3_qcom_setbits(qcom->qscratch_base, PWR_EVNT_IRQ_STAT_REG, 422 PWR_EVNT_LPM_IN_L2_MASK | PWR_EVNT_LPM_OUT_L2_MASK); 423 424 qcom->is_suspended = false; 425 426 return 0; 427} 428 429static irqreturn_t qcom_dwc3_resume_irq(int irq, void *data) 430{ 431 struct dwc3_qcom *qcom = data; 432 struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3); 433 434 /* If pm_suspended then let pm_resume take care of resuming h/w */ 435 if (qcom->pm_suspended) 436 return IRQ_HANDLED; 437 438 /* 439 * This is safe as role switching is done from a freezable workqueue 440 * and the wakeup interrupts are disabled as part of resume. 441 */ 442 if (dwc3_qcom_is_host(qcom)) 443 pm_runtime_resume(&dwc->xhci->dev); 444 445 return IRQ_HANDLED; 446} 447 448static void dwc3_qcom_select_utmi_clk(struct dwc3_qcom *qcom) 449{ 450 /* Configure dwc3 to use UTMI clock as PIPE clock not present */ 451 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG, 452 PIPE_UTMI_CLK_DIS); 453 454 usleep_range(100, 1000); 455 456 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG, 457 PIPE_UTMI_CLK_SEL | PIPE3_PHYSTATUS_SW); 458 459 usleep_range(100, 1000); 460 461 dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG, 462 PIPE_UTMI_CLK_DIS); 463} 464 465static int dwc3_qcom_get_irq(struct platform_device *pdev, 466 const char *name, int num) 467{ 468 struct dwc3_qcom *qcom = platform_get_drvdata(pdev); 469 struct platform_device *pdev_irq = qcom->urs_usb ? qcom->urs_usb : pdev; 470 struct device_node *np = pdev->dev.of_node; 471 int ret; 472 473 if (np) 474 ret = platform_get_irq_byname_optional(pdev_irq, name); 475 else 476 ret = platform_get_irq_optional(pdev_irq, num); 477 478 return ret; 479} 480 481static int dwc3_qcom_setup_irq(struct platform_device *pdev) 482{ 483 struct dwc3_qcom *qcom = platform_get_drvdata(pdev); 484 const struct dwc3_acpi_pdata *pdata = qcom->acpi_pdata; 485 int irq; 486 int ret; 487 488 irq = dwc3_qcom_get_irq(pdev, "hs_phy_irq", 489 pdata ? pdata->hs_phy_irq_index : -1); 490 if (irq > 0) { 491 /* Keep wakeup interrupts disabled until suspend */ 492 irq_set_status_flags(irq, IRQ_NOAUTOEN); 493 ret = devm_request_threaded_irq(qcom->dev, irq, NULL, 494 qcom_dwc3_resume_irq, 495 IRQF_ONESHOT, 496 "qcom_dwc3 HS", qcom); 497 if (ret) { 498 dev_err(qcom->dev, "hs_phy_irq failed: %d\n", ret); 499 return ret; 500 } 501 qcom->hs_phy_irq = irq; 502 } 503 504 irq = dwc3_qcom_get_irq(pdev, "dp_hs_phy_irq", 505 pdata ? pdata->dp_hs_phy_irq_index : -1); 506 if (irq > 0) { 507 irq_set_status_flags(irq, IRQ_NOAUTOEN); 508 ret = devm_request_threaded_irq(qcom->dev, irq, NULL, 509 qcom_dwc3_resume_irq, 510 IRQF_ONESHOT, 511 "qcom_dwc3 DP_HS", qcom); 512 if (ret) { 513 dev_err(qcom->dev, "dp_hs_phy_irq failed: %d\n", ret); 514 return ret; 515 } 516 qcom->dp_hs_phy_irq = irq; 517 } 518 519 irq = dwc3_qcom_get_irq(pdev, "dm_hs_phy_irq", 520 pdata ? pdata->dm_hs_phy_irq_index : -1); 521 if (irq > 0) { 522 irq_set_status_flags(irq, IRQ_NOAUTOEN); 523 ret = devm_request_threaded_irq(qcom->dev, irq, NULL, 524 qcom_dwc3_resume_irq, 525 IRQF_ONESHOT, 526 "qcom_dwc3 DM_HS", qcom); 527 if (ret) { 528 dev_err(qcom->dev, "dm_hs_phy_irq failed: %d\n", ret); 529 return ret; 530 } 531 qcom->dm_hs_phy_irq = irq; 532 } 533 534 irq = dwc3_qcom_get_irq(pdev, "ss_phy_irq", 535 pdata ? pdata->ss_phy_irq_index : -1); 536 if (irq > 0) { 537 irq_set_status_flags(irq, IRQ_NOAUTOEN); 538 ret = devm_request_threaded_irq(qcom->dev, irq, NULL, 539 qcom_dwc3_resume_irq, 540 IRQF_ONESHOT, 541 "qcom_dwc3 SS", qcom); 542 if (ret) { 543 dev_err(qcom->dev, "ss_phy_irq failed: %d\n", ret); 544 return ret; 545 } 546 qcom->ss_phy_irq = irq; 547 } 548 549 return 0; 550} 551 552static int dwc3_qcom_clk_init(struct dwc3_qcom *qcom, int count) 553{ 554 struct device *dev = qcom->dev; 555 struct device_node *np = dev->of_node; 556 int i; 557 558 if (!np || !count) 559 return 0; 560 561 if (count < 0) 562 return count; 563 564 qcom->num_clocks = count; 565 566 qcom->clks = devm_kcalloc(dev, qcom->num_clocks, 567 sizeof(struct clk *), GFP_KERNEL); 568 if (!qcom->clks) 569 return -ENOMEM; 570 571 for (i = 0; i < qcom->num_clocks; i++) { 572 struct clk *clk; 573 int ret; 574 575 clk = of_clk_get(np, i); 576 if (IS_ERR(clk)) { 577 while (--i >= 0) 578 clk_put(qcom->clks[i]); 579 return PTR_ERR(clk); 580 } 581 582 ret = clk_prepare_enable(clk); 583 if (ret < 0) { 584 while (--i >= 0) { 585 clk_disable_unprepare(qcom->clks[i]); 586 clk_put(qcom->clks[i]); 587 } 588 clk_put(clk); 589 590 return ret; 591 } 592 593 qcom->clks[i] = clk; 594 } 595 596 return 0; 597} 598 599static const struct property_entry dwc3_qcom_acpi_properties[] = { 600 PROPERTY_ENTRY_STRING("dr_mode", "host"), 601 {} 602}; 603 604static int dwc3_qcom_acpi_register_core(struct platform_device *pdev) 605{ 606 struct dwc3_qcom *qcom = platform_get_drvdata(pdev); 607 struct device *dev = &pdev->dev; 608 struct resource *res, *child_res = NULL; 609 struct platform_device *pdev_irq = qcom->urs_usb ? qcom->urs_usb : 610 pdev; 611 int irq; 612 int ret; 613 614 qcom->dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO); 615 if (!qcom->dwc3) 616 return -ENOMEM; 617 618 qcom->dwc3->dev.parent = dev; 619 qcom->dwc3->dev.type = dev->type; 620 qcom->dwc3->dev.dma_mask = dev->dma_mask; 621 qcom->dwc3->dev.dma_parms = dev->dma_parms; 622 qcom->dwc3->dev.coherent_dma_mask = dev->coherent_dma_mask; 623 624 child_res = kcalloc(2, sizeof(*child_res), GFP_KERNEL); 625 if (!child_res) { 626 platform_device_put(qcom->dwc3); 627 return -ENOMEM; 628 } 629 630 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 631 if (!res) { 632 dev_err(&pdev->dev, "failed to get memory resource\n"); 633 ret = -ENODEV; 634 goto out; 635 } 636 637 child_res[0].flags = res->flags; 638 child_res[0].start = res->start; 639 child_res[0].end = child_res[0].start + 640 qcom->acpi_pdata->dwc3_core_base_size; 641 642 irq = platform_get_irq(pdev_irq, 0); 643 if (irq < 0) { 644 ret = irq; 645 goto out; 646 } 647 child_res[1].flags = IORESOURCE_IRQ; 648 child_res[1].start = child_res[1].end = irq; 649 650 ret = platform_device_add_resources(qcom->dwc3, child_res, 2); 651 if (ret) { 652 dev_err(&pdev->dev, "failed to add resources\n"); 653 goto out; 654 } 655 656 ret = platform_device_add_properties(qcom->dwc3, 657 dwc3_qcom_acpi_properties); 658 if (ret < 0) { 659 dev_err(&pdev->dev, "failed to add properties\n"); 660 goto out; 661 } 662 663 ret = platform_device_add(qcom->dwc3); 664 if (ret) { 665 dev_err(&pdev->dev, "failed to add device\n"); 666 goto out; 667 } 668 kfree(child_res); 669 return 0; 670 671out: 672 platform_device_put(qcom->dwc3); 673 kfree(child_res); 674 return ret; 675} 676 677static int dwc3_qcom_of_register_core(struct platform_device *pdev) 678{ 679 struct dwc3_qcom *qcom = platform_get_drvdata(pdev); 680 struct device_node *np = pdev->dev.of_node, *dwc3_np; 681 struct device *dev = &pdev->dev; 682 int ret; 683 684 dwc3_np = of_get_child_by_name(np, "dwc3"); 685 if (!dwc3_np) { 686 dev_err(dev, "failed to find dwc3 core child\n"); 687 return -ENODEV; 688 } 689 690 ret = of_platform_populate(np, NULL, NULL, dev); 691 if (ret) { 692 dev_err(dev, "failed to register dwc3 core - %d\n", ret); 693 goto node_put; 694 } 695 696 qcom->dwc3 = of_find_device_by_node(dwc3_np); 697 if (!qcom->dwc3) { 698 ret = -ENODEV; 699 dev_err(dev, "failed to get dwc3 platform device\n"); 700 of_platform_depopulate(dev); 701 } 702 703node_put: 704 of_node_put(dwc3_np); 705 706 return ret; 707} 708 709static struct platform_device *dwc3_qcom_create_urs_usb_platdev(struct device *dev) 710{ 711 struct platform_device *urs_usb = NULL; 712 struct fwnode_handle *fwh; 713 struct acpi_device *adev; 714 char name[8]; 715 int ret; 716 int id; 717 718 /* Figure out device id */ 719 ret = sscanf(fwnode_get_name(dev->fwnode), "URS%d", &id); 720 if (!ret) 721 return NULL; 722 723 /* Find the child using name */ 724 snprintf(name, sizeof(name), "USB%d", id); 725 fwh = fwnode_get_named_child_node(dev->fwnode, name); 726 if (!fwh) 727 return NULL; 728 729 adev = to_acpi_device_node(fwh); 730 if (!adev) 731 goto err_put_handle; 732 733 urs_usb = acpi_create_platform_device(adev, NULL); 734 if (IS_ERR_OR_NULL(urs_usb)) 735 goto err_put_handle; 736 737 return urs_usb; 738 739err_put_handle: 740 fwnode_handle_put(fwh); 741 742 return urs_usb; 743} 744 745static void dwc3_qcom_destroy_urs_usb_platdev(struct platform_device *urs_usb) 746{ 747 struct fwnode_handle *fwh = urs_usb->dev.fwnode; 748 749 platform_device_unregister(urs_usb); 750 fwnode_handle_put(fwh); 751} 752 753static int dwc3_qcom_probe(struct platform_device *pdev) 754{ 755 struct device_node *np = pdev->dev.of_node; 756 struct device *dev = &pdev->dev; 757 struct dwc3_qcom *qcom; 758 struct resource *res, *parent_res = NULL; 759 struct resource local_res; 760 int ret, i; 761 bool ignore_pipe_clk; 762 763 qcom = devm_kzalloc(&pdev->dev, sizeof(*qcom), GFP_KERNEL); 764 if (!qcom) 765 return -ENOMEM; 766 767 platform_set_drvdata(pdev, qcom); 768 qcom->dev = &pdev->dev; 769 770 if (has_acpi_companion(dev)) { 771 qcom->acpi_pdata = acpi_device_get_match_data(dev); 772 if (!qcom->acpi_pdata) { 773 dev_err(&pdev->dev, "no supporting ACPI device data\n"); 774 return -EINVAL; 775 } 776 } 777 778 qcom->resets = devm_reset_control_array_get_optional_exclusive(dev); 779 if (IS_ERR(qcom->resets)) { 780 ret = PTR_ERR(qcom->resets); 781 dev_err(&pdev->dev, "failed to get resets, err=%d\n", ret); 782 return ret; 783 } 784 785 ret = reset_control_assert(qcom->resets); 786 if (ret) { 787 dev_err(&pdev->dev, "failed to assert resets, err=%d\n", ret); 788 return ret; 789 } 790 791 usleep_range(10, 1000); 792 793 ret = reset_control_deassert(qcom->resets); 794 if (ret) { 795 dev_err(&pdev->dev, "failed to deassert resets, err=%d\n", ret); 796 goto reset_assert; 797 } 798 799 ret = dwc3_qcom_clk_init(qcom, of_clk_get_parent_count(np)); 800 if (ret) { 801 dev_err(dev, "failed to get clocks\n"); 802 goto reset_assert; 803 } 804 805 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 806 807 if (np) { 808 parent_res = res; 809 } else { 810 memcpy(&local_res, res, sizeof(struct resource)); 811 parent_res = &local_res; 812 813 parent_res->start = res->start + 814 qcom->acpi_pdata->qscratch_base_offset; 815 parent_res->end = parent_res->start + 816 qcom->acpi_pdata->qscratch_base_size; 817 818 if (qcom->acpi_pdata->is_urs) { 819 qcom->urs_usb = dwc3_qcom_create_urs_usb_platdev(dev); 820 if (IS_ERR_OR_NULL(qcom->urs_usb)) { 821 dev_err(dev, "failed to create URS USB platdev\n"); 822 if (!qcom->urs_usb) 823 ret = -ENODEV; 824 else 825 ret = PTR_ERR(qcom->urs_usb); 826 goto clk_disable; 827 } 828 } 829 } 830 831 qcom->qscratch_base = devm_ioremap_resource(dev, parent_res); 832 if (IS_ERR(qcom->qscratch_base)) { 833 dev_err(dev, "failed to map qscratch, err=%d\n", ret); 834 ret = PTR_ERR(qcom->qscratch_base); 835 goto free_urs; 836 } 837 838 ret = dwc3_qcom_setup_irq(pdev); 839 if (ret) { 840 dev_err(dev, "failed to setup IRQs, err=%d\n", ret); 841 goto free_urs; 842 } 843 844 /* 845 * Disable pipe_clk requirement if specified. Used when dwc3 846 * operates without SSPHY and only HS/FS/LS modes are supported. 847 */ 848 ignore_pipe_clk = device_property_read_bool(dev, 849 "qcom,select-utmi-as-pipe-clk"); 850 if (ignore_pipe_clk) 851 dwc3_qcom_select_utmi_clk(qcom); 852 853 if (np) 854 ret = dwc3_qcom_of_register_core(pdev); 855 else 856 ret = dwc3_qcom_acpi_register_core(pdev); 857 858 if (ret) { 859 dev_err(dev, "failed to register DWC3 Core, err=%d\n", ret); 860 goto free_urs; 861 } 862 863 ret = dwc3_qcom_interconnect_init(qcom); 864 if (ret) 865 goto depopulate; 866 867 qcom->mode = usb_get_dr_mode(&qcom->dwc3->dev); 868 869 /* enable vbus override for device mode */ 870 if (qcom->mode != USB_DR_MODE_HOST) 871 dwc3_qcom_vbus_override_enable(qcom, true); 872 873 /* register extcon to override sw_vbus on Vbus change later */ 874 ret = dwc3_qcom_register_extcon(qcom); 875 if (ret) 876 goto interconnect_exit; 877 878 device_init_wakeup(&pdev->dev, 1); 879 qcom->is_suspended = false; 880 pm_runtime_set_active(dev); 881 pm_runtime_enable(dev); 882 pm_runtime_forbid(dev); 883 884 return 0; 885 886interconnect_exit: 887 dwc3_qcom_interconnect_exit(qcom); 888depopulate: 889 if (np) 890 of_platform_depopulate(&pdev->dev); 891 else 892 platform_device_del(qcom->dwc3); 893 platform_device_put(qcom->dwc3); 894free_urs: 895 if (qcom->urs_usb) 896 dwc3_qcom_destroy_urs_usb_platdev(qcom->urs_usb); 897clk_disable: 898 for (i = qcom->num_clocks - 1; i >= 0; i--) { 899 clk_disable_unprepare(qcom->clks[i]); 900 clk_put(qcom->clks[i]); 901 } 902reset_assert: 903 reset_control_assert(qcom->resets); 904 905 return ret; 906} 907 908static int dwc3_qcom_remove(struct platform_device *pdev) 909{ 910 struct dwc3_qcom *qcom = platform_get_drvdata(pdev); 911 struct device_node *np = pdev->dev.of_node; 912 struct device *dev = &pdev->dev; 913 int i; 914 915 if (np) 916 of_platform_depopulate(&pdev->dev); 917 else 918 platform_device_del(qcom->dwc3); 919 platform_device_put(qcom->dwc3); 920 921 if (qcom->urs_usb) 922 dwc3_qcom_destroy_urs_usb_platdev(qcom->urs_usb); 923 924 for (i = qcom->num_clocks - 1; i >= 0; i--) { 925 clk_disable_unprepare(qcom->clks[i]); 926 clk_put(qcom->clks[i]); 927 } 928 qcom->num_clocks = 0; 929 930 dwc3_qcom_interconnect_exit(qcom); 931 reset_control_assert(qcom->resets); 932 933 pm_runtime_allow(dev); 934 pm_runtime_disable(dev); 935 936 return 0; 937} 938 939static int __maybe_unused dwc3_qcom_pm_suspend(struct device *dev) 940{ 941 struct dwc3_qcom *qcom = dev_get_drvdata(dev); 942 int ret = 0; 943 944 ret = dwc3_qcom_suspend(qcom); 945 if (!ret) 946 qcom->pm_suspended = true; 947 948 return ret; 949} 950 951static int __maybe_unused dwc3_qcom_pm_resume(struct device *dev) 952{ 953 struct dwc3_qcom *qcom = dev_get_drvdata(dev); 954 int ret; 955 956 ret = dwc3_qcom_resume(qcom); 957 if (!ret) 958 qcom->pm_suspended = false; 959 960 return ret; 961} 962 963static int __maybe_unused dwc3_qcom_runtime_suspend(struct device *dev) 964{ 965 struct dwc3_qcom *qcom = dev_get_drvdata(dev); 966 967 return dwc3_qcom_suspend(qcom); 968} 969 970static int __maybe_unused dwc3_qcom_runtime_resume(struct device *dev) 971{ 972 struct dwc3_qcom *qcom = dev_get_drvdata(dev); 973 974 return dwc3_qcom_resume(qcom); 975} 976 977static const struct dev_pm_ops dwc3_qcom_dev_pm_ops = { 978 SET_SYSTEM_SLEEP_PM_OPS(dwc3_qcom_pm_suspend, dwc3_qcom_pm_resume) 979 SET_RUNTIME_PM_OPS(dwc3_qcom_runtime_suspend, dwc3_qcom_runtime_resume, 980 NULL) 981}; 982 983static const struct of_device_id dwc3_qcom_of_match[] = { 984 { .compatible = "qcom,dwc3" }, 985 { .compatible = "qcom,msm8996-dwc3" }, 986 { .compatible = "qcom,msm8998-dwc3" }, 987 { .compatible = "qcom,sdm845-dwc3" }, 988 { } 989}; 990MODULE_DEVICE_TABLE(of, dwc3_qcom_of_match); 991 992#ifdef CONFIG_ACPI 993static const struct dwc3_acpi_pdata sdm845_acpi_pdata = { 994 .qscratch_base_offset = SDM845_QSCRATCH_BASE_OFFSET, 995 .qscratch_base_size = SDM845_QSCRATCH_SIZE, 996 .dwc3_core_base_size = SDM845_DWC3_CORE_SIZE, 997 .hs_phy_irq_index = 1, 998 .dp_hs_phy_irq_index = 4, 999 .dm_hs_phy_irq_index = 3, 1000 .ss_phy_irq_index = 2 1001}; 1002 1003static const struct dwc3_acpi_pdata sdm845_acpi_urs_pdata = { 1004 .qscratch_base_offset = SDM845_QSCRATCH_BASE_OFFSET, 1005 .qscratch_base_size = SDM845_QSCRATCH_SIZE, 1006 .dwc3_core_base_size = SDM845_DWC3_CORE_SIZE, 1007 .hs_phy_irq_index = 1, 1008 .dp_hs_phy_irq_index = 4, 1009 .dm_hs_phy_irq_index = 3, 1010 .ss_phy_irq_index = 2, 1011 .is_urs = true, 1012}; 1013 1014static const struct acpi_device_id dwc3_qcom_acpi_match[] = { 1015 { "QCOM2430", (unsigned long)&sdm845_acpi_pdata }, 1016 { "QCOM0304", (unsigned long)&sdm845_acpi_urs_pdata }, 1017 { "QCOM0497", (unsigned long)&sdm845_acpi_urs_pdata }, 1018 { "QCOM04A6", (unsigned long)&sdm845_acpi_pdata }, 1019 { }, 1020}; 1021MODULE_DEVICE_TABLE(acpi, dwc3_qcom_acpi_match); 1022#endif 1023 1024static struct platform_driver dwc3_qcom_driver = { 1025 .probe = dwc3_qcom_probe, 1026 .remove = dwc3_qcom_remove, 1027 .driver = { 1028 .name = "dwc3-qcom", 1029 .pm = &dwc3_qcom_dev_pm_ops, 1030 .of_match_table = dwc3_qcom_of_match, 1031 .acpi_match_table = ACPI_PTR(dwc3_qcom_acpi_match), 1032 }, 1033}; 1034 1035module_platform_driver(dwc3_qcom_driver); 1036 1037MODULE_LICENSE("GPL v2"); 1038MODULE_DESCRIPTION("DesignWare DWC3 QCOM Glue Driver"); 1039