0001
0002
0003
0004
0005
0006
0007 #include <linux/acpi.h>
0008 #include <linux/io.h>
0009 #include <linux/of.h>
0010 #include <linux/clk.h>
0011 #include <linux/irq.h>
0012 #include <linux/of_clk.h>
0013 #include <linux/module.h>
0014 #include <linux/kernel.h>
0015 #include <linux/extcon.h>
0016 #include <linux/interconnect.h>
0017 #include <linux/of_platform.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/phy/phy.h>
0020 #include <linux/usb/of.h>
0021 #include <linux/reset.h>
0022 #include <linux/iopoll.h>
0023 #include <linux/usb/hcd.h>
0024 #include <linux/usb.h>
0025 #include "core.h"
0026
0027
0028 #define QSCRATCH_HS_PHY_CTRL 0x10
0029 #define UTMI_OTG_VBUS_VALID BIT(20)
0030 #define SW_SESSVLD_SEL BIT(28)
0031
0032 #define QSCRATCH_SS_PHY_CTRL 0x30
0033 #define LANE0_PWR_PRESENT BIT(24)
0034
0035 #define QSCRATCH_GENERAL_CFG 0x08
0036 #define PIPE_UTMI_CLK_SEL BIT(0)
0037 #define PIPE3_PHYSTATUS_SW BIT(3)
0038 #define PIPE_UTMI_CLK_DIS BIT(8)
0039
0040 #define PWR_EVNT_IRQ_STAT_REG 0x58
0041 #define PWR_EVNT_LPM_IN_L2_MASK BIT(4)
0042 #define PWR_EVNT_LPM_OUT_L2_MASK BIT(5)
0043
0044 #define SDM845_QSCRATCH_BASE_OFFSET 0xf8800
0045 #define SDM845_QSCRATCH_SIZE 0x400
0046 #define SDM845_DWC3_CORE_SIZE 0xcd00
0047
0048
0049 #define USB_MEMORY_AVG_HS_BW MBps_to_icc(240)
0050 #define USB_MEMORY_PEAK_HS_BW MBps_to_icc(700)
0051 #define USB_MEMORY_AVG_SS_BW MBps_to_icc(1000)
0052 #define USB_MEMORY_PEAK_SS_BW MBps_to_icc(2500)
0053 #define APPS_USB_AVG_BW 0
0054 #define APPS_USB_PEAK_BW MBps_to_icc(40)
0055
0056 struct dwc3_acpi_pdata {
0057 u32 qscratch_base_offset;
0058 u32 qscratch_base_size;
0059 u32 dwc3_core_base_size;
0060 int hs_phy_irq_index;
0061 int dp_hs_phy_irq_index;
0062 int dm_hs_phy_irq_index;
0063 int ss_phy_irq_index;
0064 bool is_urs;
0065 };
0066
0067 struct dwc3_qcom {
0068 struct device *dev;
0069 void __iomem *qscratch_base;
0070 struct platform_device *dwc3;
0071 struct platform_device *urs_usb;
0072 struct clk **clks;
0073 int num_clocks;
0074 struct reset_control *resets;
0075
0076 int hs_phy_irq;
0077 int dp_hs_phy_irq;
0078 int dm_hs_phy_irq;
0079 int ss_phy_irq;
0080 enum usb_device_speed usb2_speed;
0081
0082 struct extcon_dev *edev;
0083 struct extcon_dev *host_edev;
0084 struct notifier_block vbus_nb;
0085 struct notifier_block host_nb;
0086
0087 const struct dwc3_acpi_pdata *acpi_pdata;
0088
0089 enum usb_dr_mode mode;
0090 bool is_suspended;
0091 bool pm_suspended;
0092 struct icc_path *icc_path_ddr;
0093 struct icc_path *icc_path_apps;
0094 };
0095
0096 static inline void dwc3_qcom_setbits(void __iomem *base, u32 offset, u32 val)
0097 {
0098 u32 reg;
0099
0100 reg = readl(base + offset);
0101 reg |= val;
0102 writel(reg, base + offset);
0103
0104
0105 readl(base + offset);
0106 }
0107
0108 static inline void dwc3_qcom_clrbits(void __iomem *base, u32 offset, u32 val)
0109 {
0110 u32 reg;
0111
0112 reg = readl(base + offset);
0113 reg &= ~val;
0114 writel(reg, base + offset);
0115
0116
0117 readl(base + offset);
0118 }
0119
0120 static void dwc3_qcom_vbus_override_enable(struct dwc3_qcom *qcom, bool enable)
0121 {
0122 if (enable) {
0123 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_SS_PHY_CTRL,
0124 LANE0_PWR_PRESENT);
0125 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_HS_PHY_CTRL,
0126 UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
0127 } else {
0128 dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_SS_PHY_CTRL,
0129 LANE0_PWR_PRESENT);
0130 dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_HS_PHY_CTRL,
0131 UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
0132 }
0133 }
0134
0135 static int dwc3_qcom_vbus_notifier(struct notifier_block *nb,
0136 unsigned long event, void *ptr)
0137 {
0138 struct dwc3_qcom *qcom = container_of(nb, struct dwc3_qcom, vbus_nb);
0139
0140
0141 dwc3_qcom_vbus_override_enable(qcom, event);
0142 qcom->mode = event ? USB_DR_MODE_PERIPHERAL : USB_DR_MODE_HOST;
0143
0144 return NOTIFY_DONE;
0145 }
0146
0147 static int dwc3_qcom_host_notifier(struct notifier_block *nb,
0148 unsigned long event, void *ptr)
0149 {
0150 struct dwc3_qcom *qcom = container_of(nb, struct dwc3_qcom, host_nb);
0151
0152
0153 dwc3_qcom_vbus_override_enable(qcom, !event);
0154 qcom->mode = event ? USB_DR_MODE_HOST : USB_DR_MODE_PERIPHERAL;
0155
0156 return NOTIFY_DONE;
0157 }
0158
0159 static int dwc3_qcom_register_extcon(struct dwc3_qcom *qcom)
0160 {
0161 struct device *dev = qcom->dev;
0162 struct extcon_dev *host_edev;
0163 int ret;
0164
0165 if (!of_property_read_bool(dev->of_node, "extcon"))
0166 return 0;
0167
0168 qcom->edev = extcon_get_edev_by_phandle(dev, 0);
0169 if (IS_ERR(qcom->edev))
0170 return PTR_ERR(qcom->edev);
0171
0172 qcom->vbus_nb.notifier_call = dwc3_qcom_vbus_notifier;
0173
0174 qcom->host_edev = extcon_get_edev_by_phandle(dev, 1);
0175 if (IS_ERR(qcom->host_edev))
0176 qcom->host_edev = NULL;
0177
0178 ret = devm_extcon_register_notifier(dev, qcom->edev, EXTCON_USB,
0179 &qcom->vbus_nb);
0180 if (ret < 0) {
0181 dev_err(dev, "VBUS notifier register failed\n");
0182 return ret;
0183 }
0184
0185 if (qcom->host_edev)
0186 host_edev = qcom->host_edev;
0187 else
0188 host_edev = qcom->edev;
0189
0190 qcom->host_nb.notifier_call = dwc3_qcom_host_notifier;
0191 ret = devm_extcon_register_notifier(dev, host_edev, EXTCON_USB_HOST,
0192 &qcom->host_nb);
0193 if (ret < 0) {
0194 dev_err(dev, "Host notifier register failed\n");
0195 return ret;
0196 }
0197
0198
0199 if (extcon_get_state(qcom->edev, EXTCON_USB) ||
0200 !extcon_get_state(host_edev, EXTCON_USB_HOST))
0201 dwc3_qcom_vbus_notifier(&qcom->vbus_nb, true, qcom->edev);
0202 else
0203 dwc3_qcom_vbus_notifier(&qcom->vbus_nb, false, qcom->edev);
0204
0205 return 0;
0206 }
0207
0208 static int dwc3_qcom_interconnect_enable(struct dwc3_qcom *qcom)
0209 {
0210 int ret;
0211
0212 ret = icc_enable(qcom->icc_path_ddr);
0213 if (ret)
0214 return ret;
0215
0216 ret = icc_enable(qcom->icc_path_apps);
0217 if (ret)
0218 icc_disable(qcom->icc_path_ddr);
0219
0220 return ret;
0221 }
0222
0223 static int dwc3_qcom_interconnect_disable(struct dwc3_qcom *qcom)
0224 {
0225 int ret;
0226
0227 ret = icc_disable(qcom->icc_path_ddr);
0228 if (ret)
0229 return ret;
0230
0231 ret = icc_disable(qcom->icc_path_apps);
0232 if (ret)
0233 icc_enable(qcom->icc_path_ddr);
0234
0235 return ret;
0236 }
0237
0238
0239
0240
0241
0242
0243
0244 static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom)
0245 {
0246 struct device *dev = qcom->dev;
0247 int ret;
0248
0249 if (has_acpi_companion(dev))
0250 return 0;
0251
0252 qcom->icc_path_ddr = of_icc_get(dev, "usb-ddr");
0253 if (IS_ERR(qcom->icc_path_ddr)) {
0254 dev_err(dev, "failed to get usb-ddr path: %ld\n",
0255 PTR_ERR(qcom->icc_path_ddr));
0256 return PTR_ERR(qcom->icc_path_ddr);
0257 }
0258
0259 qcom->icc_path_apps = of_icc_get(dev, "apps-usb");
0260 if (IS_ERR(qcom->icc_path_apps)) {
0261 dev_err(dev, "failed to get apps-usb path: %ld\n",
0262 PTR_ERR(qcom->icc_path_apps));
0263 return PTR_ERR(qcom->icc_path_apps);
0264 }
0265
0266 if (usb_get_maximum_speed(&qcom->dwc3->dev) >= USB_SPEED_SUPER ||
0267 usb_get_maximum_speed(&qcom->dwc3->dev) == USB_SPEED_UNKNOWN)
0268 ret = icc_set_bw(qcom->icc_path_ddr,
0269 USB_MEMORY_AVG_SS_BW, USB_MEMORY_PEAK_SS_BW);
0270 else
0271 ret = icc_set_bw(qcom->icc_path_ddr,
0272 USB_MEMORY_AVG_HS_BW, USB_MEMORY_PEAK_HS_BW);
0273
0274 if (ret) {
0275 dev_err(dev, "failed to set bandwidth for usb-ddr path: %d\n", ret);
0276 return ret;
0277 }
0278
0279 ret = icc_set_bw(qcom->icc_path_apps,
0280 APPS_USB_AVG_BW, APPS_USB_PEAK_BW);
0281 if (ret) {
0282 dev_err(dev, "failed to set bandwidth for apps-usb path: %d\n", ret);
0283 return ret;
0284 }
0285
0286 return 0;
0287 }
0288
0289
0290
0291
0292
0293
0294
0295 static void dwc3_qcom_interconnect_exit(struct dwc3_qcom *qcom)
0296 {
0297 icc_put(qcom->icc_path_ddr);
0298 icc_put(qcom->icc_path_apps);
0299 }
0300
0301
0302 static bool dwc3_qcom_is_host(struct dwc3_qcom *qcom)
0303 {
0304 struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3);
0305
0306 return dwc->xhci;
0307 }
0308
0309 static enum usb_device_speed dwc3_qcom_read_usb2_speed(struct dwc3_qcom *qcom)
0310 {
0311 struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3);
0312 struct usb_device *udev;
0313 struct usb_hcd __maybe_unused *hcd;
0314
0315
0316
0317
0318 hcd = platform_get_drvdata(dwc->xhci);
0319
0320
0321
0322
0323
0324
0325
0326 #ifdef CONFIG_USB
0327 udev = usb_hub_find_child(hcd->self.root_hub, 1);
0328 #else
0329 udev = NULL;
0330 #endif
0331 if (!udev)
0332 return USB_SPEED_UNKNOWN;
0333
0334 return udev->speed;
0335 }
0336
0337 static void dwc3_qcom_enable_wakeup_irq(int irq, unsigned int polarity)
0338 {
0339 if (!irq)
0340 return;
0341
0342 if (polarity)
0343 irq_set_irq_type(irq, polarity);
0344
0345 enable_irq(irq);
0346 enable_irq_wake(irq);
0347 }
0348
0349 static void dwc3_qcom_disable_wakeup_irq(int irq)
0350 {
0351 if (!irq)
0352 return;
0353
0354 disable_irq_wake(irq);
0355 disable_irq_nosync(irq);
0356 }
0357
0358 static void dwc3_qcom_disable_interrupts(struct dwc3_qcom *qcom)
0359 {
0360 dwc3_qcom_disable_wakeup_irq(qcom->hs_phy_irq);
0361
0362 if (qcom->usb2_speed == USB_SPEED_LOW) {
0363 dwc3_qcom_disable_wakeup_irq(qcom->dm_hs_phy_irq);
0364 } else if ((qcom->usb2_speed == USB_SPEED_HIGH) ||
0365 (qcom->usb2_speed == USB_SPEED_FULL)) {
0366 dwc3_qcom_disable_wakeup_irq(qcom->dp_hs_phy_irq);
0367 } else {
0368 dwc3_qcom_disable_wakeup_irq(qcom->dp_hs_phy_irq);
0369 dwc3_qcom_disable_wakeup_irq(qcom->dm_hs_phy_irq);
0370 }
0371
0372 dwc3_qcom_disable_wakeup_irq(qcom->ss_phy_irq);
0373 }
0374
0375 static void dwc3_qcom_enable_interrupts(struct dwc3_qcom *qcom)
0376 {
0377 dwc3_qcom_enable_wakeup_irq(qcom->hs_phy_irq, 0);
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388 if (qcom->usb2_speed == USB_SPEED_LOW) {
0389 dwc3_qcom_enable_wakeup_irq(qcom->dm_hs_phy_irq,
0390 IRQ_TYPE_EDGE_FALLING);
0391 } else if ((qcom->usb2_speed == USB_SPEED_HIGH) ||
0392 (qcom->usb2_speed == USB_SPEED_FULL)) {
0393 dwc3_qcom_enable_wakeup_irq(qcom->dp_hs_phy_irq,
0394 IRQ_TYPE_EDGE_FALLING);
0395 } else {
0396 dwc3_qcom_enable_wakeup_irq(qcom->dp_hs_phy_irq,
0397 IRQ_TYPE_EDGE_RISING);
0398 dwc3_qcom_enable_wakeup_irq(qcom->dm_hs_phy_irq,
0399 IRQ_TYPE_EDGE_RISING);
0400 }
0401
0402 dwc3_qcom_enable_wakeup_irq(qcom->ss_phy_irq, 0);
0403 }
0404
0405 static int dwc3_qcom_suspend(struct dwc3_qcom *qcom, bool wakeup)
0406 {
0407 u32 val;
0408 int i, ret;
0409
0410 if (qcom->is_suspended)
0411 return 0;
0412
0413 val = readl(qcom->qscratch_base + PWR_EVNT_IRQ_STAT_REG);
0414 if (!(val & PWR_EVNT_LPM_IN_L2_MASK))
0415 dev_err(qcom->dev, "HS-PHY not in L2\n");
0416
0417 for (i = qcom->num_clocks - 1; i >= 0; i--)
0418 clk_disable_unprepare(qcom->clks[i]);
0419
0420 ret = dwc3_qcom_interconnect_disable(qcom);
0421 if (ret)
0422 dev_warn(qcom->dev, "failed to disable interconnect: %d\n", ret);
0423
0424
0425
0426
0427
0428 if (dwc3_qcom_is_host(qcom) && wakeup) {
0429 qcom->usb2_speed = dwc3_qcom_read_usb2_speed(qcom);
0430 dwc3_qcom_enable_interrupts(qcom);
0431 }
0432
0433 qcom->is_suspended = true;
0434
0435 return 0;
0436 }
0437
0438 static int dwc3_qcom_resume(struct dwc3_qcom *qcom, bool wakeup)
0439 {
0440 int ret;
0441 int i;
0442
0443 if (!qcom->is_suspended)
0444 return 0;
0445
0446 if (dwc3_qcom_is_host(qcom) && wakeup)
0447 dwc3_qcom_disable_interrupts(qcom);
0448
0449 for (i = 0; i < qcom->num_clocks; i++) {
0450 ret = clk_prepare_enable(qcom->clks[i]);
0451 if (ret < 0) {
0452 while (--i >= 0)
0453 clk_disable_unprepare(qcom->clks[i]);
0454 return ret;
0455 }
0456 }
0457
0458 ret = dwc3_qcom_interconnect_enable(qcom);
0459 if (ret)
0460 dev_warn(qcom->dev, "failed to enable interconnect: %d\n", ret);
0461
0462
0463 dwc3_qcom_setbits(qcom->qscratch_base, PWR_EVNT_IRQ_STAT_REG,
0464 PWR_EVNT_LPM_IN_L2_MASK | PWR_EVNT_LPM_OUT_L2_MASK);
0465
0466 qcom->is_suspended = false;
0467
0468 return 0;
0469 }
0470
0471 static irqreturn_t qcom_dwc3_resume_irq(int irq, void *data)
0472 {
0473 struct dwc3_qcom *qcom = data;
0474 struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3);
0475
0476
0477 if (qcom->pm_suspended)
0478 return IRQ_HANDLED;
0479
0480
0481
0482
0483
0484 if (dwc3_qcom_is_host(qcom))
0485 pm_runtime_resume(&dwc->xhci->dev);
0486
0487 return IRQ_HANDLED;
0488 }
0489
0490 static void dwc3_qcom_select_utmi_clk(struct dwc3_qcom *qcom)
0491 {
0492
0493 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG,
0494 PIPE_UTMI_CLK_DIS);
0495
0496 usleep_range(100, 1000);
0497
0498 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG,
0499 PIPE_UTMI_CLK_SEL | PIPE3_PHYSTATUS_SW);
0500
0501 usleep_range(100, 1000);
0502
0503 dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG,
0504 PIPE_UTMI_CLK_DIS);
0505 }
0506
0507 static int dwc3_qcom_get_irq(struct platform_device *pdev,
0508 const char *name, int num)
0509 {
0510 struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
0511 struct platform_device *pdev_irq = qcom->urs_usb ? qcom->urs_usb : pdev;
0512 struct device_node *np = pdev->dev.of_node;
0513 int ret;
0514
0515 if (np)
0516 ret = platform_get_irq_byname_optional(pdev_irq, name);
0517 else
0518 ret = platform_get_irq_optional(pdev_irq, num);
0519
0520 return ret;
0521 }
0522
0523 static int dwc3_qcom_setup_irq(struct platform_device *pdev)
0524 {
0525 struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
0526 const struct dwc3_acpi_pdata *pdata = qcom->acpi_pdata;
0527 int irq;
0528 int ret;
0529
0530 irq = dwc3_qcom_get_irq(pdev, "hs_phy_irq",
0531 pdata ? pdata->hs_phy_irq_index : -1);
0532 if (irq > 0) {
0533
0534 irq_set_status_flags(irq, IRQ_NOAUTOEN);
0535 ret = devm_request_threaded_irq(qcom->dev, irq, NULL,
0536 qcom_dwc3_resume_irq,
0537 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
0538 "qcom_dwc3 HS", qcom);
0539 if (ret) {
0540 dev_err(qcom->dev, "hs_phy_irq failed: %d\n", ret);
0541 return ret;
0542 }
0543 qcom->hs_phy_irq = irq;
0544 }
0545
0546 irq = dwc3_qcom_get_irq(pdev, "dp_hs_phy_irq",
0547 pdata ? pdata->dp_hs_phy_irq_index : -1);
0548 if (irq > 0) {
0549 irq_set_status_flags(irq, IRQ_NOAUTOEN);
0550 ret = devm_request_threaded_irq(qcom->dev, irq, NULL,
0551 qcom_dwc3_resume_irq,
0552 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
0553 "qcom_dwc3 DP_HS", qcom);
0554 if (ret) {
0555 dev_err(qcom->dev, "dp_hs_phy_irq failed: %d\n", ret);
0556 return ret;
0557 }
0558 qcom->dp_hs_phy_irq = irq;
0559 }
0560
0561 irq = dwc3_qcom_get_irq(pdev, "dm_hs_phy_irq",
0562 pdata ? pdata->dm_hs_phy_irq_index : -1);
0563 if (irq > 0) {
0564 irq_set_status_flags(irq, IRQ_NOAUTOEN);
0565 ret = devm_request_threaded_irq(qcom->dev, irq, NULL,
0566 qcom_dwc3_resume_irq,
0567 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
0568 "qcom_dwc3 DM_HS", qcom);
0569 if (ret) {
0570 dev_err(qcom->dev, "dm_hs_phy_irq failed: %d\n", ret);
0571 return ret;
0572 }
0573 qcom->dm_hs_phy_irq = irq;
0574 }
0575
0576 irq = dwc3_qcom_get_irq(pdev, "ss_phy_irq",
0577 pdata ? pdata->ss_phy_irq_index : -1);
0578 if (irq > 0) {
0579 irq_set_status_flags(irq, IRQ_NOAUTOEN);
0580 ret = devm_request_threaded_irq(qcom->dev, irq, NULL,
0581 qcom_dwc3_resume_irq,
0582 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
0583 "qcom_dwc3 SS", qcom);
0584 if (ret) {
0585 dev_err(qcom->dev, "ss_phy_irq failed: %d\n", ret);
0586 return ret;
0587 }
0588 qcom->ss_phy_irq = irq;
0589 }
0590
0591 return 0;
0592 }
0593
0594 static int dwc3_qcom_clk_init(struct dwc3_qcom *qcom, int count)
0595 {
0596 struct device *dev = qcom->dev;
0597 struct device_node *np = dev->of_node;
0598 int i;
0599
0600 if (!np || !count)
0601 return 0;
0602
0603 if (count < 0)
0604 return count;
0605
0606 qcom->num_clocks = count;
0607
0608 qcom->clks = devm_kcalloc(dev, qcom->num_clocks,
0609 sizeof(struct clk *), GFP_KERNEL);
0610 if (!qcom->clks)
0611 return -ENOMEM;
0612
0613 for (i = 0; i < qcom->num_clocks; i++) {
0614 struct clk *clk;
0615 int ret;
0616
0617 clk = of_clk_get(np, i);
0618 if (IS_ERR(clk)) {
0619 while (--i >= 0)
0620 clk_put(qcom->clks[i]);
0621 return PTR_ERR(clk);
0622 }
0623
0624 ret = clk_prepare_enable(clk);
0625 if (ret < 0) {
0626 while (--i >= 0) {
0627 clk_disable_unprepare(qcom->clks[i]);
0628 clk_put(qcom->clks[i]);
0629 }
0630 clk_put(clk);
0631
0632 return ret;
0633 }
0634
0635 qcom->clks[i] = clk;
0636 }
0637
0638 return 0;
0639 }
0640
0641 static const struct property_entry dwc3_qcom_acpi_properties[] = {
0642 PROPERTY_ENTRY_STRING("dr_mode", "host"),
0643 {}
0644 };
0645
0646 static const struct software_node dwc3_qcom_swnode = {
0647 .properties = dwc3_qcom_acpi_properties,
0648 };
0649
0650 static int dwc3_qcom_acpi_register_core(struct platform_device *pdev)
0651 {
0652 struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
0653 struct device *dev = &pdev->dev;
0654 struct resource *res, *child_res = NULL;
0655 struct platform_device *pdev_irq = qcom->urs_usb ? qcom->urs_usb :
0656 pdev;
0657 int irq;
0658 int ret;
0659
0660 qcom->dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
0661 if (!qcom->dwc3)
0662 return -ENOMEM;
0663
0664 qcom->dwc3->dev.parent = dev;
0665 qcom->dwc3->dev.type = dev->type;
0666 qcom->dwc3->dev.dma_mask = dev->dma_mask;
0667 qcom->dwc3->dev.dma_parms = dev->dma_parms;
0668 qcom->dwc3->dev.coherent_dma_mask = dev->coherent_dma_mask;
0669
0670 child_res = kcalloc(2, sizeof(*child_res), GFP_KERNEL);
0671 if (!child_res) {
0672 platform_device_put(qcom->dwc3);
0673 return -ENOMEM;
0674 }
0675
0676 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0677 if (!res) {
0678 dev_err(&pdev->dev, "failed to get memory resource\n");
0679 ret = -ENODEV;
0680 goto out;
0681 }
0682
0683 child_res[0].flags = res->flags;
0684 child_res[0].start = res->start;
0685 child_res[0].end = child_res[0].start +
0686 qcom->acpi_pdata->dwc3_core_base_size;
0687
0688 irq = platform_get_irq(pdev_irq, 0);
0689 if (irq < 0) {
0690 ret = irq;
0691 goto out;
0692 }
0693 child_res[1].flags = IORESOURCE_IRQ;
0694 child_res[1].start = child_res[1].end = irq;
0695
0696 ret = platform_device_add_resources(qcom->dwc3, child_res, 2);
0697 if (ret) {
0698 dev_err(&pdev->dev, "failed to add resources\n");
0699 goto out;
0700 }
0701
0702 ret = device_add_software_node(&qcom->dwc3->dev, &dwc3_qcom_swnode);
0703 if (ret < 0) {
0704 dev_err(&pdev->dev, "failed to add properties\n");
0705 goto out;
0706 }
0707
0708 ret = platform_device_add(qcom->dwc3);
0709 if (ret) {
0710 dev_err(&pdev->dev, "failed to add device\n");
0711 device_remove_software_node(&qcom->dwc3->dev);
0712 goto out;
0713 }
0714 kfree(child_res);
0715 return 0;
0716
0717 out:
0718 platform_device_put(qcom->dwc3);
0719 kfree(child_res);
0720 return ret;
0721 }
0722
0723 static int dwc3_qcom_of_register_core(struct platform_device *pdev)
0724 {
0725 struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
0726 struct device_node *np = pdev->dev.of_node, *dwc3_np;
0727 struct device *dev = &pdev->dev;
0728 int ret;
0729
0730 dwc3_np = of_get_compatible_child(np, "snps,dwc3");
0731 if (!dwc3_np) {
0732 dev_err(dev, "failed to find dwc3 core child\n");
0733 return -ENODEV;
0734 }
0735
0736 ret = of_platform_populate(np, NULL, NULL, dev);
0737 if (ret) {
0738 dev_err(dev, "failed to register dwc3 core - %d\n", ret);
0739 goto node_put;
0740 }
0741
0742 qcom->dwc3 = of_find_device_by_node(dwc3_np);
0743 if (!qcom->dwc3) {
0744 ret = -ENODEV;
0745 dev_err(dev, "failed to get dwc3 platform device\n");
0746 }
0747
0748 node_put:
0749 of_node_put(dwc3_np);
0750
0751 return ret;
0752 }
0753
0754 static struct platform_device *
0755 dwc3_qcom_create_urs_usb_platdev(struct device *dev)
0756 {
0757 struct fwnode_handle *fwh;
0758 struct acpi_device *adev;
0759 char name[8];
0760 int ret;
0761 int id;
0762
0763
0764 ret = sscanf(fwnode_get_name(dev->fwnode), "URS%d", &id);
0765 if (!ret)
0766 return NULL;
0767
0768
0769 snprintf(name, sizeof(name), "USB%d", id);
0770 fwh = fwnode_get_named_child_node(dev->fwnode, name);
0771 if (!fwh)
0772 return NULL;
0773
0774 adev = to_acpi_device_node(fwh);
0775 if (!adev)
0776 return NULL;
0777
0778 return acpi_create_platform_device(adev, NULL);
0779 }
0780
0781 static int dwc3_qcom_probe(struct platform_device *pdev)
0782 {
0783 struct device_node *np = pdev->dev.of_node;
0784 struct device *dev = &pdev->dev;
0785 struct dwc3_qcom *qcom;
0786 struct resource *res, *parent_res = NULL;
0787 int ret, i;
0788 bool ignore_pipe_clk;
0789 bool wakeup_source;
0790
0791 qcom = devm_kzalloc(&pdev->dev, sizeof(*qcom), GFP_KERNEL);
0792 if (!qcom)
0793 return -ENOMEM;
0794
0795 platform_set_drvdata(pdev, qcom);
0796 qcom->dev = &pdev->dev;
0797
0798 if (has_acpi_companion(dev)) {
0799 qcom->acpi_pdata = acpi_device_get_match_data(dev);
0800 if (!qcom->acpi_pdata) {
0801 dev_err(&pdev->dev, "no supporting ACPI device data\n");
0802 return -EINVAL;
0803 }
0804 }
0805
0806 qcom->resets = devm_reset_control_array_get_optional_exclusive(dev);
0807 if (IS_ERR(qcom->resets)) {
0808 ret = PTR_ERR(qcom->resets);
0809 dev_err(&pdev->dev, "failed to get resets, err=%d\n", ret);
0810 return ret;
0811 }
0812
0813 ret = reset_control_assert(qcom->resets);
0814 if (ret) {
0815 dev_err(&pdev->dev, "failed to assert resets, err=%d\n", ret);
0816 return ret;
0817 }
0818
0819 usleep_range(10, 1000);
0820
0821 ret = reset_control_deassert(qcom->resets);
0822 if (ret) {
0823 dev_err(&pdev->dev, "failed to deassert resets, err=%d\n", ret);
0824 goto reset_assert;
0825 }
0826
0827 ret = dwc3_qcom_clk_init(qcom, of_clk_get_parent_count(np));
0828 if (ret) {
0829 dev_err(dev, "failed to get clocks\n");
0830 goto reset_assert;
0831 }
0832
0833 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0834
0835 if (np) {
0836 parent_res = res;
0837 } else {
0838 parent_res = kmemdup(res, sizeof(struct resource), GFP_KERNEL);
0839 if (!parent_res)
0840 return -ENOMEM;
0841
0842 parent_res->start = res->start +
0843 qcom->acpi_pdata->qscratch_base_offset;
0844 parent_res->end = parent_res->start +
0845 qcom->acpi_pdata->qscratch_base_size;
0846
0847 if (qcom->acpi_pdata->is_urs) {
0848 qcom->urs_usb = dwc3_qcom_create_urs_usb_platdev(dev);
0849 if (IS_ERR_OR_NULL(qcom->urs_usb)) {
0850 dev_err(dev, "failed to create URS USB platdev\n");
0851 if (!qcom->urs_usb)
0852 return -ENODEV;
0853 else
0854 return PTR_ERR(qcom->urs_usb);
0855 }
0856 }
0857 }
0858
0859 qcom->qscratch_base = devm_ioremap_resource(dev, parent_res);
0860 if (IS_ERR(qcom->qscratch_base)) {
0861 ret = PTR_ERR(qcom->qscratch_base);
0862 goto clk_disable;
0863 }
0864
0865 ret = dwc3_qcom_setup_irq(pdev);
0866 if (ret) {
0867 dev_err(dev, "failed to setup IRQs, err=%d\n", ret);
0868 goto clk_disable;
0869 }
0870
0871
0872
0873
0874
0875 ignore_pipe_clk = device_property_read_bool(dev,
0876 "qcom,select-utmi-as-pipe-clk");
0877 if (ignore_pipe_clk)
0878 dwc3_qcom_select_utmi_clk(qcom);
0879
0880 if (np)
0881 ret = dwc3_qcom_of_register_core(pdev);
0882 else
0883 ret = dwc3_qcom_acpi_register_core(pdev);
0884
0885 if (ret) {
0886 dev_err(dev, "failed to register DWC3 Core, err=%d\n", ret);
0887 goto depopulate;
0888 }
0889
0890 ret = dwc3_qcom_interconnect_init(qcom);
0891 if (ret)
0892 goto depopulate;
0893
0894 qcom->mode = usb_get_dr_mode(&qcom->dwc3->dev);
0895
0896
0897 if (qcom->mode == USB_DR_MODE_PERIPHERAL)
0898 dwc3_qcom_vbus_override_enable(qcom, true);
0899
0900
0901 ret = dwc3_qcom_register_extcon(qcom);
0902 if (ret)
0903 goto interconnect_exit;
0904
0905 wakeup_source = of_property_read_bool(dev->of_node, "wakeup-source");
0906 device_init_wakeup(&pdev->dev, wakeup_source);
0907 device_init_wakeup(&qcom->dwc3->dev, wakeup_source);
0908
0909 qcom->is_suspended = false;
0910 pm_runtime_set_active(dev);
0911 pm_runtime_enable(dev);
0912 pm_runtime_forbid(dev);
0913
0914 return 0;
0915
0916 interconnect_exit:
0917 dwc3_qcom_interconnect_exit(qcom);
0918 depopulate:
0919 if (np)
0920 of_platform_depopulate(&pdev->dev);
0921 else
0922 platform_device_put(pdev);
0923 clk_disable:
0924 for (i = qcom->num_clocks - 1; i >= 0; i--) {
0925 clk_disable_unprepare(qcom->clks[i]);
0926 clk_put(qcom->clks[i]);
0927 }
0928 reset_assert:
0929 reset_control_assert(qcom->resets);
0930
0931 return ret;
0932 }
0933
0934 static int dwc3_qcom_remove(struct platform_device *pdev)
0935 {
0936 struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
0937 struct device *dev = &pdev->dev;
0938 int i;
0939
0940 device_remove_software_node(&qcom->dwc3->dev);
0941 of_platform_depopulate(dev);
0942
0943 for (i = qcom->num_clocks - 1; i >= 0; i--) {
0944 clk_disable_unprepare(qcom->clks[i]);
0945 clk_put(qcom->clks[i]);
0946 }
0947 qcom->num_clocks = 0;
0948
0949 dwc3_qcom_interconnect_exit(qcom);
0950 reset_control_assert(qcom->resets);
0951
0952 pm_runtime_allow(dev);
0953 pm_runtime_disable(dev);
0954
0955 return 0;
0956 }
0957
0958 static int __maybe_unused dwc3_qcom_pm_suspend(struct device *dev)
0959 {
0960 struct dwc3_qcom *qcom = dev_get_drvdata(dev);
0961 bool wakeup = device_may_wakeup(dev);
0962 int ret;
0963
0964 ret = dwc3_qcom_suspend(qcom, wakeup);
0965 if (ret)
0966 return ret;
0967
0968 qcom->pm_suspended = true;
0969
0970 return 0;
0971 }
0972
0973 static int __maybe_unused dwc3_qcom_pm_resume(struct device *dev)
0974 {
0975 struct dwc3_qcom *qcom = dev_get_drvdata(dev);
0976 bool wakeup = device_may_wakeup(dev);
0977 int ret;
0978
0979 ret = dwc3_qcom_resume(qcom, wakeup);
0980 if (ret)
0981 return ret;
0982
0983 qcom->pm_suspended = false;
0984
0985 return 0;
0986 }
0987
0988 static int __maybe_unused dwc3_qcom_runtime_suspend(struct device *dev)
0989 {
0990 struct dwc3_qcom *qcom = dev_get_drvdata(dev);
0991
0992 return dwc3_qcom_suspend(qcom, true);
0993 }
0994
0995 static int __maybe_unused dwc3_qcom_runtime_resume(struct device *dev)
0996 {
0997 struct dwc3_qcom *qcom = dev_get_drvdata(dev);
0998
0999 return dwc3_qcom_resume(qcom, true);
1000 }
1001
1002 static const struct dev_pm_ops dwc3_qcom_dev_pm_ops = {
1003 SET_SYSTEM_SLEEP_PM_OPS(dwc3_qcom_pm_suspend, dwc3_qcom_pm_resume)
1004 SET_RUNTIME_PM_OPS(dwc3_qcom_runtime_suspend, dwc3_qcom_runtime_resume,
1005 NULL)
1006 };
1007
1008 static const struct of_device_id dwc3_qcom_of_match[] = {
1009 { .compatible = "qcom,dwc3" },
1010 { .compatible = "qcom,msm8996-dwc3" },
1011 { .compatible = "qcom,msm8998-dwc3" },
1012 { .compatible = "qcom,sdm660-dwc3" },
1013 { .compatible = "qcom,sdm845-dwc3" },
1014 { }
1015 };
1016 MODULE_DEVICE_TABLE(of, dwc3_qcom_of_match);
1017
1018 #ifdef CONFIG_ACPI
1019 static const struct dwc3_acpi_pdata sdm845_acpi_pdata = {
1020 .qscratch_base_offset = SDM845_QSCRATCH_BASE_OFFSET,
1021 .qscratch_base_size = SDM845_QSCRATCH_SIZE,
1022 .dwc3_core_base_size = SDM845_DWC3_CORE_SIZE,
1023 .hs_phy_irq_index = 1,
1024 .dp_hs_phy_irq_index = 4,
1025 .dm_hs_phy_irq_index = 3,
1026 .ss_phy_irq_index = 2
1027 };
1028
1029 static const struct dwc3_acpi_pdata sdm845_acpi_urs_pdata = {
1030 .qscratch_base_offset = SDM845_QSCRATCH_BASE_OFFSET,
1031 .qscratch_base_size = SDM845_QSCRATCH_SIZE,
1032 .dwc3_core_base_size = SDM845_DWC3_CORE_SIZE,
1033 .hs_phy_irq_index = 1,
1034 .dp_hs_phy_irq_index = 4,
1035 .dm_hs_phy_irq_index = 3,
1036 .ss_phy_irq_index = 2,
1037 .is_urs = true,
1038 };
1039
1040 static const struct acpi_device_id dwc3_qcom_acpi_match[] = {
1041 { "QCOM2430", (unsigned long)&sdm845_acpi_pdata },
1042 { "QCOM0304", (unsigned long)&sdm845_acpi_urs_pdata },
1043 { "QCOM0497", (unsigned long)&sdm845_acpi_urs_pdata },
1044 { "QCOM04A6", (unsigned long)&sdm845_acpi_pdata },
1045 { },
1046 };
1047 MODULE_DEVICE_TABLE(acpi, dwc3_qcom_acpi_match);
1048 #endif
1049
1050 static struct platform_driver dwc3_qcom_driver = {
1051 .probe = dwc3_qcom_probe,
1052 .remove = dwc3_qcom_remove,
1053 .driver = {
1054 .name = "dwc3-qcom",
1055 .pm = &dwc3_qcom_dev_pm_ops,
1056 .of_match_table = dwc3_qcom_of_match,
1057 .acpi_match_table = ACPI_PTR(dwc3_qcom_acpi_match),
1058 },
1059 };
1060
1061 module_platform_driver(dwc3_qcom_driver);
1062
1063 MODULE_LICENSE("GPL v2");
1064 MODULE_DESCRIPTION("DesignWare DWC3 QCOM Glue Driver");