drd.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Cadence USBSS DRD Driver.
  4. *
  5. * Copyright (C) 2018-2019 Cadence.
  6. * Copyright (C) 2019 Texas Instruments
  7. *
  8. * Author: Pawel Laszczak <pawell@cadence.com>
  9. * Roger Quadros <rogerq@ti.com>
  10. *
  11. *
  12. */
  13. #include <linux/kernel.h>
  14. #include <linux/interrupt.h>
  15. #include <linux/delay.h>
  16. #include <linux/iopoll.h>
  17. #include <linux/usb/otg.h>
  18. #include "gadget.h"
  19. #include "drd.h"
  20. #include "core.h"
  21. /**
  22. * cdns3_set_mode - change mode of OTG Core
  23. * @cdns: pointer to context structure
  24. * @mode: selected mode from cdns_role
  25. *
  26. * Returns 0 on success otherwise negative errno
  27. */
  28. int cdns3_set_mode(struct cdns3 *cdns, enum usb_dr_mode mode)
  29. {
  30. int ret = 0;
  31. u32 reg;
  32. switch (mode) {
  33. case USB_DR_MODE_PERIPHERAL:
  34. break;
  35. case USB_DR_MODE_HOST:
  36. break;
  37. case USB_DR_MODE_OTG:
  38. dev_dbg(cdns->dev, "Set controller to OTG mode\n");
  39. if (cdns->version == CDNS3_CONTROLLER_V1) {
  40. reg = readl(&cdns->otg_v1_regs->override);
  41. reg |= OVERRIDE_IDPULLUP;
  42. writel(reg, &cdns->otg_v1_regs->override);
  43. } else {
  44. reg = readl(&cdns->otg_v0_regs->ctrl1);
  45. reg |= OVERRIDE_IDPULLUP_V0;
  46. writel(reg, &cdns->otg_v0_regs->ctrl1);
  47. }
  48. /*
  49. * Hardware specification says: "ID_VALUE must be valid within
  50. * 50ms after idpullup is set to '1" so driver must wait
  51. * 50ms before reading this pin.
  52. */
  53. usleep_range(50000, 60000);
  54. break;
  55. default:
  56. dev_err(cdns->dev, "Unsupported mode of operation %d\n", mode);
  57. return -EINVAL;
  58. }
  59. return ret;
  60. }
  61. int cdns3_get_id(struct cdns3 *cdns)
  62. {
  63. int id;
  64. id = readl(&cdns->otg_regs->sts) & OTGSTS_ID_VALUE;
  65. dev_dbg(cdns->dev, "OTG ID: %d", id);
  66. return id;
  67. }
  68. int cdns3_get_vbus(struct cdns3 *cdns)
  69. {
  70. int vbus;
  71. vbus = !!(readl(&cdns->otg_regs->sts) & OTGSTS_VBUS_VALID);
  72. dev_dbg(cdns->dev, "OTG VBUS: %d", vbus);
  73. return vbus;
  74. }
  75. int cdns3_is_host(struct cdns3 *cdns)
  76. {
  77. if (cdns->dr_mode == USB_DR_MODE_HOST)
  78. return 1;
  79. else if (!cdns3_get_id(cdns))
  80. return 1;
  81. return 0;
  82. }
  83. int cdns3_is_device(struct cdns3 *cdns)
  84. {
  85. if (cdns->dr_mode == USB_DR_MODE_PERIPHERAL)
  86. return 1;
  87. else if (cdns->dr_mode == USB_DR_MODE_OTG)
  88. if (cdns3_get_id(cdns))
  89. return 1;
  90. return 0;
  91. }
  92. /**
  93. * cdns3_otg_disable_irq - Disable all OTG interrupts
  94. * @cdns: Pointer to controller context structure
  95. */
  96. static void cdns3_otg_disable_irq(struct cdns3 *cdns)
  97. {
  98. writel(0, &cdns->otg_regs->ien);
  99. }
  100. /**
  101. * cdns3_otg_enable_irq - enable id and sess_valid interrupts
  102. * @cdns: Pointer to controller context structure
  103. */
  104. static void cdns3_otg_enable_irq(struct cdns3 *cdns)
  105. {
  106. writel(OTGIEN_ID_CHANGE_INT | OTGIEN_VBUSVALID_RISE_INT |
  107. OTGIEN_VBUSVALID_FALL_INT, &cdns->otg_regs->ien);
  108. }
  109. /**
  110. * cdns3_drd_switch_host - start/stop host
  111. * @cdns: Pointer to controller context structure
  112. * @on: 1 for start, 0 for stop
  113. *
  114. * Returns 0 on success otherwise negative errno
  115. */
  116. int cdns3_drd_switch_host(struct cdns3 *cdns, int on)
  117. {
  118. int ret, val;
  119. u32 reg = OTGCMD_OTG_DIS;
  120. /* switch OTG core */
  121. if (on) {
  122. writel(OTGCMD_HOST_BUS_REQ | reg, &cdns->otg_regs->cmd);
  123. dev_dbg(cdns->dev, "Waiting till Host mode is turned on\n");
  124. ret = readl_poll_timeout_atomic(&cdns->otg_regs->sts, val,
  125. val & OTGSTS_XHCI_READY,
  126. 1, 100000);
  127. if (ret) {
  128. dev_err(cdns->dev, "timeout waiting for xhci_ready\n");
  129. return ret;
  130. }
  131. } else {
  132. writel(OTGCMD_HOST_BUS_DROP | OTGCMD_DEV_BUS_DROP |
  133. OTGCMD_DEV_POWER_OFF | OTGCMD_HOST_POWER_OFF,
  134. &cdns->otg_regs->cmd);
  135. /* Waiting till H_IDLE state.*/
  136. readl_poll_timeout_atomic(&cdns->otg_regs->state, val,
  137. !(val & OTGSTATE_HOST_STATE_MASK),
  138. 1, 2000000);
  139. }
  140. return 0;
  141. }
  142. /**
  143. * cdns3_drd_switch_gadget - start/stop gadget
  144. * @cdns: Pointer to controller context structure
  145. * @on: 1 for start, 0 for stop
  146. *
  147. * Returns 0 on success otherwise negative errno
  148. */
  149. int cdns3_drd_switch_gadget(struct cdns3 *cdns, int on)
  150. {
  151. int ret, val;
  152. u32 reg = OTGCMD_OTG_DIS;
  153. /* switch OTG core */
  154. if (on) {
  155. writel(OTGCMD_DEV_BUS_REQ | reg, &cdns->otg_regs->cmd);
  156. dev_dbg(cdns->dev, "Waiting till Device mode is turned on\n");
  157. ret = readl_poll_timeout_atomic(&cdns->otg_regs->sts, val,
  158. val & OTGSTS_DEV_READY,
  159. 1, 100000);
  160. if (ret) {
  161. dev_err(cdns->dev, "timeout waiting for dev_ready\n");
  162. return ret;
  163. }
  164. } else {
  165. /*
  166. * driver should wait at least 10us after disabling Device
  167. * before turning-off Device (DEV_BUS_DROP)
  168. */
  169. usleep_range(20, 30);
  170. writel(OTGCMD_HOST_BUS_DROP | OTGCMD_DEV_BUS_DROP |
  171. OTGCMD_DEV_POWER_OFF | OTGCMD_HOST_POWER_OFF,
  172. &cdns->otg_regs->cmd);
  173. /* Waiting till DEV_IDLE state.*/
  174. readl_poll_timeout_atomic(&cdns->otg_regs->state, val,
  175. !(val & OTGSTATE_DEV_STATE_MASK),
  176. 1, 2000000);
  177. }
  178. return 0;
  179. }
  180. /**
  181. * cdns3_init_otg_mode - initialize drd controller
  182. * @cdns: Pointer to controller context structure
  183. *
  184. * Returns 0 on success otherwise negative errno
  185. */
  186. static int cdns3_init_otg_mode(struct cdns3 *cdns)
  187. {
  188. int ret = 0;
  189. cdns3_otg_disable_irq(cdns);
  190. /* clear all interrupts */
  191. writel(~0, &cdns->otg_regs->ivect);
  192. ret = cdns3_set_mode(cdns, USB_DR_MODE_OTG);
  193. if (ret)
  194. return ret;
  195. cdns3_otg_enable_irq(cdns);
  196. return ret;
  197. }
  198. /**
  199. * cdns3_drd_update_mode - initialize mode of operation
  200. * @cdns: Pointer to controller context structure
  201. *
  202. * Returns 0 on success otherwise negative errno
  203. */
  204. int cdns3_drd_update_mode(struct cdns3 *cdns)
  205. {
  206. int ret = 0;
  207. switch (cdns->dr_mode) {
  208. case USB_DR_MODE_PERIPHERAL:
  209. ret = cdns3_set_mode(cdns, USB_DR_MODE_PERIPHERAL);
  210. break;
  211. case USB_DR_MODE_HOST:
  212. ret = cdns3_set_mode(cdns, USB_DR_MODE_HOST);
  213. break;
  214. case USB_DR_MODE_OTG:
  215. ret = cdns3_init_otg_mode(cdns);
  216. break;
  217. default:
  218. dev_err(cdns->dev, "Unsupported mode of operation %d\n",
  219. cdns->dr_mode);
  220. return -EINVAL;
  221. }
  222. return ret;
  223. }
  224. static irqreturn_t cdns3_drd_thread_irq(int irq, void *data)
  225. {
  226. struct cdns3 *cdns = data;
  227. cdns3_hw_role_switch(cdns);
  228. return IRQ_HANDLED;
  229. }
  230. /**
  231. * cdns3_drd_irq - interrupt handler for OTG events
  232. *
  233. * @irq: irq number for cdns3 core device
  234. * @data: structure of cdns3
  235. *
  236. * Returns IRQ_HANDLED or IRQ_NONE
  237. */
  238. static irqreturn_t cdns3_drd_irq(int irq, void *data)
  239. {
  240. irqreturn_t ret = IRQ_NONE;
  241. struct cdns3 *cdns = data;
  242. u32 reg;
  243. if (cdns->dr_mode != USB_DR_MODE_OTG)
  244. return ret;
  245. reg = readl(&cdns->otg_regs->ivect);
  246. if (!reg)
  247. return ret;
  248. if (reg & OTGIEN_ID_CHANGE_INT) {
  249. dev_dbg(cdns->dev, "OTG IRQ: new ID: %d\n",
  250. cdns3_get_id(cdns));
  251. ret = IRQ_WAKE_THREAD;
  252. }
  253. if (reg & (OTGIEN_VBUSVALID_RISE_INT | OTGIEN_VBUSVALID_FALL_INT)) {
  254. dev_dbg(cdns->dev, "OTG IRQ: new VBUS: %d\n",
  255. cdns3_get_vbus(cdns));
  256. ret = IRQ_WAKE_THREAD;
  257. }
  258. writel(~0, &cdns->otg_regs->ivect);
  259. return ret;
  260. }
  261. int cdns3_drd_init(struct cdns3 *cdns)
  262. {
  263. void __iomem *regs;
  264. int ret = 0;
  265. u32 state;
  266. regs = devm_ioremap_resource(cdns->dev, &cdns->otg_res);
  267. if (IS_ERR(regs))
  268. return PTR_ERR(regs);
  269. /* Detection of DRD version. Controller has been released
  270. * in two versions. Both are similar, but they have same changes
  271. * in register maps.
  272. * The first register in old version is command register and it's read
  273. * only, so driver should read 0 from it. On the other hand, in v1
  274. * the first register contains device ID number which is not set to 0.
  275. * Driver uses this fact to detect the proper version of
  276. * controller.
  277. */
  278. cdns->otg_v0_regs = regs;
  279. if (!readl(&cdns->otg_v0_regs->cmd)) {
  280. cdns->version = CDNS3_CONTROLLER_V0;
  281. cdns->otg_v1_regs = NULL;
  282. cdns->otg_regs = regs;
  283. writel(1, &cdns->otg_v0_regs->simulate);
  284. dev_info(cdns->dev, "DRD version v0 (%08x)\n",
  285. readl(&cdns->otg_v0_regs->version));
  286. } else {
  287. cdns->otg_v0_regs = NULL;
  288. cdns->otg_v1_regs = regs;
  289. cdns->otg_regs = (void *)&cdns->otg_v1_regs->cmd;
  290. cdns->version = CDNS3_CONTROLLER_V1;
  291. writel(1, &cdns->otg_v1_regs->simulate);
  292. dev_info(cdns->dev, "DRD version v1 (ID: %08x, rev: %08x)\n",
  293. readl(&cdns->otg_v1_regs->did),
  294. readl(&cdns->otg_v1_regs->rid));
  295. }
  296. state = OTGSTS_STRAP(readl(&cdns->otg_regs->sts));
  297. /* Update dr_mode according to STRAP configuration. */
  298. cdns->dr_mode = USB_DR_MODE_OTG;
  299. if (state == OTGSTS_STRAP_HOST) {
  300. dev_dbg(cdns->dev, "Controller strapped to HOST\n");
  301. cdns->dr_mode = USB_DR_MODE_HOST;
  302. } else if (state == OTGSTS_STRAP_GADGET) {
  303. dev_dbg(cdns->dev, "Controller strapped to PERIPHERAL\n");
  304. cdns->dr_mode = USB_DR_MODE_PERIPHERAL;
  305. }
  306. ret = devm_request_threaded_irq(cdns->dev, cdns->otg_irq,
  307. cdns3_drd_irq,
  308. cdns3_drd_thread_irq,
  309. IRQF_SHARED,
  310. dev_name(cdns->dev), cdns);
  311. if (ret) {
  312. dev_err(cdns->dev, "couldn't get otg_irq\n");
  313. return ret;
  314. }
  315. state = readl(&cdns->otg_regs->sts);
  316. if (OTGSTS_OTG_NRDY(state) != 0) {
  317. dev_err(cdns->dev, "Cadence USB3 OTG device not ready\n");
  318. return -ENODEV;
  319. }
  320. return ret;
  321. }
  322. int cdns3_drd_exit(struct cdns3 *cdns)
  323. {
  324. cdns3_otg_disable_irq(cdns);
  325. return 0;
  326. }