1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Cadence USBSS DRD Driver. 4 * 5 * Copyright (C) 2018-2019 Cadence. 6 * Copyright (C) 2017-2018 NXP 7 * Copyright (C) 2019 Texas Instruments 8 * 9 * Author: Peter Chen <peter.chen@nxp.com> 10 * Pawel Laszczak <pawell@cadence.com> 11 * Roger Quadros <rogerq@ti.com> 12 */ 13 14 #include <linux/dma-mapping.h> 15 #include <linux/module.h> 16 #include <linux/kernel.h> 17 #include <linux/platform_device.h> 18 #include <linux/interrupt.h> 19 #include <linux/io.h> 20 #include <linux/pm_runtime.h> 21 22 #include "core.h" 23 #include "host-export.h" 24 #include "drd.h" 25 26 static int cdns_idle_init(struct cdns *cdns); 27 28 static int cdns_role_start(struct cdns *cdns, enum usb_role role) 29 { 30 int ret; 31 32 if (WARN_ON(role > USB_ROLE_DEVICE)) 33 return 0; 34 35 mutex_lock(&cdns->mutex); 36 cdns->role = role; 37 mutex_unlock(&cdns->mutex); 38 39 if (!cdns->roles[role]) 40 return -ENXIO; 41 42 if (cdns->roles[role]->state == CDNS_ROLE_STATE_ACTIVE) 43 return 0; 44 45 mutex_lock(&cdns->mutex); 46 ret = cdns->roles[role]->start(cdns); 47 if (!ret) 48 cdns->roles[role]->state = CDNS_ROLE_STATE_ACTIVE; 49 mutex_unlock(&cdns->mutex); 50 51 return ret; 52 } 53 54 static void cdns_role_stop(struct cdns *cdns) 55 { 56 enum usb_role role = cdns->role; 57 58 if (WARN_ON(role > USB_ROLE_DEVICE)) 59 return; 60 61 if (cdns->roles[role]->state == CDNS_ROLE_STATE_INACTIVE) 62 return; 63 64 mutex_lock(&cdns->mutex); 65 cdns->roles[role]->stop(cdns); 66 cdns->roles[role]->state = CDNS_ROLE_STATE_INACTIVE; 67 mutex_unlock(&cdns->mutex); 68 } 69 70 static void cdns_exit_roles(struct cdns *cdns) 71 { 72 cdns_role_stop(cdns); 73 cdns_drd_exit(cdns); 74 } 75 76 /** 77 * cdns_core_init_role - initialize role of operation 78 * @cdns: Pointer to cdns structure 79 * 80 * Returns 0 on success otherwise negative errno 81 */ 82 static int cdns_core_init_role(struct cdns *cdns) 83 { 84 struct device *dev = cdns->dev; 85 enum usb_dr_mode best_dr_mode; 86 enum usb_dr_mode dr_mode; 87 int ret; 88 89 dr_mode = usb_get_dr_mode(dev); 90 cdns->role = USB_ROLE_NONE; 91 92 /* 93 * If driver can't read mode by means of usb_get_dr_mode function then 94 * chooses mode according with Kernel configuration. This setting 95 * can be restricted later depending on strap pin configuration. 96 */ 97 if (dr_mode == USB_DR_MODE_UNKNOWN) { 98 if (cdns->version == CDNSP_CONTROLLER_V2) { 99 if (IS_ENABLED(CONFIG_USB_CDNSP_HOST) && 100 IS_ENABLED(CONFIG_USB_CDNSP_GADGET)) 101 dr_mode = USB_DR_MODE_OTG; 102 else if (IS_ENABLED(CONFIG_USB_CDNSP_HOST)) 103 dr_mode = USB_DR_MODE_HOST; 104 else if (IS_ENABLED(CONFIG_USB_CDNSP_GADGET)) 105 dr_mode = USB_DR_MODE_PERIPHERAL; 106 } else { 107 if (IS_ENABLED(CONFIG_USB_CDNS3_HOST) && 108 IS_ENABLED(CONFIG_USB_CDNS3_GADGET)) 109 dr_mode = USB_DR_MODE_OTG; 110 else if (IS_ENABLED(CONFIG_USB_CDNS3_HOST)) 111 dr_mode = USB_DR_MODE_HOST; 112 else if (IS_ENABLED(CONFIG_USB_CDNS3_GADGET)) 113 dr_mode = USB_DR_MODE_PERIPHERAL; 114 } 115 } 116 117 /* 118 * At this point cdns->dr_mode contains strap configuration. 119 * Driver try update this setting considering kernel configuration 120 */ 121 best_dr_mode = cdns->dr_mode; 122 123 ret = cdns_idle_init(cdns); 124 if (ret) 125 return ret; 126 127 if (dr_mode == USB_DR_MODE_OTG) { 128 best_dr_mode = cdns->dr_mode; 129 } else if (cdns->dr_mode == USB_DR_MODE_OTG) { 130 best_dr_mode = dr_mode; 131 } else if (cdns->dr_mode != dr_mode) { 132 dev_err(dev, "Incorrect DRD configuration\n"); 133 return -EINVAL; 134 } 135 136 dr_mode = best_dr_mode; 137 138 if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) { 139 ret = cdns_host_init(cdns); 140 if (ret) { 141 dev_err(dev, "Host initialization failed with %d\n", 142 ret); 143 goto err; 144 } 145 } 146 147 if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_PERIPHERAL) { 148 if (cdns->gadget_init) 149 ret = cdns->gadget_init(cdns); 150 else 151 ret = -ENXIO; 152 153 if (ret) { 154 dev_err(dev, "Device initialization failed with %d\n", 155 ret); 156 goto err; 157 } 158 } 159 160 cdns->dr_mode = dr_mode; 161 162 ret = cdns_drd_update_mode(cdns); 163 if (ret) 164 goto err; 165 166 /* Initialize idle role to start with */ 167 ret = cdns_role_start(cdns, USB_ROLE_NONE); 168 if (ret) 169 goto err; 170 171 switch (cdns->dr_mode) { 172 case USB_DR_MODE_OTG: 173 ret = cdns_hw_role_switch(cdns); 174 if (ret) 175 goto err; 176 break; 177 case USB_DR_MODE_PERIPHERAL: 178 ret = cdns_role_start(cdns, USB_ROLE_DEVICE); 179 if (ret) 180 goto err; 181 break; 182 case USB_DR_MODE_HOST: 183 ret = cdns_role_start(cdns, USB_ROLE_HOST); 184 if (ret) 185 goto err; 186 break; 187 default: 188 ret = -EINVAL; 189 goto err; 190 } 191 192 return 0; 193 err: 194 cdns_exit_roles(cdns); 195 return ret; 196 } 197 198 /** 199 * cdns_hw_role_state_machine - role switch state machine based on hw events. 200 * @cdns: Pointer to controller structure. 201 * 202 * Returns next role to be entered based on hw events. 203 */ 204 static enum usb_role cdns_hw_role_state_machine(struct cdns *cdns) 205 { 206 enum usb_role role = USB_ROLE_NONE; 207 int id, vbus; 208 209 if (cdns->dr_mode != USB_DR_MODE_OTG) { 210 if (cdns_is_host(cdns)) 211 role = USB_ROLE_HOST; 212 if (cdns_is_device(cdns)) 213 role = USB_ROLE_DEVICE; 214 215 return role; 216 } 217 218 id = cdns_get_id(cdns); 219 vbus = cdns_get_vbus(cdns); 220 221 /* 222 * Role change state machine 223 * Inputs: ID, VBUS 224 * Previous state: cdns->role 225 * Next state: role 226 */ 227 role = cdns->role; 228 229 switch (role) { 230 case USB_ROLE_NONE: 231 /* 232 * Driver treats USB_ROLE_NONE synonymous to IDLE state from 233 * controller specification. 234 */ 235 if (!id) 236 role = USB_ROLE_HOST; 237 else if (vbus) 238 role = USB_ROLE_DEVICE; 239 break; 240 case USB_ROLE_HOST: /* from HOST, we can only change to NONE */ 241 if (id) 242 role = USB_ROLE_NONE; 243 break; 244 case USB_ROLE_DEVICE: /* from GADGET, we can only change to NONE*/ 245 if (!vbus) 246 role = USB_ROLE_NONE; 247 break; 248 } 249 250 dev_dbg(cdns->dev, "role %d -> %d\n", cdns->role, role); 251 252 return role; 253 } 254 255 static int cdns_idle_role_start(struct cdns *cdns) 256 { 257 return 0; 258 } 259 260 static void cdns_idle_role_stop(struct cdns *cdns) 261 { 262 /* Program Lane swap and bring PHY out of RESET */ 263 phy_reset(cdns->usb3_phy); 264 } 265 266 static int cdns_idle_init(struct cdns *cdns) 267 { 268 struct cdns_role_driver *rdrv; 269 270 rdrv = devm_kzalloc(cdns->dev, sizeof(*rdrv), GFP_KERNEL); 271 if (!rdrv) 272 return -ENOMEM; 273 274 rdrv->start = cdns_idle_role_start; 275 rdrv->stop = cdns_idle_role_stop; 276 rdrv->state = CDNS_ROLE_STATE_INACTIVE; 277 rdrv->suspend = NULL; 278 rdrv->resume = NULL; 279 rdrv->name = "idle"; 280 281 cdns->roles[USB_ROLE_NONE] = rdrv; 282 283 return 0; 284 } 285 286 /** 287 * cdns_hw_role_switch - switch roles based on HW state 288 * @cdns: controller 289 */ 290 int cdns_hw_role_switch(struct cdns *cdns) 291 { 292 enum usb_role real_role, current_role; 293 int ret = 0; 294 295 /* Depends on role switch class */ 296 if (cdns->role_sw) 297 return 0; 298 299 pm_runtime_get_sync(cdns->dev); 300 301 current_role = cdns->role; 302 real_role = cdns_hw_role_state_machine(cdns); 303 304 /* Do nothing if nothing changed */ 305 if (current_role == real_role) 306 goto exit; 307 308 cdns_role_stop(cdns); 309 310 dev_dbg(cdns->dev, "Switching role %d -> %d", current_role, real_role); 311 312 ret = cdns_role_start(cdns, real_role); 313 if (ret) { 314 /* Back to current role */ 315 dev_err(cdns->dev, "set %d has failed, back to %d\n", 316 real_role, current_role); 317 ret = cdns_role_start(cdns, current_role); 318 if (ret) 319 dev_err(cdns->dev, "back to %d failed too\n", 320 current_role); 321 } 322 exit: 323 pm_runtime_put_sync(cdns->dev); 324 return ret; 325 } 326 327 /** 328 * cdsn3_role_get - get current role of controller. 329 * 330 * @sw: pointer to USB role switch structure 331 * 332 * Returns role 333 */ 334 static enum usb_role cdns_role_get(struct usb_role_switch *sw) 335 { 336 struct cdns *cdns = usb_role_switch_get_drvdata(sw); 337 338 return cdns->role; 339 } 340 341 /** 342 * cdns_role_set - set current role of controller. 343 * 344 * @sw: pointer to USB role switch structure 345 * @role: the previous role 346 * Handles below events: 347 * - Role switch for dual-role devices 348 * - USB_ROLE_GADGET <--> USB_ROLE_NONE for peripheral-only devices 349 */ 350 static int cdns_role_set(struct usb_role_switch *sw, enum usb_role role) 351 { 352 struct cdns *cdns = usb_role_switch_get_drvdata(sw); 353 int ret = 0; 354 355 pm_runtime_get_sync(cdns->dev); 356 357 if (cdns->role == role) 358 goto pm_put; 359 360 if (cdns->dr_mode == USB_DR_MODE_HOST) { 361 switch (role) { 362 case USB_ROLE_NONE: 363 case USB_ROLE_HOST: 364 break; 365 default: 366 goto pm_put; 367 } 368 } 369 370 if (cdns->dr_mode == USB_DR_MODE_PERIPHERAL) { 371 switch (role) { 372 case USB_ROLE_NONE: 373 case USB_ROLE_DEVICE: 374 break; 375 default: 376 goto pm_put; 377 } 378 } 379 380 cdns_role_stop(cdns); 381 ret = cdns_role_start(cdns, role); 382 if (ret) 383 dev_err(cdns->dev, "set role %d has failed\n", role); 384 385 pm_put: 386 pm_runtime_put_sync(cdns->dev); 387 return ret; 388 } 389 390 391 /** 392 * cdns_wakeup_irq - interrupt handler for wakeup events 393 * @irq: irq number for cdns3/cdnsp core device 394 * @data: structure of cdns 395 * 396 * Returns IRQ_HANDLED or IRQ_NONE 397 */ 398 static irqreturn_t cdns_wakeup_irq(int irq, void *data) 399 { 400 struct cdns *cdns = data; 401 402 if (cdns->in_lpm) { 403 disable_irq_nosync(irq); 404 cdns->wakeup_pending = true; 405 if ((cdns->role == USB_ROLE_HOST) && cdns->host_dev) 406 pm_request_resume(&cdns->host_dev->dev); 407 408 return IRQ_HANDLED; 409 } 410 411 return IRQ_NONE; 412 } 413 414 /** 415 * cdns_probe - probe for cdns3/cdnsp core device 416 * @cdns: Pointer to cdns structure. 417 * 418 * Returns 0 on success otherwise negative errno 419 */ 420 int cdns_init(struct cdns *cdns) 421 { 422 struct device *dev = cdns->dev; 423 int ret; 424 425 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); 426 if (ret) { 427 dev_err(dev, "error setting dma mask: %d\n", ret); 428 return ret; 429 } 430 431 mutex_init(&cdns->mutex); 432 433 if (device_property_read_bool(dev, "usb-role-switch")) { 434 struct usb_role_switch_desc sw_desc = { }; 435 436 sw_desc.set = cdns_role_set; 437 sw_desc.get = cdns_role_get; 438 sw_desc.allow_userspace_control = true; 439 sw_desc.driver_data = cdns; 440 sw_desc.fwnode = dev->fwnode; 441 442 cdns->role_sw = usb_role_switch_register(dev, &sw_desc); 443 if (IS_ERR(cdns->role_sw)) { 444 dev_warn(dev, "Unable to register Role Switch\n"); 445 return PTR_ERR(cdns->role_sw); 446 } 447 } 448 449 if (cdns->wakeup_irq) { 450 ret = devm_request_irq(cdns->dev, cdns->wakeup_irq, 451 cdns_wakeup_irq, 452 IRQF_SHARED, 453 dev_name(cdns->dev), cdns); 454 455 if (ret) { 456 dev_err(cdns->dev, "couldn't register wakeup irq handler\n"); 457 goto role_switch_unregister; 458 } 459 } 460 461 ret = cdns_drd_init(cdns); 462 if (ret) 463 goto init_failed; 464 465 ret = cdns_core_init_role(cdns); 466 if (ret) 467 goto init_failed; 468 469 spin_lock_init(&cdns->lock); 470 471 dev_dbg(dev, "Cadence USB3 core: probe succeed\n"); 472 473 return 0; 474 init_failed: 475 cdns_drd_exit(cdns); 476 role_switch_unregister: 477 if (cdns->role_sw) 478 usb_role_switch_unregister(cdns->role_sw); 479 480 return ret; 481 } 482 EXPORT_SYMBOL_GPL(cdns_init); 483 484 /** 485 * cdns_remove - unbind drd driver and clean up 486 * @cdns: Pointer to cdns structure. 487 * 488 * Returns 0 on success otherwise negative errno 489 */ 490 int cdns_remove(struct cdns *cdns) 491 { 492 cdns_exit_roles(cdns); 493 usb_role_switch_unregister(cdns->role_sw); 494 495 return 0; 496 } 497 EXPORT_SYMBOL_GPL(cdns_remove); 498 499 #ifdef CONFIG_PM_SLEEP 500 int cdns_suspend(struct cdns *cdns) 501 { 502 struct device *dev = cdns->dev; 503 unsigned long flags; 504 505 if (pm_runtime_status_suspended(dev)) 506 pm_runtime_resume(dev); 507 508 if (cdns->roles[cdns->role]->suspend) { 509 spin_lock_irqsave(&cdns->lock, flags); 510 cdns->roles[cdns->role]->suspend(cdns, false); 511 spin_unlock_irqrestore(&cdns->lock, flags); 512 } 513 514 return 0; 515 } 516 EXPORT_SYMBOL_GPL(cdns_suspend); 517 518 int cdns_resume(struct cdns *cdns, u8 set_active) 519 { 520 struct device *dev = cdns->dev; 521 522 if (cdns->roles[cdns->role]->resume) 523 cdns->roles[cdns->role]->resume(cdns, false); 524 525 if (set_active) { 526 pm_runtime_disable(dev); 527 pm_runtime_set_active(dev); 528 pm_runtime_enable(dev); 529 } 530 531 return 0; 532 } 533 EXPORT_SYMBOL_GPL(cdns_resume); 534 #endif /* CONFIG_PM_SLEEP */ 535 536 MODULE_AUTHOR("Peter Chen <peter.chen@nxp.com>"); 537 MODULE_AUTHOR("Pawel Laszczak <pawell@cadence.com>"); 538 MODULE_AUTHOR("Roger Quadros <rogerq@ti.com>"); 539 MODULE_DESCRIPTION("Cadence USBSS and USBSSP DRD Driver"); 540 MODULE_LICENSE("GPL"); 541