core.c 12 KB

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