gadget.c (879f99ef2c4c05d9a7f0a67a05f1415663119825) gadget.c (b09e99ee7c2b7ee80cca128b93b07fb830e6ecad)
1/**
2 * gadget.c - DesignWare USB3 DRD Controller Gadget Framework Link
3 *
4 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
5 *
6 * Authors: Felipe Balbi <balbi@ti.com>,
7 * Sebastian Andrzej Siewior <bigeasy@linutronix.de>
8 *

--- 173 unchanged lines hidden (view full) ---

182 mdwidth >>= 3;
183
184 /*
185 * FIXME For now we will only allocate 1 wMaxPacketSize space
186 * for each enabled endpoint, later patches will come to
187 * improve this algorithm so that we better use the internal
188 * FIFO space
189 */
1/**
2 * gadget.c - DesignWare USB3 DRD Controller Gadget Framework Link
3 *
4 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
5 *
6 * Authors: Felipe Balbi <balbi@ti.com>,
7 * Sebastian Andrzej Siewior <bigeasy@linutronix.de>
8 *

--- 173 unchanged lines hidden (view full) ---

182 mdwidth >>= 3;
183
184 /*
185 * FIXME For now we will only allocate 1 wMaxPacketSize space
186 * for each enabled endpoint, later patches will come to
187 * improve this algorithm so that we better use the internal
188 * FIFO space
189 */
190 for (num = 0; num < dwc->num_in_eps; num++) {
191 /* bit0 indicates direction; 1 means IN ep */
192 struct dwc3_ep *dep = dwc->eps[(num << 1) | 1];
190 for (num = 0; num < DWC3_ENDPOINTS_NUM; num++) {
191 struct dwc3_ep *dep = dwc->eps[num];
192 int fifo_number = dep->number >> 1;
193 int mult = 1;
194 int tmp;
195
193 int mult = 1;
194 int tmp;
195
196 if (!(dep->number & 1))
197 continue;
198
196 if (!(dep->flags & DWC3_EP_ENABLED))
197 continue;
198
199 if (usb_endpoint_xfer_bulk(dep->endpoint.desc)
200 || usb_endpoint_xfer_isoc(dep->endpoint.desc))
201 mult = 3;
202
203 /*

--- 12 unchanged lines hidden (view full) ---

216
217 fifo_size = DIV_ROUND_UP(tmp, mdwidth);
218
219 fifo_size |= (last_fifo_depth << 16);
220
221 dev_vdbg(dwc->dev, "%s: Fifo Addr %04x Size %d\n",
222 dep->name, last_fifo_depth, fifo_size & 0xffff);
223
199 if (!(dep->flags & DWC3_EP_ENABLED))
200 continue;
201
202 if (usb_endpoint_xfer_bulk(dep->endpoint.desc)
203 || usb_endpoint_xfer_isoc(dep->endpoint.desc))
204 mult = 3;
205
206 /*

--- 12 unchanged lines hidden (view full) ---

219
220 fifo_size = DIV_ROUND_UP(tmp, mdwidth);
221
222 fifo_size |= (last_fifo_depth << 16);
223
224 dev_vdbg(dwc->dev, "%s: Fifo Addr %04x Size %d\n",
225 dep->name, last_fifo_depth, fifo_size & 0xffff);
226
224 dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(num), fifo_size);
227 dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(fifo_number),
228 fifo_size);
225
226 last_fifo_depth += (fifo_size & 0xffff);
227 }
228
229 return 0;
230}
231
232void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,

--- 60 unchanged lines hidden (view full) ---

293 return "Set Endpoint Transfer Resource";
294 case DWC3_DEPCMD_SETEPCONFIG:
295 return "Set Endpoint Configuration";
296 default:
297 return "UNKNOWN command";
298 }
299}
300
229
230 last_fifo_depth += (fifo_size & 0xffff);
231 }
232
233 return 0;
234}
235
236void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,

--- 60 unchanged lines hidden (view full) ---

297 return "Set Endpoint Transfer Resource";
298 case DWC3_DEPCMD_SETEPCONFIG:
299 return "Set Endpoint Configuration";
300 default:
301 return "UNKNOWN command";
302 }
303}
304
305static const char *dwc3_gadget_generic_cmd_string(u8 cmd)
306{
307 switch (cmd) {
308 case DWC3_DGCMD_SET_LMP:
309 return "Set LMP";
310 case DWC3_DGCMD_SET_PERIODIC_PAR:
311 return "Set Periodic Parameters";
312 case DWC3_DGCMD_XMIT_FUNCTION:
313 return "Transmit Function Wake Device Notification";
314 case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_LO:
315 return "Set Scratchpad Buffer Array Address Lo";
316 case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_HI:
317 return "Set Scratchpad Buffer Array Address Hi";
318 case DWC3_DGCMD_SELECTED_FIFO_FLUSH:
319 return "Selected FIFO Flush";
320 case DWC3_DGCMD_ALL_FIFO_FLUSH:
321 return "All FIFO Flush";
322 case DWC3_DGCMD_SET_ENDPOINT_NRDY:
323 return "Set Endpoint NRDY";
324 case DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK:
325 return "Run SoC Bus Loopback Test";
326 default:
327 return "UNKNOWN";
328 }
329}
330
331static const char *dwc3_gadget_link_string(enum dwc3_link_state link_state)
332{
333 switch (link_state) {
334 case DWC3_LINK_STATE_U0:
335 return "U0";
336 case DWC3_LINK_STATE_U1:
337 return "U1";
338 case DWC3_LINK_STATE_U2:
339 return "U2";
340 case DWC3_LINK_STATE_U3:
341 return "U3";
342 case DWC3_LINK_STATE_SS_DIS:
343 return "SS.Disabled";
344 case DWC3_LINK_STATE_RX_DET:
345 return "RX.Detect";
346 case DWC3_LINK_STATE_SS_INACT:
347 return "SS.Inactive";
348 case DWC3_LINK_STATE_POLL:
349 return "Polling";
350 case DWC3_LINK_STATE_RECOV:
351 return "Recovery";
352 case DWC3_LINK_STATE_HRESET:
353 return "Hot Reset";
354 case DWC3_LINK_STATE_CMPLY:
355 return "Compliance";
356 case DWC3_LINK_STATE_LPBK:
357 return "Loopback";
358 case DWC3_LINK_STATE_RESET:
359 return "Reset";
360 case DWC3_LINK_STATE_RESUME:
361 return "Resume";
362 default:
363 return "UNKNOWN link state\n";
364 }
365}
366
301int dwc3_send_gadget_generic_command(struct dwc3 *dwc, int cmd, u32 param)
302{
303 u32 timeout = 500;
304 u32 reg;
305
367int dwc3_send_gadget_generic_command(struct dwc3 *dwc, int cmd, u32 param)
368{
369 u32 timeout = 500;
370 u32 reg;
371
372 dev_vdbg(dwc->dev, "generic cmd '%s' [%d] param %08x\n",
373 dwc3_gadget_generic_cmd_string(cmd), cmd, param);
374
306 dwc3_writel(dwc->regs, DWC3_DGCMDPAR, param);
307 dwc3_writel(dwc->regs, DWC3_DGCMD, cmd | DWC3_DGCMD_CMDACT);
308
309 do {
310 reg = dwc3_readl(dwc->regs, DWC3_DGCMD);
311 if (!(reg & DWC3_DGCMD_CMDACT)) {
312 dev_vdbg(dwc->dev, "Command Complete --> %d\n",
313 DWC3_DGCMD_STATUS(reg));

--- 13 unchanged lines hidden (view full) ---

327
328int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
329 unsigned cmd, struct dwc3_gadget_ep_cmd_params *params)
330{
331 struct dwc3_ep *dep = dwc->eps[ep];
332 u32 timeout = 500;
333 u32 reg;
334
375 dwc3_writel(dwc->regs, DWC3_DGCMDPAR, param);
376 dwc3_writel(dwc->regs, DWC3_DGCMD, cmd | DWC3_DGCMD_CMDACT);
377
378 do {
379 reg = dwc3_readl(dwc->regs, DWC3_DGCMD);
380 if (!(reg & DWC3_DGCMD_CMDACT)) {
381 dev_vdbg(dwc->dev, "Command Complete --> %d\n",
382 DWC3_DGCMD_STATUS(reg));

--- 13 unchanged lines hidden (view full) ---

396
397int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
398 unsigned cmd, struct dwc3_gadget_ep_cmd_params *params)
399{
400 struct dwc3_ep *dep = dwc->eps[ep];
401 u32 timeout = 500;
402 u32 reg;
403
335 dev_vdbg(dwc->dev, "%s: cmd '%s' params %08x %08x %08x\n",
404 dev_vdbg(dwc->dev, "%s: cmd '%s' [%d] params %08x %08x %08x\n",
336 dep->name,
405 dep->name,
337 dwc3_gadget_ep_cmd_string(cmd), params->param0,
406 dwc3_gadget_ep_cmd_string(cmd), cmd, params->param0,
338 params->param1, params->param2);
339
340 dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0);
341 dwc3_writel(dwc->regs, DWC3_DEPCMDPAR1(ep), params->param1);
342 dwc3_writel(dwc->regs, DWC3_DEPCMDPAR2(ep), params->param2);
343
344 dwc3_writel(dwc->regs, DWC3_DEPCMD(ep), cmd | DWC3_DEPCMD_CMDACT);
345 do {

--- 164 unchanged lines hidden (view full) ---

510 */
511static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,
512 const struct usb_endpoint_descriptor *desc,
513 const struct usb_ss_ep_comp_descriptor *comp_desc,
514 bool ignore, bool restore)
515{
516 struct dwc3 *dwc = dep->dwc;
517 u32 reg;
407 params->param1, params->param2);
408
409 dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0);
410 dwc3_writel(dwc->regs, DWC3_DEPCMDPAR1(ep), params->param1);
411 dwc3_writel(dwc->regs, DWC3_DEPCMDPAR2(ep), params->param2);
412
413 dwc3_writel(dwc->regs, DWC3_DEPCMD(ep), cmd | DWC3_DEPCMD_CMDACT);
414 do {

--- 164 unchanged lines hidden (view full) ---

579 */
580static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,
581 const struct usb_endpoint_descriptor *desc,
582 const struct usb_ss_ep_comp_descriptor *comp_desc,
583 bool ignore, bool restore)
584{
585 struct dwc3 *dwc = dep->dwc;
586 u32 reg;
518 int ret = -ENOMEM;
587 int ret;
519
520 dev_vdbg(dwc->dev, "Enabling %s\n", dep->name);
521
522 if (!(dep->flags & DWC3_EP_ENABLED)) {
523 ret = dwc3_gadget_start_config(dwc, dep);
524 if (ret)
525 return ret;
526 }

--- 72 unchanged lines hidden (view full) ---

599 */
600static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
601{
602 struct dwc3 *dwc = dep->dwc;
603 u32 reg;
604
605 dwc3_remove_requests(dwc, dep);
606
588
589 dev_vdbg(dwc->dev, "Enabling %s\n", dep->name);
590
591 if (!(dep->flags & DWC3_EP_ENABLED)) {
592 ret = dwc3_gadget_start_config(dwc, dep);
593 if (ret)
594 return ret;
595 }

--- 72 unchanged lines hidden (view full) ---

668 */
669static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
670{
671 struct dwc3 *dwc = dep->dwc;
672 u32 reg;
673
674 dwc3_remove_requests(dwc, dep);
675
676 /* make sure HW endpoint isn't stalled */
677 if (dep->flags & DWC3_EP_STALL)
678 __dwc3_gadget_ep_set_halt(dep, 0);
679
607 reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);
608 reg &= ~DWC3_DALEPENA_EP(dep->number);
609 dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
610
611 dep->stream_capable = false;
612 dep->endpoint.desc = NULL;
613 dep->comp_desc = NULL;
614 dep->type = 0;

--- 1821 unchanged lines hidden (view full) ---

2436 break;
2437 default:
2438 /* do nothing */
2439 break;
2440 }
2441 }
2442 }
2443
680 reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);
681 reg &= ~DWC3_DALEPENA_EP(dep->number);
682 dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
683
684 dep->stream_capable = false;
685 dep->endpoint.desc = NULL;
686 dep->comp_desc = NULL;
687 dep->type = 0;

