blob: 037052db50ef2322abafa29ae0ea335ac038e66a [file] [log] [blame]
Felipe Balbi72246da2011-08-19 18:10:58 +03001/**
2 * core.c - DesignWare USB3 DRD Controller Core file
3 *
4 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
Felipe Balbi72246da2011-08-19 18:10:58 +03005 *
6 * Authors: Felipe Balbi <balbi@ti.com>,
7 * Sebastian Andrzej Siewior <bigeasy@linutronix.de>
8 *
Felipe Balbi5945f782013-06-30 14:15:11 +03009 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 of
11 * the License as published by the Free Software Foundation.
Felipe Balbi72246da2011-08-19 18:10:58 +030012 *
Felipe Balbi5945f782013-06-30 14:15:11 +030013 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
Felipe Balbi72246da2011-08-19 18:10:58 +030017 *
Felipe Balbi5945f782013-06-30 14:15:11 +030018 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Felipe Balbi72246da2011-08-19 18:10:58 +030020 */
21
Felipe Balbifa0ea132014-09-19 15:51:11 -050022#include <linux/version.h>
Felipe Balbia72e6582011-09-05 13:37:28 +030023#include <linux/module.h>
Felipe Balbi72246da2011-08-19 18:10:58 +030024#include <linux/kernel.h>
25#include <linux/slab.h>
26#include <linux/spinlock.h>
27#include <linux/platform_device.h>
28#include <linux/pm_runtime.h>
29#include <linux/interrupt.h>
30#include <linux/ioport.h>
31#include <linux/io.h>
32#include <linux/list.h>
33#include <linux/delay.h>
34#include <linux/dma-mapping.h>
Felipe Balbi457e84b2012-01-18 18:04:09 +020035#include <linux/of.h>
Heikki Krogerus404905a2014-09-25 10:57:02 +030036#include <linux/acpi.h>
Sekhar Nori63444752015-08-31 21:09:08 +053037#include <linux/pinctrl/consumer.h>
Felipe Balbi72246da2011-08-19 18:10:58 +030038
39#include <linux/usb/ch9.h>
40#include <linux/usb/gadget.h>
Felipe Balbif7e846f2013-06-30 14:29:51 +030041#include <linux/usb/of.h>
Ruchika Kharwara45c82b82013-07-06 07:52:49 -050042#include <linux/usb/otg.h>
Felipe Balbi72246da2011-08-19 18:10:58 +030043
44#include "core.h"
45#include "gadget.h"
46#include "io.h"
47
48#include "debug.h"
49
Felipe Balbifc8bb912016-05-16 13:14:48 +030050#define DWC3_DEFAULT_AUTOSUSPEND_DELAY 5000 /* ms */
Felipe Balbi8300dd22011-10-18 13:54:01 +030051
Thinh Nguyen9d6173e2016-09-06 19:22:03 -070052/**
53 * dwc3_get_dr_mode - Validates and sets dr_mode
54 * @dwc: pointer to our context structure
55 */
56static int dwc3_get_dr_mode(struct dwc3 *dwc)
57{
58 enum usb_dr_mode mode;
59 struct device *dev = dwc->dev;
60 unsigned int hw_mode;
61
62 if (dwc->dr_mode == USB_DR_MODE_UNKNOWN)
63 dwc->dr_mode = USB_DR_MODE_OTG;
64
65 mode = dwc->dr_mode;
66 hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0);
67
68 switch (hw_mode) {
69 case DWC3_GHWPARAMS0_MODE_GADGET:
70 if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) {
71 dev_err(dev,
72 "Controller does not support host mode.\n");
73 return -EINVAL;
74 }
75 mode = USB_DR_MODE_PERIPHERAL;
76 break;
77 case DWC3_GHWPARAMS0_MODE_HOST:
78 if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) {
79 dev_err(dev,
80 "Controller does not support device mode.\n");
81 return -EINVAL;
82 }
83 mode = USB_DR_MODE_HOST;
84 break;
85 default:
86 if (IS_ENABLED(CONFIG_USB_DWC3_HOST))
87 mode = USB_DR_MODE_HOST;
88 else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET))
89 mode = USB_DR_MODE_PERIPHERAL;
90 }
91
92 if (mode != dwc->dr_mode) {
93 dev_warn(dev,
94 "Configuration mismatch. dr_mode forced to %s\n",
95 mode == USB_DR_MODE_HOST ? "host" : "gadget");
96
97 dwc->dr_mode = mode;
98 }
99
100 return 0;
101}
102
Sebastian Andrzej Siewior3140e8cb2011-10-31 22:25:40 +0100103void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
104{
105 u32 reg;
106
107 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
108 reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
109 reg |= DWC3_GCTL_PRTCAPDIR(mode);
110 dwc3_writel(dwc->regs, DWC3_GCTL, reg);
111}
Felipe Balbi8300dd22011-10-18 13:54:01 +0300112
Felipe Balbicf6d8672016-04-14 15:03:39 +0300113u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type)
114{
115 struct dwc3 *dwc = dep->dwc;
116 u32 reg;
117
118 dwc3_writel(dwc->regs, DWC3_GDBGFIFOSPACE,
119 DWC3_GDBGFIFOSPACE_NUM(dep->number) |
120 DWC3_GDBGFIFOSPACE_TYPE(type));
121
122 reg = dwc3_readl(dwc->regs, DWC3_GDBGFIFOSPACE);
123
124 return DWC3_GDBGFIFOSPACE_SPACE_AVAILABLE(reg);
125}
126
Felipe Balbi72246da2011-08-19 18:10:58 +0300127/**
128 * dwc3_core_soft_reset - Issues core soft reset and PHY reset
129 * @dwc: pointer to our context structure
130 */
Kishon Vijay Abraham I57303482014-03-03 17:08:11 +0530131static int dwc3_core_soft_reset(struct dwc3 *dwc)
Felipe Balbi72246da2011-08-19 18:10:58 +0300132{
133 u32 reg;
Felipe Balbif59dcab2016-03-11 10:51:52 +0200134 int retries = 1000;
Kishon Vijay Abraham I57303482014-03-03 17:08:11 +0530135 int ret;
Felipe Balbi72246da2011-08-19 18:10:58 +0300136
Felipe Balbi51e1e7b2012-07-19 14:09:48 +0300137 usb_phy_init(dwc->usb2_phy);
138 usb_phy_init(dwc->usb3_phy);
Kishon Vijay Abraham I57303482014-03-03 17:08:11 +0530139 ret = phy_init(dwc->usb2_generic_phy);
140 if (ret < 0)
141 return ret;
142
143 ret = phy_init(dwc->usb3_generic_phy);
144 if (ret < 0) {
145 phy_exit(dwc->usb2_generic_phy);
146 return ret;
147 }
Felipe Balbi72246da2011-08-19 18:10:58 +0300148
Felipe Balbif59dcab2016-03-11 10:51:52 +0200149 /*
150 * We're resetting only the device side because, if we're in host mode,
151 * XHCI driver will reset the host block. If dwc3 was configured for
152 * host-only mode, then we can return early.
153 */
154 if (dwc->dr_mode == USB_DR_MODE_HOST)
155 return 0;
Felipe Balbi72246da2011-08-19 18:10:58 +0300156
Felipe Balbif59dcab2016-03-11 10:51:52 +0200157 reg = dwc3_readl(dwc->regs, DWC3_DCTL);
158 reg |= DWC3_DCTL_CSFTRST;
159 dwc3_writel(dwc->regs, DWC3_DCTL, reg);
Felipe Balbi72246da2011-08-19 18:10:58 +0300160
Felipe Balbif59dcab2016-03-11 10:51:52 +0200161 do {
162 reg = dwc3_readl(dwc->regs, DWC3_DCTL);
163 if (!(reg & DWC3_DCTL_CSFTRST))
164 return 0;
Pratyush Anand45627ac2012-06-21 17:44:28 +0530165
Felipe Balbif59dcab2016-03-11 10:51:52 +0200166 udelay(1);
167 } while (--retries);
Kishon Vijay Abraham I57303482014-03-03 17:08:11 +0530168
Felipe Balbif59dcab2016-03-11 10:51:52 +0200169 return -ETIMEDOUT;
Felipe Balbi72246da2011-08-19 18:10:58 +0300170}
171
172/**
Heikki Krogerusc5cc74e2015-05-13 15:26:47 +0300173 * dwc3_soft_reset - Issue soft reset
174 * @dwc: Pointer to our controller context structure
175 */
176static int dwc3_soft_reset(struct dwc3 *dwc)
177{
178 unsigned long timeout;
179 u32 reg;
180
181 timeout = jiffies + msecs_to_jiffies(500);
182 dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST);
183 do {
184 reg = dwc3_readl(dwc->regs, DWC3_DCTL);
185 if (!(reg & DWC3_DCTL_CSFTRST))
186 break;
187
188 if (time_after(jiffies, timeout)) {
189 dev_err(dwc->dev, "Reset Timed Out\n");
190 return -ETIMEDOUT;
191 }
192
193 cpu_relax();
194 } while (true);
195
196 return 0;
197}
198
Nikhil Badoladb2be4e2015-09-04 10:15:58 +0530199/*
200 * dwc3_frame_length_adjustment - Adjusts frame length if required
201 * @dwc3: Pointer to our controller context structure
Nikhil Badoladb2be4e2015-09-04 10:15:58 +0530202 */
Felipe Balbibcdb3272016-05-16 10:42:23 +0300203static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
Nikhil Badoladb2be4e2015-09-04 10:15:58 +0530204{
205 u32 reg;
206 u32 dft;
207
208 if (dwc->revision < DWC3_REVISION_250A)
209 return;
210
Felipe Balbibcdb3272016-05-16 10:42:23 +0300211 if (dwc->fladj == 0)
Nikhil Badoladb2be4e2015-09-04 10:15:58 +0530212 return;
213
214 reg = dwc3_readl(dwc->regs, DWC3_GFLADJ);
215 dft = reg & DWC3_GFLADJ_30MHZ_MASK;
Felipe Balbibcdb3272016-05-16 10:42:23 +0300216 if (!dev_WARN_ONCE(dwc->dev, dft == dwc->fladj,
Nikhil Badoladb2be4e2015-09-04 10:15:58 +0530217 "request value same as default, ignoring\n")) {
218 reg &= ~DWC3_GFLADJ_30MHZ_MASK;
Felipe Balbibcdb3272016-05-16 10:42:23 +0300219 reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | dwc->fladj;
Nikhil Badoladb2be4e2015-09-04 10:15:58 +0530220 dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
221 }
222}
223
Heikki Krogerusc5cc74e2015-05-13 15:26:47 +0300224/**
Felipe Balbi72246da2011-08-19 18:10:58 +0300225 * dwc3_free_one_event_buffer - Frees one event buffer
226 * @dwc: Pointer to our controller context structure
227 * @evt: Pointer to event buffer to be freed
228 */
229static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
230 struct dwc3_event_buffer *evt)
231{
232 dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
Felipe Balbi72246da2011-08-19 18:10:58 +0300233}
234
235/**
Paul Zimmerman1d046792012-02-15 18:56:56 -0800236 * dwc3_alloc_one_event_buffer - Allocates one event buffer structure
Felipe Balbi72246da2011-08-19 18:10:58 +0300237 * @dwc: Pointer to our controller context structure
238 * @length: size of the event buffer
239 *
Paul Zimmerman1d046792012-02-15 18:56:56 -0800240 * Returns a pointer to the allocated event buffer structure on success
Felipe Balbi72246da2011-08-19 18:10:58 +0300241 * otherwise ERR_PTR(errno).
242 */
Felipe Balbi67d0b502013-02-22 16:31:07 +0200243static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc,
244 unsigned length)
Felipe Balbi72246da2011-08-19 18:10:58 +0300245{
246 struct dwc3_event_buffer *evt;
247
Felipe Balbi380f0d22012-10-11 13:48:36 +0300248 evt = devm_kzalloc(dwc->dev, sizeof(*evt), GFP_KERNEL);
Felipe Balbi72246da2011-08-19 18:10:58 +0300249 if (!evt)
250 return ERR_PTR(-ENOMEM);
251
252 evt->dwc = dwc;
253 evt->length = length;
254 evt->buf = dma_alloc_coherent(dwc->dev, length,
255 &evt->dma, GFP_KERNEL);
Felipe Balbie32672f2012-11-08 15:26:41 +0200256 if (!evt->buf)
Felipe Balbi72246da2011-08-19 18:10:58 +0300257 return ERR_PTR(-ENOMEM);
Felipe Balbi72246da2011-08-19 18:10:58 +0300258
259 return evt;
260}
261
262/**
263 * dwc3_free_event_buffers - frees all allocated event buffers
264 * @dwc: Pointer to our controller context structure
265 */
266static void dwc3_free_event_buffers(struct dwc3 *dwc)
267{
268 struct dwc3_event_buffer *evt;
Felipe Balbi72246da2011-08-19 18:10:58 +0300269
Felipe Balbi696c8b12016-03-30 09:37:03 +0300270 evt = dwc->ev_buf;
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300271 if (evt)
272 dwc3_free_one_event_buffer(dwc, evt);
Felipe Balbi72246da2011-08-19 18:10:58 +0300273}
274
275/**
276 * dwc3_alloc_event_buffers - Allocates @num event buffers of size @length
Paul Zimmerman1d046792012-02-15 18:56:56 -0800277 * @dwc: pointer to our controller context structure
Felipe Balbi72246da2011-08-19 18:10:58 +0300278 * @length: size of event buffer
279 *
Paul Zimmerman1d046792012-02-15 18:56:56 -0800280 * Returns 0 on success otherwise negative errno. In the error case, dwc
Felipe Balbi72246da2011-08-19 18:10:58 +0300281 * may contain some buffers allocated but not all which were requested.
282 */
Bill Pemberton41ac7b32012-11-19 13:21:48 -0500283static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
Felipe Balbi72246da2011-08-19 18:10:58 +0300284{
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300285 struct dwc3_event_buffer *evt;
Felipe Balbi72246da2011-08-19 18:10:58 +0300286
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300287 evt = dwc3_alloc_one_event_buffer(dwc, length);
288 if (IS_ERR(evt)) {
289 dev_err(dwc->dev, "can't allocate event buffer\n");
290 return PTR_ERR(evt);
Felipe Balbi72246da2011-08-19 18:10:58 +0300291 }
Felipe Balbi696c8b12016-03-30 09:37:03 +0300292 dwc->ev_buf = evt;
Felipe Balbi72246da2011-08-19 18:10:58 +0300293
294 return 0;
295}
296
297/**
298 * dwc3_event_buffers_setup - setup our allocated event buffers
Paul Zimmerman1d046792012-02-15 18:56:56 -0800299 * @dwc: pointer to our controller context structure
Felipe Balbi72246da2011-08-19 18:10:58 +0300300 *
301 * Returns 0 on success otherwise negative errno.
302 */
Paul Zimmerman7acd85e2012-04-27 14:28:02 +0300303static int dwc3_event_buffers_setup(struct dwc3 *dwc)
Felipe Balbi72246da2011-08-19 18:10:58 +0300304{
305 struct dwc3_event_buffer *evt;
Felipe Balbi72246da2011-08-19 18:10:58 +0300306
Felipe Balbi696c8b12016-03-30 09:37:03 +0300307 evt = dwc->ev_buf;
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300308 evt->lpos = 0;
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300309 dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0),
310 lower_32_bits(evt->dma));
311 dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0),
312 upper_32_bits(evt->dma));
313 dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0),
314 DWC3_GEVNTSIZ_SIZE(evt->length));
315 dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
Felipe Balbi72246da2011-08-19 18:10:58 +0300316
317 return 0;
318}
319
320static void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
321{
322 struct dwc3_event_buffer *evt;
Felipe Balbi72246da2011-08-19 18:10:58 +0300323
Felipe Balbi696c8b12016-03-30 09:37:03 +0300324 evt = dwc->ev_buf;
Paul Zimmerman7acd85e2012-04-27 14:28:02 +0300325
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300326 evt->lpos = 0;
Paul Zimmerman7acd85e2012-04-27 14:28:02 +0300327
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300328 dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0), 0);
329 dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), 0);
330 dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK
331 | DWC3_GEVNTSIZ_SIZE(0));
332 dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
Felipe Balbi72246da2011-08-19 18:10:58 +0300333}
334
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600335static int dwc3_alloc_scratch_buffers(struct dwc3 *dwc)
336{
337 if (!dwc->has_hibernation)
338 return 0;
339
340 if (!dwc->nr_scratch)
341 return 0;
342
343 dwc->scratchbuf = kmalloc_array(dwc->nr_scratch,
344 DWC3_SCRATCHBUF_SIZE, GFP_KERNEL);
345 if (!dwc->scratchbuf)
346 return -ENOMEM;
347
348 return 0;
349}
350
351static int dwc3_setup_scratch_buffers(struct dwc3 *dwc)
352{
353 dma_addr_t scratch_addr;
354 u32 param;
355 int ret;
356
357 if (!dwc->has_hibernation)
358 return 0;
359
360 if (!dwc->nr_scratch)
361 return 0;
362
363 /* should never fall here */
364 if (!WARN_ON(dwc->scratchbuf))
365 return 0;
366
367 scratch_addr = dma_map_single(dwc->dev, dwc->scratchbuf,
368 dwc->nr_scratch * DWC3_SCRATCHBUF_SIZE,
369 DMA_BIDIRECTIONAL);
370 if (dma_mapping_error(dwc->dev, scratch_addr)) {
371 dev_err(dwc->dev, "failed to map scratch buffer\n");
372 ret = -EFAULT;
373 goto err0;
374 }
375
376 dwc->scratch_addr = scratch_addr;
377
378 param = lower_32_bits(scratch_addr);
379
380 ret = dwc3_send_gadget_generic_command(dwc,
381 DWC3_DGCMD_SET_SCRATCHPAD_ADDR_LO, param);
382 if (ret < 0)
383 goto err1;
384
385 param = upper_32_bits(scratch_addr);
386
387 ret = dwc3_send_gadget_generic_command(dwc,
388 DWC3_DGCMD_SET_SCRATCHPAD_ADDR_HI, param);
389 if (ret < 0)
390 goto err1;
391
392 return 0;
393
394err1:
395 dma_unmap_single(dwc->dev, dwc->scratch_addr, dwc->nr_scratch *
396 DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL);
397
398err0:
399 return ret;
400}
401
402static void dwc3_free_scratch_buffers(struct dwc3 *dwc)
403{
404 if (!dwc->has_hibernation)
405 return;
406
407 if (!dwc->nr_scratch)
408 return;
409
410 /* should never fall here */
411 if (!WARN_ON(dwc->scratchbuf))
412 return;
413
414 dma_unmap_single(dwc->dev, dwc->scratch_addr, dwc->nr_scratch *
415 DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL);
416 kfree(dwc->scratchbuf);
417}
418
Felipe Balbi789451f62011-05-05 15:53:10 +0300419static void dwc3_core_num_eps(struct dwc3 *dwc)
420{
421 struct dwc3_hwparams *parms = &dwc->hwparams;
422
423 dwc->num_in_eps = DWC3_NUM_IN_EPS(parms);
424 dwc->num_out_eps = DWC3_NUM_EPS(parms) - dwc->num_in_eps;
Felipe Balbi789451f62011-05-05 15:53:10 +0300425}
426
Bill Pemberton41ac7b32012-11-19 13:21:48 -0500427static void dwc3_cache_hwparams(struct dwc3 *dwc)
Felipe Balbi26ceca92011-09-30 10:58:49 +0300428{
429 struct dwc3_hwparams *parms = &dwc->hwparams;
430
431 parms->hwparams0 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS0);
432 parms->hwparams1 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS1);
433 parms->hwparams2 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS2);
434 parms->hwparams3 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS3);
435 parms->hwparams4 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS4);
436 parms->hwparams5 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS5);
437 parms->hwparams6 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
438 parms->hwparams7 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS7);
439 parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8);
440}
441
Felipe Balbi72246da2011-08-19 18:10:58 +0300442/**
Huang Ruib5a65c42014-10-28 19:54:28 +0800443 * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core
444 * @dwc: Pointer to our controller context structure
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300445 *
446 * Returns 0 on success. The USB PHY interfaces are configured but not
447 * initialized. The PHY interfaces and the PHYs get initialized together with
448 * the core in dwc3_core_init.
Huang Ruib5a65c42014-10-28 19:54:28 +0800449 */
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300450static int dwc3_phy_setup(struct dwc3 *dwc)
Huang Ruib5a65c42014-10-28 19:54:28 +0800451{
452 u32 reg;
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300453 int ret;
Huang Ruib5a65c42014-10-28 19:54:28 +0800454
455 reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
456
Huang Rui2164a472014-10-28 19:54:35 +0800457 /*
458 * Above 1.94a, it is recommended to set DWC3_GUSB3PIPECTL_SUSPHY
459 * to '0' during coreConsultant configuration. So default value
460 * will be '0' when the core is reset. Application needs to set it
461 * to '1' after the core initialization is completed.
462 */
463 if (dwc->revision > DWC3_REVISION_194A)
464 reg |= DWC3_GUSB3PIPECTL_SUSPHY;
465
Huang Ruib5a65c42014-10-28 19:54:28 +0800466 if (dwc->u2ss_inp3_quirk)
467 reg |= DWC3_GUSB3PIPECTL_U2SSINP3OK;
468
Rajesh Bhagate58dd352016-03-14 14:40:50 +0530469 if (dwc->dis_rxdet_inp3_quirk)
470 reg |= DWC3_GUSB3PIPECTL_DISRXDETINP3;
471
Huang Ruidf31f5b2014-10-28 19:54:29 +0800472 if (dwc->req_p1p2p3_quirk)
473 reg |= DWC3_GUSB3PIPECTL_REQP1P2P3;
474
Huang Ruia2a1d0f2014-10-28 19:54:30 +0800475 if (dwc->del_p1p2p3_quirk)
476 reg |= DWC3_GUSB3PIPECTL_DEP1P2P3_EN;
477
Huang Rui41c06ff2014-10-28 19:54:31 +0800478 if (dwc->del_phy_power_chg_quirk)
479 reg |= DWC3_GUSB3PIPECTL_DEPOCHANGE;
480
Huang Ruifb67afc2014-10-28 19:54:32 +0800481 if (dwc->lfps_filter_quirk)
482 reg |= DWC3_GUSB3PIPECTL_LFPSFILT;
483
Huang Rui14f4ac52014-10-28 19:54:33 +0800484 if (dwc->rx_detect_poll_quirk)
485 reg |= DWC3_GUSB3PIPECTL_RX_DETOPOLL;
486
Huang Rui6b6a0c92014-10-31 11:11:12 +0800487 if (dwc->tx_de_emphasis_quirk)
488 reg |= DWC3_GUSB3PIPECTL_TX_DEEPH(dwc->tx_de_emphasis);
489
Felipe Balbicd72f892014-11-06 11:31:00 -0600490 if (dwc->dis_u3_susphy_quirk)
Huang Rui59acfa22014-10-31 11:11:13 +0800491 reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
492
William Wu00fe0812016-08-16 22:44:39 +0800493 if (dwc->dis_del_phy_power_chg_quirk)
494 reg &= ~DWC3_GUSB3PIPECTL_DEPOCHANGE;
495
Huang Ruib5a65c42014-10-28 19:54:28 +0800496 dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
497
Huang Rui2164a472014-10-28 19:54:35 +0800498 reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
499
Heikki Krogerus3e10a2c2015-05-13 15:26:49 +0300500 /* Select the HS PHY interface */
501 switch (DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3)) {
502 case DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI:
Felipe Balbi43cacb02015-07-01 22:03:09 -0500503 if (dwc->hsphy_interface &&
504 !strncmp(dwc->hsphy_interface, "utmi", 4)) {
Heikki Krogerus3e10a2c2015-05-13 15:26:49 +0300505 reg &= ~DWC3_GUSB2PHYCFG_ULPI_UTMI;
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300506 break;
Felipe Balbi43cacb02015-07-01 22:03:09 -0500507 } else if (dwc->hsphy_interface &&
508 !strncmp(dwc->hsphy_interface, "ulpi", 4)) {
Heikki Krogerus3e10a2c2015-05-13 15:26:49 +0300509 reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI;
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300510 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
Heikki Krogerus3e10a2c2015-05-13 15:26:49 +0300511 } else {
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300512 /* Relying on default value. */
513 if (!(reg & DWC3_GUSB2PHYCFG_ULPI_UTMI))
514 break;
Heikki Krogerus3e10a2c2015-05-13 15:26:49 +0300515 }
516 /* FALLTHROUGH */
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300517 case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI:
518 /* Making sure the interface and PHY are operational */
519 ret = dwc3_soft_reset(dwc);
520 if (ret)
521 return ret;
522
523 udelay(1);
524
525 ret = dwc3_ulpi_init(dwc);
526 if (ret)
527 return ret;
528 /* FALLTHROUGH */
Heikki Krogerus3e10a2c2015-05-13 15:26:49 +0300529 default:
530 break;
531 }
532
William Wu32f2ed82016-08-16 22:44:38 +0800533 switch (dwc->hsphy_mode) {
534 case USBPHY_INTERFACE_MODE_UTMI:
535 reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
536 DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
537 reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_8_BIT) |
538 DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_8_BIT);
539 break;
540 case USBPHY_INTERFACE_MODE_UTMIW:
541 reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
542 DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
543 reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_16_BIT) |
544 DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_16_BIT);
545 break;
546 default:
547 break;
548 }
549
Huang Rui2164a472014-10-28 19:54:35 +0800550 /*
551 * Above 1.94a, it is recommended to set DWC3_GUSB2PHYCFG_SUSPHY to
552 * '0' during coreConsultant configuration. So default value will
553 * be '0' when the core is reset. Application needs to set it to
554 * '1' after the core initialization is completed.
555 */
556 if (dwc->revision > DWC3_REVISION_194A)
557 reg |= DWC3_GUSB2PHYCFG_SUSPHY;
558
Felipe Balbicd72f892014-11-06 11:31:00 -0600559 if (dwc->dis_u2_susphy_quirk)
Huang Rui0effe0a2014-10-31 11:11:14 +0800560 reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
561
John Younec791d12015-10-02 20:30:57 -0700562 if (dwc->dis_enblslpm_quirk)
563 reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
564
William Wu16199f32016-08-16 22:44:37 +0800565 if (dwc->dis_u2_freeclk_exists_quirk)
566 reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS;
567
Huang Rui2164a472014-10-28 19:54:35 +0800568 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300569
570 return 0;
Huang Ruib5a65c42014-10-28 19:54:28 +0800571}
572
Felipe Balbic499ff72016-05-16 10:49:01 +0300573static void dwc3_core_exit(struct dwc3 *dwc)
574{
575 dwc3_event_buffers_cleanup(dwc);
576
577 usb_phy_shutdown(dwc->usb2_phy);
578 usb_phy_shutdown(dwc->usb3_phy);
579 phy_exit(dwc->usb2_generic_phy);
580 phy_exit(dwc->usb3_generic_phy);
581
582 usb_phy_set_suspend(dwc->usb2_phy, 1);
583 usb_phy_set_suspend(dwc->usb3_phy, 1);
584 phy_power_off(dwc->usb2_generic_phy);
585 phy_power_off(dwc->usb3_generic_phy);
586}
587
Felipe Balbi07599562016-10-14 16:19:01 +0300588static bool dwc3_core_is_valid(struct dwc3 *dwc)
589{
590 u32 reg;
591
592 reg = dwc3_readl(dwc->regs, DWC3_GSNPSID);
593
594 /* This should read as U3 followed by revision number */
595 if ((reg & DWC3_GSNPSID_MASK) == 0x55330000) {
596 /* Detected DWC_usb3 IP */
597 dwc->revision = reg;
598 } else if ((reg & DWC3_GSNPSID_MASK) == 0x33310000) {
599 /* Detected DWC_usb31 IP */
600 dwc->revision = dwc3_readl(dwc->regs, DWC3_VER_NUMBER);
601 dwc->revision |= DWC3_REVISION_IS_DWC31;
602 } else {
603 return false;
604 }
605
606 return true;
607}
608
Felipe Balbi941f9182016-10-14 16:23:24 +0300609static void dwc3_core_setup_global_control(struct dwc3 *dwc)
Felipe Balbi72246da2011-08-19 18:10:58 +0300610{
Felipe Balbi941f9182016-10-14 16:23:24 +0300611 u32 hwparams4 = dwc->hwparams.hwparams4;
612 u32 reg;
Felipe Balbic499ff72016-05-16 10:49:01 +0300613
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100614 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
Paul Zimmerman3e87c422012-02-24 17:32:13 -0800615 reg &= ~DWC3_GCTL_SCALEDOWN_MASK;
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100616
Sebastian Andrzej Siewior164d7732011-11-24 11:22:05 +0100617 switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1)) {
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100618 case DWC3_GHWPARAMS1_EN_PWROPT_CLK:
Felipe Balbi32a4a132014-02-25 14:00:13 -0600619 /**
620 * WORKAROUND: DWC3 revisions between 2.10a and 2.50a have an
621 * issue which would cause xHCI compliance tests to fail.
622 *
623 * Because of that we cannot enable clock gating on such
624 * configurations.
625 *
626 * Refers to:
627 *
628 * STAR#9000588375: Clock Gating, SOF Issues when ref_clk-Based
629 * SOF/ITP Mode Used
630 */
631 if ((dwc->dr_mode == USB_DR_MODE_HOST ||
632 dwc->dr_mode == USB_DR_MODE_OTG) &&
633 (dwc->revision >= DWC3_REVISION_210A &&
634 dwc->revision <= DWC3_REVISION_250A))
635 reg |= DWC3_GCTL_DSBLCLKGTNG | DWC3_GCTL_SOFITPSYNC;
636 else
637 reg &= ~DWC3_GCTL_DSBLCLKGTNG;
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100638 break;
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600639 case DWC3_GHWPARAMS1_EN_PWROPT_HIB:
640 /* enable hibernation here */
641 dwc->nr_scratch = DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(hwparams4);
Huang Rui2eac3992014-10-28 19:54:22 +0800642
643 /*
644 * REVISIT Enabling this bit so that host-mode hibernation
645 * will work. Device-mode hibernation is not yet implemented.
646 */
647 reg |= DWC3_GCTL_GBLHIBERNATIONEN;
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600648 break;
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100649 default:
Felipe Balbi5eb30ce2016-11-03 14:07:51 +0200650 /* nothing */
651 break;
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100652 }
653
Huang Rui946bd572014-10-28 19:54:23 +0800654 /* check if current dwc3 is on simulation board */
655 if (dwc->hwparams.hwparams6 & DWC3_GHWPARAMS6_EN_FPGA) {
Felipe Balbi5eb30ce2016-11-03 14:07:51 +0200656 dev_info(dwc->dev, "Running with FPGA optmizations\n");
Huang Rui946bd572014-10-28 19:54:23 +0800657 dwc->is_fpga = true;
658 }
659
Huang Rui3b812212014-10-28 19:54:25 +0800660 WARN_ONCE(dwc->disable_scramble_quirk && !dwc->is_fpga,
661 "disable_scramble cannot be used on non-FPGA builds\n");
662
663 if (dwc->disable_scramble_quirk && dwc->is_fpga)
664 reg |= DWC3_GCTL_DISSCRAMBLE;
665 else
666 reg &= ~DWC3_GCTL_DISSCRAMBLE;
667
Huang Rui9a5b2f32014-10-28 19:54:27 +0800668 if (dwc->u2exit_lfps_quirk)
669 reg |= DWC3_GCTL_U2EXIT_LFPS;
670
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100671 /*
672 * WORKAROUND: DWC3 revisions <1.90a have a bug
Paul Zimmerman1d046792012-02-15 18:56:56 -0800673 * where the device can fail to connect at SuperSpeed
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100674 * and falls back to high-speed mode which causes
Paul Zimmerman1d046792012-02-15 18:56:56 -0800675 * the device to enter a Connect/Disconnect loop
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100676 */
677 if (dwc->revision < DWC3_REVISION_190A)
678 reg |= DWC3_GCTL_U2RSTECN;
679
680 dwc3_writel(dwc->regs, DWC3_GCTL, reg);
Felipe Balbi941f9182016-10-14 16:23:24 +0300681}
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100682
Felipe Balbi941f9182016-10-14 16:23:24 +0300683/**
684 * dwc3_core_init - Low-level initialization of DWC3 Core
685 * @dwc: Pointer to our controller context structure
686 *
687 * Returns 0 on success otherwise negative errno.
688 */
689static int dwc3_core_init(struct dwc3 *dwc)
690{
691 u32 reg;
692 int ret;
693
694 if (!dwc3_core_is_valid(dwc)) {
695 dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n");
696 ret = -ENODEV;
697 goto err0;
698 }
699
700 /*
701 * Write Linux Version Code to our GUID register so it's easy to figure
702 * out which kernel version a bug was found.
703 */
704 dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE);
705
706 /* Handle USB2.0-only core configuration */
707 if (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) ==
708 DWC3_GHWPARAMS3_SSPHY_IFC_DIS) {
709 if (dwc->maximum_speed == USB_SPEED_SUPER)
710 dwc->maximum_speed = USB_SPEED_HIGH;
711 }
712
713 /* issue device SoftReset too */
714 ret = dwc3_soft_reset(dwc);
715 if (ret)
716 goto err0;
717
718 ret = dwc3_core_soft_reset(dwc);
719 if (ret)
720 goto err0;
721
722 ret = dwc3_phy_setup(dwc);
723 if (ret)
724 goto err0;
725
726 dwc3_core_setup_global_control(dwc);
Felipe Balbic499ff72016-05-16 10:49:01 +0300727 dwc3_core_num_eps(dwc);
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600728
729 ret = dwc3_setup_scratch_buffers(dwc);
730 if (ret)
Felipe Balbic499ff72016-05-16 10:49:01 +0300731 goto err1;
732
733 /* Adjust Frame Length */
734 dwc3_frame_length_adjustment(dwc);
735
736 usb_phy_set_suspend(dwc->usb2_phy, 0);
737 usb_phy_set_suspend(dwc->usb3_phy, 0);
738 ret = phy_power_on(dwc->usb2_generic_phy);
739 if (ret < 0)
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600740 goto err2;
741
Felipe Balbic499ff72016-05-16 10:49:01 +0300742 ret = phy_power_on(dwc->usb3_generic_phy);
743 if (ret < 0)
744 goto err3;
745
746 ret = dwc3_event_buffers_setup(dwc);
747 if (ret) {
748 dev_err(dwc->dev, "failed to setup event buffers\n");
749 goto err4;
750 }
751
Baolin Wang00af6232016-07-15 17:13:27 +0800752 switch (dwc->dr_mode) {
753 case USB_DR_MODE_PERIPHERAL:
754 dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE);
755 break;
756 case USB_DR_MODE_HOST:
757 dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST);
758 break;
759 case USB_DR_MODE_OTG:
760 dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG);
761 break;
762 default:
763 dev_warn(dwc->dev, "Unsupported mode %d\n", dwc->dr_mode);
764 break;
765 }
766
John Youn06281d42016-08-22 15:39:13 -0700767 /*
768 * ENDXFER polling is available on version 3.10a and later of
769 * the DWC_usb3 controller. It is NOT available in the
770 * DWC_usb31 controller.
771 */
772 if (!dwc3_is_usb31(dwc) && dwc->revision >= DWC3_REVISION_310A) {
773 reg = dwc3_readl(dwc->regs, DWC3_GUCTL2);
774 reg |= DWC3_GUCTL2_RST_ACTBITLATER;
775 dwc3_writel(dwc->regs, DWC3_GUCTL2, reg);
776 }
777
John Youn0bb39ca2016-10-12 18:00:55 -0700778 /*
779 * Enable hardware control of sending remote wakeup in HS when
780 * the device is in the L1 state.
781 */
782 if (dwc->revision >= DWC3_REVISION_290A) {
783 reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
784 reg |= DWC3_GUCTL1_DEV_L1_EXIT_BY_HW;
785 dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
786 }
787
Felipe Balbi72246da2011-08-19 18:10:58 +0300788 return 0;
789
Felipe Balbic499ff72016-05-16 10:49:01 +0300790err4:
791 phy_power_off(dwc->usb2_generic_phy);
792
793err3:
794 phy_power_off(dwc->usb3_generic_phy);
795
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600796err2:
Felipe Balbic499ff72016-05-16 10:49:01 +0300797 usb_phy_set_suspend(dwc->usb2_phy, 1);
798 usb_phy_set_suspend(dwc->usb3_phy, 1);
799 dwc3_core_exit(dwc);
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600800
801err1:
802 usb_phy_shutdown(dwc->usb2_phy);
803 usb_phy_shutdown(dwc->usb3_phy);
Kishon Vijay Abraham I57303482014-03-03 17:08:11 +0530804 phy_exit(dwc->usb2_generic_phy);
805 phy_exit(dwc->usb3_generic_phy);
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600806
Felipe Balbi72246da2011-08-19 18:10:58 +0300807err0:
808 return ret;
809}
810
Felipe Balbi3c9f94a2014-04-16 15:08:29 -0500811static int dwc3_core_get_phy(struct dwc3 *dwc)
Felipe Balbi72246da2011-08-19 18:10:58 +0300812{
Felipe Balbi3c9f94a2014-04-16 15:08:29 -0500813 struct device *dev = dwc->dev;
Felipe Balbi941ea362013-07-31 09:21:25 +0300814 struct device_node *node = dev->of_node;
Felipe Balbi3c9f94a2014-04-16 15:08:29 -0500815 int ret;
Felipe Balbi72246da2011-08-19 18:10:58 +0300816
Kishon Vijay Abraham I5088b6f2013-01-25 16:36:53 +0530817 if (node) {
818 dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
819 dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
Felipe Balbibb674902013-08-14 13:21:23 -0500820 } else {
821 dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
822 dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
Kishon Vijay Abraham I5088b6f2013-01-25 16:36:53 +0530823 }
824
Felipe Balbid105e7f2013-03-15 10:52:08 +0200825 if (IS_ERR(dwc->usb2_phy)) {
826 ret = PTR_ERR(dwc->usb2_phy);
Kishon Vijay Abraham I122f06e2014-03-03 17:08:10 +0530827 if (ret == -ENXIO || ret == -ENODEV) {
828 dwc->usb2_phy = NULL;
829 } else if (ret == -EPROBE_DEFER) {
Felipe Balbid105e7f2013-03-15 10:52:08 +0200830 return ret;
Kishon Vijay Abraham I122f06e2014-03-03 17:08:10 +0530831 } else {
832 dev_err(dev, "no usb2 phy configured\n");
833 return ret;
834 }
Felipe Balbi51e1e7b2012-07-19 14:09:48 +0300835 }
836
Felipe Balbid105e7f2013-03-15 10:52:08 +0200837 if (IS_ERR(dwc->usb3_phy)) {
Ruchika Kharwar315955d72013-07-04 00:59:34 -0500838 ret = PTR_ERR(dwc->usb3_phy);
Kishon Vijay Abraham I122f06e2014-03-03 17:08:10 +0530839 if (ret == -ENXIO || ret == -ENODEV) {
840 dwc->usb3_phy = NULL;
841 } else if (ret == -EPROBE_DEFER) {
Felipe Balbid105e7f2013-03-15 10:52:08 +0200842 return ret;
Kishon Vijay Abraham I122f06e2014-03-03 17:08:10 +0530843 } else {
844 dev_err(dev, "no usb3 phy configured\n");
845 return ret;
846 }
Felipe Balbi51e1e7b2012-07-19 14:09:48 +0300847 }
848
Kishon Vijay Abraham I57303482014-03-03 17:08:11 +0530849 dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
850 if (IS_ERR(dwc->usb2_generic_phy)) {
851 ret = PTR_ERR(dwc->usb2_generic_phy);
852 if (ret == -ENOSYS || ret == -ENODEV) {
853 dwc->usb2_generic_phy = NULL;
854 } else if (ret == -EPROBE_DEFER) {
855 return ret;
856 } else {
857 dev_err(dev, "no usb2 phy configured\n");
858 return ret;
859 }
860 }
861
862 dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
863 if (IS_ERR(dwc->usb3_generic_phy)) {
864 ret = PTR_ERR(dwc->usb3_generic_phy);
865 if (ret == -ENOSYS || ret == -ENODEV) {
866 dwc->usb3_generic_phy = NULL;
867 } else if (ret == -EPROBE_DEFER) {
868 return ret;
869 } else {
870 dev_err(dev, "no usb3 phy configured\n");
871 return ret;
872 }
873 }
874
Felipe Balbi3c9f94a2014-04-16 15:08:29 -0500875 return 0;
876}
877
Felipe Balbi5f94adf2014-04-16 15:13:45 -0500878static int dwc3_core_init_mode(struct dwc3 *dwc)
879{
880 struct device *dev = dwc->dev;
881 int ret;
882
883 switch (dwc->dr_mode) {
884 case USB_DR_MODE_PERIPHERAL:
Felipe Balbi5f94adf2014-04-16 15:13:45 -0500885 ret = dwc3_gadget_init(dwc);
886 if (ret) {
Roger Quadros9522def2016-06-10 14:48:38 +0300887 if (ret != -EPROBE_DEFER)
888 dev_err(dev, "failed to initialize gadget\n");
Felipe Balbi5f94adf2014-04-16 15:13:45 -0500889 return ret;
890 }
891 break;
892 case USB_DR_MODE_HOST:
Felipe Balbi5f94adf2014-04-16 15:13:45 -0500893 ret = dwc3_host_init(dwc);
894 if (ret) {
Roger Quadros9522def2016-06-10 14:48:38 +0300895 if (ret != -EPROBE_DEFER)
896 dev_err(dev, "failed to initialize host\n");
Felipe Balbi5f94adf2014-04-16 15:13:45 -0500897 return ret;
898 }
899 break;
900 case USB_DR_MODE_OTG:
Felipe Balbi5f94adf2014-04-16 15:13:45 -0500901 ret = dwc3_host_init(dwc);
902 if (ret) {
Roger Quadros9522def2016-06-10 14:48:38 +0300903 if (ret != -EPROBE_DEFER)
904 dev_err(dev, "failed to initialize host\n");
Felipe Balbi5f94adf2014-04-16 15:13:45 -0500905 return ret;
906 }
907
908 ret = dwc3_gadget_init(dwc);
909 if (ret) {
Roger Quadros9522def2016-06-10 14:48:38 +0300910 if (ret != -EPROBE_DEFER)
911 dev_err(dev, "failed to initialize gadget\n");
Felipe Balbi5f94adf2014-04-16 15:13:45 -0500912 return ret;
913 }
914 break;
915 default:
916 dev_err(dev, "Unsupported mode of operation %d\n", dwc->dr_mode);
917 return -EINVAL;
918 }
919
920 return 0;
921}
922
923static void dwc3_core_exit_mode(struct dwc3 *dwc)
924{
925 switch (dwc->dr_mode) {
926 case USB_DR_MODE_PERIPHERAL:
927 dwc3_gadget_exit(dwc);
928 break;
929 case USB_DR_MODE_HOST:
930 dwc3_host_exit(dwc);
931 break;
932 case USB_DR_MODE_OTG:
933 dwc3_host_exit(dwc);
934 dwc3_gadget_exit(dwc);
935 break;
936 default:
937 /* do nothing */
938 break;
939 }
940}
941
Felipe Balbic5ac6112016-10-14 16:30:52 +0300942static void dwc3_get_properties(struct dwc3 *dwc)
Felipe Balbi3c9f94a2014-04-16 15:08:29 -0500943{
Felipe Balbic5ac6112016-10-14 16:30:52 +0300944 struct device *dev = dwc->dev;
Huang Rui80caf7d2014-10-28 19:54:26 +0800945 u8 lpm_nyet_threshold;
Huang Rui6b6a0c92014-10-31 11:11:12 +0800946 u8 tx_de_emphasis;
Huang Rui460d0982014-10-31 11:11:18 +0800947 u8 hird_threshold;
Felipe Balbi3c9f94a2014-04-16 15:08:29 -0500948
Huang Rui80caf7d2014-10-28 19:54:26 +0800949 /* default to highest possible threshold */
950 lpm_nyet_threshold = 0xff;
951
Huang Rui6b6a0c92014-10-31 11:11:12 +0800952 /* default to -3.5dB de-emphasis */
953 tx_de_emphasis = 1;
954
Huang Rui460d0982014-10-31 11:11:18 +0800955 /*
956 * default to assert utmi_sleep_n and use maximum allowed HIRD
957 * threshold value of 0b1100
958 */
959 hird_threshold = 12;
960
Heikki Krogerus63863b92015-09-21 11:14:32 +0300961 dwc->maximum_speed = usb_get_maximum_speed(dev);
Heikki Krogerus06e71142015-09-21 11:14:34 +0300962 dwc->dr_mode = usb_get_dr_mode(dev);
William Wu32f2ed82016-08-16 22:44:38 +0800963 dwc->hsphy_mode = of_usb_get_phy_mode(dev->of_node);
Heikki Krogerus63863b92015-09-21 11:14:32 +0300964
Heikki Krogerus3d128912015-09-21 11:14:35 +0300965 dwc->has_lpm_erratum = device_property_read_bool(dev,
Huang Rui80caf7d2014-10-28 19:54:26 +0800966 "snps,has-lpm-erratum");
Heikki Krogerus3d128912015-09-21 11:14:35 +0300967 device_property_read_u8(dev, "snps,lpm-nyet-threshold",
Huang Rui80caf7d2014-10-28 19:54:26 +0800968 &lpm_nyet_threshold);
Heikki Krogerus3d128912015-09-21 11:14:35 +0300969 dwc->is_utmi_l1_suspend = device_property_read_bool(dev,
Huang Rui460d0982014-10-31 11:11:18 +0800970 "snps,is-utmi-l1-suspend");
Heikki Krogerus3d128912015-09-21 11:14:35 +0300971 device_property_read_u8(dev, "snps,hird-threshold",
Huang Rui460d0982014-10-31 11:11:18 +0800972 &hird_threshold);
Heikki Krogerus3d128912015-09-21 11:14:35 +0300973 dwc->usb3_lpm_capable = device_property_read_bool(dev,
Robert Baldygaeac68e82015-03-09 15:06:12 +0100974 "snps,usb3_lpm_capable");
Felipe Balbi3c9f94a2014-04-16 15:08:29 -0500975
Heikki Krogerus3d128912015-09-21 11:14:35 +0300976 dwc->disable_scramble_quirk = device_property_read_bool(dev,
Huang Rui3b812212014-10-28 19:54:25 +0800977 "snps,disable_scramble_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +0300978 dwc->u2exit_lfps_quirk = device_property_read_bool(dev,
Huang Rui9a5b2f32014-10-28 19:54:27 +0800979 "snps,u2exit_lfps_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +0300980 dwc->u2ss_inp3_quirk = device_property_read_bool(dev,
Huang Ruib5a65c42014-10-28 19:54:28 +0800981 "snps,u2ss_inp3_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +0300982 dwc->req_p1p2p3_quirk = device_property_read_bool(dev,
Huang Ruidf31f5b2014-10-28 19:54:29 +0800983 "snps,req_p1p2p3_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +0300984 dwc->del_p1p2p3_quirk = device_property_read_bool(dev,
Huang Ruia2a1d0f2014-10-28 19:54:30 +0800985 "snps,del_p1p2p3_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +0300986 dwc->del_phy_power_chg_quirk = device_property_read_bool(dev,
Huang Rui41c06ff2014-10-28 19:54:31 +0800987 "snps,del_phy_power_chg_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +0300988 dwc->lfps_filter_quirk = device_property_read_bool(dev,
Huang Ruifb67afc2014-10-28 19:54:32 +0800989 "snps,lfps_filter_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +0300990 dwc->rx_detect_poll_quirk = device_property_read_bool(dev,
Huang Rui14f4ac52014-10-28 19:54:33 +0800991 "snps,rx_detect_poll_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +0300992 dwc->dis_u3_susphy_quirk = device_property_read_bool(dev,
Huang Rui59acfa22014-10-31 11:11:13 +0800993 "snps,dis_u3_susphy_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +0300994 dwc->dis_u2_susphy_quirk = device_property_read_bool(dev,
Huang Rui0effe0a2014-10-31 11:11:14 +0800995 "snps,dis_u2_susphy_quirk");
John Younec791d12015-10-02 20:30:57 -0700996 dwc->dis_enblslpm_quirk = device_property_read_bool(dev,
997 "snps,dis_enblslpm_quirk");
Rajesh Bhagate58dd352016-03-14 14:40:50 +0530998 dwc->dis_rxdet_inp3_quirk = device_property_read_bool(dev,
999 "snps,dis_rxdet_inp3_quirk");
William Wu16199f32016-08-16 22:44:37 +08001000 dwc->dis_u2_freeclk_exists_quirk = device_property_read_bool(dev,
1001 "snps,dis-u2-freeclk-exists-quirk");
William Wu00fe0812016-08-16 22:44:39 +08001002 dwc->dis_del_phy_power_chg_quirk = device_property_read_bool(dev,
1003 "snps,dis-del-phy-power-chg-quirk");
Huang Rui6b6a0c92014-10-31 11:11:12 +08001004
Heikki Krogerus3d128912015-09-21 11:14:35 +03001005 dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
Huang Rui6b6a0c92014-10-31 11:11:12 +08001006 "snps,tx_de_emphasis_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001007 device_property_read_u8(dev, "snps,tx_de_emphasis",
Huang Rui6b6a0c92014-10-31 11:11:12 +08001008 &tx_de_emphasis);
Heikki Krogerus3d128912015-09-21 11:14:35 +03001009 device_property_read_string(dev, "snps,hsphy_interface",
1010 &dwc->hsphy_interface);
1011 device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
Felipe Balbibcdb3272016-05-16 10:42:23 +03001012 &dwc->fladj);
Heikki Krogerus3d128912015-09-21 11:14:35 +03001013
Huang Rui80caf7d2014-10-28 19:54:26 +08001014 dwc->lpm_nyet_threshold = lpm_nyet_threshold;
Huang Rui6b6a0c92014-10-31 11:11:12 +08001015 dwc->tx_de_emphasis = tx_de_emphasis;
Huang Rui80caf7d2014-10-28 19:54:26 +08001016
Huang Rui460d0982014-10-31 11:11:18 +08001017 dwc->hird_threshold = hird_threshold
1018 | (dwc->is_utmi_l1_suspend << 4);
1019
Felipe Balbic5ac6112016-10-14 16:30:52 +03001020}
1021
1022static int dwc3_probe(struct platform_device *pdev)
1023{
1024 struct device *dev = &pdev->dev;
1025 struct resource *res;
1026 struct dwc3 *dwc;
1027
1028 int ret;
1029
1030 void __iomem *regs;
1031
1032 dwc = devm_kzalloc(dev, sizeof(*dwc), GFP_KERNEL);
1033 if (!dwc)
1034 return -ENOMEM;
1035
1036 dwc->dev = dev;
1037
1038 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1039 if (!res) {
1040 dev_err(dev, "missing memory resource\n");
1041 return -ENODEV;
1042 }
1043
1044 dwc->xhci_resources[0].start = res->start;
1045 dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
1046 DWC3_XHCI_REGS_END;
1047 dwc->xhci_resources[0].flags = res->flags;
1048 dwc->xhci_resources[0].name = res->name;
1049
1050 res->start += DWC3_GLOBALS_REGS_START;
1051
1052 /*
1053 * Request memory region but exclude xHCI regs,
1054 * since it will be requested by the xhci-plat driver.
1055 */
1056 regs = devm_ioremap_resource(dev, res);
1057 if (IS_ERR(regs)) {
1058 ret = PTR_ERR(regs);
1059 goto err0;
1060 }
1061
1062 dwc->regs = regs;
1063 dwc->regs_size = resource_size(res);
1064
1065 dwc3_get_properties(dwc);
1066
Heikki Krogerus6c89cce02015-05-13 15:26:45 +03001067 platform_set_drvdata(pdev, dwc);
Heikki Krogerus2917e712015-05-13 15:26:46 +03001068 dwc3_cache_hwparams(dwc);
Heikki Krogerus6c89cce02015-05-13 15:26:45 +03001069
Felipe Balbi3c9f94a2014-04-16 15:08:29 -05001070 ret = dwc3_core_get_phy(dwc);
1071 if (ret)
Felipe Balbi3da1f6e2014-09-02 15:19:43 -05001072 goto err0;
Felipe Balbi3c9f94a2014-04-16 15:08:29 -05001073
Felipe Balbi72246da2011-08-19 18:10:58 +03001074 spin_lock_init(&dwc->lock);
Felipe Balbi72246da2011-08-19 18:10:58 +03001075
Heikki Krogerus19bacdc2014-09-24 11:00:38 +03001076 if (!dev->dma_mask) {
1077 dev->dma_mask = dev->parent->dma_mask;
1078 dev->dma_parms = dev->parent->dma_parms;
1079 dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask);
1080 }
Kishon Vijay Abraham Iddff14f2013-03-07 18:51:43 +05301081
Felipe Balbifc8bb912016-05-16 13:14:48 +03001082 pm_runtime_set_active(dev);
1083 pm_runtime_use_autosuspend(dev);
1084 pm_runtime_set_autosuspend_delay(dev, DWC3_DEFAULT_AUTOSUSPEND_DELAY);
Chanho Park802ca852012-02-15 18:27:55 +09001085 pm_runtime_enable(dev);
Roger Quadros32808232016-06-10 14:38:02 +03001086 ret = pm_runtime_get_sync(dev);
1087 if (ret < 0)
1088 goto err1;
1089
Chanho Park802ca852012-02-15 18:27:55 +09001090 pm_runtime_forbid(dev);
Felipe Balbi72246da2011-08-19 18:10:58 +03001091
Felipe Balbi39214262012-10-11 13:54:36 +03001092 ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
1093 if (ret) {
1094 dev_err(dwc->dev, "failed to allocate event buffers\n");
1095 ret = -ENOMEM;
Roger Quadros32808232016-06-10 14:38:02 +03001096 goto err2;
Felipe Balbi39214262012-10-11 13:54:36 +03001097 }
1098
Thinh Nguyen9d6173e2016-09-06 19:22:03 -07001099 ret = dwc3_get_dr_mode(dwc);
1100 if (ret)
1101 goto err3;
Felipe Balbi32a4a132014-02-25 14:00:13 -06001102
Felipe Balbic499ff72016-05-16 10:49:01 +03001103 ret = dwc3_alloc_scratch_buffers(dwc);
1104 if (ret)
Roger Quadros32808232016-06-10 14:38:02 +03001105 goto err3;
Felipe Balbic499ff72016-05-16 10:49:01 +03001106
Felipe Balbi72246da2011-08-19 18:10:58 +03001107 ret = dwc3_core_init(dwc);
1108 if (ret) {
Chanho Park802ca852012-02-15 18:27:55 +09001109 dev_err(dev, "failed to initialize core\n");
Roger Quadros32808232016-06-10 14:38:02 +03001110 goto err4;
Felipe Balbi72246da2011-08-19 18:10:58 +03001111 }
1112
John Youn77966eb2016-02-19 17:31:01 -08001113 /* Check the maximum_speed parameter */
1114 switch (dwc->maximum_speed) {
1115 case USB_SPEED_LOW:
1116 case USB_SPEED_FULL:
1117 case USB_SPEED_HIGH:
1118 case USB_SPEED_SUPER:
1119 case USB_SPEED_SUPER_PLUS:
1120 break;
1121 default:
1122 dev_err(dev, "invalid maximum_speed parameter %d\n",
1123 dwc->maximum_speed);
1124 /* fall through */
1125 case USB_SPEED_UNKNOWN:
1126 /* default to superspeed */
John Youn2c7f1bd2016-02-05 17:08:59 -08001127 dwc->maximum_speed = USB_SPEED_SUPER;
1128
1129 /*
1130 * default to superspeed plus if we are capable.
1131 */
1132 if (dwc3_is_usb31(dwc) &&
1133 (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) ==
1134 DWC3_GHWPARAMS3_SSPHY_IFC_GEN2))
1135 dwc->maximum_speed = USB_SPEED_SUPER_PLUS;
John Youn77966eb2016-02-19 17:31:01 -08001136
1137 break;
John Youn2c7f1bd2016-02-05 17:08:59 -08001138 }
1139
Felipe Balbi5f94adf2014-04-16 15:13:45 -05001140 ret = dwc3_core_init_mode(dwc);
1141 if (ret)
Roger Quadros32808232016-06-10 14:38:02 +03001142 goto err5;
Felipe Balbi72246da2011-08-19 18:10:58 +03001143
Du, Changbin4e9f3112016-04-12 19:10:18 +08001144 dwc3_debugfs_init(dwc);
Felipe Balbifc8bb912016-05-16 13:14:48 +03001145 pm_runtime_put(dev);
Felipe Balbi72246da2011-08-19 18:10:58 +03001146
1147 return 0;
1148
Roger Quadros32808232016-06-10 14:38:02 +03001149err5:
Felipe Balbif122d332013-02-08 15:15:11 +02001150 dwc3_event_buffers_cleanup(dwc);
1151
Roger Quadros32808232016-06-10 14:38:02 +03001152err4:
Felipe Balbic499ff72016-05-16 10:49:01 +03001153 dwc3_free_scratch_buffers(dwc);
Felipe Balbi72246da2011-08-19 18:10:58 +03001154
Roger Quadros32808232016-06-10 14:38:02 +03001155err3:
Felipe Balbi39214262012-10-11 13:54:36 +03001156 dwc3_free_event_buffers(dwc);
Heikki Krogerus88bc9d12015-05-13 15:26:51 +03001157 dwc3_ulpi_exit(dwc);
Felipe Balbi39214262012-10-11 13:54:36 +03001158
Roger Quadros32808232016-06-10 14:38:02 +03001159err2:
1160 pm_runtime_allow(&pdev->dev);
1161
1162err1:
1163 pm_runtime_put_sync(&pdev->dev);
1164 pm_runtime_disable(&pdev->dev);
1165
Felipe Balbi3da1f6e2014-09-02 15:19:43 -05001166err0:
1167 /*
1168 * restore res->start back to its original value so that, in case the
1169 * probe is deferred, we don't end up getting error in request the
1170 * memory region the next time probe is called.
1171 */
1172 res->start -= DWC3_GLOBALS_REGS_START;
1173
Felipe Balbi72246da2011-08-19 18:10:58 +03001174 return ret;
1175}
1176
Bill Pembertonfb4e98a2012-11-19 13:26:20 -05001177static int dwc3_remove(struct platform_device *pdev)
Felipe Balbi72246da2011-08-19 18:10:58 +03001178{
Felipe Balbi72246da2011-08-19 18:10:58 +03001179 struct dwc3 *dwc = platform_get_drvdata(pdev);
Felipe Balbi3da1f6e2014-09-02 15:19:43 -05001180 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1181
Felipe Balbifc8bb912016-05-16 13:14:48 +03001182 pm_runtime_get_sync(&pdev->dev);
Felipe Balbi3da1f6e2014-09-02 15:19:43 -05001183 /*
1184 * restore res->start back to its original value so that, in case the
1185 * probe is deferred, we don't end up getting error in request the
1186 * memory region the next time probe is called.
1187 */
1188 res->start -= DWC3_GLOBALS_REGS_START;
Felipe Balbi72246da2011-08-19 18:10:58 +03001189
Felipe Balbidc99f162014-09-03 16:13:37 -05001190 dwc3_debugfs_exit(dwc);
1191 dwc3_core_exit_mode(dwc);
Kishon Vijay Abraham I8ba007a2013-01-25 08:30:54 +05301192
Felipe Balbi72246da2011-08-19 18:10:58 +03001193 dwc3_core_exit(dwc);
Heikki Krogerus88bc9d12015-05-13 15:26:51 +03001194 dwc3_ulpi_exit(dwc);
Felipe Balbi72246da2011-08-19 18:10:58 +03001195
Felipe Balbifc8bb912016-05-16 13:14:48 +03001196 pm_runtime_put_sync(&pdev->dev);
1197 pm_runtime_allow(&pdev->dev);
1198 pm_runtime_disable(&pdev->dev);
1199
Felipe Balbic499ff72016-05-16 10:49:01 +03001200 dwc3_free_event_buffers(dwc);
1201 dwc3_free_scratch_buffers(dwc);
1202
Felipe Balbi72246da2011-08-19 18:10:58 +03001203 return 0;
1204}
1205
Felipe Balbifc8bb912016-05-16 13:14:48 +03001206#ifdef CONFIG_PM
1207static int dwc3_suspend_common(struct dwc3 *dwc)
Felipe Balbi7415f172012-04-30 14:56:33 +03001208{
Felipe Balbifc8bb912016-05-16 13:14:48 +03001209 unsigned long flags;
Felipe Balbi7415f172012-04-30 14:56:33 +03001210
Ruchika Kharwara45c82b82013-07-06 07:52:49 -05001211 switch (dwc->dr_mode) {
1212 case USB_DR_MODE_PERIPHERAL:
1213 case USB_DR_MODE_OTG:
Felipe Balbifc8bb912016-05-16 13:14:48 +03001214 spin_lock_irqsave(&dwc->lock, flags);
Felipe Balbi7415f172012-04-30 14:56:33 +03001215 dwc3_gadget_suspend(dwc);
Felipe Balbifc8bb912016-05-16 13:14:48 +03001216 spin_unlock_irqrestore(&dwc->lock, flags);
Felipe Balbi51f5d492016-05-16 10:52:58 +03001217 break;
Ruchika Kharwara45c82b82013-07-06 07:52:49 -05001218 case USB_DR_MODE_HOST:
Felipe Balbi7415f172012-04-30 14:56:33 +03001219 default:
Felipe Balbi51f5d492016-05-16 10:52:58 +03001220 /* do nothing */
Felipe Balbi7415f172012-04-30 14:56:33 +03001221 break;
1222 }
1223
Felipe Balbi51f5d492016-05-16 10:52:58 +03001224 dwc3_core_exit(dwc);
Felipe Balbi5c4ad3182016-04-11 17:12:34 +03001225
Felipe Balbifc8bb912016-05-16 13:14:48 +03001226 return 0;
1227}
1228
1229static int dwc3_resume_common(struct dwc3 *dwc)
1230{
1231 unsigned long flags;
1232 int ret;
1233
1234 ret = dwc3_core_init(dwc);
1235 if (ret)
1236 return ret;
1237
1238 switch (dwc->dr_mode) {
1239 case USB_DR_MODE_PERIPHERAL:
1240 case USB_DR_MODE_OTG:
1241 spin_lock_irqsave(&dwc->lock, flags);
1242 dwc3_gadget_resume(dwc);
1243 spin_unlock_irqrestore(&dwc->lock, flags);
1244 /* FALLTHROUGH */
1245 case USB_DR_MODE_HOST:
1246 default:
1247 /* do nothing */
1248 break;
1249 }
1250
1251 return 0;
1252}
1253
1254static int dwc3_runtime_checks(struct dwc3 *dwc)
1255{
1256 switch (dwc->dr_mode) {
1257 case USB_DR_MODE_PERIPHERAL:
1258 case USB_DR_MODE_OTG:
1259 if (dwc->connected)
1260 return -EBUSY;
1261 break;
1262 case USB_DR_MODE_HOST:
1263 default:
1264 /* do nothing */
1265 break;
1266 }
1267
1268 return 0;
1269}
1270
1271static int dwc3_runtime_suspend(struct device *dev)
1272{
1273 struct dwc3 *dwc = dev_get_drvdata(dev);
1274 int ret;
1275
1276 if (dwc3_runtime_checks(dwc))
1277 return -EBUSY;
1278
1279 ret = dwc3_suspend_common(dwc);
1280 if (ret)
1281 return ret;
1282
1283 device_init_wakeup(dev, true);
1284
1285 return 0;
1286}
1287
1288static int dwc3_runtime_resume(struct device *dev)
1289{
1290 struct dwc3 *dwc = dev_get_drvdata(dev);
1291 int ret;
1292
1293 device_init_wakeup(dev, false);
1294
1295 ret = dwc3_resume_common(dwc);
1296 if (ret)
1297 return ret;
1298
1299 switch (dwc->dr_mode) {
1300 case USB_DR_MODE_PERIPHERAL:
1301 case USB_DR_MODE_OTG:
1302 dwc3_gadget_process_pending_events(dwc);
1303 break;
1304 case USB_DR_MODE_HOST:
1305 default:
1306 /* do nothing */
1307 break;
1308 }
1309
1310 pm_runtime_mark_last_busy(dev);
Felipe Balbib74c2d82016-07-28 13:07:07 +03001311 pm_runtime_put(dev);
Felipe Balbifc8bb912016-05-16 13:14:48 +03001312
1313 return 0;
1314}
1315
1316static int dwc3_runtime_idle(struct device *dev)
1317{
1318 struct dwc3 *dwc = dev_get_drvdata(dev);
1319
1320 switch (dwc->dr_mode) {
1321 case USB_DR_MODE_PERIPHERAL:
1322 case USB_DR_MODE_OTG:
1323 if (dwc3_runtime_checks(dwc))
1324 return -EBUSY;
1325 break;
1326 case USB_DR_MODE_HOST:
1327 default:
1328 /* do nothing */
1329 break;
1330 }
1331
1332 pm_runtime_mark_last_busy(dev);
1333 pm_runtime_autosuspend(dev);
1334
1335 return 0;
1336}
1337#endif /* CONFIG_PM */
1338
1339#ifdef CONFIG_PM_SLEEP
1340static int dwc3_suspend(struct device *dev)
1341{
1342 struct dwc3 *dwc = dev_get_drvdata(dev);
1343 int ret;
1344
1345 ret = dwc3_suspend_common(dwc);
1346 if (ret)
1347 return ret;
1348
Sekhar Nori63444752015-08-31 21:09:08 +05301349 pinctrl_pm_select_sleep_state(dev);
1350
Felipe Balbi7415f172012-04-30 14:56:33 +03001351 return 0;
1352}
1353
1354static int dwc3_resume(struct device *dev)
1355{
1356 struct dwc3 *dwc = dev_get_drvdata(dev);
Kishon Vijay Abraham I57303482014-03-03 17:08:11 +05301357 int ret;
Felipe Balbi7415f172012-04-30 14:56:33 +03001358
Sekhar Nori63444752015-08-31 21:09:08 +05301359 pinctrl_pm_select_default_state(dev);
1360
Felipe Balbifc8bb912016-05-16 13:14:48 +03001361 ret = dwc3_resume_common(dwc);
Felipe Balbi51f5d492016-05-16 10:52:58 +03001362 if (ret)
Felipe Balbi5c4ad3182016-04-11 17:12:34 +03001363 return ret;
1364
Felipe Balbi7415f172012-04-30 14:56:33 +03001365 pm_runtime_disable(dev);
1366 pm_runtime_set_active(dev);
1367 pm_runtime_enable(dev);
1368
1369 return 0;
1370}
Felipe Balbi7f370ed2016-05-09 15:27:01 +03001371#endif /* CONFIG_PM_SLEEP */
Felipe Balbi7415f172012-04-30 14:56:33 +03001372
1373static const struct dev_pm_ops dwc3_dev_pm_ops = {
Felipe Balbi7415f172012-04-30 14:56:33 +03001374 SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume)
Felipe Balbifc8bb912016-05-16 13:14:48 +03001375 SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume,
1376 dwc3_runtime_idle)
Felipe Balbi7415f172012-04-30 14:56:33 +03001377};
1378
Kishon Vijay Abraham I5088b6f2013-01-25 16:36:53 +05301379#ifdef CONFIG_OF
1380static const struct of_device_id of_dwc3_match[] = {
1381 {
Felipe Balbi22a5aa12013-07-02 21:20:24 +03001382 .compatible = "snps,dwc3"
1383 },
1384 {
Kishon Vijay Abraham I5088b6f2013-01-25 16:36:53 +05301385 .compatible = "synopsys,dwc3"
1386 },
1387 { },
1388};
1389MODULE_DEVICE_TABLE(of, of_dwc3_match);
1390#endif
1391
Heikki Krogerus404905a2014-09-25 10:57:02 +03001392#ifdef CONFIG_ACPI
1393
1394#define ACPI_ID_INTEL_BSW "808622B7"
1395
1396static const struct acpi_device_id dwc3_acpi_match[] = {
1397 { ACPI_ID_INTEL_BSW, 0 },
1398 { },
1399};
1400MODULE_DEVICE_TABLE(acpi, dwc3_acpi_match);
1401#endif
1402
Felipe Balbi72246da2011-08-19 18:10:58 +03001403static struct platform_driver dwc3_driver = {
1404 .probe = dwc3_probe,
Bill Pemberton76904172012-11-19 13:21:08 -05001405 .remove = dwc3_remove,
Felipe Balbi72246da2011-08-19 18:10:58 +03001406 .driver = {
1407 .name = "dwc3",
Kishon Vijay Abraham I5088b6f2013-01-25 16:36:53 +05301408 .of_match_table = of_match_ptr(of_dwc3_match),
Heikki Krogerus404905a2014-09-25 10:57:02 +03001409 .acpi_match_table = ACPI_PTR(dwc3_acpi_match),
Felipe Balbi7f370ed2016-05-09 15:27:01 +03001410 .pm = &dwc3_dev_pm_ops,
Felipe Balbi72246da2011-08-19 18:10:58 +03001411 },
Felipe Balbi72246da2011-08-19 18:10:58 +03001412};
1413
Tobias Klauserb1116dc2012-02-28 12:57:20 +01001414module_platform_driver(dwc3_driver);
1415
Sebastian Andrzej Siewior7ae4fc42011-10-19 19:39:50 +02001416MODULE_ALIAS("platform:dwc3");
Felipe Balbi72246da2011-08-19 18:10:58 +03001417MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
Felipe Balbi5945f782013-06-30 14:15:11 +03001418MODULE_LICENSE("GPL v2");
Felipe Balbi72246da2011-08-19 18:10:58 +03001419MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");