0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/dma-mapping.h>
0015 #include <linux/module.h>
0016 #include <linux/kernel.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/interrupt.h>
0019 #include <linux/io.h>
0020 #include <linux/pm_runtime.h>
0021
0022 #include "core.h"
0023 #include "host-export.h"
0024 #include "drd.h"
0025
0026 static int cdns_idle_init(struct cdns *cdns);
0027
0028 static int cdns_role_start(struct cdns *cdns, enum usb_role role)
0029 {
0030 int ret;
0031
0032 if (WARN_ON(role > USB_ROLE_DEVICE))
0033 return 0;
0034
0035 mutex_lock(&cdns->mutex);
0036 cdns->role = role;
0037 mutex_unlock(&cdns->mutex);
0038
0039 if (!cdns->roles[role])
0040 return -ENXIO;
0041
0042 if (cdns->roles[role]->state == CDNS_ROLE_STATE_ACTIVE)
0043 return 0;
0044
0045 mutex_lock(&cdns->mutex);
0046 ret = cdns->roles[role]->start(cdns);
0047 if (!ret)
0048 cdns->roles[role]->state = CDNS_ROLE_STATE_ACTIVE;
0049 mutex_unlock(&cdns->mutex);
0050
0051 return ret;
0052 }
0053
0054 static void cdns_role_stop(struct cdns *cdns)
0055 {
0056 enum usb_role role = cdns->role;
0057
0058 if (WARN_ON(role > USB_ROLE_DEVICE))
0059 return;
0060
0061 if (cdns->roles[role]->state == CDNS_ROLE_STATE_INACTIVE)
0062 return;
0063
0064 mutex_lock(&cdns->mutex);
0065 cdns->roles[role]->stop(cdns);
0066 cdns->roles[role]->state = CDNS_ROLE_STATE_INACTIVE;
0067 mutex_unlock(&cdns->mutex);
0068 }
0069
0070 static void cdns_exit_roles(struct cdns *cdns)
0071 {
0072 cdns_role_stop(cdns);
0073 cdns_drd_exit(cdns);
0074 }
0075
0076
0077
0078
0079
0080
0081
0082 static int cdns_core_init_role(struct cdns *cdns)
0083 {
0084 struct device *dev = cdns->dev;
0085 enum usb_dr_mode best_dr_mode;
0086 enum usb_dr_mode dr_mode;
0087 int ret;
0088
0089 dr_mode = usb_get_dr_mode(dev);
0090 cdns->role = USB_ROLE_NONE;
0091
0092
0093
0094
0095
0096
0097 if (dr_mode == USB_DR_MODE_UNKNOWN) {
0098 if (cdns->version == CDNSP_CONTROLLER_V2) {
0099 if (IS_ENABLED(CONFIG_USB_CDNSP_HOST) &&
0100 IS_ENABLED(CONFIG_USB_CDNSP_GADGET))
0101 dr_mode = USB_DR_MODE_OTG;
0102 else if (IS_ENABLED(CONFIG_USB_CDNSP_HOST))
0103 dr_mode = USB_DR_MODE_HOST;
0104 else if (IS_ENABLED(CONFIG_USB_CDNSP_GADGET))
0105 dr_mode = USB_DR_MODE_PERIPHERAL;
0106 } else {
0107 if (IS_ENABLED(CONFIG_USB_CDNS3_HOST) &&
0108 IS_ENABLED(CONFIG_USB_CDNS3_GADGET))
0109 dr_mode = USB_DR_MODE_OTG;
0110 else if (IS_ENABLED(CONFIG_USB_CDNS3_HOST))
0111 dr_mode = USB_DR_MODE_HOST;
0112 else if (IS_ENABLED(CONFIG_USB_CDNS3_GADGET))
0113 dr_mode = USB_DR_MODE_PERIPHERAL;
0114 }
0115 }
0116
0117
0118
0119
0120
0121 best_dr_mode = cdns->dr_mode;
0122
0123 ret = cdns_idle_init(cdns);
0124 if (ret)
0125 return ret;
0126
0127 if (dr_mode == USB_DR_MODE_OTG) {
0128 best_dr_mode = cdns->dr_mode;
0129 } else if (cdns->dr_mode == USB_DR_MODE_OTG) {
0130 best_dr_mode = dr_mode;
0131 } else if (cdns->dr_mode != dr_mode) {
0132 dev_err(dev, "Incorrect DRD configuration\n");
0133 return -EINVAL;
0134 }
0135
0136 dr_mode = best_dr_mode;
0137
0138 if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
0139 if ((cdns->version == CDNSP_CONTROLLER_V2 &&
0140 IS_ENABLED(CONFIG_USB_CDNSP_HOST)) ||
0141 (cdns->version < CDNSP_CONTROLLER_V2 &&
0142 IS_ENABLED(CONFIG_USB_CDNS3_HOST)))
0143 ret = cdns_host_init(cdns);
0144 else
0145 ret = -ENXIO;
0146
0147 if (ret) {
0148 dev_err(dev, "Host initialization failed with %d\n",
0149 ret);
0150 goto err;
0151 }
0152 }
0153
0154 if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_PERIPHERAL) {
0155 if (cdns->gadget_init)
0156 ret = cdns->gadget_init(cdns);
0157 else
0158 ret = -ENXIO;
0159
0160 if (ret) {
0161 dev_err(dev, "Device initialization failed with %d\n",
0162 ret);
0163 goto err;
0164 }
0165 }
0166
0167 cdns->dr_mode = dr_mode;
0168
0169 ret = cdns_drd_update_mode(cdns);
0170 if (ret)
0171 goto err;
0172
0173
0174 ret = cdns_role_start(cdns, USB_ROLE_NONE);
0175 if (ret)
0176 goto err;
0177
0178 switch (cdns->dr_mode) {
0179 case USB_DR_MODE_OTG:
0180 ret = cdns_hw_role_switch(cdns);
0181 if (ret)
0182 goto err;
0183 break;
0184 case USB_DR_MODE_PERIPHERAL:
0185 ret = cdns_role_start(cdns, USB_ROLE_DEVICE);
0186 if (ret)
0187 goto err;
0188 break;
0189 case USB_DR_MODE_HOST:
0190 ret = cdns_role_start(cdns, USB_ROLE_HOST);
0191 if (ret)
0192 goto err;
0193 break;
0194 default:
0195 ret = -EINVAL;
0196 goto err;
0197 }
0198
0199 return 0;
0200 err:
0201 cdns_exit_roles(cdns);
0202 return ret;
0203 }
0204
0205
0206
0207
0208
0209
0210
0211 static enum usb_role cdns_hw_role_state_machine(struct cdns *cdns)
0212 {
0213 enum usb_role role = USB_ROLE_NONE;
0214 int id, vbus;
0215
0216 if (cdns->dr_mode != USB_DR_MODE_OTG) {
0217 if (cdns_is_host(cdns))
0218 role = USB_ROLE_HOST;
0219 if (cdns_is_device(cdns))
0220 role = USB_ROLE_DEVICE;
0221
0222 return role;
0223 }
0224
0225 id = cdns_get_id(cdns);
0226 vbus = cdns_get_vbus(cdns);
0227
0228
0229
0230
0231
0232
0233
0234 role = cdns->role;
0235
0236 switch (role) {
0237 case USB_ROLE_NONE:
0238
0239
0240
0241
0242 if (!id)
0243 role = USB_ROLE_HOST;
0244 else if (vbus)
0245 role = USB_ROLE_DEVICE;
0246 break;
0247 case USB_ROLE_HOST:
0248 if (id)
0249 role = USB_ROLE_NONE;
0250 break;
0251 case USB_ROLE_DEVICE:
0252 if (!vbus)
0253 role = USB_ROLE_NONE;
0254 break;
0255 }
0256
0257 dev_dbg(cdns->dev, "role %d -> %d\n", cdns->role, role);
0258
0259 return role;
0260 }
0261
0262 static int cdns_idle_role_start(struct cdns *cdns)
0263 {
0264 return 0;
0265 }
0266
0267 static void cdns_idle_role_stop(struct cdns *cdns)
0268 {
0269
0270 phy_reset(cdns->usb3_phy);
0271 }
0272
0273 static int cdns_idle_init(struct cdns *cdns)
0274 {
0275 struct cdns_role_driver *rdrv;
0276
0277 rdrv = devm_kzalloc(cdns->dev, sizeof(*rdrv), GFP_KERNEL);
0278 if (!rdrv)
0279 return -ENOMEM;
0280
0281 rdrv->start = cdns_idle_role_start;
0282 rdrv->stop = cdns_idle_role_stop;
0283 rdrv->state = CDNS_ROLE_STATE_INACTIVE;
0284 rdrv->suspend = NULL;
0285 rdrv->resume = NULL;
0286 rdrv->name = "idle";
0287
0288 cdns->roles[USB_ROLE_NONE] = rdrv;
0289
0290 return 0;
0291 }
0292
0293
0294
0295
0296
0297 int cdns_hw_role_switch(struct cdns *cdns)
0298 {
0299 enum usb_role real_role, current_role;
0300 int ret = 0;
0301
0302
0303 if (cdns->role_sw)
0304 return 0;
0305
0306 pm_runtime_get_sync(cdns->dev);
0307
0308 current_role = cdns->role;
0309 real_role = cdns_hw_role_state_machine(cdns);
0310
0311
0312 if (current_role == real_role)
0313 goto exit;
0314
0315 cdns_role_stop(cdns);
0316
0317 dev_dbg(cdns->dev, "Switching role %d -> %d", current_role, real_role);
0318
0319 ret = cdns_role_start(cdns, real_role);
0320 if (ret) {
0321
0322 dev_err(cdns->dev, "set %d has failed, back to %d\n",
0323 real_role, current_role);
0324 ret = cdns_role_start(cdns, current_role);
0325 if (ret)
0326 dev_err(cdns->dev, "back to %d failed too\n",
0327 current_role);
0328 }
0329 exit:
0330 pm_runtime_put_sync(cdns->dev);
0331 return ret;
0332 }
0333
0334
0335
0336
0337
0338
0339
0340
0341 static enum usb_role cdns_role_get(struct usb_role_switch *sw)
0342 {
0343 struct cdns *cdns = usb_role_switch_get_drvdata(sw);
0344
0345 return cdns->role;
0346 }
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357 static int cdns_role_set(struct usb_role_switch *sw, enum usb_role role)
0358 {
0359 struct cdns *cdns = usb_role_switch_get_drvdata(sw);
0360 int ret = 0;
0361
0362 pm_runtime_get_sync(cdns->dev);
0363
0364 if (cdns->role == role)
0365 goto pm_put;
0366
0367 if (cdns->dr_mode == USB_DR_MODE_HOST) {
0368 switch (role) {
0369 case USB_ROLE_NONE:
0370 case USB_ROLE_HOST:
0371 break;
0372 default:
0373 goto pm_put;
0374 }
0375 }
0376
0377 if (cdns->dr_mode == USB_DR_MODE_PERIPHERAL) {
0378 switch (role) {
0379 case USB_ROLE_NONE:
0380 case USB_ROLE_DEVICE:
0381 break;
0382 default:
0383 goto pm_put;
0384 }
0385 }
0386
0387 cdns_role_stop(cdns);
0388 ret = cdns_role_start(cdns, role);
0389 if (ret)
0390 dev_err(cdns->dev, "set role %d has failed\n", role);
0391
0392 pm_put:
0393 pm_runtime_put_sync(cdns->dev);
0394 return ret;
0395 }
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405 static irqreturn_t cdns_wakeup_irq(int irq, void *data)
0406 {
0407 struct cdns *cdns = data;
0408
0409 if (cdns->in_lpm) {
0410 disable_irq_nosync(irq);
0411 cdns->wakeup_pending = true;
0412 if ((cdns->role == USB_ROLE_HOST) && cdns->host_dev)
0413 pm_request_resume(&cdns->host_dev->dev);
0414
0415 return IRQ_HANDLED;
0416 }
0417
0418 return IRQ_NONE;
0419 }
0420
0421
0422
0423
0424
0425
0426
0427 int cdns_init(struct cdns *cdns)
0428 {
0429 struct device *dev = cdns->dev;
0430 int ret;
0431
0432 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
0433 if (ret) {
0434 dev_err(dev, "error setting dma mask: %d\n", ret);
0435 return ret;
0436 }
0437
0438 mutex_init(&cdns->mutex);
0439
0440 if (device_property_read_bool(dev, "usb-role-switch")) {
0441 struct usb_role_switch_desc sw_desc = { };
0442
0443 sw_desc.set = cdns_role_set;
0444 sw_desc.get = cdns_role_get;
0445 sw_desc.allow_userspace_control = true;
0446 sw_desc.driver_data = cdns;
0447 sw_desc.fwnode = dev->fwnode;
0448
0449 cdns->role_sw = usb_role_switch_register(dev, &sw_desc);
0450 if (IS_ERR(cdns->role_sw)) {
0451 dev_warn(dev, "Unable to register Role Switch\n");
0452 return PTR_ERR(cdns->role_sw);
0453 }
0454 }
0455
0456 if (cdns->wakeup_irq) {
0457 ret = devm_request_irq(cdns->dev, cdns->wakeup_irq,
0458 cdns_wakeup_irq,
0459 IRQF_SHARED,
0460 dev_name(cdns->dev), cdns);
0461
0462 if (ret) {
0463 dev_err(cdns->dev, "couldn't register wakeup irq handler\n");
0464 goto role_switch_unregister;
0465 }
0466 }
0467
0468 ret = cdns_drd_init(cdns);
0469 if (ret)
0470 goto init_failed;
0471
0472 ret = cdns_core_init_role(cdns);
0473 if (ret)
0474 goto init_failed;
0475
0476 spin_lock_init(&cdns->lock);
0477
0478 dev_dbg(dev, "Cadence USB3 core: probe succeed\n");
0479
0480 return 0;
0481 init_failed:
0482 cdns_drd_exit(cdns);
0483 role_switch_unregister:
0484 if (cdns->role_sw)
0485 usb_role_switch_unregister(cdns->role_sw);
0486
0487 return ret;
0488 }
0489 EXPORT_SYMBOL_GPL(cdns_init);
0490
0491
0492
0493
0494
0495
0496
0497 int cdns_remove(struct cdns *cdns)
0498 {
0499 cdns_exit_roles(cdns);
0500 usb_role_switch_unregister(cdns->role_sw);
0501
0502 return 0;
0503 }
0504 EXPORT_SYMBOL_GPL(cdns_remove);
0505
0506 #ifdef CONFIG_PM_SLEEP
0507 int cdns_suspend(struct cdns *cdns)
0508 {
0509 struct device *dev = cdns->dev;
0510 unsigned long flags;
0511
0512 if (pm_runtime_status_suspended(dev))
0513 pm_runtime_resume(dev);
0514
0515 if (cdns->roles[cdns->role]->suspend) {
0516 spin_lock_irqsave(&cdns->lock, flags);
0517 cdns->roles[cdns->role]->suspend(cdns, false);
0518 spin_unlock_irqrestore(&cdns->lock, flags);
0519 }
0520
0521 return 0;
0522 }
0523 EXPORT_SYMBOL_GPL(cdns_suspend);
0524
0525 int cdns_resume(struct cdns *cdns, u8 set_active)
0526 {
0527 struct device *dev = cdns->dev;
0528 enum usb_role real_role;
0529 bool role_changed = false;
0530 int ret = 0;
0531
0532 if (cdns_power_is_lost(cdns)) {
0533 if (cdns->role_sw) {
0534 cdns->role = cdns_role_get(cdns->role_sw);
0535 } else {
0536 real_role = cdns_hw_role_state_machine(cdns);
0537 if (real_role != cdns->role) {
0538 ret = cdns_hw_role_switch(cdns);
0539 if (ret)
0540 return ret;
0541 role_changed = true;
0542 }
0543 }
0544
0545 if (!role_changed) {
0546 if (cdns->role == USB_ROLE_HOST)
0547 ret = cdns_drd_host_on(cdns);
0548 else if (cdns->role == USB_ROLE_DEVICE)
0549 ret = cdns_drd_gadget_on(cdns);
0550
0551 if (ret)
0552 return ret;
0553 }
0554 }
0555
0556 if (cdns->roles[cdns->role]->resume)
0557 cdns->roles[cdns->role]->resume(cdns, cdns_power_is_lost(cdns));
0558
0559 if (set_active) {
0560 pm_runtime_disable(dev);
0561 pm_runtime_set_active(dev);
0562 pm_runtime_enable(dev);
0563 }
0564
0565 return 0;
0566 }
0567 EXPORT_SYMBOL_GPL(cdns_resume);
0568 #endif
0569
0570 MODULE_AUTHOR("Peter Chen <peter.chen@nxp.com>");
0571 MODULE_AUTHOR("Pawel Laszczak <pawell@cadence.com>");
0572 MODULE_AUTHOR("Roger Quadros <rogerq@ti.com>");
0573 MODULE_DESCRIPTION("Cadence USBSS and USBSSP DRD Driver");
0574 MODULE_LICENSE("GPL");