blob: c397b87bd575f819f33388784917dcafe2c26f0a [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>
Mayank Ranaa99689a2016-08-10 17:39:47 -070038#include <linux/irq.h>
Felipe Balbi72246da2011-08-19 18:10:58 +030039
40#include <linux/usb/ch9.h>
41#include <linux/usb/gadget.h>
Felipe Balbif7e846f2013-06-30 14:29:51 +030042#include <linux/usb/of.h>
Ruchika Kharwara45c82b82013-07-06 07:52:49 -050043#include <linux/usb/otg.h>
Felipe Balbi72246da2011-08-19 18:10:58 +030044
45#include "core.h"
46#include "gadget.h"
47#include "io.h"
48
49#include "debug.h"
50
Felipe Balbifc8bb912016-05-16 13:14:48 +030051#define DWC3_DEFAULT_AUTOSUSPEND_DELAY 5000 /* ms */
Felipe Balbi8300dd22011-10-18 13:54:01 +030052
Mayank Ranaa99689a2016-08-10 17:39:47 -070053void dwc3_usb3_phy_suspend(struct dwc3 *dwc, int suspend)
54{
55 u32 reg;
56
57 reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
58
59 if (suspend)
60 reg |= DWC3_GUSB3PIPECTL_SUSPHY;
61 else
62 reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
63
64 dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
65}
66
Thinh Nguyen9d6173e2016-09-06 19:22:03 -070067/**
68 * dwc3_get_dr_mode - Validates and sets dr_mode
69 * @dwc: pointer to our context structure
70 */
71static int dwc3_get_dr_mode(struct dwc3 *dwc)
72{
73 enum usb_dr_mode mode;
74 struct device *dev = dwc->dev;
75 unsigned int hw_mode;
76
77 if (dwc->dr_mode == USB_DR_MODE_UNKNOWN)
78 dwc->dr_mode = USB_DR_MODE_OTG;
79
80 mode = dwc->dr_mode;
81 hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0);
82
83 switch (hw_mode) {
84 case DWC3_GHWPARAMS0_MODE_GADGET:
85 if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) {
86 dev_err(dev,
87 "Controller does not support host mode.\n");
88 return -EINVAL;
89 }
90 mode = USB_DR_MODE_PERIPHERAL;
91 break;
92 case DWC3_GHWPARAMS0_MODE_HOST:
93 if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) {
94 dev_err(dev,
95 "Controller does not support device mode.\n");
96 return -EINVAL;
97 }
98 mode = USB_DR_MODE_HOST;
99 break;
100 default:
101 if (IS_ENABLED(CONFIG_USB_DWC3_HOST))
102 mode = USB_DR_MODE_HOST;
103 else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET))
104 mode = USB_DR_MODE_PERIPHERAL;
105 }
106
107 if (mode != dwc->dr_mode) {
108 dev_warn(dev,
109 "Configuration mismatch. dr_mode forced to %s\n",
110 mode == USB_DR_MODE_HOST ? "host" : "gadget");
111
112 dwc->dr_mode = mode;
113 }
114
115 return 0;
116}
117
Sebastian Andrzej Siewior3140e8c2011-10-31 22:25:40 +0100118void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
119{
120 u32 reg;
121
122 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
123 reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
124 reg |= DWC3_GCTL_PRTCAPDIR(mode);
125 dwc3_writel(dwc->regs, DWC3_GCTL, reg);
Mayank Ranaa99689a2016-08-10 17:39:47 -0700126
127 /*
128 * Set this bit so that device attempts three more times at SS, even
129 * if it failed previously to operate in SS mode.
130 */
131 reg |= DWC3_GCTL_U2RSTECN;
132 reg &= ~(DWC3_GCTL_SOFITPSYNC);
133 reg &= ~(DWC3_GCTL_PWRDNSCALEMASK);
134 reg |= DWC3_GCTL_PWRDNSCALE(2);
135 reg |= DWC3_GCTL_U2EXIT_LFPS;
136 dwc3_writel(dwc->regs, DWC3_GCTL, reg);
137
138 if (mode == DWC3_GCTL_PRTCAP_OTG || mode == DWC3_GCTL_PRTCAP_HOST) {
139 /*
140 * Allow ITP generated off of ref clk based counter instead
141 * of UTMI/ULPI clk based counter, when superspeed only is
142 * active so that UTMI/ULPI PHY can be suspened.
143 *
144 * Starting with revision 2.50A, GFLADJ_REFCLK_LPM_SEL is used
145 * instead.
146 */
147 if (dwc->revision < DWC3_REVISION_250A) {
148 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
149 reg |= DWC3_GCTL_SOFITPSYNC;
150 dwc3_writel(dwc->regs, DWC3_GCTL, reg);
151 } else {
152 reg = dwc3_readl(dwc->regs, DWC3_GFLADJ);
153 reg |= DWC3_GFLADJ_REFCLK_LPM_SEL;
154 dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
155 }
156 }
Sebastian Andrzej Siewior3140e8c2011-10-31 22:25:40 +0100157}
Felipe Balbi8300dd22011-10-18 13:54:01 +0300158
Felipe Balbicf6d8672016-04-14 15:03:39 +0300159u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type)
160{
161 struct dwc3 *dwc = dep->dwc;
162 u32 reg;
163
164 dwc3_writel(dwc->regs, DWC3_GDBGFIFOSPACE,
165 DWC3_GDBGFIFOSPACE_NUM(dep->number) |
166 DWC3_GDBGFIFOSPACE_TYPE(type));
167
168 reg = dwc3_readl(dwc->regs, DWC3_GDBGFIFOSPACE);
169
170 return DWC3_GDBGFIFOSPACE_SPACE_AVAILABLE(reg);
171}
172
Felipe Balbi72246da2011-08-19 18:10:58 +0300173/**
Mayank Ranaa99689a2016-08-10 17:39:47 -0700174 * Peforms initialization of HS and SS PHYs.
175 * If used as a part of POR or init sequence it is recommended
176 * that we should perform hard reset of the PHYs prior to invoking
177 * this function.
Felipe Balbi72246da2011-08-19 18:10:58 +0300178 * @dwc: pointer to our context structure
Mayank Ranaa99689a2016-08-10 17:39:47 -0700179*/
180static int dwc3_init_usb_phys(struct dwc3 *dwc)
Felipe Balbi72246da2011-08-19 18:10:58 +0300181{
Kishon Vijay Abraham I57303482014-03-03 17:08:11 +0530182 int ret;
Felipe Balbi72246da2011-08-19 18:10:58 +0300183
Mayank Ranaa99689a2016-08-10 17:39:47 -0700184 /* Bring up PHYs */
185 ret = usb_phy_init(dwc->usb2_phy);
186 if (ret) {
187 pr_err("%s: usb_phy_init(dwc->usb2_phy) returned %d\n",
188 __func__, ret);
189 return ret;
190 }
191
192 ret = usb_phy_init(dwc->usb3_phy);
193 if (ret == -EBUSY) {
194 /*
195 * Setting Max speed as high when USB3 PHY initialiation
196 * is failing and USB superspeed can't be supported.
197 */
198 dwc->maximum_speed = USB_SPEED_HIGH;
199 } else if (ret) {
200 pr_err("%s: usb_phy_init(dwc->usb3_phy) returned %d\n",
201 __func__, ret);
202 return ret;
203 }
Kishon Vijay Abraham I57303482014-03-03 17:08:11 +0530204 ret = phy_init(dwc->usb2_generic_phy);
205 if (ret < 0)
206 return ret;
207
208 ret = phy_init(dwc->usb3_generic_phy);
209 if (ret < 0) {
210 phy_exit(dwc->usb2_generic_phy);
211 return ret;
212 }
Felipe Balbi72246da2011-08-19 18:10:58 +0300213
Mayank Ranaa99689a2016-08-10 17:39:47 -0700214 return 0;
215}
Felipe Balbi72246da2011-08-19 18:10:58 +0300216
Mayank Ranaa99689a2016-08-10 17:39:47 -0700217/**
218 * dwc3_core_reset - Issues core soft reset and PHY reset
219 * @dwc: pointer to our context structure
220 */
221static int dwc3_core_reset(struct dwc3 *dwc)
222{
223 int ret;
Felipe Balbi72246da2011-08-19 18:10:58 +0300224
Mayank Ranaa99689a2016-08-10 17:39:47 -0700225 /* Reset PHYs */
226 usb_phy_reset(dwc->usb2_phy);
227 usb_phy_reset(dwc->usb3_phy);
Pratyush Anand45627ac2012-06-21 17:44:28 +0530228
Mayank Ranaa99689a2016-08-10 17:39:47 -0700229 /* Initialize PHYs */
230 ret = dwc3_init_usb_phys(dwc);
231 if (ret) {
232 pr_err("%s: dwc3_init_phys returned %d\n",
233 __func__, ret);
234 return ret;
235 }
Kishon Vijay Abraham I57303482014-03-03 17:08:11 +0530236
Mayank Ranaa99689a2016-08-10 17:39:47 -0700237 dwc3_notify_event(dwc, DWC3_CONTROLLER_RESET_EVENT);
238
239 dwc3_notify_event(dwc, DWC3_CONTROLLER_POST_RESET_EVENT);
240
241 return 0;
Felipe Balbi72246da2011-08-19 18:10:58 +0300242}
243
244/**
Heikki Krogerusc5cc74e2015-05-13 15:26:47 +0300245 * dwc3_soft_reset - Issue soft reset
246 * @dwc: Pointer to our controller context structure
247 */
248static int dwc3_soft_reset(struct dwc3 *dwc)
249{
250 unsigned long timeout;
251 u32 reg;
252
253 timeout = jiffies + msecs_to_jiffies(500);
254 dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST);
255 do {
256 reg = dwc3_readl(dwc->regs, DWC3_DCTL);
257 if (!(reg & DWC3_DCTL_CSFTRST))
258 break;
259
260 if (time_after(jiffies, timeout)) {
261 dev_err(dwc->dev, "Reset Timed Out\n");
262 return -ETIMEDOUT;
263 }
264
265 cpu_relax();
266 } while (true);
267
268 return 0;
269}
270
Nikhil Badoladb2be4e2015-09-04 10:15:58 +0530271/*
272 * dwc3_frame_length_adjustment - Adjusts frame length if required
273 * @dwc3: Pointer to our controller context structure
Nikhil Badoladb2be4e2015-09-04 10:15:58 +0530274 */
Felipe Balbibcdb3272016-05-16 10:42:23 +0300275static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
Nikhil Badoladb2be4e2015-09-04 10:15:58 +0530276{
277 u32 reg;
278 u32 dft;
279
280 if (dwc->revision < DWC3_REVISION_250A)
281 return;
282
Felipe Balbibcdb3272016-05-16 10:42:23 +0300283 if (dwc->fladj == 0)
Nikhil Badoladb2be4e2015-09-04 10:15:58 +0530284 return;
285
286 reg = dwc3_readl(dwc->regs, DWC3_GFLADJ);
287 dft = reg & DWC3_GFLADJ_30MHZ_MASK;
Felipe Balbibcdb3272016-05-16 10:42:23 +0300288 if (!dev_WARN_ONCE(dwc->dev, dft == dwc->fladj,
Nikhil Badoladb2be4e2015-09-04 10:15:58 +0530289 "request value same as default, ignoring\n")) {
290 reg &= ~DWC3_GFLADJ_30MHZ_MASK;
Felipe Balbibcdb3272016-05-16 10:42:23 +0300291 reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | dwc->fladj;
Nikhil Badoladb2be4e2015-09-04 10:15:58 +0530292 dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
293 }
294}
295
Heikki Krogerusc5cc74e2015-05-13 15:26:47 +0300296/**
Felipe Balbi72246da2011-08-19 18:10:58 +0300297 * dwc3_free_one_event_buffer - Frees one event buffer
298 * @dwc: Pointer to our controller context structure
299 * @evt: Pointer to event buffer to be freed
300 */
301static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
302 struct dwc3_event_buffer *evt)
303{
304 dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
Felipe Balbi72246da2011-08-19 18:10:58 +0300305}
306
307/**
Paul Zimmerman1d046792012-02-15 18:56:56 -0800308 * dwc3_alloc_one_event_buffer - Allocates one event buffer structure
Felipe Balbi72246da2011-08-19 18:10:58 +0300309 * @dwc: Pointer to our controller context structure
310 * @length: size of the event buffer
311 *
Paul Zimmerman1d046792012-02-15 18:56:56 -0800312 * Returns a pointer to the allocated event buffer structure on success
Felipe Balbi72246da2011-08-19 18:10:58 +0300313 * otherwise ERR_PTR(errno).
314 */
Felipe Balbi67d0b502013-02-22 16:31:07 +0200315static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc,
316 unsigned length)
Felipe Balbi72246da2011-08-19 18:10:58 +0300317{
318 struct dwc3_event_buffer *evt;
319
Felipe Balbi380f0d22012-10-11 13:48:36 +0300320 evt = devm_kzalloc(dwc->dev, sizeof(*evt), GFP_KERNEL);
Felipe Balbi72246da2011-08-19 18:10:58 +0300321 if (!evt)
322 return ERR_PTR(-ENOMEM);
323
324 evt->dwc = dwc;
325 evt->length = length;
326 evt->buf = dma_alloc_coherent(dwc->dev, length,
327 &evt->dma, GFP_KERNEL);
Felipe Balbie32672f2012-11-08 15:26:41 +0200328 if (!evt->buf)
Felipe Balbi72246da2011-08-19 18:10:58 +0300329 return ERR_PTR(-ENOMEM);
Felipe Balbi72246da2011-08-19 18:10:58 +0300330
331 return evt;
332}
333
334/**
335 * dwc3_free_event_buffers - frees all allocated event buffers
336 * @dwc: Pointer to our controller context structure
337 */
338static void dwc3_free_event_buffers(struct dwc3 *dwc)
339{
340 struct dwc3_event_buffer *evt;
Felipe Balbi72246da2011-08-19 18:10:58 +0300341
Felipe Balbi696c8b12016-03-30 09:37:03 +0300342 evt = dwc->ev_buf;
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300343 if (evt)
344 dwc3_free_one_event_buffer(dwc, evt);
Felipe Balbi72246da2011-08-19 18:10:58 +0300345}
346
347/**
348 * dwc3_alloc_event_buffers - Allocates @num event buffers of size @length
Paul Zimmerman1d046792012-02-15 18:56:56 -0800349 * @dwc: pointer to our controller context structure
Felipe Balbi72246da2011-08-19 18:10:58 +0300350 * @length: size of event buffer
351 *
Paul Zimmerman1d046792012-02-15 18:56:56 -0800352 * Returns 0 on success otherwise negative errno. In the error case, dwc
Felipe Balbi72246da2011-08-19 18:10:58 +0300353 * may contain some buffers allocated but not all which were requested.
354 */
Bill Pemberton41ac7b32012-11-19 13:21:48 -0500355static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
Felipe Balbi72246da2011-08-19 18:10:58 +0300356{
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300357 struct dwc3_event_buffer *evt;
Felipe Balbi72246da2011-08-19 18:10:58 +0300358
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300359 evt = dwc3_alloc_one_event_buffer(dwc, length);
360 if (IS_ERR(evt)) {
361 dev_err(dwc->dev, "can't allocate event buffer\n");
362 return PTR_ERR(evt);
Felipe Balbi72246da2011-08-19 18:10:58 +0300363 }
Felipe Balbi696c8b12016-03-30 09:37:03 +0300364 dwc->ev_buf = evt;
Felipe Balbi72246da2011-08-19 18:10:58 +0300365
366 return 0;
367}
368
369/**
370 * dwc3_event_buffers_setup - setup our allocated event buffers
Paul Zimmerman1d046792012-02-15 18:56:56 -0800371 * @dwc: pointer to our controller context structure
Felipe Balbi72246da2011-08-19 18:10:58 +0300372 *
373 * Returns 0 on success otherwise negative errno.
374 */
Mayank Ranaa99689a2016-08-10 17:39:47 -0700375int dwc3_event_buffers_setup(struct dwc3 *dwc)
Felipe Balbi72246da2011-08-19 18:10:58 +0300376{
377 struct dwc3_event_buffer *evt;
Felipe Balbi72246da2011-08-19 18:10:58 +0300378
Felipe Balbi696c8b12016-03-30 09:37:03 +0300379 evt = dwc->ev_buf;
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300380 dwc3_trace(trace_dwc3_core,
381 "Event buf %p dma %08llx length %d\n",
382 evt->buf, (unsigned long long) evt->dma,
383 evt->length);
Felipe Balbi72246da2011-08-19 18:10:58 +0300384
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300385 evt->lpos = 0;
Paul Zimmerman7acd85e2012-04-27 14:28:02 +0300386
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300387 dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0),
388 lower_32_bits(evt->dma));
389 dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0),
390 upper_32_bits(evt->dma));
391 dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0),
392 DWC3_GEVNTSIZ_SIZE(evt->length));
393 dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
Felipe Balbi72246da2011-08-19 18:10:58 +0300394
395 return 0;
396}
397
398static void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
399{
400 struct dwc3_event_buffer *evt;
Felipe Balbi72246da2011-08-19 18:10:58 +0300401
Felipe Balbi696c8b12016-03-30 09:37:03 +0300402 evt = dwc->ev_buf;
Paul Zimmerman7acd85e2012-04-27 14:28:02 +0300403
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300404 evt->lpos = 0;
Paul Zimmerman7acd85e2012-04-27 14:28:02 +0300405
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300406 dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0), 0);
407 dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), 0);
408 dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK
409 | DWC3_GEVNTSIZ_SIZE(0));
410 dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
Felipe Balbi72246da2011-08-19 18:10:58 +0300411}
412
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600413static int dwc3_alloc_scratch_buffers(struct dwc3 *dwc)
414{
415 if (!dwc->has_hibernation)
416 return 0;
417
418 if (!dwc->nr_scratch)
419 return 0;
420
421 dwc->scratchbuf = kmalloc_array(dwc->nr_scratch,
422 DWC3_SCRATCHBUF_SIZE, GFP_KERNEL);
423 if (!dwc->scratchbuf)
424 return -ENOMEM;
425
426 return 0;
427}
428
429static int dwc3_setup_scratch_buffers(struct dwc3 *dwc)
430{
431 dma_addr_t scratch_addr;
432 u32 param;
433 int ret;
434
435 if (!dwc->has_hibernation)
436 return 0;
437
438 if (!dwc->nr_scratch)
439 return 0;
440
441 /* should never fall here */
442 if (!WARN_ON(dwc->scratchbuf))
443 return 0;
444
445 scratch_addr = dma_map_single(dwc->dev, dwc->scratchbuf,
446 dwc->nr_scratch * DWC3_SCRATCHBUF_SIZE,
447 DMA_BIDIRECTIONAL);
448 if (dma_mapping_error(dwc->dev, scratch_addr)) {
449 dev_err(dwc->dev, "failed to map scratch buffer\n");
450 ret = -EFAULT;
451 goto err0;
452 }
453
454 dwc->scratch_addr = scratch_addr;
455
456 param = lower_32_bits(scratch_addr);
457
458 ret = dwc3_send_gadget_generic_command(dwc,
459 DWC3_DGCMD_SET_SCRATCHPAD_ADDR_LO, param);
460 if (ret < 0)
461 goto err1;
462
463 param = upper_32_bits(scratch_addr);
464
465 ret = dwc3_send_gadget_generic_command(dwc,
466 DWC3_DGCMD_SET_SCRATCHPAD_ADDR_HI, param);
467 if (ret < 0)
468 goto err1;
469
470 return 0;
471
472err1:
473 dma_unmap_single(dwc->dev, dwc->scratch_addr, dwc->nr_scratch *
474 DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL);
475
476err0:
477 return ret;
478}
479
480static void dwc3_free_scratch_buffers(struct dwc3 *dwc)
481{
482 if (!dwc->has_hibernation)
483 return;
484
485 if (!dwc->nr_scratch)
486 return;
487
488 /* should never fall here */
489 if (!WARN_ON(dwc->scratchbuf))
490 return;
491
492 dma_unmap_single(dwc->dev, dwc->scratch_addr, dwc->nr_scratch *
493 DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL);
494 kfree(dwc->scratchbuf);
495}
496
Felipe Balbi789451f62011-05-05 15:53:10 +0300497static void dwc3_core_num_eps(struct dwc3 *dwc)
498{
499 struct dwc3_hwparams *parms = &dwc->hwparams;
500
501 dwc->num_in_eps = DWC3_NUM_IN_EPS(parms);
502 dwc->num_out_eps = DWC3_NUM_EPS(parms) - dwc->num_in_eps;
503
Felipe Balbi73815282015-01-27 13:48:14 -0600504 dwc3_trace(trace_dwc3_core, "found %d IN and %d OUT endpoints",
Felipe Balbi789451f62011-05-05 15:53:10 +0300505 dwc->num_in_eps, dwc->num_out_eps);
506}
507
Bill Pemberton41ac7b32012-11-19 13:21:48 -0500508static void dwc3_cache_hwparams(struct dwc3 *dwc)
Felipe Balbi26ceca92011-09-30 10:58:49 +0300509{
510 struct dwc3_hwparams *parms = &dwc->hwparams;
511
512 parms->hwparams0 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS0);
513 parms->hwparams1 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS1);
514 parms->hwparams2 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS2);
515 parms->hwparams3 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS3);
516 parms->hwparams4 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS4);
517 parms->hwparams5 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS5);
518 parms->hwparams6 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
519 parms->hwparams7 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS7);
520 parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8);
521}
522
Felipe Balbi72246da2011-08-19 18:10:58 +0300523/**
Huang Ruib5a65c42014-10-28 19:54:28 +0800524 * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core
525 * @dwc: Pointer to our controller context structure
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300526 *
527 * Returns 0 on success. The USB PHY interfaces are configured but not
528 * initialized. The PHY interfaces and the PHYs get initialized together with
529 * the core in dwc3_core_init.
Huang Ruib5a65c42014-10-28 19:54:28 +0800530 */
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300531static int dwc3_phy_setup(struct dwc3 *dwc)
Huang Ruib5a65c42014-10-28 19:54:28 +0800532{
533 u32 reg;
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300534 int ret;
Huang Ruib5a65c42014-10-28 19:54:28 +0800535
536 reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
537
Huang Rui2164a472014-10-28 19:54:35 +0800538 /*
539 * Above 1.94a, it is recommended to set DWC3_GUSB3PIPECTL_SUSPHY
540 * to '0' during coreConsultant configuration. So default value
541 * will be '0' when the core is reset. Application needs to set it
542 * to '1' after the core initialization is completed.
543 */
544 if (dwc->revision > DWC3_REVISION_194A)
545 reg |= DWC3_GUSB3PIPECTL_SUSPHY;
546
Huang Ruib5a65c42014-10-28 19:54:28 +0800547 if (dwc->u2ss_inp3_quirk)
548 reg |= DWC3_GUSB3PIPECTL_U2SSINP3OK;
549
Rajesh Bhagate58dd352016-03-14 14:40:50 +0530550 if (dwc->dis_rxdet_inp3_quirk)
551 reg |= DWC3_GUSB3PIPECTL_DISRXDETINP3;
552
Huang Ruidf31f5b2014-10-28 19:54:29 +0800553 if (dwc->req_p1p2p3_quirk)
554 reg |= DWC3_GUSB3PIPECTL_REQP1P2P3;
555
Huang Ruia2a1d0f2014-10-28 19:54:30 +0800556 if (dwc->del_p1p2p3_quirk)
557 reg |= DWC3_GUSB3PIPECTL_DEP1P2P3_EN;
558
Huang Rui41c06ff2014-10-28 19:54:31 +0800559 if (dwc->del_phy_power_chg_quirk)
560 reg |= DWC3_GUSB3PIPECTL_DEPOCHANGE;
561
Huang Ruifb67afc2014-10-28 19:54:32 +0800562 if (dwc->lfps_filter_quirk)
563 reg |= DWC3_GUSB3PIPECTL_LFPSFILT;
564
Huang Rui14f4ac52014-10-28 19:54:33 +0800565 if (dwc->rx_detect_poll_quirk)
566 reg |= DWC3_GUSB3PIPECTL_RX_DETOPOLL;
567
Huang Rui6b6a0c92014-10-31 11:11:12 +0800568 if (dwc->tx_de_emphasis_quirk)
569 reg |= DWC3_GUSB3PIPECTL_TX_DEEPH(dwc->tx_de_emphasis);
570
Felipe Balbicd72f892014-11-06 11:31:00 -0600571 if (dwc->dis_u3_susphy_quirk)
Huang Rui59acfa22014-10-31 11:11:13 +0800572 reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
573
William Wu00fe0812016-08-16 22:44:39 +0800574 if (dwc->dis_del_phy_power_chg_quirk)
575 reg &= ~DWC3_GUSB3PIPECTL_DEPOCHANGE;
576
Huang Ruib5a65c42014-10-28 19:54:28 +0800577 dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
578
Huang Rui2164a472014-10-28 19:54:35 +0800579 reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
580
Heikki Krogerus3e10a2c2015-05-13 15:26:49 +0300581 /* Select the HS PHY interface */
582 switch (DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3)) {
583 case DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI:
Felipe Balbi43cacb02015-07-01 22:03:09 -0500584 if (dwc->hsphy_interface &&
585 !strncmp(dwc->hsphy_interface, "utmi", 4)) {
Heikki Krogerus3e10a2c2015-05-13 15:26:49 +0300586 reg &= ~DWC3_GUSB2PHYCFG_ULPI_UTMI;
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300587 break;
Felipe Balbi43cacb02015-07-01 22:03:09 -0500588 } else if (dwc->hsphy_interface &&
589 !strncmp(dwc->hsphy_interface, "ulpi", 4)) {
Heikki Krogerus3e10a2c2015-05-13 15:26:49 +0300590 reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI;
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300591 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
Heikki Krogerus3e10a2c2015-05-13 15:26:49 +0300592 } else {
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300593 /* Relying on default value. */
594 if (!(reg & DWC3_GUSB2PHYCFG_ULPI_UTMI))
595 break;
Heikki Krogerus3e10a2c2015-05-13 15:26:49 +0300596 }
597 /* FALLTHROUGH */
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300598 case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI:
599 /* Making sure the interface and PHY are operational */
600 ret = dwc3_soft_reset(dwc);
601 if (ret)
602 return ret;
603
604 udelay(1);
605
606 ret = dwc3_ulpi_init(dwc);
607 if (ret)
608 return ret;
609 /* FALLTHROUGH */
Heikki Krogerus3e10a2c2015-05-13 15:26:49 +0300610 default:
611 break;
612 }
613
William Wu32f2ed82016-08-16 22:44:38 +0800614 switch (dwc->hsphy_mode) {
615 case USBPHY_INTERFACE_MODE_UTMI:
616 reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
617 DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
618 reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_8_BIT) |
619 DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_8_BIT);
620 break;
621 case USBPHY_INTERFACE_MODE_UTMIW:
622 reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
623 DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
624 reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_16_BIT) |
625 DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_16_BIT);
626 break;
627 default:
628 break;
629 }
630
Huang Rui2164a472014-10-28 19:54:35 +0800631 /*
632 * Above 1.94a, it is recommended to set DWC3_GUSB2PHYCFG_SUSPHY to
633 * '0' during coreConsultant configuration. So default value will
634 * be '0' when the core is reset. Application needs to set it to
635 * '1' after the core initialization is completed.
636 */
637 if (dwc->revision > DWC3_REVISION_194A)
638 reg |= DWC3_GUSB2PHYCFG_SUSPHY;
639
Felipe Balbicd72f892014-11-06 11:31:00 -0600640 if (dwc->dis_u2_susphy_quirk)
Huang Rui0effe0a2014-10-31 11:11:14 +0800641 reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
642
John Younec791d12015-10-02 20:30:57 -0700643 if (dwc->dis_enblslpm_quirk)
644 reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
645
William Wu16199f32016-08-16 22:44:37 +0800646 if (dwc->dis_u2_freeclk_exists_quirk)
647 reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS;
648
Huang Rui2164a472014-10-28 19:54:35 +0800649 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300650
651 return 0;
Huang Ruib5a65c42014-10-28 19:54:28 +0800652}
653
Felipe Balbic499ff72016-05-16 10:49:01 +0300654static void dwc3_core_exit(struct dwc3 *dwc)
655{
656 dwc3_event_buffers_cleanup(dwc);
657
658 usb_phy_shutdown(dwc->usb2_phy);
659 usb_phy_shutdown(dwc->usb3_phy);
660 phy_exit(dwc->usb2_generic_phy);
661 phy_exit(dwc->usb3_generic_phy);
662
663 usb_phy_set_suspend(dwc->usb2_phy, 1);
664 usb_phy_set_suspend(dwc->usb3_phy, 1);
665 phy_power_off(dwc->usb2_generic_phy);
666 phy_power_off(dwc->usb3_generic_phy);
667}
668
Huang Ruib5a65c42014-10-28 19:54:28 +0800669/**
Felipe Balbi72246da2011-08-19 18:10:58 +0300670 * dwc3_core_init - Low-level initialization of DWC3 Core
671 * @dwc: Pointer to our controller context structure
672 *
673 * Returns 0 on success otherwise negative errno.
674 */
Mayank Ranaa99689a2016-08-10 17:39:47 -0700675int dwc3_core_init(struct dwc3 *dwc)
Felipe Balbi72246da2011-08-19 18:10:58 +0300676{
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600677 u32 hwparams4 = dwc->hwparams.hwparams4;
Felipe Balbi72246da2011-08-19 18:10:58 +0300678 u32 reg;
679 int ret;
680
Sebastian Andrzej Siewior7650bd72011-08-29 13:56:36 +0200681 reg = dwc3_readl(dwc->regs, DWC3_GSNPSID);
682 /* This should read as U3 followed by revision number */
John Youn690fb372015-09-04 19:15:10 -0700683 if ((reg & DWC3_GSNPSID_MASK) == 0x55330000) {
684 /* Detected DWC_usb3 IP */
685 dwc->revision = reg;
686 } else if ((reg & DWC3_GSNPSID_MASK) == 0x33310000) {
687 /* Detected DWC_usb31 IP */
688 dwc->revision = dwc3_readl(dwc->regs, DWC3_VER_NUMBER);
689 dwc->revision |= DWC3_REVISION_IS_DWC31;
690 } else {
Sebastian Andrzej Siewior7650bd72011-08-29 13:56:36 +0200691 dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n");
692 ret = -ENODEV;
693 goto err0;
694 }
Sebastian Andrzej Siewior7650bd72011-08-29 13:56:36 +0200695
Felipe Balbifa0ea132014-09-19 15:51:11 -0500696 /*
697 * Write Linux Version Code to our GUID register so it's easy to figure
698 * out which kernel version a bug was found.
699 */
700 dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE);
701
Paul Zimmerman0e1e5c42014-05-23 11:39:24 -0700702 /* Handle USB2.0-only core configuration */
703 if (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) ==
704 DWC3_GHWPARAMS3_SSPHY_IFC_DIS) {
705 if (dwc->maximum_speed == USB_SPEED_SUPER)
706 dwc->maximum_speed = USB_SPEED_HIGH;
707 }
708
Felipe Balbi72246da2011-08-19 18:10:58 +0300709 /* issue device SoftReset too */
Mayank Ranaa99689a2016-08-10 17:39:47 -0700710 ret = dwc3_core_reset(dwc);
Heikki Krogerusc5cc74e2015-05-13 15:26:47 +0300711 if (ret)
712 goto err0;
Felipe Balbi72246da2011-08-19 18:10:58 +0300713
Mayank Ranaa99689a2016-08-10 17:39:47 -0700714 /* issue device SoftReset too */
715 ret = dwc3_soft_reset(dwc);
Kishon Vijay Abraham I57303482014-03-03 17:08:11 +0530716 if (ret)
717 goto err0;
Pratyush Anand58a0f232012-06-21 17:44:29 +0530718
Felipe Balbic499ff72016-05-16 10:49:01 +0300719 ret = dwc3_phy_setup(dwc);
720 if (ret)
721 goto err0;
722
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100723 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
Paul Zimmerman3e87c422012-02-24 17:32:13 -0800724 reg &= ~DWC3_GCTL_SCALEDOWN_MASK;
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100725
Sebastian Andrzej Siewior164d7732011-11-24 11:22:05 +0100726 switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1)) {
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100727 case DWC3_GHWPARAMS1_EN_PWROPT_CLK:
Felipe Balbi32a4a132014-02-25 14:00:13 -0600728 /**
729 * WORKAROUND: DWC3 revisions between 2.10a and 2.50a have an
730 * issue which would cause xHCI compliance tests to fail.
731 *
732 * Because of that we cannot enable clock gating on such
733 * configurations.
734 *
735 * Refers to:
736 *
737 * STAR#9000588375: Clock Gating, SOF Issues when ref_clk-Based
738 * SOF/ITP Mode Used
739 */
740 if ((dwc->dr_mode == USB_DR_MODE_HOST ||
741 dwc->dr_mode == USB_DR_MODE_OTG) &&
742 (dwc->revision >= DWC3_REVISION_210A &&
743 dwc->revision <= DWC3_REVISION_250A))
744 reg |= DWC3_GCTL_DSBLCLKGTNG | DWC3_GCTL_SOFITPSYNC;
745 else
746 reg &= ~DWC3_GCTL_DSBLCLKGTNG;
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100747 break;
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600748 case DWC3_GHWPARAMS1_EN_PWROPT_HIB:
749 /* enable hibernation here */
750 dwc->nr_scratch = DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(hwparams4);
Huang Rui2eac3992014-10-28 19:54:22 +0800751
752 /*
753 * REVISIT Enabling this bit so that host-mode hibernation
754 * will work. Device-mode hibernation is not yet implemented.
755 */
756 reg |= DWC3_GCTL_GBLHIBERNATIONEN;
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600757 break;
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100758 default:
Felipe Balbi1407bf12015-11-16 16:06:37 -0600759 dwc3_trace(trace_dwc3_core, "No power optimization available\n");
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100760 }
761
Huang Rui946bd572014-10-28 19:54:23 +0800762 /* check if current dwc3 is on simulation board */
763 if (dwc->hwparams.hwparams6 & DWC3_GHWPARAMS6_EN_FPGA) {
Felipe Balbi1407bf12015-11-16 16:06:37 -0600764 dwc3_trace(trace_dwc3_core,
765 "running on FPGA platform\n");
Huang Rui946bd572014-10-28 19:54:23 +0800766 dwc->is_fpga = true;
767 }
768
Huang Rui3b812212014-10-28 19:54:25 +0800769 WARN_ONCE(dwc->disable_scramble_quirk && !dwc->is_fpga,
770 "disable_scramble cannot be used on non-FPGA builds\n");
771
772 if (dwc->disable_scramble_quirk && dwc->is_fpga)
773 reg |= DWC3_GCTL_DISSCRAMBLE;
774 else
775 reg &= ~DWC3_GCTL_DISSCRAMBLE;
776
Huang Rui9a5b2f32014-10-28 19:54:27 +0800777 if (dwc->u2exit_lfps_quirk)
778 reg |= DWC3_GCTL_U2EXIT_LFPS;
779
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100780 /*
781 * WORKAROUND: DWC3 revisions <1.90a have a bug
Paul Zimmerman1d046792012-02-15 18:56:56 -0800782 * where the device can fail to connect at SuperSpeed
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100783 * and falls back to high-speed mode which causes
Paul Zimmerman1d046792012-02-15 18:56:56 -0800784 * the device to enter a Connect/Disconnect loop
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100785 */
786 if (dwc->revision < DWC3_REVISION_190A)
787 reg |= DWC3_GCTL_U2RSTECN;
788
Mayank Ranaa99689a2016-08-10 17:39:47 -0700789 dwc3_core_num_eps(dwc);
790
791 /*
792 * Disable clock gating to work around a known HW bug that causes the
793 * internal RAM clock to get stuck when entering low power modes.
794 */
795 if (dwc->disable_clk_gating) {
796 dev_dbg(dwc->dev, "Disabling controller clock gating.\n");
797 reg |= DWC3_GCTL_DSBLCLKGTNG;
798 }
799
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100800 dwc3_writel(dwc->regs, DWC3_GCTL, reg);
801
Mayank Ranaa99689a2016-08-10 17:39:47 -0700802 ret = dwc3_alloc_scratch_buffers(dwc);
803 if (ret)
804 goto err1;
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600805
806 ret = dwc3_setup_scratch_buffers(dwc);
807 if (ret)
Mayank Ranaa99689a2016-08-10 17:39:47 -0700808 goto err2;
Felipe Balbic499ff72016-05-16 10:49:01 +0300809
810 /* Adjust Frame Length */
811 dwc3_frame_length_adjustment(dwc);
812
813 usb_phy_set_suspend(dwc->usb2_phy, 0);
814 usb_phy_set_suspend(dwc->usb3_phy, 0);
815 ret = phy_power_on(dwc->usb2_generic_phy);
816 if (ret < 0)
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600817 goto err2;
818
Mayank Ranaa99689a2016-08-10 17:39:47 -0700819 /*
820 * clear Elastic buffer mode in GUSBPIPE_CTRL(0) register, otherwise
821 * it results in high link errors and could cause SS mode transfer
822 * failure.
823 */
824 if (!dwc->nominal_elastic_buffer) {
825 reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
826 reg &= ~DWC3_GUSB3PIPECTL_ELASTIC_BUF_MODE;
827 dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
Felipe Balbic499ff72016-05-16 10:49:01 +0300828 }
829
Baolin Wang00af6232016-07-15 17:13:27 +0800830 switch (dwc->dr_mode) {
831 case USB_DR_MODE_PERIPHERAL:
832 dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE);
833 break;
834 case USB_DR_MODE_HOST:
835 dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST);
836 break;
837 case USB_DR_MODE_OTG:
838 dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG);
839 break;
840 default:
841 dev_warn(dwc->dev, "Unsupported mode %d\n", dwc->dr_mode);
842 break;
843 }
844
John Youn06281d42016-08-22 15:39:13 -0700845 /*
846 * ENDXFER polling is available on version 3.10a and later of
847 * the DWC_usb3 controller. It is NOT available in the
848 * DWC_usb31 controller.
849 */
850 if (!dwc3_is_usb31(dwc) && dwc->revision >= DWC3_REVISION_310A) {
851 reg = dwc3_readl(dwc->regs, DWC3_GUCTL2);
852 reg |= DWC3_GUCTL2_RST_ACTBITLATER;
853 dwc3_writel(dwc->regs, DWC3_GUCTL2, reg);
854 }
855
Felipe Balbi72246da2011-08-19 18:10:58 +0300856 return 0;
857
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600858err2:
Mayank Ranaa99689a2016-08-10 17:39:47 -0700859 dwc3_free_scratch_buffers(dwc);
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600860
861err1:
862 usb_phy_shutdown(dwc->usb2_phy);
863 usb_phy_shutdown(dwc->usb3_phy);
Kishon Vijay Abraham I57303482014-03-03 17:08:11 +0530864 phy_exit(dwc->usb2_generic_phy);
865 phy_exit(dwc->usb3_generic_phy);
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600866
Felipe Balbi72246da2011-08-19 18:10:58 +0300867err0:
868 return ret;
869}
870
Felipe Balbi3c9f94a2014-04-16 15:08:29 -0500871static int dwc3_core_get_phy(struct dwc3 *dwc)
Felipe Balbi72246da2011-08-19 18:10:58 +0300872{
Felipe Balbi3c9f94a2014-04-16 15:08:29 -0500873 struct device *dev = dwc->dev;
Felipe Balbi941ea362013-07-31 09:21:25 +0300874 struct device_node *node = dev->of_node;
Felipe Balbi3c9f94a2014-04-16 15:08:29 -0500875 int ret;
Felipe Balbi72246da2011-08-19 18:10:58 +0300876
Kishon Vijay Abraham I5088b6f2013-01-25 16:36:53 +0530877 if (node) {
878 dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
879 dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
Felipe Balbibb674902013-08-14 13:21:23 -0500880 } else {
881 dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
882 dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
Kishon Vijay Abraham I5088b6f2013-01-25 16:36:53 +0530883 }
884
Felipe Balbid105e7f2013-03-15 10:52:08 +0200885 if (IS_ERR(dwc->usb2_phy)) {
886 ret = PTR_ERR(dwc->usb2_phy);
Kishon Vijay Abraham I122f06e2014-03-03 17:08:10 +0530887 if (ret == -ENXIO || ret == -ENODEV) {
888 dwc->usb2_phy = NULL;
889 } else if (ret == -EPROBE_DEFER) {
Felipe Balbid105e7f2013-03-15 10:52:08 +0200890 return ret;
Kishon Vijay Abraham I122f06e2014-03-03 17:08:10 +0530891 } else {
892 dev_err(dev, "no usb2 phy configured\n");
893 return ret;
894 }
Felipe Balbi51e1e7b2012-07-19 14:09:48 +0300895 }
896
Felipe Balbid105e7f2013-03-15 10:52:08 +0200897 if (IS_ERR(dwc->usb3_phy)) {
Ruchika Kharwar315955d72013-07-04 00:59:34 -0500898 ret = PTR_ERR(dwc->usb3_phy);
Kishon Vijay Abraham I122f06e2014-03-03 17:08:10 +0530899 if (ret == -ENXIO || ret == -ENODEV) {
900 dwc->usb3_phy = NULL;
901 } else if (ret == -EPROBE_DEFER) {
Felipe Balbid105e7f2013-03-15 10:52:08 +0200902 return ret;
Kishon Vijay Abraham I122f06e2014-03-03 17:08:10 +0530903 } else {
904 dev_err(dev, "no usb3 phy configured\n");
905 return ret;
906 }
Felipe Balbi51e1e7b2012-07-19 14:09:48 +0300907 }
908
Kishon Vijay Abraham I57303482014-03-03 17:08:11 +0530909 dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
910 if (IS_ERR(dwc->usb2_generic_phy)) {
911 ret = PTR_ERR(dwc->usb2_generic_phy);
912 if (ret == -ENOSYS || ret == -ENODEV) {
913 dwc->usb2_generic_phy = NULL;
914 } else if (ret == -EPROBE_DEFER) {
915 return ret;
916 } else {
917 dev_err(dev, "no usb2 phy configured\n");
918 return ret;
919 }
920 }
921
922 dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
923 if (IS_ERR(dwc->usb3_generic_phy)) {
924 ret = PTR_ERR(dwc->usb3_generic_phy);
925 if (ret == -ENOSYS || ret == -ENODEV) {
926 dwc->usb3_generic_phy = NULL;
927 } else if (ret == -EPROBE_DEFER) {
928 return ret;
929 } else {
930 dev_err(dev, "no usb3 phy configured\n");
931 return ret;
932 }
933 }
934
Felipe Balbi3c9f94a2014-04-16 15:08:29 -0500935 return 0;
936}
937
Felipe Balbi5f94adf2014-04-16 15:13:45 -0500938static int dwc3_core_init_mode(struct dwc3 *dwc)
939{
940 struct device *dev = dwc->dev;
941 int ret;
942
943 switch (dwc->dr_mode) {
944 case USB_DR_MODE_PERIPHERAL:
Felipe Balbi5f94adf2014-04-16 15:13:45 -0500945 ret = dwc3_gadget_init(dwc);
946 if (ret) {
Roger Quadros9522def2016-06-10 14:48:38 +0300947 if (ret != -EPROBE_DEFER)
948 dev_err(dev, "failed to initialize gadget\n");
Felipe Balbi5f94adf2014-04-16 15:13:45 -0500949 return ret;
950 }
951 break;
952 case USB_DR_MODE_HOST:
Felipe Balbi5f94adf2014-04-16 15:13:45 -0500953 ret = dwc3_host_init(dwc);
954 if (ret) {
Roger Quadros9522def2016-06-10 14:48:38 +0300955 if (ret != -EPROBE_DEFER)
956 dev_err(dev, "failed to initialize host\n");
Felipe Balbi5f94adf2014-04-16 15:13:45 -0500957 return ret;
958 }
959 break;
960 case USB_DR_MODE_OTG:
Felipe Balbi5f94adf2014-04-16 15:13:45 -0500961 ret = dwc3_host_init(dwc);
962 if (ret) {
Roger Quadros9522def2016-06-10 14:48:38 +0300963 if (ret != -EPROBE_DEFER)
964 dev_err(dev, "failed to initialize host\n");
Felipe Balbi5f94adf2014-04-16 15:13:45 -0500965 return ret;
966 }
967
968 ret = dwc3_gadget_init(dwc);
969 if (ret) {
Roger Quadros9522def2016-06-10 14:48:38 +0300970 if (ret != -EPROBE_DEFER)
971 dev_err(dev, "failed to initialize gadget\n");
Felipe Balbi5f94adf2014-04-16 15:13:45 -0500972 return ret;
973 }
974 break;
975 default:
976 dev_err(dev, "Unsupported mode of operation %d\n", dwc->dr_mode);
977 return -EINVAL;
978 }
979
980 return 0;
981}
982
983static void dwc3_core_exit_mode(struct dwc3 *dwc)
984{
985 switch (dwc->dr_mode) {
986 case USB_DR_MODE_PERIPHERAL:
987 dwc3_gadget_exit(dwc);
988 break;
989 case USB_DR_MODE_HOST:
990 dwc3_host_exit(dwc);
991 break;
992 case USB_DR_MODE_OTG:
993 dwc3_host_exit(dwc);
994 dwc3_gadget_exit(dwc);
995 break;
996 default:
997 /* do nothing */
998 break;
999 }
1000}
1001
Mayank Ranaa99689a2016-08-10 17:39:47 -07001002/* XHCI reset, resets other CORE registers as well, re-init those */
1003void dwc3_post_host_reset_core_init(struct dwc3 *dwc)
1004{
1005 dwc3_core_init(dwc);
1006 dwc3_gadget_restart(dwc);
1007}
1008
1009static void (*notify_event)(struct dwc3 *, unsigned int);
1010void dwc3_set_notifier(void (*notify)(struct dwc3 *, unsigned int))
1011{
1012 notify_event = notify;
1013}
1014EXPORT_SYMBOL(dwc3_set_notifier);
1015
1016int dwc3_notify_event(struct dwc3 *dwc, unsigned int event)
1017{
1018 int ret = 0;
1019
1020 if (dwc->notify_event)
1021 dwc->notify_event(dwc, event);
1022 else
1023 ret = -ENODEV;
1024
1025 return ret;
1026}
1027EXPORT_SYMBOL(dwc3_notify_event);
1028
1029int dwc3_core_pre_init(struct dwc3 *dwc)
1030{
1031 int ret;
1032
1033 dwc3_cache_hwparams(dwc);
1034
1035 ret = dwc3_phy_setup(dwc);
1036 if (ret)
1037 goto err0;
1038
1039 if (!dwc->ev_buf) {
1040 ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
1041 if (ret) {
1042 dev_err(dwc->dev, "failed to allocate event buffers\n");
1043 ret = -ENOMEM;
1044 goto err1;
1045 }
1046 }
1047
1048 ret = dwc3_core_init(dwc);
1049 if (ret) {
1050 dev_err(dwc->dev, "failed to initialize core\n");
1051 goto err2;
1052 }
1053
1054 ret = phy_power_on(dwc->usb2_generic_phy);
1055 if (ret < 0)
1056 goto err3;
1057
1058 ret = phy_power_on(dwc->usb3_generic_phy);
1059 if (ret < 0)
1060 goto err4;
1061
1062 ret = dwc3_event_buffers_setup(dwc);
1063 if (ret) {
1064 dev_err(dwc->dev, "failed to setup event buffers\n");
1065 goto err5;
1066 }
1067
Mayank Ranaa99689a2016-08-10 17:39:47 -07001068 return ret;
1069
Mayank Ranaa99689a2016-08-10 17:39:47 -07001070err5:
1071 phy_power_off(dwc->usb3_generic_phy);
1072err4:
1073 phy_power_off(dwc->usb2_generic_phy);
1074err3:
1075 dwc3_core_exit(dwc);
1076err2:
1077 dwc3_free_event_buffers(dwc);
1078err1:
1079 dwc3_ulpi_exit(dwc);
1080err0:
1081 return ret;
1082}
1083
Felipe Balbi3c9f94a2014-04-16 15:08:29 -05001084#define DWC3_ALIGN_MASK (16 - 1)
1085
1086static int dwc3_probe(struct platform_device *pdev)
1087{
1088 struct device *dev = &pdev->dev;
Felipe Balbi3c9f94a2014-04-16 15:08:29 -05001089 struct resource *res;
1090 struct dwc3 *dwc;
Huang Rui80caf7d2014-10-28 19:54:26 +08001091 u8 lpm_nyet_threshold;
Huang Rui6b6a0c92014-10-31 11:11:12 +08001092 u8 tx_de_emphasis;
Huang Rui460d0982014-10-31 11:11:18 +08001093 u8 hird_threshold;
Mayank Ranaa99689a2016-08-10 17:39:47 -07001094 int irq;
Felipe Balbi3c9f94a2014-04-16 15:08:29 -05001095
Andy Shevchenkob09e99e2014-05-15 15:53:32 +03001096 int ret;
Felipe Balbi3c9f94a2014-04-16 15:08:29 -05001097
1098 void __iomem *regs;
1099 void *mem;
1100
1101 mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL);
Jingoo Han734d5a52014-07-17 12:45:11 +09001102 if (!mem)
Felipe Balbi3c9f94a2014-04-16 15:08:29 -05001103 return -ENOMEM;
Jingoo Han734d5a52014-07-17 12:45:11 +09001104
Felipe Balbi3c9f94a2014-04-16 15:08:29 -05001105 dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
1106 dwc->mem = mem;
1107 dwc->dev = dev;
1108
Mayank Ranaa99689a2016-08-10 17:39:47 -07001109 dwc->notify_event = notify_event;
1110 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1111 if (!res) {
1112 dev_err(dev, "missing IRQ\n");
1113 return -ENODEV;
1114 }
1115 dwc->xhci_resources[1].start = res->start;
1116 dwc->xhci_resources[1].end = res->end;
1117 dwc->xhci_resources[1].flags = res->flags;
1118 dwc->xhci_resources[1].name = res->name;
1119
1120 irq = platform_get_irq(to_platform_device(dwc->dev), 0);
1121
1122 /* will be enabled in dwc3_msm_resume() */
1123 irq_set_status_flags(irq, IRQ_NOAUTOEN);
1124 ret = devm_request_threaded_irq(dev, irq, NULL, dwc3_interrupt,
1125 IRQF_SHARED | IRQF_ONESHOT, "dwc3", dwc);
1126 if (ret) {
1127 dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
1128 irq, ret);
1129 return -ENODEV;
1130 }
1131
1132 dwc->irq = irq;
Felipe Balbi3c9f94a2014-04-16 15:08:29 -05001133 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1134 if (!res) {
1135 dev_err(dev, "missing memory resource\n");
1136 return -ENODEV;
1137 }
1138
Mayank Ranaa99689a2016-08-10 17:39:47 -07001139 dwc->reg_phys = res->start;
Vivek Gautamf32a5e22014-06-04 14:34:52 +05301140 dwc->xhci_resources[0].start = res->start;
1141 dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
1142 DWC3_XHCI_REGS_END;
1143 dwc->xhci_resources[0].flags = res->flags;
1144 dwc->xhci_resources[0].name = res->name;
1145
1146 res->start += DWC3_GLOBALS_REGS_START;
1147
1148 /*
1149 * Request memory region but exclude xHCI regs,
1150 * since it will be requested by the xhci-plat driver.
1151 */
1152 regs = devm_ioremap_resource(dev, res);
Felipe Balbi3da1f6e2014-09-02 15:19:43 -05001153 if (IS_ERR(regs)) {
1154 ret = PTR_ERR(regs);
1155 goto err0;
1156 }
Vivek Gautamf32a5e22014-06-04 14:34:52 +05301157
1158 dwc->regs = regs;
1159 dwc->regs_size = resource_size(res);
Vivek Gautamf32a5e22014-06-04 14:34:52 +05301160
Huang Rui80caf7d2014-10-28 19:54:26 +08001161 /* default to highest possible threshold */
1162 lpm_nyet_threshold = 0xff;
1163
Huang Rui6b6a0c92014-10-31 11:11:12 +08001164 /* default to -3.5dB de-emphasis */
1165 tx_de_emphasis = 1;
1166
Huang Rui460d0982014-10-31 11:11:18 +08001167 /*
1168 * default to assert utmi_sleep_n and use maximum allowed HIRD
1169 * threshold value of 0b1100
1170 */
1171 hird_threshold = 12;
1172
Heikki Krogerus63863b92015-09-21 11:14:32 +03001173 dwc->maximum_speed = usb_get_maximum_speed(dev);
Heikki Krogerus06e71142015-09-21 11:14:34 +03001174 dwc->dr_mode = usb_get_dr_mode(dev);
William Wu32f2ed82016-08-16 22:44:38 +08001175 dwc->hsphy_mode = of_usb_get_phy_mode(dev->of_node);
Heikki Krogerus63863b92015-09-21 11:14:32 +03001176
Heikki Krogerus3d128912015-09-21 11:14:35 +03001177 dwc->has_lpm_erratum = device_property_read_bool(dev,
Huang Rui80caf7d2014-10-28 19:54:26 +08001178 "snps,has-lpm-erratum");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001179 device_property_read_u8(dev, "snps,lpm-nyet-threshold",
Huang Rui80caf7d2014-10-28 19:54:26 +08001180 &lpm_nyet_threshold);
Heikki Krogerus3d128912015-09-21 11:14:35 +03001181 dwc->is_utmi_l1_suspend = device_property_read_bool(dev,
Huang Rui460d0982014-10-31 11:11:18 +08001182 "snps,is-utmi-l1-suspend");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001183 device_property_read_u8(dev, "snps,hird-threshold",
Huang Rui460d0982014-10-31 11:11:18 +08001184 &hird_threshold);
Heikki Krogerus3d128912015-09-21 11:14:35 +03001185 dwc->usb3_lpm_capable = device_property_read_bool(dev,
Robert Baldygaeac68e82015-03-09 15:06:12 +01001186 "snps,usb3_lpm_capable");
Felipe Balbi3c9f94a2014-04-16 15:08:29 -05001187
Heikki Krogerus3d128912015-09-21 11:14:35 +03001188 dwc->disable_scramble_quirk = device_property_read_bool(dev,
Huang Rui3b812212014-10-28 19:54:25 +08001189 "snps,disable_scramble_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001190 dwc->u2exit_lfps_quirk = device_property_read_bool(dev,
Huang Rui9a5b2f32014-10-28 19:54:27 +08001191 "snps,u2exit_lfps_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001192 dwc->u2ss_inp3_quirk = device_property_read_bool(dev,
Huang Ruib5a65c42014-10-28 19:54:28 +08001193 "snps,u2ss_inp3_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001194 dwc->req_p1p2p3_quirk = device_property_read_bool(dev,
Huang Ruidf31f5b2014-10-28 19:54:29 +08001195 "snps,req_p1p2p3_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001196 dwc->del_p1p2p3_quirk = device_property_read_bool(dev,
Huang Ruia2a1d0f2014-10-28 19:54:30 +08001197 "snps,del_p1p2p3_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001198 dwc->del_phy_power_chg_quirk = device_property_read_bool(dev,
Huang Rui41c06ff2014-10-28 19:54:31 +08001199 "snps,del_phy_power_chg_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001200 dwc->lfps_filter_quirk = device_property_read_bool(dev,
Huang Ruifb67afc2014-10-28 19:54:32 +08001201 "snps,lfps_filter_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001202 dwc->rx_detect_poll_quirk = device_property_read_bool(dev,
Huang Rui14f4ac52014-10-28 19:54:33 +08001203 "snps,rx_detect_poll_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001204 dwc->dis_u3_susphy_quirk = device_property_read_bool(dev,
Huang Rui59acfa22014-10-31 11:11:13 +08001205 "snps,dis_u3_susphy_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001206 dwc->dis_u2_susphy_quirk = device_property_read_bool(dev,
Huang Rui0effe0a2014-10-31 11:11:14 +08001207 "snps,dis_u2_susphy_quirk");
John Younec791d12015-10-02 20:30:57 -07001208 dwc->dis_enblslpm_quirk = device_property_read_bool(dev,
1209 "snps,dis_enblslpm_quirk");
Rajesh Bhagate58dd352016-03-14 14:40:50 +05301210 dwc->dis_rxdet_inp3_quirk = device_property_read_bool(dev,
1211 "snps,dis_rxdet_inp3_quirk");
William Wu16199f32016-08-16 22:44:37 +08001212 dwc->dis_u2_freeclk_exists_quirk = device_property_read_bool(dev,
1213 "snps,dis-u2-freeclk-exists-quirk");
William Wu00fe0812016-08-16 22:44:39 +08001214 dwc->dis_del_phy_power_chg_quirk = device_property_read_bool(dev,
1215 "snps,dis-del-phy-power-chg-quirk");
Huang Rui6b6a0c92014-10-31 11:11:12 +08001216
Heikki Krogerus3d128912015-09-21 11:14:35 +03001217 dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
Huang Rui6b6a0c92014-10-31 11:11:12 +08001218 "snps,tx_de_emphasis_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001219 device_property_read_u8(dev, "snps,tx_de_emphasis",
Huang Rui6b6a0c92014-10-31 11:11:12 +08001220 &tx_de_emphasis);
Heikki Krogerus3d128912015-09-21 11:14:35 +03001221 device_property_read_string(dev, "snps,hsphy_interface",
1222 &dwc->hsphy_interface);
1223 device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
Felipe Balbibcdb3272016-05-16 10:42:23 +03001224 &dwc->fladj);
Heikki Krogerus3d128912015-09-21 11:14:35 +03001225
Mayank Ranaa99689a2016-08-10 17:39:47 -07001226 if (dwc->enable_bus_suspend) {
1227 pm_runtime_set_autosuspend_delay(dev, 500);
1228 pm_runtime_use_autosuspend(dev);
1229 }
1230
Huang Rui80caf7d2014-10-28 19:54:26 +08001231 dwc->lpm_nyet_threshold = lpm_nyet_threshold;
Huang Rui6b6a0c92014-10-31 11:11:12 +08001232 dwc->tx_de_emphasis = tx_de_emphasis;
Huang Rui80caf7d2014-10-28 19:54:26 +08001233
Huang Rui460d0982014-10-31 11:11:18 +08001234 dwc->hird_threshold = hird_threshold
1235 | (dwc->is_utmi_l1_suspend << 4);
1236
Mayank Ranaa99689a2016-08-10 17:39:47 -07001237 init_waitqueue_head(&dwc->wait_linkstate);
Heikki Krogerus6c89cce02015-05-13 15:26:45 +03001238 platform_set_drvdata(pdev, dwc);
1239
Felipe Balbi3c9f94a2014-04-16 15:08:29 -05001240 ret = dwc3_core_get_phy(dwc);
1241 if (ret)
Felipe Balbi3da1f6e2014-09-02 15:19:43 -05001242 goto err0;
Felipe Balbi3c9f94a2014-04-16 15:08:29 -05001243
Felipe Balbi72246da2011-08-19 18:10:58 +03001244 spin_lock_init(&dwc->lock);
Felipe Balbi72246da2011-08-19 18:10:58 +03001245
Heikki Krogerus19bacdc2014-09-24 11:00:38 +03001246 if (!dev->dma_mask) {
1247 dev->dma_mask = dev->parent->dma_mask;
1248 dev->dma_parms = dev->parent->dma_parms;
1249 dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask);
1250 }
Kishon Vijay Abraham Iddff14f2013-03-07 18:51:43 +05301251
Mayank Ranaa99689a2016-08-10 17:39:47 -07001252 pm_runtime_no_callbacks(dev);
Felipe Balbifc8bb912016-05-16 13:14:48 +03001253 pm_runtime_set_active(dev);
Chanho Park802ca852012-02-15 18:27:55 +09001254 pm_runtime_enable(dev);
Chanho Park802ca852012-02-15 18:27:55 +09001255 pm_runtime_forbid(dev);
Felipe Balbi72246da2011-08-19 18:10:58 +03001256
Thinh Nguyen9d6173e2016-09-06 19:22:03 -07001257 ret = dwc3_get_dr_mode(dwc);
1258 if (ret)
Kyle Yan65be4a52016-10-31 15:05:00 -07001259 goto err0;
Felipe Balbi72246da2011-08-19 18:10:58 +03001260
John Youn77966eb2016-02-19 17:31:01 -08001261 /* Check the maximum_speed parameter */
1262 switch (dwc->maximum_speed) {
1263 case USB_SPEED_LOW:
1264 case USB_SPEED_FULL:
1265 case USB_SPEED_HIGH:
1266 case USB_SPEED_SUPER:
1267 case USB_SPEED_SUPER_PLUS:
1268 break;
1269 default:
1270 dev_err(dev, "invalid maximum_speed parameter %d\n",
1271 dwc->maximum_speed);
1272 /* fall through */
1273 case USB_SPEED_UNKNOWN:
1274 /* default to superspeed */
John Youn2c7f1bd2016-02-05 17:08:59 -08001275 dwc->maximum_speed = USB_SPEED_SUPER;
1276
1277 /*
1278 * default to superspeed plus if we are capable.
1279 */
1280 if (dwc3_is_usb31(dwc) &&
1281 (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) ==
1282 DWC3_GHWPARAMS3_SSPHY_IFC_GEN2))
1283 dwc->maximum_speed = USB_SPEED_SUPER_PLUS;
John Youn77966eb2016-02-19 17:31:01 -08001284
1285 break;
John Youn2c7f1bd2016-02-05 17:08:59 -08001286 }
1287
Mayank Ranaa99689a2016-08-10 17:39:47 -07001288 /* Adjust Frame Length */
1289 dwc3_frame_length_adjustment(dwc);
Felipe Balbi72246da2011-08-19 18:10:58 +03001290
Mayank Ranaa99689a2016-08-10 17:39:47 -07001291 /* Hardcode number of eps */
1292 dwc->num_in_eps = 16;
1293 dwc->num_out_eps = 16;
Felipe Balbi72246da2011-08-19 18:10:58 +03001294
Felipe Balbi72246da2011-08-19 18:10:58 +03001295 ret = dwc3_core_init_mode(dwc);
1296 if (ret)
Kyle Yan65be4a52016-10-31 15:05:00 -07001297 goto err0;
Mayank Ranaa99689a2016-08-10 17:39:47 -07001298
1299 ret = dwc3_debugfs_init(dwc);
1300 if (ret) {
1301 dev_err(dev, "failed to initialize debugfs\n");
Kyle Yan65be4a52016-10-31 15:05:00 -07001302 goto err_core_init;
Mayank Ranaa99689a2016-08-10 17:39:47 -07001303 }
1304
1305 pm_runtime_allow(dev);
Felipe Balbi72246da2011-08-19 18:10:58 +03001306 return 0;
1307
Kyle Yan65be4a52016-10-31 15:05:00 -07001308err_core_init:
1309 dwc3_core_exit_mode(dwc);
Felipe Balbi3da1f6e2014-09-02 15:19:43 -05001310err0:
1311 /*
1312 * restore res->start back to its original value so that, in case the
1313 * probe is deferred, we don't end up getting error in request the
1314 * memory region the next time probe is called.
1315 */
1316 res->start -= DWC3_GLOBALS_REGS_START;
1317
Felipe Balbi72246da2011-08-19 18:10:58 +03001318 return ret;
1319}
1320
Bill Pembertonfb4e98a2012-11-19 13:26:20 -05001321static int dwc3_remove(struct platform_device *pdev)
Felipe Balbi72246da2011-08-19 18:10:58 +03001322{
Felipe Balbi72246da2011-08-19 18:10:58 +03001323 struct dwc3 *dwc = platform_get_drvdata(pdev);
Felipe Balbi3da1f6e2014-09-02 15:19:43 -05001324 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1325
Felipe Balbifc8bb912016-05-16 13:14:48 +03001326 pm_runtime_get_sync(&pdev->dev);
Felipe Balbi3da1f6e2014-09-02 15:19:43 -05001327 /*
1328 * restore res->start back to its original value so that, in case the
1329 * probe is deferred, we don't end up getting error in request the
1330 * memory region the next time probe is called.
1331 */
1332 res->start -= DWC3_GLOBALS_REGS_START;
Felipe Balbi72246da2011-08-19 18:10:58 +03001333
Felipe Balbidc99f162014-09-03 16:13:37 -05001334 dwc3_debugfs_exit(dwc);
1335 dwc3_core_exit_mode(dwc);
Kishon Vijay Abraham I8ba007a2013-01-25 08:30:54 +05301336
Felipe Balbi72246da2011-08-19 18:10:58 +03001337 dwc3_core_exit(dwc);
Heikki Krogerus88bc9d12015-05-13 15:26:51 +03001338 dwc3_ulpi_exit(dwc);
Felipe Balbi72246da2011-08-19 18:10:58 +03001339
Felipe Balbifc8bb912016-05-16 13:14:48 +03001340 pm_runtime_put_sync(&pdev->dev);
1341 pm_runtime_allow(&pdev->dev);
1342 pm_runtime_disable(&pdev->dev);
1343
Felipe Balbic499ff72016-05-16 10:49:01 +03001344 dwc3_free_event_buffers(dwc);
1345 dwc3_free_scratch_buffers(dwc);
1346
Felipe Balbi72246da2011-08-19 18:10:58 +03001347 return 0;
1348}
1349
Felipe Balbifc8bb912016-05-16 13:14:48 +03001350#ifdef CONFIG_PM
1351static int dwc3_suspend_common(struct dwc3 *dwc)
Felipe Balbi7415f172012-04-30 14:56:33 +03001352{
Felipe Balbifc8bb912016-05-16 13:14:48 +03001353 unsigned long flags;
Felipe Balbi7415f172012-04-30 14:56:33 +03001354
Ruchika Kharwara45c82b82013-07-06 07:52:49 -05001355 switch (dwc->dr_mode) {
1356 case USB_DR_MODE_PERIPHERAL:
1357 case USB_DR_MODE_OTG:
Felipe Balbifc8bb912016-05-16 13:14:48 +03001358 spin_lock_irqsave(&dwc->lock, flags);
Felipe Balbi7415f172012-04-30 14:56:33 +03001359 dwc3_gadget_suspend(dwc);
Felipe Balbifc8bb912016-05-16 13:14:48 +03001360 spin_unlock_irqrestore(&dwc->lock, flags);
Felipe Balbi51f5d492016-05-16 10:52:58 +03001361 break;
Ruchika Kharwara45c82b82013-07-06 07:52:49 -05001362 case USB_DR_MODE_HOST:
Felipe Balbi7415f172012-04-30 14:56:33 +03001363 default:
Felipe Balbi51f5d492016-05-16 10:52:58 +03001364 /* do nothing */
Felipe Balbi7415f172012-04-30 14:56:33 +03001365 break;
1366 }
1367
Felipe Balbi51f5d492016-05-16 10:52:58 +03001368 dwc3_core_exit(dwc);
Felipe Balbi5c4ad3182016-04-11 17:12:34 +03001369
Felipe Balbifc8bb912016-05-16 13:14:48 +03001370 return 0;
1371}
1372
1373static int dwc3_resume_common(struct dwc3 *dwc)
1374{
1375 unsigned long flags;
1376 int ret;
1377
1378 ret = dwc3_core_init(dwc);
1379 if (ret)
1380 return ret;
1381
1382 switch (dwc->dr_mode) {
1383 case USB_DR_MODE_PERIPHERAL:
1384 case USB_DR_MODE_OTG:
1385 spin_lock_irqsave(&dwc->lock, flags);
1386 dwc3_gadget_resume(dwc);
1387 spin_unlock_irqrestore(&dwc->lock, flags);
1388 /* FALLTHROUGH */
1389 case USB_DR_MODE_HOST:
1390 default:
1391 /* do nothing */
1392 break;
1393 }
1394
1395 return 0;
1396}
1397
1398static int dwc3_runtime_checks(struct dwc3 *dwc)
1399{
1400 switch (dwc->dr_mode) {
1401 case USB_DR_MODE_PERIPHERAL:
1402 case USB_DR_MODE_OTG:
1403 if (dwc->connected)
1404 return -EBUSY;
1405 break;
1406 case USB_DR_MODE_HOST:
1407 default:
1408 /* do nothing */
1409 break;
1410 }
1411
1412 return 0;
1413}
1414
1415static int dwc3_runtime_suspend(struct device *dev)
1416{
1417 struct dwc3 *dwc = dev_get_drvdata(dev);
1418 int ret;
1419
Mayank Ranaa99689a2016-08-10 17:39:47 -07001420 /* Check if platform glue driver handling PM, if not then handle here */
1421 if (!dwc3_notify_event(dwc, DWC3_CORE_PM_RESUME_EVENT))
1422 return 0;
Felipe Balbifc8bb912016-05-16 13:14:48 +03001423
1424 ret = dwc3_suspend_common(dwc);
1425 if (ret)
1426 return ret;
1427
1428 device_init_wakeup(dev, true);
1429
1430 return 0;
1431}
1432
1433static int dwc3_runtime_resume(struct device *dev)
1434{
1435 struct dwc3 *dwc = dev_get_drvdata(dev);
1436 int ret;
1437
Mayank Ranaa99689a2016-08-10 17:39:47 -07001438 /* Check if platform glue driver handling PM, if not then handle here */
1439 if (!dwc3_notify_event(dwc, DWC3_CORE_PM_RESUME_EVENT))
1440 return 0;
1441
Felipe Balbifc8bb912016-05-16 13:14:48 +03001442 device_init_wakeup(dev, false);
1443
1444 ret = dwc3_resume_common(dwc);
1445 if (ret)
1446 return ret;
1447
1448 switch (dwc->dr_mode) {
1449 case USB_DR_MODE_PERIPHERAL:
1450 case USB_DR_MODE_OTG:
1451 dwc3_gadget_process_pending_events(dwc);
1452 break;
1453 case USB_DR_MODE_HOST:
1454 default:
1455 /* do nothing */
1456 break;
1457 }
1458
1459 pm_runtime_mark_last_busy(dev);
Felipe Balbib74c2d82016-07-28 13:07:07 +03001460 pm_runtime_put(dev);
Felipe Balbifc8bb912016-05-16 13:14:48 +03001461
1462 return 0;
1463}
1464
1465static int dwc3_runtime_idle(struct device *dev)
1466{
1467 struct dwc3 *dwc = dev_get_drvdata(dev);
1468
1469 switch (dwc->dr_mode) {
1470 case USB_DR_MODE_PERIPHERAL:
1471 case USB_DR_MODE_OTG:
1472 if (dwc3_runtime_checks(dwc))
1473 return -EBUSY;
1474 break;
1475 case USB_DR_MODE_HOST:
1476 default:
1477 /* do nothing */
1478 break;
1479 }
1480
1481 pm_runtime_mark_last_busy(dev);
1482 pm_runtime_autosuspend(dev);
1483
1484 return 0;
1485}
1486#endif /* CONFIG_PM */
1487
1488#ifdef CONFIG_PM_SLEEP
1489static int dwc3_suspend(struct device *dev)
1490{
1491 struct dwc3 *dwc = dev_get_drvdata(dev);
1492 int ret;
1493
1494 ret = dwc3_suspend_common(dwc);
1495 if (ret)
1496 return ret;
1497
Sekhar Nori63444752015-08-31 21:09:08 +05301498 pinctrl_pm_select_sleep_state(dev);
1499
Felipe Balbi7415f172012-04-30 14:56:33 +03001500 return 0;
1501}
1502
1503static int dwc3_resume(struct device *dev)
1504{
1505 struct dwc3 *dwc = dev_get_drvdata(dev);
Kishon Vijay Abraham I57303482014-03-03 17:08:11 +05301506 int ret;
Felipe Balbi7415f172012-04-30 14:56:33 +03001507
Sekhar Nori63444752015-08-31 21:09:08 +05301508 pinctrl_pm_select_default_state(dev);
1509
Felipe Balbifc8bb912016-05-16 13:14:48 +03001510 ret = dwc3_resume_common(dwc);
Felipe Balbi51f5d492016-05-16 10:52:58 +03001511 if (ret)
Felipe Balbi5c4ad3182016-04-11 17:12:34 +03001512 return ret;
1513
Felipe Balbi7415f172012-04-30 14:56:33 +03001514 pm_runtime_disable(dev);
1515 pm_runtime_set_active(dev);
1516 pm_runtime_enable(dev);
1517
1518 return 0;
1519}
Felipe Balbi7f370ed2016-05-09 15:27:01 +03001520#endif /* CONFIG_PM_SLEEP */
Felipe Balbi7415f172012-04-30 14:56:33 +03001521
1522static const struct dev_pm_ops dwc3_dev_pm_ops = {
Felipe Balbi7415f172012-04-30 14:56:33 +03001523 SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume)
Felipe Balbifc8bb912016-05-16 13:14:48 +03001524 SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume,
1525 dwc3_runtime_idle)
Felipe Balbi7415f172012-04-30 14:56:33 +03001526};
1527
Kishon Vijay Abraham I5088b6f2013-01-25 16:36:53 +05301528#ifdef CONFIG_OF
1529static const struct of_device_id of_dwc3_match[] = {
1530 {
Felipe Balbi22a5aa12013-07-02 21:20:24 +03001531 .compatible = "snps,dwc3"
1532 },
1533 {
Kishon Vijay Abraham I5088b6f2013-01-25 16:36:53 +05301534 .compatible = "synopsys,dwc3"
1535 },
1536 { },
1537};
1538MODULE_DEVICE_TABLE(of, of_dwc3_match);
1539#endif
1540
Heikki Krogerus404905a2014-09-25 10:57:02 +03001541#ifdef CONFIG_ACPI
1542
1543#define ACPI_ID_INTEL_BSW "808622B7"
1544
1545static const struct acpi_device_id dwc3_acpi_match[] = {
1546 { ACPI_ID_INTEL_BSW, 0 },
1547 { },
1548};
1549MODULE_DEVICE_TABLE(acpi, dwc3_acpi_match);
1550#endif
1551
Felipe Balbi72246da2011-08-19 18:10:58 +03001552static struct platform_driver dwc3_driver = {
1553 .probe = dwc3_probe,
Bill Pemberton76904172012-11-19 13:21:08 -05001554 .remove = dwc3_remove,
Felipe Balbi72246da2011-08-19 18:10:58 +03001555 .driver = {
1556 .name = "dwc3",
Kishon Vijay Abraham I5088b6f2013-01-25 16:36:53 +05301557 .of_match_table = of_match_ptr(of_dwc3_match),
Heikki Krogerus404905a2014-09-25 10:57:02 +03001558 .acpi_match_table = ACPI_PTR(dwc3_acpi_match),
Felipe Balbi7f370ed2016-05-09 15:27:01 +03001559 .pm = &dwc3_dev_pm_ops,
Felipe Balbi72246da2011-08-19 18:10:58 +03001560 },
Felipe Balbi72246da2011-08-19 18:10:58 +03001561};
1562
Tobias Klauserb1116dc2012-02-28 12:57:20 +01001563module_platform_driver(dwc3_driver);
1564
Sebastian Andrzej Siewior7ae4fc42011-10-19 19:39:50 +02001565MODULE_ALIAS("platform:dwc3");
Felipe Balbi72246da2011-08-19 18:10:58 +03001566MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
Felipe Balbi5945f782013-06-30 14:15:11 +03001567MODULE_LICENSE("GPL v2");
Felipe Balbi72246da2011-08-19 18:10:58 +03001568MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");