dwc3-qcom.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright (c) 2018, The Linux Foundation. All rights reserved.
  3. *
  4. * Inspired by dwc3-of-simple.c
  5. */
  6. #include <linux/cleanup.h>
  7. #include <linux/io.h>
  8. #include <linux/of.h>
  9. #include <linux/clk.h>
  10. #include <linux/irq.h>
  11. #include <linux/of_clk.h>
  12. #include <linux/module.h>
  13. #include <linux/kernel.h>
  14. #include <linux/extcon.h>
  15. #include <linux/interconnect.h>
  16. #include <linux/of_platform.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/phy/phy.h>
  19. #include <linux/usb/of.h>
  20. #include <linux/reset.h>
  21. #include <linux/iopoll.h>
  22. #include <linux/usb/hcd.h>
  23. #include <linux/usb.h>
  24. #include "core.h"
  25. /* USB QSCRATCH Hardware registers */
  26. #define QSCRATCH_HS_PHY_CTRL 0x10
  27. #define UTMI_OTG_VBUS_VALID BIT(20)
  28. #define SW_SESSVLD_SEL BIT(28)
  29. #define QSCRATCH_SS_PHY_CTRL 0x30
  30. #define LANE0_PWR_PRESENT BIT(24)
  31. #define QSCRATCH_GENERAL_CFG 0x08
  32. #define PIPE_UTMI_CLK_SEL BIT(0)
  33. #define PIPE3_PHYSTATUS_SW BIT(3)
  34. #define PIPE_UTMI_CLK_DIS BIT(8)
  35. #define PWR_EVNT_LPM_IN_L2_MASK BIT(4)
  36. #define PWR_EVNT_LPM_OUT_L2_MASK BIT(5)
  37. #define SDM845_QSCRATCH_BASE_OFFSET 0xf8800
  38. #define SDM845_QSCRATCH_SIZE 0x400
  39. #define SDM845_DWC3_CORE_SIZE 0xcd00
  40. /* Interconnect path bandwidths in MBps */
  41. #define USB_MEMORY_AVG_HS_BW MBps_to_icc(240)
  42. #define USB_MEMORY_PEAK_HS_BW MBps_to_icc(700)
  43. #define USB_MEMORY_AVG_SS_BW MBps_to_icc(1000)
  44. #define USB_MEMORY_PEAK_SS_BW MBps_to_icc(2500)
  45. #define APPS_USB_AVG_BW 0
  46. #define APPS_USB_PEAK_BW MBps_to_icc(40)
  47. /* Qualcomm SoCs with multiport support has up to 4 ports */
  48. #define DWC3_QCOM_MAX_PORTS 4
  49. static const u32 pwr_evnt_irq_stat_reg[DWC3_QCOM_MAX_PORTS] = {
  50. 0x58,
  51. 0x1dc,
  52. 0x228,
  53. 0x238,
  54. };
  55. struct dwc3_qcom_port {
  56. int qusb2_phy_irq;
  57. int dp_hs_phy_irq;
  58. int dm_hs_phy_irq;
  59. int ss_phy_irq;
  60. enum usb_device_speed usb2_speed;
  61. };
  62. struct dwc3_qcom {
  63. struct device *dev;
  64. void __iomem *qscratch_base;
  65. struct platform_device *dwc3;
  66. struct clk **clks;
  67. int num_clocks;
  68. struct reset_control *resets;
  69. struct dwc3_qcom_port ports[DWC3_QCOM_MAX_PORTS];
  70. u8 num_ports;
  71. struct extcon_dev *edev;
  72. struct extcon_dev *host_edev;
  73. struct notifier_block vbus_nb;
  74. struct notifier_block host_nb;
  75. enum usb_dr_mode mode;
  76. bool is_suspended;
  77. bool pm_suspended;
  78. struct icc_path *icc_path_ddr;
  79. struct icc_path *icc_path_apps;
  80. };
  81. static inline void dwc3_qcom_setbits(void __iomem *base, u32 offset, u32 val)
  82. {
  83. u32 reg;
  84. reg = readl(base + offset);
  85. reg |= val;
  86. writel(reg, base + offset);
  87. /* ensure that above write is through */
  88. readl(base + offset);
  89. }
  90. static inline void dwc3_qcom_clrbits(void __iomem *base, u32 offset, u32 val)
  91. {
  92. u32 reg;
  93. reg = readl(base + offset);
  94. reg &= ~val;
  95. writel(reg, base + offset);
  96. /* ensure that above write is through */
  97. readl(base + offset);
  98. }
  99. static void dwc3_qcom_vbus_override_enable(struct dwc3_qcom *qcom, bool enable)
  100. {
  101. if (enable) {
  102. dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_SS_PHY_CTRL,
  103. LANE0_PWR_PRESENT);
  104. dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_HS_PHY_CTRL,
  105. UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
  106. } else {
  107. dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_SS_PHY_CTRL,
  108. LANE0_PWR_PRESENT);
  109. dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_HS_PHY_CTRL,
  110. UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
  111. }
  112. }
  113. static int dwc3_qcom_vbus_notifier(struct notifier_block *nb,
  114. unsigned long event, void *ptr)
  115. {
  116. struct dwc3_qcom *qcom = container_of(nb, struct dwc3_qcom, vbus_nb);
  117. /* enable vbus override for device mode */
  118. dwc3_qcom_vbus_override_enable(qcom, event);
  119. qcom->mode = event ? USB_DR_MODE_PERIPHERAL : USB_DR_MODE_HOST;
  120. return NOTIFY_DONE;
  121. }
  122. static int dwc3_qcom_host_notifier(struct notifier_block *nb,
  123. unsigned long event, void *ptr)
  124. {
  125. struct dwc3_qcom *qcom = container_of(nb, struct dwc3_qcom, host_nb);
  126. /* disable vbus override in host mode */
  127. dwc3_qcom_vbus_override_enable(qcom, !event);
  128. qcom->mode = event ? USB_DR_MODE_HOST : USB_DR_MODE_PERIPHERAL;
  129. return NOTIFY_DONE;
  130. }
  131. static int dwc3_qcom_register_extcon(struct dwc3_qcom *qcom)
  132. {
  133. struct device *dev = qcom->dev;
  134. struct extcon_dev *host_edev;
  135. int ret;
  136. if (!of_property_read_bool(dev->of_node, "extcon"))
  137. return 0;
  138. qcom->edev = extcon_get_edev_by_phandle(dev, 0);
  139. if (IS_ERR(qcom->edev))
  140. return dev_err_probe(dev, PTR_ERR(qcom->edev),
  141. "Failed to get extcon\n");
  142. qcom->vbus_nb.notifier_call = dwc3_qcom_vbus_notifier;
  143. qcom->host_edev = extcon_get_edev_by_phandle(dev, 1);
  144. if (IS_ERR(qcom->host_edev))
  145. qcom->host_edev = NULL;
  146. ret = devm_extcon_register_notifier(dev, qcom->edev, EXTCON_USB,
  147. &qcom->vbus_nb);
  148. if (ret < 0) {
  149. dev_err(dev, "VBUS notifier register failed\n");
  150. return ret;
  151. }
  152. if (qcom->host_edev)
  153. host_edev = qcom->host_edev;
  154. else
  155. host_edev = qcom->edev;
  156. qcom->host_nb.notifier_call = dwc3_qcom_host_notifier;
  157. ret = devm_extcon_register_notifier(dev, host_edev, EXTCON_USB_HOST,
  158. &qcom->host_nb);
  159. if (ret < 0) {
  160. dev_err(dev, "Host notifier register failed\n");
  161. return ret;
  162. }
  163. /* Update initial VBUS override based on extcon state */
  164. if (extcon_get_state(qcom->edev, EXTCON_USB) ||
  165. !extcon_get_state(host_edev, EXTCON_USB_HOST))
  166. dwc3_qcom_vbus_notifier(&qcom->vbus_nb, true, qcom->edev);
  167. else
  168. dwc3_qcom_vbus_notifier(&qcom->vbus_nb, false, qcom->edev);
  169. return 0;
  170. }
  171. static int dwc3_qcom_interconnect_enable(struct dwc3_qcom *qcom)
  172. {
  173. int ret;
  174. ret = icc_enable(qcom->icc_path_ddr);
  175. if (ret)
  176. return ret;
  177. ret = icc_enable(qcom->icc_path_apps);
  178. if (ret)
  179. icc_disable(qcom->icc_path_ddr);
  180. return ret;
  181. }
  182. static int dwc3_qcom_interconnect_disable(struct dwc3_qcom *qcom)
  183. {
  184. int ret;
  185. ret = icc_disable(qcom->icc_path_ddr);
  186. if (ret)
  187. return ret;
  188. ret = icc_disable(qcom->icc_path_apps);
  189. if (ret)
  190. icc_enable(qcom->icc_path_ddr);
  191. return ret;
  192. }
  193. /**
  194. * dwc3_qcom_interconnect_init() - Get interconnect path handles
  195. * and set bandwidth.
  196. * @qcom: Pointer to the concerned usb core.
  197. *
  198. */
  199. static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom)
  200. {
  201. enum usb_device_speed max_speed;
  202. struct device *dev = qcom->dev;
  203. int ret;
  204. qcom->icc_path_ddr = of_icc_get(dev, "usb-ddr");
  205. if (IS_ERR(qcom->icc_path_ddr)) {
  206. return dev_err_probe(dev, PTR_ERR(qcom->icc_path_ddr),
  207. "failed to get usb-ddr path\n");
  208. }
  209. qcom->icc_path_apps = of_icc_get(dev, "apps-usb");
  210. if (IS_ERR(qcom->icc_path_apps)) {
  211. ret = dev_err_probe(dev, PTR_ERR(qcom->icc_path_apps),
  212. "failed to get apps-usb path\n");
  213. goto put_path_ddr;
  214. }
  215. max_speed = usb_get_maximum_speed(&qcom->dwc3->dev);
  216. if (max_speed >= USB_SPEED_SUPER || max_speed == USB_SPEED_UNKNOWN) {
  217. ret = icc_set_bw(qcom->icc_path_ddr,
  218. USB_MEMORY_AVG_SS_BW, USB_MEMORY_PEAK_SS_BW);
  219. } else {
  220. ret = icc_set_bw(qcom->icc_path_ddr,
  221. USB_MEMORY_AVG_HS_BW, USB_MEMORY_PEAK_HS_BW);
  222. }
  223. if (ret) {
  224. dev_err(dev, "failed to set bandwidth for usb-ddr path: %d\n", ret);
  225. goto put_path_apps;
  226. }
  227. ret = icc_set_bw(qcom->icc_path_apps, APPS_USB_AVG_BW, APPS_USB_PEAK_BW);
  228. if (ret) {
  229. dev_err(dev, "failed to set bandwidth for apps-usb path: %d\n", ret);
  230. goto put_path_apps;
  231. }
  232. return 0;
  233. put_path_apps:
  234. icc_put(qcom->icc_path_apps);
  235. put_path_ddr:
  236. icc_put(qcom->icc_path_ddr);
  237. return ret;
  238. }
  239. /**
  240. * dwc3_qcom_interconnect_exit() - Release interconnect path handles
  241. * @qcom: Pointer to the concerned usb core.
  242. *
  243. * This function is used to release interconnect path handle.
  244. */
  245. static void dwc3_qcom_interconnect_exit(struct dwc3_qcom *qcom)
  246. {
  247. icc_put(qcom->icc_path_ddr);
  248. icc_put(qcom->icc_path_apps);
  249. }
  250. /* Only usable in contexts where the role can not change. */
  251. static bool dwc3_qcom_is_host(struct dwc3_qcom *qcom)
  252. {
  253. struct dwc3 *dwc;
  254. /*
  255. * FIXME: Fix this layering violation.
  256. */
  257. dwc = platform_get_drvdata(qcom->dwc3);
  258. /* Core driver may not have probed yet. */
  259. if (!dwc)
  260. return false;
  261. return dwc->xhci;
  262. }
  263. static enum usb_device_speed dwc3_qcom_read_usb2_speed(struct dwc3_qcom *qcom, int port_index)
  264. {
  265. struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3);
  266. struct usb_device *udev;
  267. struct usb_hcd __maybe_unused *hcd;
  268. /*
  269. * FIXME: Fix this layering violation.
  270. */
  271. hcd = platform_get_drvdata(dwc->xhci);
  272. #ifdef CONFIG_USB
  273. udev = usb_hub_find_child(hcd->self.root_hub, port_index + 1);
  274. #else
  275. udev = NULL;
  276. #endif
  277. if (!udev)
  278. return USB_SPEED_UNKNOWN;
  279. return udev->speed;
  280. }
  281. static void dwc3_qcom_enable_wakeup_irq(int irq, unsigned int polarity)
  282. {
  283. if (!irq)
  284. return;
  285. if (polarity)
  286. irq_set_irq_type(irq, polarity);
  287. enable_irq(irq);
  288. enable_irq_wake(irq);
  289. }
  290. static void dwc3_qcom_disable_wakeup_irq(int irq)
  291. {
  292. if (!irq)
  293. return;
  294. disable_irq_wake(irq);
  295. disable_irq_nosync(irq);
  296. }
  297. static void dwc3_qcom_disable_port_interrupts(struct dwc3_qcom_port *port)
  298. {
  299. dwc3_qcom_disable_wakeup_irq(port->qusb2_phy_irq);
  300. if (port->usb2_speed == USB_SPEED_LOW) {
  301. dwc3_qcom_disable_wakeup_irq(port->dm_hs_phy_irq);
  302. } else if ((port->usb2_speed == USB_SPEED_HIGH) ||
  303. (port->usb2_speed == USB_SPEED_FULL)) {
  304. dwc3_qcom_disable_wakeup_irq(port->dp_hs_phy_irq);
  305. } else {
  306. dwc3_qcom_disable_wakeup_irq(port->dp_hs_phy_irq);
  307. dwc3_qcom_disable_wakeup_irq(port->dm_hs_phy_irq);
  308. }
  309. dwc3_qcom_disable_wakeup_irq(port->ss_phy_irq);
  310. }
  311. static void dwc3_qcom_enable_port_interrupts(struct dwc3_qcom_port *port)
  312. {
  313. dwc3_qcom_enable_wakeup_irq(port->qusb2_phy_irq, 0);
  314. /*
  315. * Configure DP/DM line interrupts based on the USB2 device attached to
  316. * the root hub port. When HS/FS device is connected, configure the DP line
  317. * as falling edge to detect both disconnect and remote wakeup scenarios. When
  318. * LS device is connected, configure DM line as falling edge to detect both
  319. * disconnect and remote wakeup. When no device is connected, configure both
  320. * DP and DM lines as rising edge to detect HS/HS/LS device connect scenario.
  321. */
  322. if (port->usb2_speed == USB_SPEED_LOW) {
  323. dwc3_qcom_enable_wakeup_irq(port->dm_hs_phy_irq,
  324. IRQ_TYPE_EDGE_FALLING);
  325. } else if ((port->usb2_speed == USB_SPEED_HIGH) ||
  326. (port->usb2_speed == USB_SPEED_FULL)) {
  327. dwc3_qcom_enable_wakeup_irq(port->dp_hs_phy_irq,
  328. IRQ_TYPE_EDGE_FALLING);
  329. } else {
  330. dwc3_qcom_enable_wakeup_irq(port->dp_hs_phy_irq,
  331. IRQ_TYPE_EDGE_RISING);
  332. dwc3_qcom_enable_wakeup_irq(port->dm_hs_phy_irq,
  333. IRQ_TYPE_EDGE_RISING);
  334. }
  335. dwc3_qcom_enable_wakeup_irq(port->ss_phy_irq, 0);
  336. }
  337. static void dwc3_qcom_disable_interrupts(struct dwc3_qcom *qcom)
  338. {
  339. int i;
  340. for (i = 0; i < qcom->num_ports; i++)
  341. dwc3_qcom_disable_port_interrupts(&qcom->ports[i]);
  342. }
  343. static void dwc3_qcom_enable_interrupts(struct dwc3_qcom *qcom)
  344. {
  345. int i;
  346. for (i = 0; i < qcom->num_ports; i++)
  347. dwc3_qcom_enable_port_interrupts(&qcom->ports[i]);
  348. }
  349. static int dwc3_qcom_suspend(struct dwc3_qcom *qcom, bool wakeup)
  350. {
  351. u32 val;
  352. int i, ret;
  353. if (qcom->is_suspended)
  354. return 0;
  355. for (i = 0; i < qcom->num_ports; i++) {
  356. val = readl(qcom->qscratch_base + pwr_evnt_irq_stat_reg[i]);
  357. if (!(val & PWR_EVNT_LPM_IN_L2_MASK))
  358. dev_err(qcom->dev, "port-%d HS-PHY not in L2\n", i + 1);
  359. }
  360. for (i = qcom->num_clocks - 1; i >= 0; i--)
  361. clk_disable_unprepare(qcom->clks[i]);
  362. ret = dwc3_qcom_interconnect_disable(qcom);
  363. if (ret)
  364. dev_warn(qcom->dev, "failed to disable interconnect: %d\n", ret);
  365. /*
  366. * The role is stable during suspend as role switching is done from a
  367. * freezable workqueue.
  368. */
  369. if (dwc3_qcom_is_host(qcom) && wakeup) {
  370. for (i = 0; i < qcom->num_ports; i++)
  371. qcom->ports[i].usb2_speed = dwc3_qcom_read_usb2_speed(qcom, i);
  372. dwc3_qcom_enable_interrupts(qcom);
  373. }
  374. qcom->is_suspended = true;
  375. return 0;
  376. }
  377. static int dwc3_qcom_resume(struct dwc3_qcom *qcom, bool wakeup)
  378. {
  379. int ret;
  380. int i;
  381. if (!qcom->is_suspended)
  382. return 0;
  383. if (dwc3_qcom_is_host(qcom) && wakeup)
  384. dwc3_qcom_disable_interrupts(qcom);
  385. for (i = 0; i < qcom->num_clocks; i++) {
  386. ret = clk_prepare_enable(qcom->clks[i]);
  387. if (ret < 0) {
  388. while (--i >= 0)
  389. clk_disable_unprepare(qcom->clks[i]);
  390. return ret;
  391. }
  392. }
  393. ret = dwc3_qcom_interconnect_enable(qcom);
  394. if (ret)
  395. dev_warn(qcom->dev, "failed to enable interconnect: %d\n", ret);
  396. /* Clear existing events from PHY related to L2 in/out */
  397. for (i = 0; i < qcom->num_ports; i++) {
  398. dwc3_qcom_setbits(qcom->qscratch_base,
  399. pwr_evnt_irq_stat_reg[i],
  400. PWR_EVNT_LPM_IN_L2_MASK | PWR_EVNT_LPM_OUT_L2_MASK);
  401. }
  402. qcom->is_suspended = false;
  403. return 0;
  404. }
  405. static irqreturn_t qcom_dwc3_resume_irq(int irq, void *data)
  406. {
  407. struct dwc3_qcom *qcom = data;
  408. struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3);
  409. /* If pm_suspended then let pm_resume take care of resuming h/w */
  410. if (qcom->pm_suspended)
  411. return IRQ_HANDLED;
  412. /*
  413. * This is safe as role switching is done from a freezable workqueue
  414. * and the wakeup interrupts are disabled as part of resume.
  415. */
  416. if (dwc3_qcom_is_host(qcom))
  417. pm_runtime_resume(&dwc->xhci->dev);
  418. return IRQ_HANDLED;
  419. }
  420. static void dwc3_qcom_select_utmi_clk(struct dwc3_qcom *qcom)
  421. {
  422. /* Configure dwc3 to use UTMI clock as PIPE clock not present */
  423. dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG,
  424. PIPE_UTMI_CLK_DIS);
  425. usleep_range(100, 1000);
  426. dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG,
  427. PIPE_UTMI_CLK_SEL | PIPE3_PHYSTATUS_SW);
  428. usleep_range(100, 1000);
  429. dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG,
  430. PIPE_UTMI_CLK_DIS);
  431. }
  432. static int dwc3_qcom_request_irq(struct dwc3_qcom *qcom, int irq,
  433. const char *name)
  434. {
  435. int ret;
  436. /* Keep wakeup interrupts disabled until suspend */
  437. ret = devm_request_threaded_irq(qcom->dev, irq, NULL,
  438. qcom_dwc3_resume_irq,
  439. IRQF_ONESHOT | IRQF_NO_AUTOEN,
  440. name, qcom);
  441. if (ret)
  442. dev_err(qcom->dev, "failed to request irq %s: %d\n", name, ret);
  443. return ret;
  444. }
  445. static int dwc3_qcom_setup_port_irq(struct platform_device *pdev, int port_index, bool is_multiport)
  446. {
  447. struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
  448. const char *irq_name;
  449. int irq;
  450. int ret;
  451. if (is_multiport)
  452. irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "dp_hs_phy_%d", port_index + 1);
  453. else
  454. irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "dp_hs_phy_irq");
  455. if (!irq_name)
  456. return -ENOMEM;
  457. irq = platform_get_irq_byname_optional(pdev, irq_name);
  458. if (irq > 0) {
  459. ret = dwc3_qcom_request_irq(qcom, irq, irq_name);
  460. if (ret)
  461. return ret;
  462. qcom->ports[port_index].dp_hs_phy_irq = irq;
  463. }
  464. if (is_multiport)
  465. irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "dm_hs_phy_%d", port_index + 1);
  466. else
  467. irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "dm_hs_phy_irq");
  468. if (!irq_name)
  469. return -ENOMEM;
  470. irq = platform_get_irq_byname_optional(pdev, irq_name);
  471. if (irq > 0) {
  472. ret = dwc3_qcom_request_irq(qcom, irq, irq_name);
  473. if (ret)
  474. return ret;
  475. qcom->ports[port_index].dm_hs_phy_irq = irq;
  476. }
  477. if (is_multiport)
  478. irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "ss_phy_%d", port_index + 1);
  479. else
  480. irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "ss_phy_irq");
  481. if (!irq_name)
  482. return -ENOMEM;
  483. irq = platform_get_irq_byname_optional(pdev, irq_name);
  484. if (irq > 0) {
  485. ret = dwc3_qcom_request_irq(qcom, irq, irq_name);
  486. if (ret)
  487. return ret;
  488. qcom->ports[port_index].ss_phy_irq = irq;
  489. }
  490. if (is_multiport)
  491. return 0;
  492. irq = platform_get_irq_byname_optional(pdev, "qusb2_phy");
  493. if (irq > 0) {
  494. ret = dwc3_qcom_request_irq(qcom, irq, "qusb2_phy");
  495. if (ret)
  496. return ret;
  497. qcom->ports[port_index].qusb2_phy_irq = irq;
  498. }
  499. return 0;
  500. }
  501. static int dwc3_qcom_find_num_ports(struct platform_device *pdev)
  502. {
  503. char irq_name[14];
  504. int port_num;
  505. int irq;
  506. irq = platform_get_irq_byname_optional(pdev, "dp_hs_phy_1");
  507. if (irq <= 0)
  508. return 1;
  509. for (port_num = 2; port_num <= DWC3_QCOM_MAX_PORTS; port_num++) {
  510. sprintf(irq_name, "dp_hs_phy_%d", port_num);
  511. irq = platform_get_irq_byname_optional(pdev, irq_name);
  512. if (irq <= 0)
  513. return port_num - 1;
  514. }
  515. return DWC3_QCOM_MAX_PORTS;
  516. }
  517. static int dwc3_qcom_setup_irq(struct platform_device *pdev)
  518. {
  519. struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
  520. bool is_multiport;
  521. int ret;
  522. int i;
  523. qcom->num_ports = dwc3_qcom_find_num_ports(pdev);
  524. is_multiport = (qcom->num_ports > 1);
  525. for (i = 0; i < qcom->num_ports; i++) {
  526. ret = dwc3_qcom_setup_port_irq(pdev, i, is_multiport);
  527. if (ret)
  528. return ret;
  529. }
  530. return 0;
  531. }
  532. static int dwc3_qcom_clk_init(struct dwc3_qcom *qcom, int count)
  533. {
  534. struct device *dev = qcom->dev;
  535. struct device_node *np = dev->of_node;
  536. int i;
  537. if (!np || !count)
  538. return 0;
  539. if (count < 0)
  540. return count;
  541. qcom->num_clocks = count;
  542. qcom->clks = devm_kcalloc(dev, qcom->num_clocks,
  543. sizeof(struct clk *), GFP_KERNEL);
  544. if (!qcom->clks)
  545. return -ENOMEM;
  546. for (i = 0; i < qcom->num_clocks; i++) {
  547. struct clk *clk;
  548. int ret;
  549. clk = of_clk_get(np, i);
  550. if (IS_ERR(clk)) {
  551. while (--i >= 0)
  552. clk_put(qcom->clks[i]);
  553. return PTR_ERR(clk);
  554. }
  555. ret = clk_prepare_enable(clk);
  556. if (ret < 0) {
  557. while (--i >= 0) {
  558. clk_disable_unprepare(qcom->clks[i]);
  559. clk_put(qcom->clks[i]);
  560. }
  561. clk_put(clk);
  562. return ret;
  563. }
  564. qcom->clks[i] = clk;
  565. }
  566. return 0;
  567. }
  568. static int dwc3_qcom_of_register_core(struct platform_device *pdev)
  569. {
  570. struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
  571. struct device_node *np = pdev->dev.of_node;
  572. struct device *dev = &pdev->dev;
  573. int ret;
  574. struct device_node *dwc3_np __free(device_node) = of_get_compatible_child(np,
  575. "snps,dwc3");
  576. if (!dwc3_np) {
  577. dev_err(dev, "failed to find dwc3 core child\n");
  578. return -ENODEV;
  579. }
  580. ret = of_platform_populate(np, NULL, NULL, dev);
  581. if (ret) {
  582. dev_err(dev, "failed to register dwc3 core - %d\n", ret);
  583. return ret;
  584. }
  585. qcom->dwc3 = of_find_device_by_node(dwc3_np);
  586. if (!qcom->dwc3) {
  587. ret = -ENODEV;
  588. dev_err(dev, "failed to get dwc3 platform device\n");
  589. of_platform_depopulate(dev);
  590. }
  591. return ret;
  592. }
  593. static int dwc3_qcom_probe(struct platform_device *pdev)
  594. {
  595. struct device_node *np = pdev->dev.of_node;
  596. struct device *dev = &pdev->dev;
  597. struct dwc3_qcom *qcom;
  598. int ret, i;
  599. bool ignore_pipe_clk;
  600. bool wakeup_source;
  601. qcom = devm_kzalloc(&pdev->dev, sizeof(*qcom), GFP_KERNEL);
  602. if (!qcom)
  603. return -ENOMEM;
  604. platform_set_drvdata(pdev, qcom);
  605. qcom->dev = &pdev->dev;
  606. qcom->resets = devm_reset_control_array_get_optional_exclusive(dev);
  607. if (IS_ERR(qcom->resets)) {
  608. return dev_err_probe(&pdev->dev, PTR_ERR(qcom->resets),
  609. "failed to get resets\n");
  610. }
  611. ret = reset_control_assert(qcom->resets);
  612. if (ret) {
  613. dev_err(&pdev->dev, "failed to assert resets, err=%d\n", ret);
  614. return ret;
  615. }
  616. usleep_range(10, 1000);
  617. ret = reset_control_deassert(qcom->resets);
  618. if (ret) {
  619. dev_err(&pdev->dev, "failed to deassert resets, err=%d\n", ret);
  620. goto reset_assert;
  621. }
  622. ret = dwc3_qcom_clk_init(qcom, of_clk_get_parent_count(np));
  623. if (ret) {
  624. dev_err_probe(dev, ret, "failed to get clocks\n");
  625. goto reset_assert;
  626. }
  627. qcom->qscratch_base = devm_platform_ioremap_resource(pdev, 0);
  628. if (IS_ERR(qcom->qscratch_base)) {
  629. ret = PTR_ERR(qcom->qscratch_base);
  630. goto clk_disable;
  631. }
  632. ret = dwc3_qcom_setup_irq(pdev);
  633. if (ret) {
  634. dev_err(dev, "failed to setup IRQs, err=%d\n", ret);
  635. goto clk_disable;
  636. }
  637. /*
  638. * Disable pipe_clk requirement if specified. Used when dwc3
  639. * operates without SSPHY and only HS/FS/LS modes are supported.
  640. */
  641. ignore_pipe_clk = device_property_read_bool(dev,
  642. "qcom,select-utmi-as-pipe-clk");
  643. if (ignore_pipe_clk)
  644. dwc3_qcom_select_utmi_clk(qcom);
  645. ret = dwc3_qcom_of_register_core(pdev);
  646. if (ret) {
  647. dev_err(dev, "failed to register DWC3 Core, err=%d\n", ret);
  648. goto clk_disable;
  649. }
  650. ret = dwc3_qcom_interconnect_init(qcom);
  651. if (ret)
  652. goto depopulate;
  653. qcom->mode = usb_get_dr_mode(&qcom->dwc3->dev);
  654. /* enable vbus override for device mode */
  655. if (qcom->mode != USB_DR_MODE_HOST)
  656. dwc3_qcom_vbus_override_enable(qcom, true);
  657. /* register extcon to override sw_vbus on Vbus change later */
  658. ret = dwc3_qcom_register_extcon(qcom);
  659. if (ret)
  660. goto interconnect_exit;
  661. wakeup_source = of_property_read_bool(dev->of_node, "wakeup-source");
  662. device_init_wakeup(&pdev->dev, wakeup_source);
  663. device_init_wakeup(&qcom->dwc3->dev, wakeup_source);
  664. qcom->is_suspended = false;
  665. pm_runtime_set_active(dev);
  666. pm_runtime_enable(dev);
  667. pm_runtime_forbid(dev);
  668. return 0;
  669. interconnect_exit:
  670. dwc3_qcom_interconnect_exit(qcom);
  671. depopulate:
  672. of_platform_depopulate(&pdev->dev);
  673. platform_device_put(qcom->dwc3);
  674. clk_disable:
  675. for (i = qcom->num_clocks - 1; i >= 0; i--) {
  676. clk_disable_unprepare(qcom->clks[i]);
  677. clk_put(qcom->clks[i]);
  678. }
  679. reset_assert:
  680. reset_control_assert(qcom->resets);
  681. return ret;
  682. }
  683. static void dwc3_qcom_remove(struct platform_device *pdev)
  684. {
  685. struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
  686. struct device *dev = &pdev->dev;
  687. int i;
  688. of_platform_depopulate(&pdev->dev);
  689. platform_device_put(qcom->dwc3);
  690. for (i = qcom->num_clocks - 1; i >= 0; i--) {
  691. clk_disable_unprepare(qcom->clks[i]);
  692. clk_put(qcom->clks[i]);
  693. }
  694. qcom->num_clocks = 0;
  695. dwc3_qcom_interconnect_exit(qcom);
  696. reset_control_assert(qcom->resets);
  697. pm_runtime_allow(dev);
  698. pm_runtime_disable(dev);
  699. }
  700. static int __maybe_unused dwc3_qcom_pm_suspend(struct device *dev)
  701. {
  702. struct dwc3_qcom *qcom = dev_get_drvdata(dev);
  703. bool wakeup = device_may_wakeup(dev);
  704. int ret;
  705. ret = dwc3_qcom_suspend(qcom, wakeup);
  706. if (ret)
  707. return ret;
  708. qcom->pm_suspended = true;
  709. return 0;
  710. }
  711. static int __maybe_unused dwc3_qcom_pm_resume(struct device *dev)
  712. {
  713. struct dwc3_qcom *qcom = dev_get_drvdata(dev);
  714. bool wakeup = device_may_wakeup(dev);
  715. int ret;
  716. ret = dwc3_qcom_resume(qcom, wakeup);
  717. if (ret)
  718. return ret;
  719. qcom->pm_suspended = false;
  720. return 0;
  721. }
  722. static int __maybe_unused dwc3_qcom_runtime_suspend(struct device *dev)
  723. {
  724. struct dwc3_qcom *qcom = dev_get_drvdata(dev);
  725. return dwc3_qcom_suspend(qcom, true);
  726. }
  727. static int __maybe_unused dwc3_qcom_runtime_resume(struct device *dev)
  728. {
  729. struct dwc3_qcom *qcom = dev_get_drvdata(dev);
  730. return dwc3_qcom_resume(qcom, true);
  731. }
  732. static const struct dev_pm_ops dwc3_qcom_dev_pm_ops = {
  733. SET_SYSTEM_SLEEP_PM_OPS(dwc3_qcom_pm_suspend, dwc3_qcom_pm_resume)
  734. SET_RUNTIME_PM_OPS(dwc3_qcom_runtime_suspend, dwc3_qcom_runtime_resume,
  735. NULL)
  736. };
  737. static const struct of_device_id dwc3_qcom_of_match[] = {
  738. { .compatible = "qcom,dwc3" },
  739. { }
  740. };
  741. MODULE_DEVICE_TABLE(of, dwc3_qcom_of_match);
  742. static struct platform_driver dwc3_qcom_driver = {
  743. .probe = dwc3_qcom_probe,
  744. .remove_new = dwc3_qcom_remove,
  745. .driver = {
  746. .name = "dwc3-qcom",
  747. .pm = &dwc3_qcom_dev_pm_ops,
  748. .of_match_table = dwc3_qcom_of_match,
  749. },
  750. };
  751. module_platform_driver(dwc3_qcom_driver);
  752. MODULE_LICENSE("GPL v2");
  753. MODULE_DESCRIPTION("DesignWare DWC3 QCOM Glue Driver");