--- 1821 unchanged lines hidden (view full) ---

2509 break;
2510 default:
2511 /* do nothing */
2512 break;
2513 }
2514 }
2515 }
2516
2444 dwc->link_state = next;
2445
2446 switch (next) {
2447 case DWC3_LINK_STATE_U1:
2448 if (dwc->speed == USB_SPEED_SUPER)
2449 dwc3_suspend_gadget(dwc);
2450 break;
2451 case DWC3_LINK_STATE_U2:
2452 case DWC3_LINK_STATE_U3:
2453 dwc3_suspend_gadget(dwc);
2454 break;
2455 case DWC3_LINK_STATE_RESUME:
2456 dwc3_resume_gadget(dwc);
2457 break;
2458 default:
2459 /* do nothing */
2460 break;
2461 }
2462
2517 switch (next) {
2518 case DWC3_LINK_STATE_U1:
2519 if (dwc->speed == USB_SPEED_SUPER)
2520 dwc3_suspend_gadget(dwc);
2521 break;
2522 case DWC3_LINK_STATE_U2:
2523 case DWC3_LINK_STATE_U3:
2524 dwc3_suspend_gadget(dwc);
2525 break;
2526 case DWC3_LINK_STATE_RESUME:
2527 dwc3_resume_gadget(dwc);
2528 break;
2529 default:
2530 /* do nothing */
2531 break;
2532 }
2533
2463 dev_vdbg(dwc->dev, "%s link %d\n", __func__, dwc->link_state);
2534 dev_vdbg(dwc->dev, "link change: %s [%d] -> %s [%d]\n",
2535 dwc3_gadget_link_string(dwc->link_state),
2536 dwc->link_state, dwc3_gadget_link_string(next), next);
2537
2538 dwc->link_state = next;
2464}
2465
2466static void dwc3_gadget_hibernation_interrupt(struct dwc3 *dwc,
2467 unsigned int evtinfo)
2468{
2469 unsigned int is_ss = evtinfo & BIT(4);
2470
2471 /**

--- 365 unchanged lines hidden ---
2539}
2540
2541static void dwc3_gadget_hibernation_interrupt(struct dwc3 *dwc,
2542 unsigned int evtinfo)
2543{
2544 unsigned int is_ss = evtinfo & BIT(4);
2545
2546 /**

--- 365 unchanged lines hidden ---