blob: f11322afc53c94811e66637e1e11ef5d04c9e7a9 [file] [log] [blame]
Greg Kroah-Hartman5fd54ac2017-11-03 11:28:30 +01001// SPDX-License-Identifier: GPL-2.0
Felipe Balbi72246da2011-08-19 18:10:58 +03002/**
3 * core.c - DesignWare USB3 DRD Controller Core file
4 *
5 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
Felipe Balbi72246da2011-08-19 18:10:58 +03006 *
7 * Authors: Felipe Balbi <balbi@ti.com>,
8 * Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Felipe Balbi72246da2011-08-19 18:10:58 +03009 */
10
Masahiro Yamadafe8abf32018-05-16 11:41:07 +090011#include <linux/clk.h>
Felipe Balbifa0ea132014-09-19 15:51:11 -050012#include <linux/version.h>
Felipe Balbia72e6582011-09-05 13:37:28 +030013#include <linux/module.h>
Felipe Balbi72246da2011-08-19 18:10:58 +030014#include <linux/kernel.h>
15#include <linux/slab.h>
16#include <linux/spinlock.h>
17#include <linux/platform_device.h>
18#include <linux/pm_runtime.h>
19#include <linux/interrupt.h>
20#include <linux/ioport.h>
21#include <linux/io.h>
22#include <linux/list.h>
23#include <linux/delay.h>
24#include <linux/dma-mapping.h>
Felipe Balbi457e84b2012-01-18 18:04:09 +020025#include <linux/of.h>
Heikki Krogerus404905a2014-09-25 10:57:02 +030026#include <linux/acpi.h>
Sekhar Nori63444752015-08-31 21:09:08 +053027#include <linux/pinctrl/consumer.h>
Masahiro Yamadafe8abf32018-05-16 11:41:07 +090028#include <linux/reset.h>
Felipe Balbi72246da2011-08-19 18:10:58 +030029
30#include <linux/usb/ch9.h>
31#include <linux/usb/gadget.h>
Felipe Balbif7e846f2013-06-30 14:29:51 +030032#include <linux/usb/of.h>
Ruchika Kharwara45c82b82013-07-06 07:52:49 -050033#include <linux/usb/otg.h>
Jack Pham62523502018-01-15 16:37:05 -080034#include <linux/irq.h>
Felipe Balbi72246da2011-08-19 18:10:58 +030035
36#include "core.h"
37#include "gadget.h"
38#include "io.h"
39
40#include "debug.h"
41
Jack Pham62523502018-01-15 16:37:05 -080042#define DWC3_DEFAULT_AUTOSUSPEND_DELAY 500 /* ms */
Felipe Balbi8300dd22011-10-18 13:54:01 +030043
Mayank Rana679f3322018-01-15 16:23:45 -080044static int count;
45static struct dwc3 *dwc3_instance[DWC_CTRL_COUNT];
46
Jack Pham62523502018-01-15 16:37:05 -080047static void dwc3_check_params(struct dwc3 *dwc);
Jack Pham62523502018-01-15 16:37:05 -080048
49void dwc3_usb3_phy_suspend(struct dwc3 *dwc, int suspend)
50{
51 u32 reg;
52
53 reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
54
55 if (suspend)
56 reg |= DWC3_GUSB3PIPECTL_SUSPHY;
57 else
58 reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
59
60 dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
61}
62
Thinh Nguyen9d6173e2016-09-06 19:22:03 -070063/**
64 * dwc3_get_dr_mode - Validates and sets dr_mode
65 * @dwc: pointer to our context structure
66 */
67static int dwc3_get_dr_mode(struct dwc3 *dwc)
68{
69 enum usb_dr_mode mode;
70 struct device *dev = dwc->dev;
71 unsigned int hw_mode;
72
Hemant Kumard4c4fb2d2018-09-21 17:38:18 -070073 if (dwc->dr_mode == USB_DR_MODE_UNKNOWN) {
74 if (dwc3_is_usb31(dwc))
75 dwc->dr_mode = USB_DR_MODE_DRD;
76 else
77 dwc->dr_mode = USB_DR_MODE_OTG;
78 }
Thinh Nguyen9d6173e2016-09-06 19:22:03 -070079
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;
Thinh Nguyena7700462018-07-26 13:52:11 -0700105
106 /*
107 * dwc_usb31 does not support OTG mode. If the controller
108 * supports DRD but the dr_mode is not specified or set to OTG,
109 * then set the mode to peripheral.
110 */
111 if (mode == USB_DR_MODE_OTG && dwc3_is_usb31(dwc))
112 mode = USB_DR_MODE_PERIPHERAL;
Thinh Nguyen9d6173e2016-09-06 19:22:03 -0700113 }
114
115 if (mode != dwc->dr_mode) {
116 dev_warn(dev,
117 "Configuration mismatch. dr_mode forced to %s\n",
118 mode == USB_DR_MODE_HOST ? "host" : "gadget");
119
120 dwc->dr_mode = mode;
121 }
122
123 return 0;
124}
125
Roger Quadrosf09cc792018-02-27 13:30:19 +0200126void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode)
Sebastian Andrzej Siewior3140e8cb2011-10-31 22:25:40 +0100127{
128 u32 reg;
129
130 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
131 reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
132 reg |= DWC3_GCTL_PRTCAPDIR(mode);
133 dwc3_writel(dwc->regs, DWC3_GCTL, reg);
Manu Gautamc4a51532018-01-18 16:54:30 +0530134
135 dwc->current_dr_role = mode;
Roger Quadros41ce1452017-04-04 12:49:18 +0300136}
Roger Quadros6b3261a2017-04-04 11:25:27 +0300137
Vamsi Krishna Samavedamd15258c2018-05-22 16:19:49 -0700138void dwc3_en_sleep_mode(struct dwc3 *dwc)
139{
140 u32 reg;
141
142 if (dwc->dis_enblslpm_quirk)
143 return;
144
145 reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
146 reg |= DWC3_GUSB2PHYCFG_ENBLSLPM;
147 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
148}
149
150void dwc3_dis_sleep_mode(struct dwc3 *dwc)
151{
152 u32 reg;
153
154 reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
155 reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
156 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
157}
158
Roger Quadros41ce1452017-04-04 12:49:18 +0300159void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
160{
161 unsigned long flags;
162
163 spin_lock_irqsave(&dwc->lock, flags);
164 dwc->desired_dr_role = mode;
165 spin_unlock_irqrestore(&dwc->lock, flags);
166
Roger Quadros084a8042018-02-27 12:41:41 +0200167 queue_work(system_freezable_wq, &dwc->drd_work);
Sebastian Andrzej Siewior3140e8cb2011-10-31 22:25:40 +0100168}
Felipe Balbi8300dd22011-10-18 13:54:01 +0300169
Felipe Balbicf6d8672016-04-14 15:03:39 +0300170u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type)
171{
172 struct dwc3 *dwc = dep->dwc;
173 u32 reg;
174
175 dwc3_writel(dwc->regs, DWC3_GDBGFIFOSPACE,
176 DWC3_GDBGFIFOSPACE_NUM(dep->number) |
177 DWC3_GDBGFIFOSPACE_TYPE(type));
178
179 reg = dwc3_readl(dwc->regs, DWC3_GDBGFIFOSPACE);
180
181 return DWC3_GDBGFIFOSPACE_SPACE_AVAILABLE(reg);
182}
183
Felipe Balbi72246da2011-08-19 18:10:58 +0300184/**
185 * dwc3_core_soft_reset - Issues core soft reset and PHY reset
186 * @dwc: pointer to our context structure
187 */
Kishon Vijay Abraham I57303482014-03-03 17:08:11 +0530188static int dwc3_core_soft_reset(struct dwc3 *dwc)
Felipe Balbi72246da2011-08-19 18:10:58 +0300189{
190 u32 reg;
Felipe Balbif59dcab2016-03-11 10:51:52 +0200191 int retries = 1000;
Kishon Vijay Abraham I57303482014-03-03 17:08:11 +0530192 int ret;
Felipe Balbi72246da2011-08-19 18:10:58 +0300193
Jack Pham7992ce52018-03-07 18:46:02 -0800194 /* Reset and initialize PHYs */
Jack Pham62523502018-01-15 16:37:05 -0800195 usb_phy_reset(dwc->usb2_phy);
Jack Pham62523502018-01-15 16:37:05 -0800196 ret = usb_phy_init(dwc->usb2_phy);
197 if (ret) {
198 pr_err("%s: usb_phy_init(dwc->usb2_phy) returned %d\n",
199 __func__, ret);
200 return ret;
201 }
202
Jack Pham7992ce52018-03-07 18:46:02 -0800203 if (dwc->maximum_speed <= USB_SPEED_HIGH)
Jack Pham62523502018-01-15 16:37:05 -0800204 goto generic_phy_init;
205
Jack Pham7992ce52018-03-07 18:46:02 -0800206 usb_phy_reset(dwc->usb3_phy);
Jack Pham62523502018-01-15 16:37:05 -0800207 ret = usb_phy_init(dwc->usb3_phy);
208 if (ret == -EBUSY) {
209 /*
210 * Setting Max speed as high when USB3 PHY initialiation
211 * is failing and USB superspeed can't be supported.
212 */
213 dwc->maximum_speed = USB_SPEED_HIGH;
214 } else if (ret) {
215 pr_err("%s: usb_phy_init(dwc->usb3_phy) returned %d\n",
216 __func__, ret);
217 return ret;
218 }
219
220generic_phy_init:
Kishon Vijay Abraham I57303482014-03-03 17:08:11 +0530221 ret = phy_init(dwc->usb2_generic_phy);
222 if (ret < 0)
223 return ret;
224
225 ret = phy_init(dwc->usb3_generic_phy);
226 if (ret < 0) {
227 phy_exit(dwc->usb2_generic_phy);
228 return ret;
229 }
Felipe Balbi72246da2011-08-19 18:10:58 +0300230
Felipe Balbif59dcab2016-03-11 10:51:52 +0200231 /*
232 * We're resetting only the device side because, if we're in host mode,
233 * XHCI driver will reset the host block. If dwc3 was configured for
234 * host-only mode, then we can return early.
235 */
Manu Gautamc4a51532018-01-18 16:54:30 +0530236 if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST)
Felipe Balbif59dcab2016-03-11 10:51:52 +0200237 return 0;
Felipe Balbi72246da2011-08-19 18:10:58 +0300238
Felipe Balbif59dcab2016-03-11 10:51:52 +0200239 reg = dwc3_readl(dwc->regs, DWC3_DCTL);
240 reg |= DWC3_DCTL_CSFTRST;
241 dwc3_writel(dwc->regs, DWC3_DCTL, reg);
Felipe Balbi72246da2011-08-19 18:10:58 +0300242
Felipe Balbif59dcab2016-03-11 10:51:52 +0200243 do {
244 reg = dwc3_readl(dwc->regs, DWC3_DCTL);
245 if (!(reg & DWC3_DCTL_CSFTRST))
Thinh Nguyenfab38332018-03-16 15:33:48 -0700246 goto done;
Pratyush Anand45627ac2012-06-21 17:44:28 +0530247
Felipe Balbif59dcab2016-03-11 10:51:52 +0200248 udelay(1);
249 } while (--retries);
Kishon Vijay Abraham I57303482014-03-03 17:08:11 +0530250
Brian Norris00b42172018-01-17 13:22:49 -0800251 phy_exit(dwc->usb3_generic_phy);
252 phy_exit(dwc->usb2_generic_phy);
253
Felipe Balbif59dcab2016-03-11 10:51:52 +0200254 return -ETIMEDOUT;
Thinh Nguyenfab38332018-03-16 15:33:48 -0700255
256done:
257 /*
258 * For DWC_usb31 controller, once DWC3_DCTL_CSFTRST bit is cleared,
259 * we must wait at least 50ms before accessing the PHY domain
260 * (synchronization delay). DWC_usb31 programming guide section 1.3.2.
261 */
262 if (dwc3_is_usb31(dwc))
263 msleep(50);
264
265 return 0;
Felipe Balbi72246da2011-08-19 18:10:58 +0300266}
267
Masahiro Yamadafe8abf32018-05-16 11:41:07 +0900268static const struct clk_bulk_data dwc3_core_clks[] = {
269 { .id = "ref" },
270 { .id = "bus_early" },
271 { .id = "suspend" },
272};
273
Nikhil Badoladb2be4e2015-09-04 10:15:58 +0530274/*
275 * dwc3_frame_length_adjustment - Adjusts frame length if required
276 * @dwc3: Pointer to our controller context structure
Nikhil Badoladb2be4e2015-09-04 10:15:58 +0530277 */
Felipe Balbibcdb3272016-05-16 10:42:23 +0300278static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
Nikhil Badoladb2be4e2015-09-04 10:15:58 +0530279{
280 u32 reg;
281 u32 dft;
282
283 if (dwc->revision < DWC3_REVISION_250A)
284 return;
285
Felipe Balbibcdb3272016-05-16 10:42:23 +0300286 if (dwc->fladj == 0)
Nikhil Badoladb2be4e2015-09-04 10:15:58 +0530287 return;
288
289 reg = dwc3_readl(dwc->regs, DWC3_GFLADJ);
290 dft = reg & DWC3_GFLADJ_30MHZ_MASK;
Felipe Balbibcdb3272016-05-16 10:42:23 +0300291 if (!dev_WARN_ONCE(dwc->dev, dft == dwc->fladj,
Nikhil Badoladb2be4e2015-09-04 10:15:58 +0530292 "request value same as default, ignoring\n")) {
293 reg &= ~DWC3_GFLADJ_30MHZ_MASK;
Felipe Balbibcdb3272016-05-16 10:42:23 +0300294 reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | dwc->fladj;
Nikhil Badoladb2be4e2015-09-04 10:15:58 +0530295 dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
296 }
297}
298
Heikki Krogerusc5cc74e2015-05-13 15:26:47 +0300299/**
Felipe Balbi72246da2011-08-19 18:10:58 +0300300 * dwc3_free_one_event_buffer - Frees one event buffer
301 * @dwc: Pointer to our controller context structure
302 * @evt: Pointer to event buffer to be freed
303 */
304static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
305 struct dwc3_event_buffer *evt)
306{
Arnd Bergmannd64ff402016-11-17 17:13:47 +0530307 dma_free_coherent(dwc->sysdev, evt->length, evt->buf, evt->dma);
Felipe Balbi72246da2011-08-19 18:10:58 +0300308}
309
310/**
Paul Zimmerman1d046792012-02-15 18:56:56 -0800311 * dwc3_alloc_one_event_buffer - Allocates one event buffer structure
Felipe Balbi72246da2011-08-19 18:10:58 +0300312 * @dwc: Pointer to our controller context structure
313 * @length: size of the event buffer
314 *
Paul Zimmerman1d046792012-02-15 18:56:56 -0800315 * Returns a pointer to the allocated event buffer structure on success
Felipe Balbi72246da2011-08-19 18:10:58 +0300316 * otherwise ERR_PTR(errno).
317 */
Felipe Balbi67d0b502013-02-22 16:31:07 +0200318static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc,
319 unsigned length)
Felipe Balbi72246da2011-08-19 18:10:58 +0300320{
321 struct dwc3_event_buffer *evt;
322
Felipe Balbi380f0d22012-10-11 13:48:36 +0300323 evt = devm_kzalloc(dwc->dev, sizeof(*evt), GFP_KERNEL);
Felipe Balbi72246da2011-08-19 18:10:58 +0300324 if (!evt)
325 return ERR_PTR(-ENOMEM);
326
327 evt->dwc = dwc;
328 evt->length = length;
John Yound9fa4c62016-11-15 12:54:15 +0200329 evt->cache = devm_kzalloc(dwc->dev, length, GFP_KERNEL);
330 if (!evt->cache)
331 return ERR_PTR(-ENOMEM);
332
Arnd Bergmannd64ff402016-11-17 17:13:47 +0530333 evt->buf = dma_alloc_coherent(dwc->sysdev, length,
Felipe Balbi72246da2011-08-19 18:10:58 +0300334 &evt->dma, GFP_KERNEL);
Felipe Balbie32672f2012-11-08 15:26:41 +0200335 if (!evt->buf)
Felipe Balbi72246da2011-08-19 18:10:58 +0300336 return ERR_PTR(-ENOMEM);
Felipe Balbi72246da2011-08-19 18:10:58 +0300337
338 return evt;
339}
340
341/**
342 * dwc3_free_event_buffers - frees all allocated event buffers
343 * @dwc: Pointer to our controller context structure
344 */
345static void dwc3_free_event_buffers(struct dwc3 *dwc)
346{
347 struct dwc3_event_buffer *evt;
Felipe Balbi72246da2011-08-19 18:10:58 +0300348
Felipe Balbi696c8b12016-03-30 09:37:03 +0300349 evt = dwc->ev_buf;
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300350 if (evt)
351 dwc3_free_one_event_buffer(dwc, evt);
Jack Pham62523502018-01-15 16:37:05 -0800352
353 /* free GSI related event buffers */
Vijayavardhan Vennapusa6a0290f2018-07-20 10:51:27 -0700354 dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_FREE, 0);
Felipe Balbi72246da2011-08-19 18:10:58 +0300355}
356
357/**
358 * dwc3_alloc_event_buffers - Allocates @num event buffers of size @length
Paul Zimmerman1d046792012-02-15 18:56:56 -0800359 * @dwc: pointer to our controller context structure
Felipe Balbi72246da2011-08-19 18:10:58 +0300360 * @length: size of event buffer
361 *
Paul Zimmerman1d046792012-02-15 18:56:56 -0800362 * Returns 0 on success otherwise negative errno. In the error case, dwc
Felipe Balbi72246da2011-08-19 18:10:58 +0300363 * may contain some buffers allocated but not all which were requested.
364 */
Bill Pemberton41ac7b32012-11-19 13:21:48 -0500365static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
Felipe Balbi72246da2011-08-19 18:10:58 +0300366{
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300367 struct dwc3_event_buffer *evt;
Felipe Balbi72246da2011-08-19 18:10:58 +0300368
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300369 evt = dwc3_alloc_one_event_buffer(dwc, length);
370 if (IS_ERR(evt)) {
371 dev_err(dwc->dev, "can't allocate event buffer\n");
372 return PTR_ERR(evt);
Felipe Balbi72246da2011-08-19 18:10:58 +0300373 }
Felipe Balbi696c8b12016-03-30 09:37:03 +0300374 dwc->ev_buf = evt;
Felipe Balbi72246da2011-08-19 18:10:58 +0300375
Jack Pham62523502018-01-15 16:37:05 -0800376 /* alloc GSI related event buffers */
Vijayavardhan Vennapusa6a0290f2018-07-20 10:51:27 -0700377 dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_ALLOC, 0);
Felipe Balbi72246da2011-08-19 18:10:58 +0300378 return 0;
379}
380
381/**
382 * dwc3_event_buffers_setup - setup our allocated event buffers
Paul Zimmerman1d046792012-02-15 18:56:56 -0800383 * @dwc: pointer to our controller context structure
Felipe Balbi72246da2011-08-19 18:10:58 +0300384 *
385 * Returns 0 on success otherwise negative errno.
386 */
Roger Quadrosf09cc792018-02-27 13:30:19 +0200387int dwc3_event_buffers_setup(struct dwc3 *dwc)
Felipe Balbi72246da2011-08-19 18:10:58 +0300388{
389 struct dwc3_event_buffer *evt;
Felipe Balbi72246da2011-08-19 18:10:58 +0300390
Felipe Balbi696c8b12016-03-30 09:37:03 +0300391 evt = dwc->ev_buf;
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300392 evt->lpos = 0;
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300393 dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0),
394 lower_32_bits(evt->dma));
395 dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0),
396 upper_32_bits(evt->dma));
397 dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0),
398 DWC3_GEVNTSIZ_SIZE(evt->length));
399 dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
Felipe Balbi72246da2011-08-19 18:10:58 +0300400
Jack Pham62523502018-01-15 16:37:05 -0800401 /* setup GSI related event buffers */
Vijayavardhan Vennapusa6a0290f2018-07-20 10:51:27 -0700402 dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_SETUP, 0);
Felipe Balbi72246da2011-08-19 18:10:58 +0300403 return 0;
404}
405
Roger Quadrosf09cc792018-02-27 13:30:19 +0200406void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
Felipe Balbi72246da2011-08-19 18:10:58 +0300407{
408 struct dwc3_event_buffer *evt;
Felipe Balbi72246da2011-08-19 18:10:58 +0300409
Felipe Balbi696c8b12016-03-30 09:37:03 +0300410 evt = dwc->ev_buf;
Paul Zimmerman7acd85e2012-04-27 14:28:02 +0300411
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300412 evt->lpos = 0;
Paul Zimmerman7acd85e2012-04-27 14:28:02 +0300413
Felipe Balbi660e9bd2016-03-30 09:26:24 +0300414 dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0), 0);
415 dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), 0);
416 dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK
417 | DWC3_GEVNTSIZ_SIZE(0));
418 dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
Jack Pham62523502018-01-15 16:37:05 -0800419
420 /* cleanup GSI related event buffers */
Vijayavardhan Vennapusa6a0290f2018-07-20 10:51:27 -0700421 dwc3_notify_event(dwc, DWC3_GSI_EVT_BUF_CLEANUP, 0);
Felipe Balbi72246da2011-08-19 18:10:58 +0300422}
423
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600424static int dwc3_alloc_scratch_buffers(struct dwc3 *dwc)
425{
426 if (!dwc->has_hibernation)
427 return 0;
428
429 if (!dwc->nr_scratch)
430 return 0;
431
432 dwc->scratchbuf = kmalloc_array(dwc->nr_scratch,
433 DWC3_SCRATCHBUF_SIZE, GFP_KERNEL);
434 if (!dwc->scratchbuf)
435 return -ENOMEM;
436
437 return 0;
438}
439
440static int dwc3_setup_scratch_buffers(struct dwc3 *dwc)
441{
442 dma_addr_t scratch_addr;
443 u32 param;
444 int ret;
445
446 if (!dwc->has_hibernation)
447 return 0;
448
449 if (!dwc->nr_scratch)
450 return 0;
451
452 /* should never fall here */
453 if (!WARN_ON(dwc->scratchbuf))
454 return 0;
455
Arnd Bergmannd64ff402016-11-17 17:13:47 +0530456 scratch_addr = dma_map_single(dwc->sysdev, dwc->scratchbuf,
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600457 dwc->nr_scratch * DWC3_SCRATCHBUF_SIZE,
458 DMA_BIDIRECTIONAL);
Arnd Bergmannd64ff402016-11-17 17:13:47 +0530459 if (dma_mapping_error(dwc->sysdev, scratch_addr)) {
460 dev_err(dwc->sysdev, "failed to map scratch buffer\n");
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600461 ret = -EFAULT;
462 goto err0;
463 }
464
465 dwc->scratch_addr = scratch_addr;
466
467 param = lower_32_bits(scratch_addr);
468
469 ret = dwc3_send_gadget_generic_command(dwc,
470 DWC3_DGCMD_SET_SCRATCHPAD_ADDR_LO, param);
471 if (ret < 0)
472 goto err1;
473
474 param = upper_32_bits(scratch_addr);
475
476 ret = dwc3_send_gadget_generic_command(dwc,
477 DWC3_DGCMD_SET_SCRATCHPAD_ADDR_HI, param);
478 if (ret < 0)
479 goto err1;
480
481 return 0;
482
483err1:
Arnd Bergmannd64ff402016-11-17 17:13:47 +0530484 dma_unmap_single(dwc->sysdev, dwc->scratch_addr, dwc->nr_scratch *
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600485 DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL);
486
487err0:
488 return ret;
489}
490
491static void dwc3_free_scratch_buffers(struct dwc3 *dwc)
492{
493 if (!dwc->has_hibernation)
494 return;
495
496 if (!dwc->nr_scratch)
497 return;
498
499 /* should never fall here */
500 if (!WARN_ON(dwc->scratchbuf))
501 return;
502
Arnd Bergmannd64ff402016-11-17 17:13:47 +0530503 dma_unmap_single(dwc->sysdev, dwc->scratch_addr, dwc->nr_scratch *
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600504 DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL);
505 kfree(dwc->scratchbuf);
506}
507
Felipe Balbi789451f62011-05-05 15:53:10 +0300508static void dwc3_core_num_eps(struct dwc3 *dwc)
509{
510 struct dwc3_hwparams *parms = &dwc->hwparams;
511
Bryan O'Donoghue47d39462017-01-31 20:58:10 +0000512 dwc->num_eps = DWC3_NUM_EPS(parms);
Felipe Balbi789451f62011-05-05 15:53:10 +0300513}
514
Bill Pemberton41ac7b32012-11-19 13:21:48 -0500515static void dwc3_cache_hwparams(struct dwc3 *dwc)
Felipe Balbi26ceca92011-09-30 10:58:49 +0300516{
517 struct dwc3_hwparams *parms = &dwc->hwparams;
518
519 parms->hwparams0 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS0);
520 parms->hwparams1 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS1);
521 parms->hwparams2 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS2);
522 parms->hwparams3 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS3);
523 parms->hwparams4 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS4);
524 parms->hwparams5 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS5);
525 parms->hwparams6 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
526 parms->hwparams7 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS7);
527 parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8);
528}
529
Roger Quadros98112042018-02-12 15:30:08 +0200530static int dwc3_core_ulpi_init(struct dwc3 *dwc)
531{
532 int intf;
533 int ret = 0;
534
535 intf = DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3);
536
537 if (intf == DWC3_GHWPARAMS3_HSPHY_IFC_ULPI ||
538 (intf == DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI &&
539 dwc->hsphy_interface &&
540 !strncmp(dwc->hsphy_interface, "ulpi", 4)))
541 ret = dwc3_ulpi_init(dwc);
542
543 return ret;
544}
545
Felipe Balbi72246da2011-08-19 18:10:58 +0300546/**
Huang Ruib5a65c42014-10-28 19:54:28 +0800547 * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core
548 * @dwc: Pointer to our controller context structure
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300549 *
550 * Returns 0 on success. The USB PHY interfaces are configured but not
551 * initialized. The PHY interfaces and the PHYs get initialized together with
552 * the core in dwc3_core_init.
Huang Ruib5a65c42014-10-28 19:54:28 +0800553 */
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300554static int dwc3_phy_setup(struct dwc3 *dwc)
Huang Ruib5a65c42014-10-28 19:54:28 +0800555{
556 u32 reg;
557
558 reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
559
Huang Rui2164a472014-10-28 19:54:35 +0800560 /*
Felipe Balbi1966b862016-08-03 14:16:15 +0300561 * Make sure UX_EXIT_PX is cleared as that causes issues with some
562 * PHYs. Also, this bit is not supposed to be used in normal operation.
563 */
564 reg &= ~DWC3_GUSB3PIPECTL_UX_EXIT_PX;
565
566 /*
Huang Rui2164a472014-10-28 19:54:35 +0800567 * Above 1.94a, it is recommended to set DWC3_GUSB3PIPECTL_SUSPHY
568 * to '0' during coreConsultant configuration. So default value
569 * will be '0' when the core is reset. Application needs to set it
570 * to '1' after the core initialization is completed.
571 */
572 if (dwc->revision > DWC3_REVISION_194A)
573 reg |= DWC3_GUSB3PIPECTL_SUSPHY;
574
Huang Ruib5a65c42014-10-28 19:54:28 +0800575 if (dwc->u2ss_inp3_quirk)
576 reg |= DWC3_GUSB3PIPECTL_U2SSINP3OK;
577
Rajesh Bhagate58dd352016-03-14 14:40:50 +0530578 if (dwc->dis_rxdet_inp3_quirk)
579 reg |= DWC3_GUSB3PIPECTL_DISRXDETINP3;
580
Huang Ruidf31f5b2014-10-28 19:54:29 +0800581 if (dwc->req_p1p2p3_quirk)
582 reg |= DWC3_GUSB3PIPECTL_REQP1P2P3;
583
Huang Ruia2a1d0f2014-10-28 19:54:30 +0800584 if (dwc->del_p1p2p3_quirk)
585 reg |= DWC3_GUSB3PIPECTL_DEP1P2P3_EN;
586
Huang Rui41c06ff2014-10-28 19:54:31 +0800587 if (dwc->del_phy_power_chg_quirk)
588 reg |= DWC3_GUSB3PIPECTL_DEPOCHANGE;
589
Huang Ruifb67afc2014-10-28 19:54:32 +0800590 if (dwc->lfps_filter_quirk)
591 reg |= DWC3_GUSB3PIPECTL_LFPSFILT;
592
Huang Rui14f4ac52014-10-28 19:54:33 +0800593 if (dwc->rx_detect_poll_quirk)
594 reg |= DWC3_GUSB3PIPECTL_RX_DETOPOLL;
595
Huang Rui6b6a0c92014-10-31 11:11:12 +0800596 if (dwc->tx_de_emphasis_quirk)
597 reg |= DWC3_GUSB3PIPECTL_TX_DEEPH(dwc->tx_de_emphasis);
598
Felipe Balbicd72f892014-11-06 11:31:00 -0600599 if (dwc->dis_u3_susphy_quirk)
Huang Rui59acfa22014-10-31 11:11:13 +0800600 reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
601
William Wu00fe0812016-08-16 22:44:39 +0800602 if (dwc->dis_del_phy_power_chg_quirk)
603 reg &= ~DWC3_GUSB3PIPECTL_DEPOCHANGE;
604
Mayank Rana50980932018-03-28 15:29:01 -0700605 if (dwc->ssp_u3_u0_quirk)
606 reg |= (DWC3_GUSB3PIPECTL_UX_EXIT_PX |
607 DWC3_GUSB3PIPECTL_P3EXSIGP2);
608
Huang Ruib5a65c42014-10-28 19:54:28 +0800609 dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
610
Huang Rui2164a472014-10-28 19:54:35 +0800611 reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
612
Heikki Krogerus3e10a2c2015-05-13 15:26:49 +0300613 /* Select the HS PHY interface */
614 switch (DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3)) {
615 case DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI:
Felipe Balbi43cacb02015-07-01 22:03:09 -0500616 if (dwc->hsphy_interface &&
617 !strncmp(dwc->hsphy_interface, "utmi", 4)) {
Heikki Krogerus3e10a2c2015-05-13 15:26:49 +0300618 reg &= ~DWC3_GUSB2PHYCFG_ULPI_UTMI;
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300619 break;
Felipe Balbi43cacb02015-07-01 22:03:09 -0500620 } else if (dwc->hsphy_interface &&
621 !strncmp(dwc->hsphy_interface, "ulpi", 4)) {
Heikki Krogerus3e10a2c2015-05-13 15:26:49 +0300622 reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI;
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300623 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
Heikki Krogerus3e10a2c2015-05-13 15:26:49 +0300624 } else {
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300625 /* Relying on default value. */
626 if (!(reg & DWC3_GUSB2PHYCFG_ULPI_UTMI))
627 break;
Heikki Krogerus3e10a2c2015-05-13 15:26:49 +0300628 }
629 /* FALLTHROUGH */
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300630 case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI:
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300631 /* FALLTHROUGH */
Heikki Krogerus3e10a2c2015-05-13 15:26:49 +0300632 default:
633 break;
634 }
635
William Wu32f2ed82016-08-16 22:44:38 +0800636 switch (dwc->hsphy_mode) {
637 case USBPHY_INTERFACE_MODE_UTMI:
638 reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
639 DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
640 reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_8_BIT) |
641 DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_8_BIT);
642 break;
643 case USBPHY_INTERFACE_MODE_UTMIW:
644 reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
645 DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
646 reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_16_BIT) |
647 DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_16_BIT);
648 break;
649 default:
650 break;
651 }
652
Huang Rui2164a472014-10-28 19:54:35 +0800653 /*
654 * Above 1.94a, it is recommended to set DWC3_GUSB2PHYCFG_SUSPHY to
655 * '0' during coreConsultant configuration. So default value will
656 * be '0' when the core is reset. Application needs to set it to
657 * '1' after the core initialization is completed.
658 */
659 if (dwc->revision > DWC3_REVISION_194A)
660 reg |= DWC3_GUSB2PHYCFG_SUSPHY;
661
Felipe Balbicd72f892014-11-06 11:31:00 -0600662 if (dwc->dis_u2_susphy_quirk)
Huang Rui0effe0a2014-10-31 11:11:14 +0800663 reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
664
John Younec791d12015-10-02 20:30:57 -0700665 if (dwc->dis_enblslpm_quirk)
666 reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
667
William Wu16199f32016-08-16 22:44:37 +0800668 if (dwc->dis_u2_freeclk_exists_quirk)
669 reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS;
670
Huang Rui2164a472014-10-28 19:54:35 +0800671 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
Heikki Krogerus88bc9d12015-05-13 15:26:51 +0300672
673 return 0;
Huang Ruib5a65c42014-10-28 19:54:28 +0800674}
675
Felipe Balbic499ff72016-05-16 10:49:01 +0300676static void dwc3_core_exit(struct dwc3 *dwc)
677{
678 dwc3_event_buffers_cleanup(dwc);
679
680 usb_phy_shutdown(dwc->usb2_phy);
681 usb_phy_shutdown(dwc->usb3_phy);
682 phy_exit(dwc->usb2_generic_phy);
683 phy_exit(dwc->usb3_generic_phy);
684
685 usb_phy_set_suspend(dwc->usb2_phy, 1);
686 usb_phy_set_suspend(dwc->usb3_phy, 1);
687 phy_power_off(dwc->usb2_generic_phy);
688 phy_power_off(dwc->usb3_generic_phy);
Masahiro Yamadafe8abf32018-05-16 11:41:07 +0900689 clk_bulk_disable(dwc->num_clks, dwc->clks);
690 clk_bulk_unprepare(dwc->num_clks, dwc->clks);
691 reset_control_assert(dwc->reset);
Felipe Balbic499ff72016-05-16 10:49:01 +0300692}
693
Felipe Balbi07599562016-10-14 16:19:01 +0300694static bool dwc3_core_is_valid(struct dwc3 *dwc)
Felipe Balbi72246da2011-08-19 18:10:58 +0300695{
Felipe Balbi07599562016-10-14 16:19:01 +0300696 u32 reg;
Felipe Balbi72246da2011-08-19 18:10:58 +0300697
Sebastian Andrzej Siewior7650bd72011-08-29 13:56:36 +0200698 reg = dwc3_readl(dwc->regs, DWC3_GSNPSID);
Felipe Balbi07599562016-10-14 16:19:01 +0300699
Sebastian Andrzej Siewior7650bd72011-08-29 13:56:36 +0200700 /* This should read as U3 followed by revision number */
John Youn690fb372015-09-04 19:15:10 -0700701 if ((reg & DWC3_GSNPSID_MASK) == 0x55330000) {
702 /* Detected DWC_usb3 IP */
703 dwc->revision = reg;
704 } else if ((reg & DWC3_GSNPSID_MASK) == 0x33310000) {
705 /* Detected DWC_usb31 IP */
706 dwc->revision = dwc3_readl(dwc->regs, DWC3_VER_NUMBER);
707 dwc->revision |= DWC3_REVISION_IS_DWC31;
Vamsi Krishna Samavedam4ee3d5a2018-05-08 23:39:51 -0700708 dwc->versiontype = dwc3_readl(dwc->regs, DWC3_VER_TYPE);
John Youn690fb372015-09-04 19:15:10 -0700709 } else {
Felipe Balbi07599562016-10-14 16:19:01 +0300710 return false;
Sebastian Andrzej Siewior7650bd72011-08-29 13:56:36 +0200711 }
Sebastian Andrzej Siewior7650bd72011-08-29 13:56:36 +0200712
Felipe Balbi07599562016-10-14 16:19:01 +0300713 return true;
714}
Felipe Balbifa0ea132014-09-19 15:51:11 -0500715
Felipe Balbi941f9182016-10-14 16:23:24 +0300716static void dwc3_core_setup_global_control(struct dwc3 *dwc)
Felipe Balbi72246da2011-08-19 18:10:58 +0300717{
Felipe Balbi941f9182016-10-14 16:23:24 +0300718 u32 hwparams4 = dwc->hwparams.hwparams4;
719 u32 reg;
Felipe Balbic499ff72016-05-16 10:49:01 +0300720
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100721 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
Paul Zimmerman3e87c422012-02-24 17:32:13 -0800722 reg &= ~DWC3_GCTL_SCALEDOWN_MASK;
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100723
Sebastian Andrzej Siewior164d7732011-11-24 11:22:05 +0100724 switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1)) {
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100725 case DWC3_GHWPARAMS1_EN_PWROPT_CLK:
Felipe Balbi32a4a132014-02-25 14:00:13 -0600726 /**
727 * WORKAROUND: DWC3 revisions between 2.10a and 2.50a have an
728 * issue which would cause xHCI compliance tests to fail.
729 *
730 * Because of that we cannot enable clock gating on such
731 * configurations.
732 *
733 * Refers to:
734 *
735 * STAR#9000588375: Clock Gating, SOF Issues when ref_clk-Based
736 * SOF/ITP Mode Used
737 */
738 if ((dwc->dr_mode == USB_DR_MODE_HOST ||
Hemant Kumard4c4fb2d2018-09-21 17:38:18 -0700739 dwc3_is_otg_or_drd(dwc)) &&
Felipe Balbi32a4a132014-02-25 14:00:13 -0600740 (dwc->revision >= DWC3_REVISION_210A &&
741 dwc->revision <= DWC3_REVISION_250A))
742 reg |= DWC3_GCTL_DSBLCLKGTNG | DWC3_GCTL_SOFITPSYNC;
743 else
744 reg &= ~DWC3_GCTL_DSBLCLKGTNG;
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100745 break;
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600746 case DWC3_GHWPARAMS1_EN_PWROPT_HIB:
747 /* enable hibernation here */
748 dwc->nr_scratch = DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(hwparams4);
Huang Rui2eac3992014-10-28 19:54:22 +0800749
750 /*
751 * REVISIT Enabling this bit so that host-mode hibernation
752 * will work. Device-mode hibernation is not yet implemented.
753 */
754 reg |= DWC3_GCTL_GBLHIBERNATIONEN;
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600755 break;
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100756 default:
Felipe Balbi5eb30ce2016-11-03 14:07:51 +0200757 /* nothing */
758 break;
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100759 }
760
Huang Rui946bd572014-10-28 19:54:23 +0800761 /* check if current dwc3 is on simulation board */
762 if (dwc->hwparams.hwparams6 & DWC3_GHWPARAMS6_EN_FPGA) {
Felipe Balbi5eb30ce2016-11-03 14:07:51 +0200763 dev_info(dwc->dev, "Running with FPGA optmizations\n");
Huang Rui946bd572014-10-28 19:54:23 +0800764 dwc->is_fpga = true;
765 }
766
Huang Rui3b812212014-10-28 19:54:25 +0800767 WARN_ONCE(dwc->disable_scramble_quirk && !dwc->is_fpga,
768 "disable_scramble cannot be used on non-FPGA builds\n");
769
770 if (dwc->disable_scramble_quirk && dwc->is_fpga)
771 reg |= DWC3_GCTL_DISSCRAMBLE;
772 else
773 reg &= ~DWC3_GCTL_DISSCRAMBLE;
774
Huang Rui9a5b2f32014-10-28 19:54:27 +0800775 if (dwc->u2exit_lfps_quirk)
776 reg |= DWC3_GCTL_U2EXIT_LFPS;
777
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100778 /*
779 * WORKAROUND: DWC3 revisions <1.90a have a bug
Paul Zimmerman1d046792012-02-15 18:56:56 -0800780 * where the device can fail to connect at SuperSpeed
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100781 * and falls back to high-speed mode which causes
Paul Zimmerman1d046792012-02-15 18:56:56 -0800782 * the device to enter a Connect/Disconnect loop
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100783 */
784 if (dwc->revision < DWC3_REVISION_190A)
785 reg |= DWC3_GCTL_U2RSTECN;
786
Mayank Ranab39f3fd2018-05-16 09:39:33 -0700787 if (dwc->disable_clk_gating)
788 reg |= DWC3_GCTL_DSBLCLKGTNG;
789
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100790 dwc3_writel(dwc->regs, DWC3_GCTL, reg);
Felipe Balbi941f9182016-10-14 16:23:24 +0300791}
Sebastian Andrzej Siewior4878a022011-10-31 22:25:41 +0100792
Felipe Balbif54edb52017-06-05 17:03:18 +0300793static int dwc3_core_get_phy(struct dwc3 *dwc);
Roger Quadros98112042018-02-12 15:30:08 +0200794static int dwc3_core_ulpi_init(struct dwc3 *dwc);
Felipe Balbif54edb52017-06-05 17:03:18 +0300795
Pengbo Mud9612c22018-07-23 18:32:37 +0800796/* set global incr burst type configuration registers */
797static void dwc3_set_incr_burst_type(struct dwc3 *dwc)
798{
799 struct device *dev = dwc->dev;
800 /* incrx_mode : for INCR burst type. */
801 bool incrx_mode;
802 /* incrx_size : for size of INCRX burst. */
803 u32 incrx_size;
804 u32 *vals;
805 u32 cfg;
806 int ntype;
807 int ret;
808 int i;
809
810 cfg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG0);
811
812 /*
813 * Handle property "snps,incr-burst-type-adjustment".
814 * Get the number of value from this property:
815 * result <= 0, means this property is not supported.
816 * result = 1, means INCRx burst mode supported.
817 * result > 1, means undefined length burst mode supported.
818 */
819 ntype = device_property_read_u32_array(dev,
820 "snps,incr-burst-type-adjustment", NULL, 0);
821 if (ntype <= 0)
822 return;
823
824 vals = kcalloc(ntype, sizeof(u32), GFP_KERNEL);
825 if (!vals) {
826 dev_err(dev, "Error to get memory\n");
827 return;
828 }
829
830 /* Get INCR burst type, and parse it */
831 ret = device_property_read_u32_array(dev,
832 "snps,incr-burst-type-adjustment", vals, ntype);
833 if (ret) {
834 dev_err(dev, "Error to get property\n");
835 return;
836 }
837
838 incrx_size = *vals;
839
840 if (ntype > 1) {
841 /* INCRX (undefined length) burst mode */
842 incrx_mode = INCRX_UNDEF_LENGTH_BURST_MODE;
843 for (i = 1; i < ntype; i++) {
844 if (vals[i] > incrx_size)
845 incrx_size = vals[i];
846 }
847 } else {
848 /* INCRX burst mode */
849 incrx_mode = INCRX_BURST_MODE;
850 }
851
852 /* Enable Undefined Length INCR Burst and Enable INCRx Burst */
853 cfg &= ~DWC3_GSBUSCFG0_INCRBRST_MASK;
854 if (incrx_mode)
855 cfg |= DWC3_GSBUSCFG0_INCRBRSTENA;
856 switch (incrx_size) {
857 case 256:
858 cfg |= DWC3_GSBUSCFG0_INCR256BRSTENA;
859 break;
860 case 128:
861 cfg |= DWC3_GSBUSCFG0_INCR128BRSTENA;
862 break;
863 case 64:
864 cfg |= DWC3_GSBUSCFG0_INCR64BRSTENA;
865 break;
866 case 32:
867 cfg |= DWC3_GSBUSCFG0_INCR32BRSTENA;
868 break;
869 case 16:
870 cfg |= DWC3_GSBUSCFG0_INCR16BRSTENA;
871 break;
872 case 8:
873 cfg |= DWC3_GSBUSCFG0_INCR8BRSTENA;
874 break;
875 case 4:
876 cfg |= DWC3_GSBUSCFG0_INCR4BRSTENA;
877 break;
878 case 1:
879 break;
880 default:
881 dev_err(dev, "Invalid property\n");
882 break;
883 }
884
885 dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, cfg);
886}
887
Felipe Balbi941f9182016-10-14 16:23:24 +0300888/**
889 * dwc3_core_init - Low-level initialization of DWC3 Core
890 * @dwc: Pointer to our controller context structure
891 *
892 * Returns 0 on success otherwise negative errno.
893 */
Jack Pham62523502018-01-15 16:37:05 -0800894int dwc3_core_init(struct dwc3 *dwc)
Felipe Balbi941f9182016-10-14 16:23:24 +0300895{
896 u32 reg;
897 int ret;
898
899 if (!dwc3_core_is_valid(dwc)) {
900 dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n");
901 ret = -ENODEV;
902 goto err0;
903 }
904
Jack Pham62523502018-01-15 16:37:05 -0800905 dwc3_cache_hwparams(dwc);
Mayank Rana0f67c832018-03-07 14:11:41 -0800906 dwc3_check_params(dwc);
Jack Pham62523502018-01-15 16:37:05 -0800907 ret = dwc3_get_dr_mode(dwc);
908 if (ret) {
909 ret = -EINVAL;
910 goto err0;
911 }
912
Felipe Balbi941f9182016-10-14 16:23:24 +0300913 /*
914 * Write Linux Version Code to our GUID register so it's easy to figure
915 * out which kernel version a bug was found.
916 */
917 dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE);
918
919 /* Handle USB2.0-only core configuration */
920 if (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) ==
921 DWC3_GHWPARAMS3_SSPHY_IFC_DIS) {
Jack Pham7992ce52018-03-07 18:46:02 -0800922 if (dwc->maximum_speed >= USB_SPEED_SUPER)
Felipe Balbi941f9182016-10-14 16:23:24 +0300923 dwc->maximum_speed = USB_SPEED_HIGH;
924 }
925
Felipe Balbi941f9182016-10-14 16:23:24 +0300926 ret = dwc3_phy_setup(dwc);
927 if (ret)
928 goto err0;
929
Roger Quadros98112042018-02-12 15:30:08 +0200930 if (!dwc->ulpi_ready) {
931 ret = dwc3_core_ulpi_init(dwc);
932 if (ret)
933 goto err0;
934 dwc->ulpi_ready = true;
935 }
936
937 if (!dwc->phys_ready) {
938 ret = dwc3_core_get_phy(dwc);
939 if (ret)
940 goto err0a;
941 dwc->phys_ready = true;
942 }
943
944 ret = dwc3_core_soft_reset(dwc);
945 if (ret)
946 goto err0a;
947
Felipe Balbi941f9182016-10-14 16:23:24 +0300948 dwc3_core_setup_global_control(dwc);
Felipe Balbic499ff72016-05-16 10:49:01 +0300949 dwc3_core_num_eps(dwc);
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600950
951 ret = dwc3_setup_scratch_buffers(dwc);
952 if (ret)
Felipe Balbic499ff72016-05-16 10:49:01 +0300953 goto err1;
954
955 /* Adjust Frame Length */
956 dwc3_frame_length_adjustment(dwc);
957
Pengbo Mud9612c22018-07-23 18:32:37 +0800958 dwc3_set_incr_burst_type(dwc);
959
Felipe Balbic499ff72016-05-16 10:49:01 +0300960 usb_phy_set_suspend(dwc->usb2_phy, 0);
Jack Pham62523502018-01-15 16:37:05 -0800961 if (dwc->maximum_speed >= USB_SPEED_SUPER)
962 usb_phy_set_suspend(dwc->usb3_phy, 0);
963
Felipe Balbic499ff72016-05-16 10:49:01 +0300964 ret = phy_power_on(dwc->usb2_generic_phy);
965 if (ret < 0)
Felipe Balbi0ffcaf32013-12-19 13:04:28 -0600966 goto err2;
967
Felipe Balbic499ff72016-05-16 10:49:01 +0300968 ret = phy_power_on(dwc->usb3_generic_phy);
969 if (ret < 0)
970 goto err3;
971
John Youn06281d42016-08-22 15:39:13 -0700972 /*
973 * ENDXFER polling is available on version 3.10a and later of
974 * the DWC_usb3 controller. It is NOT available in the
975 * DWC_usb31 controller.
976 */
977 if (!dwc3_is_usb31(dwc) && dwc->revision >= DWC3_REVISION_310A) {
978 reg = dwc3_readl(dwc->regs, DWC3_GUCTL2);
979 reg |= DWC3_GUCTL2_RST_ACTBITLATER;
980 dwc3_writel(dwc->regs, DWC3_GUCTL2, reg);
981 }
982
William Wu65db7a02017-04-19 20:11:38 +0800983 if (dwc->revision >= DWC3_REVISION_250A) {
John Youn0bb39ca2016-10-12 18:00:55 -0700984 reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
William Wu65db7a02017-04-19 20:11:38 +0800985
986 /*
987 * Enable hardware control of sending remote wakeup
988 * in HS when the device is in the L1 state.
989 */
990 if (dwc->revision >= DWC3_REVISION_290A)
991 reg |= DWC3_GUCTL1_DEV_L1_EXIT_BY_HW;
992
993 if (dwc->dis_tx_ipgap_linecheck_quirk)
994 reg |= DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS;
995
John Youn0bb39ca2016-10-12 18:00:55 -0700996 dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
997 }
998
Hemant Kumard4c4fb2d2018-09-21 17:38:18 -0700999 if (dwc->dr_mode == USB_DR_MODE_HOST || dwc3_is_otg_or_drd(dwc)) {
Anurag Kumar Vulishab138e232018-07-27 13:11:20 +05301000 reg = dwc3_readl(dwc->regs, DWC3_GUCTL);
1001
1002 /*
1003 * Enable Auto retry Feature to make the controller operating in
1004 * Host mode on seeing transaction errors(CRC errors or internal
1005 * overrun scenerios) on IN transfers to reply to the device
1006 * with a non-terminating retry ACK (i.e, an ACK transcation
1007 * packet with Retry=1 & Nump != 0)
1008 */
1009 reg |= DWC3_GUCTL_HSTINAUTORETRY;
1010
1011 dwc3_writel(dwc->regs, DWC3_GUCTL, reg);
1012 }
1013
Thinh Nguyen938a5ad2018-03-16 15:35:44 -07001014 /*
1015 * Must config both number of packets and max burst settings to enable
1016 * RX and/or TX threshold.
1017 */
1018 if (dwc3_is_usb31(dwc) && dwc->dr_mode == USB_DR_MODE_HOST) {
1019 u8 rx_thr_num = dwc->rx_thr_num_pkt_prd;
1020 u8 rx_maxburst = dwc->rx_max_burst_prd;
1021 u8 tx_thr_num = dwc->tx_thr_num_pkt_prd;
1022 u8 tx_maxburst = dwc->tx_max_burst_prd;
1023
1024 if (rx_thr_num && rx_maxburst) {
1025 reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG);
1026 reg |= DWC31_RXTHRNUMPKTSEL_PRD;
1027
1028 reg &= ~DWC31_RXTHRNUMPKT_PRD(~0);
1029 reg |= DWC31_RXTHRNUMPKT_PRD(rx_thr_num);
1030
1031 reg &= ~DWC31_MAXRXBURSTSIZE_PRD(~0);
1032 reg |= DWC31_MAXRXBURSTSIZE_PRD(rx_maxburst);
1033
1034 dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg);
1035 }
1036
1037 if (tx_thr_num && tx_maxburst) {
1038 reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG);
1039 reg |= DWC31_TXTHRNUMPKTSEL_PRD;
1040
1041 reg &= ~DWC31_TXTHRNUMPKT_PRD(~0);
1042 reg |= DWC31_TXTHRNUMPKT_PRD(tx_thr_num);
1043
1044 reg &= ~DWC31_MAXTXBURSTSIZE_PRD(~0);
1045 reg |= DWC31_MAXTXBURSTSIZE_PRD(tx_maxburst);
1046
1047 dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg);
1048 }
1049 }
1050
Vamsi Krishna Samavedamc81de8e2018-06-07 13:17:21 -07001051 /*
1052 * STAR: 9001346572:Host stops transfers to other EPs when a single
1053 * USB2.0 EP NAKs continuously requires to disable internal retry
1054 * feature
1055 */
1056 if ((dwc->revision == DWC3_USB31_REVISION_170A) &&
1057 (dwc->versiontype == DWC3_USB31_VER_TYPE_GA)) {
1058 reg = dwc3_readl(dwc->regs, DWC3_GUCTL3);
1059 reg |= DWC3_GUCTL3_USB20_RETRY_DISABLE;
1060 dwc3_writel(dwc->regs, DWC3_GUCTL3, reg);
1061 }
1062
Vijayavardhan Vennapusa6a0290f2018-07-20 10:51:27 -07001063 dwc3_notify_event(dwc, DWC3_CONTROLLER_POST_RESET_EVENT, 0);
Felipe Balbi72246da2011-08-19 18:10:58 +03001064
Hemant Kumar930f9fd2018-11-07 21:13:41 -08001065 /* set inter-packet gap 199.794ns to improve EL_23 margin */
1066 if (dwc->revision >= DWC3_USB31_REVISION_170A) {
1067 reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
1068 reg |= DWC3_GUCTL1_IP_GAP_ADD_ON(1);
1069 dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
1070 }
1071
Jack Pham62523502018-01-15 16:37:05 -08001072 return 0;
Felipe Balbic499ff72016-05-16 10:49:01 +03001073
1074err3:
Vivek Gautam9b9d7cd2016-10-21 16:21:07 +05301075 phy_power_off(dwc->usb2_generic_phy);
Felipe Balbic499ff72016-05-16 10:49:01 +03001076
Felipe Balbi0ffcaf32013-12-19 13:04:28 -06001077err2:
Felipe Balbic499ff72016-05-16 10:49:01 +03001078 usb_phy_set_suspend(dwc->usb2_phy, 1);
1079 usb_phy_set_suspend(dwc->usb3_phy, 1);
Jack Pham62523502018-01-15 16:37:05 -08001080 dwc3_free_scratch_buffers(dwc);
Felipe Balbi0ffcaf32013-12-19 13:04:28 -06001081
1082err1:
1083 usb_phy_shutdown(dwc->usb2_phy);
1084 usb_phy_shutdown(dwc->usb3_phy);
Kishon Vijay Abraham I57303482014-03-03 17:08:11 +05301085 phy_exit(dwc->usb2_generic_phy);
1086 phy_exit(dwc->usb3_generic_phy);
Felipe Balbi0ffcaf32013-12-19 13:04:28 -06001087
Roger Quadros98112042018-02-12 15:30:08 +02001088err0a:
1089 dwc3_ulpi_exit(dwc);
1090
Felipe Balbi72246da2011-08-19 18:10:58 +03001091err0:
1092 return ret;
1093}
1094
Felipe Balbi3c9f94a2014-04-16 15:08:29 -05001095static int dwc3_core_get_phy(struct dwc3 *dwc)
Felipe Balbi72246da2011-08-19 18:10:58 +03001096{
Felipe Balbi3c9f94a2014-04-16 15:08:29 -05001097 struct device *dev = dwc->dev;
Felipe Balbi941ea362013-07-31 09:21:25 +03001098 struct device_node *node = dev->of_node;
Felipe Balbi3c9f94a2014-04-16 15:08:29 -05001099 int ret;
Felipe Balbi72246da2011-08-19 18:10:58 +03001100
Kishon Vijay Abraham I5088b6f2013-01-25 16:36:53 +05301101 if (node) {
1102 dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
1103 dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
Felipe Balbibb674902013-08-14 13:21:23 -05001104 } else {
1105 dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
1106 dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
Kishon Vijay Abraham I5088b6f2013-01-25 16:36:53 +05301107 }
1108
Felipe Balbid105e7f2013-03-15 10:52:08 +02001109 if (IS_ERR(dwc->usb2_phy)) {
1110 ret = PTR_ERR(dwc->usb2_phy);
Kishon Vijay Abraham I122f06e2014-03-03 17:08:10 +05301111 if (ret == -ENXIO || ret == -ENODEV) {
1112 dwc->usb2_phy = NULL;
1113 } else if (ret == -EPROBE_DEFER) {
Felipe Balbid105e7f2013-03-15 10:52:08 +02001114 return ret;
Kishon Vijay Abraham I122f06e2014-03-03 17:08:10 +05301115 } else {
1116 dev_err(dev, "no usb2 phy configured\n");
1117 return ret;
1118 }
Felipe Balbi51e1e7b2012-07-19 14:09:48 +03001119 }
1120
Felipe Balbid105e7f2013-03-15 10:52:08 +02001121 if (IS_ERR(dwc->usb3_phy)) {
Ruchika Kharwar315955d72013-07-04 00:59:34 -05001122 ret = PTR_ERR(dwc->usb3_phy);
Kishon Vijay Abraham I122f06e2014-03-03 17:08:10 +05301123 if (ret == -ENXIO || ret == -ENODEV) {
1124 dwc->usb3_phy = NULL;
1125 } else if (ret == -EPROBE_DEFER) {
Felipe Balbid105e7f2013-03-15 10:52:08 +02001126 return ret;
Kishon Vijay Abraham I122f06e2014-03-03 17:08:10 +05301127 } else {
1128 dev_err(dev, "no usb3 phy configured\n");
1129 return ret;
1130 }
Felipe Balbi51e1e7b2012-07-19 14:09:48 +03001131 }
1132
Kishon Vijay Abraham I57303482014-03-03 17:08:11 +05301133 dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
1134 if (IS_ERR(dwc->usb2_generic_phy)) {
1135 ret = PTR_ERR(dwc->usb2_generic_phy);
1136 if (ret == -ENOSYS || ret == -ENODEV) {
1137 dwc->usb2_generic_phy = NULL;
1138 } else if (ret == -EPROBE_DEFER) {
1139 return ret;
1140 } else {
1141 dev_err(dev, "no usb2 phy configured\n");
1142 return ret;
1143 }
1144 }
1145
1146 dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
1147 if (IS_ERR(dwc->usb3_generic_phy)) {
1148 ret = PTR_ERR(dwc->usb3_generic_phy);
1149 if (ret == -ENOSYS || ret == -ENODEV) {
1150 dwc->usb3_generic_phy = NULL;
1151 } else if (ret == -EPROBE_DEFER) {
1152 return ret;
1153 } else {
1154 dev_err(dev, "no usb3 phy configured\n");
1155 return ret;
1156 }
1157 }
1158
Felipe Balbi3c9f94a2014-04-16 15:08:29 -05001159 return 0;
1160}
1161
Jack Pham62523502018-01-15 16:37:05 -08001162static void __maybe_unused dwc3_core_exit_mode(struct dwc3 *dwc)
Felipe Balbi5f94adf2014-04-16 15:13:45 -05001163{
1164 switch (dwc->dr_mode) {
1165 case USB_DR_MODE_PERIPHERAL:
1166 dwc3_gadget_exit(dwc);
1167 break;
1168 case USB_DR_MODE_HOST:
1169 dwc3_host_exit(dwc);
1170 break;
1171 case USB_DR_MODE_OTG:
Roger Quadros98403542017-04-05 13:39:31 +03001172 dwc3_drd_exit(dwc);
Felipe Balbi5f94adf2014-04-16 15:13:45 -05001173 break;
1174 default:
1175 /* do nothing */
1176 break;
1177 }
1178}
1179
Vijayavardhan Vennapusa6a0290f2018-07-20 10:51:27 -07001180static void (*notify_event)(struct dwc3 *, unsigned int, unsigned int);
1181void dwc3_set_notifier(void (*notify)(struct dwc3 *, unsigned int,
1182 unsigned int))
Jack Pham62523502018-01-15 16:37:05 -08001183{
1184 notify_event = notify;
1185}
1186EXPORT_SYMBOL(dwc3_set_notifier);
1187
Vijayavardhan Vennapusa6a0290f2018-07-20 10:51:27 -07001188int dwc3_notify_event(struct dwc3 *dwc, unsigned int event, unsigned int value)
Jack Pham62523502018-01-15 16:37:05 -08001189{
1190 int ret = 0;
1191
1192 if (notify_event)
Vijayavardhan Vennapusa6a0290f2018-07-20 10:51:27 -07001193 notify_event(dwc, event, value);
Jack Pham62523502018-01-15 16:37:05 -08001194 else
1195 ret = -ENODEV;
1196
1197 return ret;
1198}
1199EXPORT_SYMBOL(dwc3_notify_event);
1200
Felipe Balbic5ac6112016-10-14 16:30:52 +03001201static void dwc3_get_properties(struct dwc3 *dwc)
Felipe Balbi3c9f94a2014-04-16 15:08:29 -05001202{
Felipe Balbic5ac6112016-10-14 16:30:52 +03001203 struct device *dev = dwc->dev;
Huang Rui80caf7d2014-10-28 19:54:26 +08001204 u8 lpm_nyet_threshold;
Huang Rui6b6a0c92014-10-31 11:11:12 +08001205 u8 tx_de_emphasis;
Huang Rui460d0982014-10-31 11:11:18 +08001206 u8 hird_threshold;
Thinh Nguyen938a5ad2018-03-16 15:35:44 -07001207 u8 rx_thr_num_pkt_prd;
1208 u8 rx_max_burst_prd;
1209 u8 tx_thr_num_pkt_prd;
1210 u8 tx_max_burst_prd;
Felipe Balbi3c9f94a2014-04-16 15:08:29 -05001211
Huang Rui80caf7d2014-10-28 19:54:26 +08001212 /* default to highest possible threshold */
1213 lpm_nyet_threshold = 0xff;
1214
Huang Rui6b6a0c92014-10-31 11:11:12 +08001215 /* default to -3.5dB de-emphasis */
1216 tx_de_emphasis = 1;
1217
Huang Rui460d0982014-10-31 11:11:18 +08001218 /*
1219 * default to assert utmi_sleep_n and use maximum allowed HIRD
1220 * threshold value of 0b1100
1221 */
1222 hird_threshold = 12;
1223
Heikki Krogerus63863b92015-09-21 11:14:32 +03001224 dwc->maximum_speed = usb_get_maximum_speed(dev);
Jack Pham62523502018-01-15 16:37:05 -08001225 dwc->max_hw_supp_speed = dwc->maximum_speed;
Heikki Krogerus06e71142015-09-21 11:14:34 +03001226 dwc->dr_mode = usb_get_dr_mode(dev);
William Wu32f2ed82016-08-16 22:44:38 +08001227 dwc->hsphy_mode = of_usb_get_phy_mode(dev->of_node);
Heikki Krogerus63863b92015-09-21 11:14:32 +03001228
Arnd Bergmannd64ff402016-11-17 17:13:47 +05301229 dwc->sysdev_is_parent = device_property_read_bool(dev,
1230 "linux,sysdev_is_parent");
1231 if (dwc->sysdev_is_parent)
1232 dwc->sysdev = dwc->dev->parent;
1233 else
1234 dwc->sysdev = dwc->dev;
1235
Heikki Krogerus3d128912015-09-21 11:14:35 +03001236 dwc->has_lpm_erratum = device_property_read_bool(dev,
Huang Rui80caf7d2014-10-28 19:54:26 +08001237 "snps,has-lpm-erratum");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001238 device_property_read_u8(dev, "snps,lpm-nyet-threshold",
Huang Rui80caf7d2014-10-28 19:54:26 +08001239 &lpm_nyet_threshold);
Heikki Krogerus3d128912015-09-21 11:14:35 +03001240 dwc->is_utmi_l1_suspend = device_property_read_bool(dev,
Huang Rui460d0982014-10-31 11:11:18 +08001241 "snps,is-utmi-l1-suspend");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001242 device_property_read_u8(dev, "snps,hird-threshold",
Huang Rui460d0982014-10-31 11:11:18 +08001243 &hird_threshold);
Mayank Ranaf7437de2017-03-29 18:33:39 -07001244
1245 device_property_read_u32(dev, "snps,xhci-imod-value",
1246 &dwc->xhci_imod_value);
1247
Hemant Kumar4c874ac2017-08-18 16:40:58 -07001248 dwc->core_id = -1;
1249 device_property_read_u32(dev, "usb-core-id", &dwc->core_id);
1250
Heikki Krogerus3d128912015-09-21 11:14:35 +03001251 dwc->usb3_lpm_capable = device_property_read_bool(dev,
Robert Baldygaeac68e82015-03-09 15:06:12 +01001252 "snps,usb3_lpm_capable");
Thinh Nguyen938a5ad2018-03-16 15:35:44 -07001253 device_property_read_u8(dev, "snps,rx-thr-num-pkt-prd",
1254 &rx_thr_num_pkt_prd);
1255 device_property_read_u8(dev, "snps,rx-max-burst-prd",
1256 &rx_max_burst_prd);
1257 device_property_read_u8(dev, "snps,tx-thr-num-pkt-prd",
1258 &tx_thr_num_pkt_prd);
1259 device_property_read_u8(dev, "snps,tx-max-burst-prd",
1260 &tx_max_burst_prd);
Felipe Balbi3c9f94a2014-04-16 15:08:29 -05001261
Mayank Rana4c99f662017-04-25 13:48:46 -07001262 dwc->needs_fifo_resize = device_property_read_bool(dev,
1263 "tx-fifo-resize");
1264
Heikki Krogerus3d128912015-09-21 11:14:35 +03001265 dwc->disable_scramble_quirk = device_property_read_bool(dev,
Huang Rui3b812212014-10-28 19:54:25 +08001266 "snps,disable_scramble_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001267 dwc->u2exit_lfps_quirk = device_property_read_bool(dev,
Huang Rui9a5b2f32014-10-28 19:54:27 +08001268 "snps,u2exit_lfps_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001269 dwc->u2ss_inp3_quirk = device_property_read_bool(dev,
Huang Ruib5a65c42014-10-28 19:54:28 +08001270 "snps,u2ss_inp3_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001271 dwc->req_p1p2p3_quirk = device_property_read_bool(dev,
Huang Ruidf31f5b2014-10-28 19:54:29 +08001272 "snps,req_p1p2p3_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001273 dwc->del_p1p2p3_quirk = device_property_read_bool(dev,
Huang Ruia2a1d0f2014-10-28 19:54:30 +08001274 "snps,del_p1p2p3_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001275 dwc->del_phy_power_chg_quirk = device_property_read_bool(dev,
Huang Rui41c06ff2014-10-28 19:54:31 +08001276 "snps,del_phy_power_chg_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001277 dwc->lfps_filter_quirk = device_property_read_bool(dev,
Huang Ruifb67afc2014-10-28 19:54:32 +08001278 "snps,lfps_filter_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001279 dwc->rx_detect_poll_quirk = device_property_read_bool(dev,
Huang Rui14f4ac52014-10-28 19:54:33 +08001280 "snps,rx_detect_poll_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001281 dwc->dis_u3_susphy_quirk = device_property_read_bool(dev,
Huang Rui59acfa22014-10-31 11:11:13 +08001282 "snps,dis_u3_susphy_quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001283 dwc->dis_u2_susphy_quirk = device_property_read_bool(dev,
Huang Rui0effe0a2014-10-31 11:11:14 +08001284 "snps,dis_u2_susphy_quirk");
John Younec791d12015-10-02 20:30:57 -07001285 dwc->dis_enblslpm_quirk = device_property_read_bool(dev,
1286 "snps,dis_enblslpm_quirk");
Rajesh Bhagate58dd352016-03-14 14:40:50 +05301287 dwc->dis_rxdet_inp3_quirk = device_property_read_bool(dev,
1288 "snps,dis_rxdet_inp3_quirk");
William Wu16199f32016-08-16 22:44:37 +08001289 dwc->dis_u2_freeclk_exists_quirk = device_property_read_bool(dev,
1290 "snps,dis-u2-freeclk-exists-quirk");
William Wu00fe0812016-08-16 22:44:39 +08001291 dwc->dis_del_phy_power_chg_quirk = device_property_read_bool(dev,
1292 "snps,dis-del-phy-power-chg-quirk");
William Wu65db7a02017-04-19 20:11:38 +08001293 dwc->dis_tx_ipgap_linecheck_quirk = device_property_read_bool(dev,
1294 "snps,dis-tx-ipgap-linecheck-quirk");
Huang Rui6b6a0c92014-10-31 11:11:12 +08001295
Heikki Krogerus3d128912015-09-21 11:14:35 +03001296 dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
Huang Rui6b6a0c92014-10-31 11:11:12 +08001297 "snps,tx_de_emphasis_quirk");
Mayank Rana50980932018-03-28 15:29:01 -07001298 dwc->ssp_u3_u0_quirk = device_property_read_bool(dev,
1299 "snps,ssp-u3-u0-quirk");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001300 device_property_read_u8(dev, "snps,tx_de_emphasis",
Huang Rui6b6a0c92014-10-31 11:11:12 +08001301 &tx_de_emphasis);
Heikki Krogerus3d128912015-09-21 11:14:35 +03001302 device_property_read_string(dev, "snps,hsphy_interface",
1303 &dwc->hsphy_interface);
1304 device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
Felipe Balbibcdb3272016-05-16 10:42:23 +03001305 &dwc->fladj);
Jack Pham62523502018-01-15 16:37:05 -08001306 dwc->enable_bus_suspend = device_property_read_bool(dev,
1307 "snps,bus-suspend-enable");
Sriharsha Allenki0855ddf2018-03-08 23:20:48 +05301308 dwc->usb3_u1u2_disable = device_property_read_bool(dev,
1309 "snps,usb3-u1u2-disable");
Mayank Ranab39f3fd2018-05-16 09:39:33 -07001310 dwc->disable_clk_gating = device_property_read_bool(dev,
1311 "snps,disable-clk-gating");
Heikki Krogerus3d128912015-09-21 11:14:35 +03001312
Roger Quadros42bf02e2017-10-31 15:11:55 +02001313 dwc->dis_metastability_quirk = device_property_read_bool(dev,
1314 "snps,dis_metastability_quirk");
1315
Huang Rui80caf7d2014-10-28 19:54:26 +08001316 dwc->lpm_nyet_threshold = lpm_nyet_threshold;
Huang Rui6b6a0c92014-10-31 11:11:12 +08001317 dwc->tx_de_emphasis = tx_de_emphasis;
Huang Rui80caf7d2014-10-28 19:54:26 +08001318
Huang Rui460d0982014-10-31 11:11:18 +08001319 dwc->hird_threshold = hird_threshold
1320 | (dwc->is_utmi_l1_suspend << 4);
1321
Thinh Nguyen938a5ad2018-03-16 15:35:44 -07001322 dwc->rx_thr_num_pkt_prd = rx_thr_num_pkt_prd;
1323 dwc->rx_max_burst_prd = rx_max_burst_prd;
1324
1325 dwc->tx_thr_num_pkt_prd = tx_thr_num_pkt_prd;
1326 dwc->tx_max_burst_prd = tx_max_burst_prd;
1327
John Youncf40b862016-11-14 12:32:43 -08001328 dwc->imod_interval = 0;
1329}
1330
1331/* check whether the core supports IMOD */
1332bool dwc3_has_imod(struct dwc3 *dwc)
1333{
1334 return ((dwc3_is_usb3(dwc) &&
1335 dwc->revision >= DWC3_REVISION_300A) ||
1336 (dwc3_is_usb31(dwc) &&
1337 dwc->revision >= DWC3_USB31_REVISION_120A));
Felipe Balbic5ac6112016-10-14 16:30:52 +03001338}
1339
John Youn7ac51a12016-11-10 17:08:51 -08001340static void dwc3_check_params(struct dwc3 *dwc)
1341{
1342 struct device *dev = dwc->dev;
1343
John Youncf40b862016-11-14 12:32:43 -08001344 /* Check for proper value of imod_interval */
1345 if (dwc->imod_interval && !dwc3_has_imod(dwc)) {
1346 dev_warn(dwc->dev, "Interrupt moderation not supported\n");
1347 dwc->imod_interval = 0;
1348 }
1349
John Youn28632b42016-11-14 12:32:45 -08001350 /*
1351 * Workaround for STAR 9000961433 which affects only version
1352 * 3.00a of the DWC_usb3 core. This prevents the controller
1353 * interrupt from being masked while handling events. IMOD
1354 * allows us to work around this issue. Enable it for the
1355 * affected version.
1356 */
1357 if (!dwc->imod_interval &&
1358 (dwc->revision == DWC3_REVISION_300A))
1359 dwc->imod_interval = 1;
1360
John Youn7ac51a12016-11-10 17:08:51 -08001361 /* Check the maximum_speed parameter */
1362 switch (dwc->maximum_speed) {
1363 case USB_SPEED_LOW:
1364 case USB_SPEED_FULL:
1365 case USB_SPEED_HIGH:
1366 case USB_SPEED_SUPER:
1367 case USB_SPEED_SUPER_PLUS:
1368 break;
1369 default:
1370 dev_err(dev, "invalid maximum_speed parameter %d\n",
1371 dwc->maximum_speed);
1372 /* fall through */
1373 case USB_SPEED_UNKNOWN:
1374 /* default to superspeed */
1375 dwc->maximum_speed = USB_SPEED_SUPER;
1376
1377 /*
1378 * default to superspeed plus if we are capable.
1379 */
1380 if (dwc3_is_usb31(dwc) &&
1381 (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) ==
1382 DWC3_GHWPARAMS3_SSPHY_IFC_GEN2))
1383 dwc->maximum_speed = USB_SPEED_SUPER_PLUS;
1384
1385 break;
1386 }
1387}
1388
Felipe Balbic5ac6112016-10-14 16:30:52 +03001389static int dwc3_probe(struct platform_device *pdev)
1390{
1391 struct device *dev = &pdev->dev;
Masahiro Yamada44feb8e2018-04-19 20:03:37 +09001392 struct resource *res, dwc_res;
Felipe Balbic5ac6112016-10-14 16:30:52 +03001393 struct dwc3 *dwc;
1394
1395 int ret;
1396
1397 void __iomem *regs;
Jack Pham62523502018-01-15 16:37:05 -08001398 int irq;
1399
1400 if (count >= DWC_CTRL_COUNT) {
1401 dev_err(dev, "Err dwc instance %d >= %d available\n",
1402 count, DWC_CTRL_COUNT);
1403 ret = -EINVAL;
1404 return ret;
1405 }
Felipe Balbic5ac6112016-10-14 16:30:52 +03001406
1407 dwc = devm_kzalloc(dev, sizeof(*dwc), GFP_KERNEL);
1408 if (!dwc)
1409 return -ENOMEM;
1410
Masahiro Yamadafe8abf32018-05-16 11:41:07 +09001411 dwc->clks = devm_kmemdup(dev, dwc3_core_clks, sizeof(dwc3_core_clks),
1412 GFP_KERNEL);
1413 if (!dwc->clks)
1414 return -ENOMEM;
1415
Felipe Balbic5ac6112016-10-14 16:30:52 +03001416 dwc->dev = dev;
Felipe Balbic5ac6112016-10-14 16:30:52 +03001417 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1418 if (!res) {
1419 dev_err(dev, "missing memory resource\n");
1420 return -ENODEV;
1421 }
1422
Mayank Ranab5b8e422018-03-23 11:00:45 -07001423 dwc->reg_phys = res->start;
Felipe Balbic5ac6112016-10-14 16:30:52 +03001424 dwc->xhci_resources[0].start = res->start;
1425 dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
1426 DWC3_XHCI_REGS_END;
1427 dwc->xhci_resources[0].flags = res->flags;
1428 dwc->xhci_resources[0].name = res->name;
1429
Jack Pham62523502018-01-15 16:37:05 -08001430 irq = platform_get_irq(to_platform_device(dwc->dev), 0);
1431
Jack Pham62523502018-01-15 16:37:05 -08001432 ret = devm_request_irq(dev, irq, dwc3_interrupt, IRQF_SHARED, "dwc3",
1433 dwc);
1434 if (ret) {
1435 dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
1436 irq, ret);
1437 return -ENODEV;
1438 }
1439
Mayank Ranadda49922018-03-19 13:47:55 -07001440 /* will be enabled in dwc3_msm_resume() */
1441 disable_irq(irq);
Jack Pham62523502018-01-15 16:37:05 -08001442 dwc->irq = irq;
Felipe Balbic5ac6112016-10-14 16:30:52 +03001443 /*
1444 * Request memory region but exclude xHCI regs,
1445 * since it will be requested by the xhci-plat driver.
1446 */
Masahiro Yamada44feb8e2018-04-19 20:03:37 +09001447 dwc_res = *res;
1448 dwc_res.start += DWC3_GLOBALS_REGS_START;
1449
1450 regs = devm_ioremap_resource(dev, &dwc_res);
1451 if (IS_ERR(regs))
1452 return PTR_ERR(regs);
Felipe Balbic5ac6112016-10-14 16:30:52 +03001453
Jack Pham62523502018-01-15 16:37:05 -08001454 dwc->dwc_wq = alloc_ordered_workqueue("dwc_wq", WQ_HIGHPRI);
1455 if (!dwc->dwc_wq) {
1456 dev_err(dev,
1457 "%s: Unable to create workqueue dwc_wq\n", __func__);
1458 goto err0;
1459 }
1460
1461 INIT_WORK(&dwc->bh_work, dwc3_bh_work);
Felipe Balbic5ac6112016-10-14 16:30:52 +03001462 dwc->regs = regs;
Masahiro Yamada44feb8e2018-04-19 20:03:37 +09001463 dwc->regs_size = resource_size(&dwc_res);
Felipe Balbic5ac6112016-10-14 16:30:52 +03001464
1465 dwc3_get_properties(dwc);
1466
Masahiro Yamadafe8abf32018-05-16 11:41:07 +09001467 dwc->reset = devm_reset_control_get_optional_shared(dev, NULL);
1468 if (IS_ERR(dwc->reset))
Jack Pham62523502018-01-15 16:37:05 -08001469 goto skip_clk_reset;
Masahiro Yamadafe8abf32018-05-16 11:41:07 +09001470
Hans de Goede61527772018-06-12 10:24:48 +02001471 if (dev->of_node) {
1472 dwc->num_clks = ARRAY_SIZE(dwc3_core_clks);
1473
1474 ret = clk_bulk_get(dev, dwc->num_clks, dwc->clks);
1475 if (ret == -EPROBE_DEFER)
1476 return ret;
1477 /*
1478 * Clocks are optional, but new DT platforms should support all
1479 * clocks as required by the DT-binding.
1480 */
1481 if (ret)
1482 dwc->num_clks = 0;
1483 }
Masahiro Yamadafe8abf32018-05-16 11:41:07 +09001484
1485 ret = reset_control_deassert(dwc->reset);
1486 if (ret)
1487 goto put_clks;
1488
1489 ret = clk_bulk_prepare(dwc->num_clks, dwc->clks);
1490 if (ret)
1491 goto assert_reset;
1492
1493 ret = clk_bulk_enable(dwc->num_clks, dwc->clks);
1494 if (ret)
1495 goto unprepare_clks;
1496
Jack Pham62523502018-01-15 16:37:05 -08001497skip_clk_reset:
Heikki Krogerus6c89cce02015-05-13 15:26:45 +03001498 platform_set_drvdata(pdev, dwc);
1499
Jack Pham62523502018-01-15 16:37:05 -08001500 init_waitqueue_head(&dwc->wait_linkstate);
Felipe Balbi72246da2011-08-19 18:10:58 +03001501 spin_lock_init(&dwc->lock);
Felipe Balbi72246da2011-08-19 18:10:58 +03001502
Jack Pham62523502018-01-15 16:37:05 -08001503 pm_runtime_no_callbacks(dev);
Felipe Balbifc8bb912016-05-16 13:14:48 +03001504 pm_runtime_set_active(dev);
Jack Pham62523502018-01-15 16:37:05 -08001505 if (dwc->enable_bus_suspend) {
1506 pm_runtime_set_autosuspend_delay(dev,
1507 DWC3_DEFAULT_AUTOSUSPEND_DELAY);
1508 pm_runtime_use_autosuspend(dev);
1509 }
Chanho Park802ca852012-02-15 18:27:55 +09001510 pm_runtime_enable(dev);
Chanho Park802ca852012-02-15 18:27:55 +09001511 pm_runtime_forbid(dev);
Felipe Balbi72246da2011-08-19 18:10:58 +03001512
Felipe Balbi39214262012-10-11 13:54:36 +03001513 ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
1514 if (ret) {
1515 dev_err(dwc->dev, "failed to allocate event buffers\n");
1516 ret = -ENOMEM;
Jack Pham62523502018-01-15 16:37:05 -08001517 goto err1;
Felipe Balbi39214262012-10-11 13:54:36 +03001518 }
1519
Felipe Balbic499ff72016-05-16 10:49:01 +03001520 ret = dwc3_alloc_scratch_buffers(dwc);
1521 if (ret)
Jack Pham62523502018-01-15 16:37:05 -08001522 goto err2;
Felipe Balbi72246da2011-08-19 18:10:58 +03001523
Hemant Kumard4c4fb2d2018-09-21 17:38:18 -07001524 if (dwc3_is_otg_or_drd(dwc) ||
Mayank Rana0f67c832018-03-07 14:11:41 -08001525 dwc->dr_mode == USB_DR_MODE_PERIPHERAL) {
1526 ret = dwc3_gadget_init(dwc);
1527 if (ret) {
1528 dev_err(dwc->dev, "gadget init failed %d\n", ret);
1529 goto err3;
1530 }
1531 }
Mayank Rana679f3322018-01-15 16:23:45 -08001532
1533 dwc->dwc_ipc_log_ctxt = ipc_log_context_create(NUM_LOG_PAGES,
1534 dev_name(dwc->dev), 0);
1535 if (!dwc->dwc_ipc_log_ctxt)
1536 dev_err(dwc->dev, "Error getting ipc_log_ctxt\n");
1537
1538 dwc3_instance[count] = dwc;
1539 dwc->index = count;
1540 count++;
1541
Jack Pham62523502018-01-15 16:37:05 -08001542 pm_runtime_allow(dev);
Mayank Rana0f67c832018-03-07 14:11:41 -08001543 dwc3_debugfs_init(dwc);
Felipe Balbi72246da2011-08-19 18:10:58 +03001544 return 0;
1545
Mayank Rana0f67c832018-03-07 14:11:41 -08001546err3:
1547 dwc3_free_scratch_buffers(dwc);
Roger Quadros32808232016-06-10 14:38:02 +03001548err2:
Jack Pham62523502018-01-15 16:37:05 -08001549 dwc3_free_event_buffers(dwc);
Roger Quadros32808232016-06-10 14:38:02 +03001550err1:
Jack Pham62523502018-01-15 16:37:05 -08001551 if (dwc->num_clks) {
1552 clk_bulk_disable(dwc->num_clks, dwc->clks);
Masahiro Yamadafe8abf32018-05-16 11:41:07 +09001553unprepare_clks:
Jack Pham62523502018-01-15 16:37:05 -08001554 clk_bulk_unprepare(dwc->num_clks, dwc->clks);
Masahiro Yamadafe8abf32018-05-16 11:41:07 +09001555assert_reset:
Jack Pham62523502018-01-15 16:37:05 -08001556 reset_control_assert(dwc->reset);
Masahiro Yamadafe8abf32018-05-16 11:41:07 +09001557put_clks:
Jack Pham62523502018-01-15 16:37:05 -08001558 clk_bulk_put(dwc->num_clks, dwc->clks);
1559 }
1560 destroy_workqueue(dwc->dwc_wq);
1561err0:
Masahiro Yamadafe8abf32018-05-16 11:41:07 +09001562
Felipe Balbi72246da2011-08-19 18:10:58 +03001563 return ret;
1564}
1565
Bill Pembertonfb4e98a2012-11-19 13:26:20 -05001566static int dwc3_remove(struct platform_device *pdev)
Felipe Balbi72246da2011-08-19 18:10:58 +03001567{
Felipe Balbi72246da2011-08-19 18:10:58 +03001568 struct dwc3 *dwc = platform_get_drvdata(pdev);
Felipe Balbi72246da2011-08-19 18:10:58 +03001569
Felipe Balbidc99f162014-09-03 16:13:37 -05001570 dwc3_debugfs_exit(dwc);
Mayank Rana0f67c832018-03-07 14:11:41 -08001571 dwc3_gadget_exit(dwc);
Felipe Balbifc8bb912016-05-16 13:14:48 +03001572 pm_runtime_allow(&pdev->dev);
1573 pm_runtime_disable(&pdev->dev);
1574
Felipe Balbic499ff72016-05-16 10:49:01 +03001575 dwc3_free_event_buffers(dwc);
1576 dwc3_free_scratch_buffers(dwc);
Masahiro Yamadafe8abf32018-05-16 11:41:07 +09001577 clk_bulk_put(dwc->num_clks, dwc->clks);
Felipe Balbic499ff72016-05-16 10:49:01 +03001578
Mayank Rana679f3322018-01-15 16:23:45 -08001579 ipc_log_context_destroy(dwc->dwc_ipc_log_ctxt);
1580 dwc->dwc_ipc_log_ctxt = NULL;
1581 count--;
1582 dwc3_instance[dwc->index] = NULL;
1583
Felipe Balbi72246da2011-08-19 18:10:58 +03001584 return 0;
1585}
1586
Felipe Balbifc8bb912016-05-16 13:14:48 +03001587#ifdef CONFIG_PM
Masahiro Yamadafe8abf32018-05-16 11:41:07 +09001588static int dwc3_core_init_for_resume(struct dwc3 *dwc)
1589{
1590 int ret;
1591
1592 ret = reset_control_deassert(dwc->reset);
1593 if (ret)
1594 return ret;
1595
1596 ret = clk_bulk_prepare(dwc->num_clks, dwc->clks);
1597 if (ret)
1598 goto assert_reset;
1599
1600 ret = clk_bulk_enable(dwc->num_clks, dwc->clks);
1601 if (ret)
1602 goto unprepare_clks;
1603
1604 ret = dwc3_core_init(dwc);
1605 if (ret)
1606 goto disable_clks;
1607
1608 return 0;
1609
1610disable_clks:
1611 clk_bulk_disable(dwc->num_clks, dwc->clks);
1612unprepare_clks:
1613 clk_bulk_unprepare(dwc->num_clks, dwc->clks);
1614assert_reset:
1615 reset_control_assert(dwc->reset);
1616
1617 return ret;
1618}
1619
Manu Gautamc4a51532018-01-18 16:54:30 +05301620static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
Felipe Balbi7415f172012-04-30 14:56:33 +03001621{
Felipe Balbifc8bb912016-05-16 13:14:48 +03001622 unsigned long flags;
Manu Gautambcb12872018-05-09 23:09:21 +05301623 u32 reg;
Felipe Balbi7415f172012-04-30 14:56:33 +03001624
Manu Gautam689bf722017-09-27 16:49:20 +05301625 switch (dwc->current_dr_role) {
1626 case DWC3_GCTL_PRTCAP_DEVICE:
Felipe Balbifc8bb912016-05-16 13:14:48 +03001627 spin_lock_irqsave(&dwc->lock, flags);
Felipe Balbi7415f172012-04-30 14:56:33 +03001628 dwc3_gadget_suspend(dwc);
Felipe Balbifc8bb912016-05-16 13:14:48 +03001629 spin_unlock_irqrestore(&dwc->lock, flags);
Manu Gautam689bf722017-09-27 16:49:20 +05301630 dwc3_core_exit(dwc);
Felipe Balbi51f5d492016-05-16 10:52:58 +03001631 break;
Manu Gautam689bf722017-09-27 16:49:20 +05301632 case DWC3_GCTL_PRTCAP_HOST:
Manu Gautambcb12872018-05-09 23:09:21 +05301633 if (!PMSG_IS_AUTO(msg)) {
Manu Gautamc4a51532018-01-18 16:54:30 +05301634 dwc3_core_exit(dwc);
Manu Gautambcb12872018-05-09 23:09:21 +05301635 break;
1636 }
1637
1638 /* Let controller to suspend HSPHY before PHY driver suspends */
1639 if (dwc->dis_u2_susphy_quirk ||
1640 dwc->dis_enblslpm_quirk) {
1641 reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
1642 reg |= DWC3_GUSB2PHYCFG_ENBLSLPM |
1643 DWC3_GUSB2PHYCFG_SUSPHY;
1644 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
1645
1646 /* Give some time for USB2 PHY to suspend */
1647 usleep_range(5000, 6000);
1648 }
1649
1650 phy_pm_runtime_put_sync(dwc->usb2_generic_phy);
1651 phy_pm_runtime_put_sync(dwc->usb3_generic_phy);
Manu Gautamc4a51532018-01-18 16:54:30 +05301652 break;
Roger Quadrosf09cc792018-02-27 13:30:19 +02001653 case DWC3_GCTL_PRTCAP_OTG:
1654 /* do nothing during runtime_suspend */
1655 if (PMSG_IS_AUTO(msg))
1656 break;
1657
1658 if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) {
1659 spin_lock_irqsave(&dwc->lock, flags);
1660 dwc3_gadget_suspend(dwc);
1661 spin_unlock_irqrestore(&dwc->lock, flags);
1662 }
1663
1664 dwc3_otg_exit(dwc);
1665 dwc3_core_exit(dwc);
1666 break;
Felipe Balbi7415f172012-04-30 14:56:33 +03001667 default:
Felipe Balbi51f5d492016-05-16 10:52:58 +03001668 /* do nothing */
Felipe Balbi7415f172012-04-30 14:56:33 +03001669 break;
1670 }
1671
Felipe Balbifc8bb912016-05-16 13:14:48 +03001672 return 0;
1673}
1674
Manu Gautamc4a51532018-01-18 16:54:30 +05301675static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg)
Felipe Balbifc8bb912016-05-16 13:14:48 +03001676{
1677 unsigned long flags;
1678 int ret;
Manu Gautambcb12872018-05-09 23:09:21 +05301679 u32 reg;
Felipe Balbifc8bb912016-05-16 13:14:48 +03001680
Manu Gautam689bf722017-09-27 16:49:20 +05301681 switch (dwc->current_dr_role) {
1682 case DWC3_GCTL_PRTCAP_DEVICE:
Masahiro Yamadafe8abf32018-05-16 11:41:07 +09001683 ret = dwc3_core_init_for_resume(dwc);
Manu Gautam689bf722017-09-27 16:49:20 +05301684 if (ret)
1685 return ret;
Felipe Balbifc8bb912016-05-16 13:14:48 +03001686
Roger Quadros7d11c3a2018-03-16 16:44:27 +02001687 dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE);
Felipe Balbifc8bb912016-05-16 13:14:48 +03001688 spin_lock_irqsave(&dwc->lock, flags);
1689 dwc3_gadget_resume(dwc);
1690 spin_unlock_irqrestore(&dwc->lock, flags);
Manu Gautam689bf722017-09-27 16:49:20 +05301691 break;
1692 case DWC3_GCTL_PRTCAP_HOST:
Manu Gautamc4a51532018-01-18 16:54:30 +05301693 if (!PMSG_IS_AUTO(msg)) {
Masahiro Yamadafe8abf32018-05-16 11:41:07 +09001694 ret = dwc3_core_init_for_resume(dwc);
Manu Gautamc4a51532018-01-18 16:54:30 +05301695 if (ret)
1696 return ret;
Roger Quadros7d11c3a2018-03-16 16:44:27 +02001697 dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST);
Manu Gautambcb12872018-05-09 23:09:21 +05301698 break;
Manu Gautamc4a51532018-01-18 16:54:30 +05301699 }
Manu Gautambcb12872018-05-09 23:09:21 +05301700 /* Restore GUSB2PHYCFG bits that were modified in suspend */
1701 reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
1702 if (dwc->dis_u2_susphy_quirk)
1703 reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
1704
1705 if (dwc->dis_enblslpm_quirk)
1706 reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
1707
1708 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
1709
1710 phy_pm_runtime_get_sync(dwc->usb2_generic_phy);
1711 phy_pm_runtime_get_sync(dwc->usb3_generic_phy);
Manu Gautamc4a51532018-01-18 16:54:30 +05301712 break;
Roger Quadrosf09cc792018-02-27 13:30:19 +02001713 case DWC3_GCTL_PRTCAP_OTG:
1714 /* nothing to do on runtime_resume */
1715 if (PMSG_IS_AUTO(msg))
1716 break;
1717
1718 ret = dwc3_core_init(dwc);
1719 if (ret)
1720 return ret;
1721
1722 dwc3_set_prtcap(dwc, dwc->current_dr_role);
1723
1724 dwc3_otg_init(dwc);
1725 if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST) {
1726 dwc3_otg_host_init(dwc);
1727 } else if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) {
1728 spin_lock_irqsave(&dwc->lock, flags);
1729 dwc3_gadget_resume(dwc);
1730 spin_unlock_irqrestore(&dwc->lock, flags);
1731 }
1732
1733 break;
Felipe Balbifc8bb912016-05-16 13:14:48 +03001734 default:
1735 /* do nothing */
1736 break;
1737 }
1738
1739 return 0;
1740}
1741
1742static int dwc3_runtime_checks(struct dwc3 *dwc)
1743{
Manu Gautam689bf722017-09-27 16:49:20 +05301744 switch (dwc->current_dr_role) {
Manu Gautamc4a51532018-01-18 16:54:30 +05301745 case DWC3_GCTL_PRTCAP_DEVICE:
Felipe Balbifc8bb912016-05-16 13:14:48 +03001746 if (dwc->connected)
1747 return -EBUSY;
1748 break;
Manu Gautamc4a51532018-01-18 16:54:30 +05301749 case DWC3_GCTL_PRTCAP_HOST:
Felipe Balbifc8bb912016-05-16 13:14:48 +03001750 default:
1751 /* do nothing */
1752 break;
1753 }
1754
1755 return 0;
1756}
1757
1758static int dwc3_runtime_suspend(struct device *dev)
1759{
1760 struct dwc3 *dwc = dev_get_drvdata(dev);
1761 int ret;
1762
Jack Pham62523502018-01-15 16:37:05 -08001763 /* Check if platform glue driver handling PM, if not then handle here */
Vijayavardhan Vennapusa6a0290f2018-07-20 10:51:27 -07001764 if (!dwc3_notify_event(dwc, DWC3_CORE_PM_SUSPEND_EVENT, 0))
Jack Pham62523502018-01-15 16:37:05 -08001765 return 0;
1766
Felipe Balbifc8bb912016-05-16 13:14:48 +03001767 if (dwc3_runtime_checks(dwc))
1768 return -EBUSY;
1769
Manu Gautamc4a51532018-01-18 16:54:30 +05301770 ret = dwc3_suspend_common(dwc, PMSG_AUTO_SUSPEND);
Felipe Balbifc8bb912016-05-16 13:14:48 +03001771 if (ret)
1772 return ret;
1773
1774 device_init_wakeup(dev, true);
1775
1776 return 0;
1777}
1778
1779static int dwc3_runtime_resume(struct device *dev)
1780{
1781 struct dwc3 *dwc = dev_get_drvdata(dev);
1782 int ret;
1783
Jack Pham62523502018-01-15 16:37:05 -08001784 /* Check if platform glue driver handling PM, if not then handle here */
Vijayavardhan Vennapusa6a0290f2018-07-20 10:51:27 -07001785 if (!dwc3_notify_event(dwc, DWC3_CORE_PM_RESUME_EVENT, 0))
Jack Pham62523502018-01-15 16:37:05 -08001786 return 0;
1787
Felipe Balbifc8bb912016-05-16 13:14:48 +03001788 device_init_wakeup(dev, false);
1789
Manu Gautamc4a51532018-01-18 16:54:30 +05301790 ret = dwc3_resume_common(dwc, PMSG_AUTO_RESUME);
Felipe Balbifc8bb912016-05-16 13:14:48 +03001791 if (ret)
1792 return ret;
1793
Manu Gautam689bf722017-09-27 16:49:20 +05301794 switch (dwc->current_dr_role) {
1795 case DWC3_GCTL_PRTCAP_DEVICE:
Felipe Balbifc8bb912016-05-16 13:14:48 +03001796 dwc3_gadget_process_pending_events(dwc);
1797 break;
Manu Gautam689bf722017-09-27 16:49:20 +05301798 case DWC3_GCTL_PRTCAP_HOST:
Felipe Balbifc8bb912016-05-16 13:14:48 +03001799 default:
1800 /* do nothing */
1801 break;
1802 }
1803
1804 pm_runtime_mark_last_busy(dev);
1805
1806 return 0;
1807}
1808
1809static int dwc3_runtime_idle(struct device *dev)
1810{
1811 struct dwc3 *dwc = dev_get_drvdata(dev);
1812
Manu Gautam689bf722017-09-27 16:49:20 +05301813 switch (dwc->current_dr_role) {
1814 case DWC3_GCTL_PRTCAP_DEVICE:
Felipe Balbifc8bb912016-05-16 13:14:48 +03001815 if (dwc3_runtime_checks(dwc))
1816 return -EBUSY;
1817 break;
Manu Gautam689bf722017-09-27 16:49:20 +05301818 case DWC3_GCTL_PRTCAP_HOST:
Felipe Balbifc8bb912016-05-16 13:14:48 +03001819 default:
1820 /* do nothing */
1821 break;
1822 }
1823
1824 pm_runtime_mark_last_busy(dev);
1825 pm_runtime_autosuspend(dev);
1826
1827 return 0;
1828}
1829#endif /* CONFIG_PM */
1830
1831#ifdef CONFIG_PM_SLEEP
1832static int dwc3_suspend(struct device *dev)
1833{
1834 struct dwc3 *dwc = dev_get_drvdata(dev);
1835 int ret;
1836
Jack Pham62523502018-01-15 16:37:05 -08001837 /* Check if platform glue driver handling PM, if not then handle here */
Vijayavardhan Vennapusa6a0290f2018-07-20 10:51:27 -07001838 if (!dwc3_notify_event(dwc, DWC3_CORE_PM_SUSPEND_EVENT, 0))
Jack Pham62523502018-01-15 16:37:05 -08001839 return 0;
1840
Manu Gautamc4a51532018-01-18 16:54:30 +05301841 ret = dwc3_suspend_common(dwc, PMSG_SUSPEND);
Felipe Balbifc8bb912016-05-16 13:14:48 +03001842 if (ret)
1843 return ret;
1844
Sekhar Nori63444752015-08-31 21:09:08 +05301845 pinctrl_pm_select_sleep_state(dev);
1846
Felipe Balbi7415f172012-04-30 14:56:33 +03001847 return 0;
1848}
1849
1850static int dwc3_resume(struct device *dev)
1851{
1852 struct dwc3 *dwc = dev_get_drvdata(dev);
Kishon Vijay Abraham I57303482014-03-03 17:08:11 +05301853 int ret;
Felipe Balbi7415f172012-04-30 14:56:33 +03001854
Jack Pham62523502018-01-15 16:37:05 -08001855 /* Check if platform glue driver handling PM, if not then handle here */
Ajay Agarwal0949fa12018-09-11 12:11:48 +05301856 if (!dwc3_notify_event(dwc, DWC3_CORE_PM_RESUME_EVENT, 0)) {
1857 /*
1858 * If the core was in host mode during suspend, then set the
1859 * runtime PM state as active to reflect actual state of device
1860 * which is now out of LPM. This allows runtime_suspend later.
1861 */
1862 if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST &&
1863 dwc->host_poweroff_in_pm_suspend)
1864 goto runtime_set_active;
1865
Jack Pham62523502018-01-15 16:37:05 -08001866 return 0;
Ajay Agarwal0949fa12018-09-11 12:11:48 +05301867 }
Jack Pham62523502018-01-15 16:37:05 -08001868
Sekhar Nori63444752015-08-31 21:09:08 +05301869 pinctrl_pm_select_default_state(dev);
1870
Manu Gautamc4a51532018-01-18 16:54:30 +05301871 ret = dwc3_resume_common(dwc, PMSG_RESUME);
Felipe Balbi51f5d492016-05-16 10:52:58 +03001872 if (ret)
Felipe Balbi5c4ad3182016-04-11 17:12:34 +03001873 return ret;
1874
Ajay Agarwal0949fa12018-09-11 12:11:48 +05301875runtime_set_active:
Felipe Balbi7415f172012-04-30 14:56:33 +03001876 pm_runtime_disable(dev);
1877 pm_runtime_set_active(dev);
1878 pm_runtime_enable(dev);
1879
1880 return 0;
1881}
Felipe Balbi7f370ed2016-05-09 15:27:01 +03001882#endif /* CONFIG_PM_SLEEP */
Felipe Balbi7415f172012-04-30 14:56:33 +03001883
1884static const struct dev_pm_ops dwc3_dev_pm_ops = {
Felipe Balbi7415f172012-04-30 14:56:33 +03001885 SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume)
Felipe Balbifc8bb912016-05-16 13:14:48 +03001886 SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume,
1887 dwc3_runtime_idle)
Felipe Balbi7415f172012-04-30 14:56:33 +03001888};
1889
Kishon Vijay Abraham I5088b6f2013-01-25 16:36:53 +05301890#ifdef CONFIG_OF
1891static const struct of_device_id of_dwc3_match[] = {
1892 {
Felipe Balbi22a5aa12013-07-02 21:20:24 +03001893 .compatible = "snps,dwc3"
1894 },
1895 {
Kishon Vijay Abraham I5088b6f2013-01-25 16:36:53 +05301896 .compatible = "synopsys,dwc3"
1897 },
1898 { },
1899};
1900MODULE_DEVICE_TABLE(of, of_dwc3_match);
1901#endif
1902
Heikki Krogerus404905a2014-09-25 10:57:02 +03001903#ifdef CONFIG_ACPI
1904
1905#define ACPI_ID_INTEL_BSW "808622B7"
1906
1907static const struct acpi_device_id dwc3_acpi_match[] = {
1908 { ACPI_ID_INTEL_BSW, 0 },
1909 { },
1910};
1911MODULE_DEVICE_TABLE(acpi, dwc3_acpi_match);
1912#endif
1913
Felipe Balbi72246da2011-08-19 18:10:58 +03001914static struct platform_driver dwc3_driver = {
1915 .probe = dwc3_probe,
Bill Pemberton76904172012-11-19 13:21:08 -05001916 .remove = dwc3_remove,
Felipe Balbi72246da2011-08-19 18:10:58 +03001917 .driver = {
1918 .name = "dwc3",
Kishon Vijay Abraham I5088b6f2013-01-25 16:36:53 +05301919 .of_match_table = of_match_ptr(of_dwc3_match),
Heikki Krogerus404905a2014-09-25 10:57:02 +03001920 .acpi_match_table = ACPI_PTR(dwc3_acpi_match),
Felipe Balbi7f370ed2016-05-09 15:27:01 +03001921 .pm = &dwc3_dev_pm_ops,
Felipe Balbi72246da2011-08-19 18:10:58 +03001922 },
Felipe Balbi72246da2011-08-19 18:10:58 +03001923};
1924
Tobias Klauserb1116dc2012-02-28 12:57:20 +01001925module_platform_driver(dwc3_driver);
1926
Sebastian Andrzej Siewior7ae4fc42011-10-19 19:39:50 +02001927MODULE_ALIAS("platform:dwc3");
Felipe Balbi72246da2011-08-19 18:10:58 +03001928MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
Felipe Balbi5945f782013-06-30 14:15:11 +03001929MODULE_LICENSE("GPL v2");
Felipe Balbi72246da2011-08-19 18:10:58 +03001930MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");