Commit Graph

599099 Commits

Author SHA1 Message Date
Vardan Mikayelyan
84e6782ac8 UPSTREAM: usb: dwc2: gadget: Add Incomplete ISO IN/OUT Interrupt handlers
Incomplete ISO IN interrupt indicates one of the following conditions
occurred while transmitting an ISOC transaction.
- Corrupted IN Token for ISOC EP.
- Packet not complete in FIFO.

Incomplete ISO OUT indicates that there is at least one isochronous OUT
endpoint on which the transfer is not completed in the current
microframe.

The following actions will be taken:

In case of EP-IN
- Determine the EP
- Disable EP directly from this handler; when "Endpoint Disabled"
  interrupt is received flush FIFO

In case of EP-OUT
- Determine the EP
- If target frame elapsed set DCTL_SGOUTNAK, unmask GOUTNAKEFF and
  proceed as described in section 7.5.1 of DWC-HSOTG Programming Guide

Also added dwc2_gadget_target_frame_elapsed() helper function which
will be used in Incomplete ISO IN/OUT Interrupt handlers.

Change-Id: Id9832f7832eafc2c510f0d87bd38e4b820111352
Tested-by: John Keeping <john@metanate.com>
Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 381fc8f822)
2017-01-03 18:48:48 +08:00
Vardan Mikayelyan
29a67f7e3e UPSTREAM: usb: dwc2: gadget: Add OUTTKNEPDIS and NAKINTRPT handlers
NAKINTRPT interrupt is starting point for isoc-in transfer,
synchronization done with first in token received from host,
core asserts this interrupt when responds with 0 length data
to in token, received from host.

The first IN token is asynchronous for device - device does not
know when first one token will arrive from host. On first token
arrival HW generates 2 interrupts: 'in token received while FIFO
empty' and 'NAK'. NAK interrupt for ISOC in means that token has
arrived and ZLP was sent in response to that as there was no data
in FIFO. SW is basing on this interrupt to obtain frame in which
token has come and then based on the interval calculates next
frame for transfer.

OUTTKNEPDIS interrupt is starting point for isoc-out transfer,
synchronization done with first out token received from host
while corresponding ep is disabled.

For OUTs the reason is same - device does not know initial frame
in which out token will come. For this HW generates OUTTKNEPDIS
- out token is received while EP is disabled. Upon getting this
interrupt SW starts calculation for next transfer frame.

Change-Id: I178a19c9afbac314096e9a989966c3c778f95fce
Tested-by: John Keeping <john@metanate.com>
Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 5321922cb6)
2017-01-03 18:48:47 +08:00
Vardan Mikayelyan
d71829feff UPSTREAM: usb: dwc2: gadget: Add dwc2_gadget_start_next_request function
Replaced repeating code with function call.

Starts next request from ep queue.
If queue is empty and ep is isoc
-In case of OUT-EP unmasks OUTTKNEPDIS.

OUTTKNEPDIS is masked in it's handler, so we need to unmask it here
to be able to do resynchronization.

Change-Id: Ib9d72c0ef728e145ac959218386c333f674ae0e2
Tested-by: John Keeping <john@metanate.com>
Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 41cc4cd271)
2017-01-03 18:48:46 +08:00
Vardan Mikayelyan
ad618f0917 UPSTREAM: usb: dwc2: gadget: Add dwc2_gadget_read_ep_interrupts function
Reads and returns interrupts for given endpoint, by masking epint_reg
with corresponding mask.

Change-Id: I8f5af249b8569a19435665bef2c2a841672f1c03
Tested-by: John Keeping <john@metanate.com>
Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 326015887b)
2017-01-03 18:48:45 +08:00
Vardan Mikayelyan
e31c6f8cad UPSTREAM: usb: dwc2: gadget: Corrected interval calculation
Calculate the interval according to the USB 2.0 specification section
9.6.6.

Change-Id: I918faedbaa22d0151d48ed45907baf71f000c831
Tested-by: John Keeping <john@metanate.com>
Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 142bd33fcd)
2017-01-03 18:48:44 +08:00
Vardan Mikayelyan
206703194a UPSTREAM: usb: dwc2: gadget: Add dwc2_gadget_incr_frame_num()
Increases and checks targeted frame number of current ep
if overrun happened, sets flag and masks with DSTS_SOFFN_LIMIT

Added following fields to struct dwc2_hsotg_ep
-target_frame: Targeted frame num to setup next ISOC transfer
-frame_overrun: Indicates SOF number overrun in DSTS

Change-Id: I80c0bc7bfe18e4e88b051795486c1cfccaa95b42
Tested-by: John Keeping <john@metanate.com>
Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 92d1635d78)
2017-01-03 18:48:43 +08:00
Vardan Mikayelyan
626df6922b UPSTREAM: usb: dwc2: gadget: Fix transfer stop programming for out endpoint
According DWC-OTG databook, "GOUTNakEff" is read only and can be
cleared only by "DCTL.CGOUTNak", but here we do not need to clear
it because DWC-OTG programming guide says that before disabling
any OUT endpoint, the application must enable Global OUT NAK mode,
so if this mode is enabled we can continue without this step.

Change-Id: If85da6787d585582712ca5d116db52caa70e72fc
Tested-by: John Keeping <john@metanate.com>
Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 6b58cb07a8)
2017-01-03 18:48:42 +08:00
Vardan Mikayelyan
d0e9fbb5e2 UPSTREAM: usb: dwc2: gadget: Corrected field names
No-op change. Changed field names to prevent misunderstanding.

Change-Id: I16d6c510a8efb88c12e2205a23d838e23012ed97
Tested-by: John Keeping <john@metanate.com>
Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 26ddef5da6)
2017-01-03 18:48:41 +08:00
Vardan Mikayelyan
c31fe3bb2e UPSTREAM: usb: dwc2: gadget: Remove unnecessary code
This chunk is not needed here. There is no functionality
depend on this, so if no-op, I think we do not need to have
this interrupt unmasked.

Change-Id: I74a0861ce66e23888c001b7cf1833b7cce715362
Tested-by: John Keeping <john@metanate.com>
Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 7c01b99154)
2017-01-03 18:48:40 +08:00
Vardan Mikayelyan
128ba5bcdd UPSTREAM: usb: dwc2: gadget: Remove unnecessary line
Removed "ctrl |= DXEPCTL_USBACTEP" from
dwc2_hsotg_start_req() function because this
step is done in dwc2_hsotg_ep_enable().

Change-Id: I9675b30e1849c4f9d1ee099df44023dda8b5cf13
Tested-by: John Keeping <john@metanate.com>
Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 04cde4787d)
2017-01-03 18:48:39 +08:00
Vardan Mikayelyan
816c10f4d5 UPSTREAM: usb: dwc2: Add missing register field definitions
Added register field definitions, register names are according
DWC-OTG databook.

Change-Id: I4eb5aa7763760bb9c9ef9e0107250fe4015c8750
Tested-by: John Keeping <john@metanate.com>
Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 106528b21d)
2017-01-03 18:48:38 +08:00
Vahram Aharonyan
4e33319307 UPSTREAM: usb: dwc2: gadget: Do not halt isochronous endpoints
Add a check in dwc2_hsotg_ep_sethalt() so that it does not halt
isochronous endpoints.

Change-Id: I72d5cf2ba7fb6cfa8ab8e33d16c4e3b33ce31e4f
Signed-off-by: Vahram Aharonyan <vahrama@synopsys.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 15186f1011)
2017-01-03 18:48:37 +08:00
Vahram Aharonyan
5ce894611b UPSTREAM: usb: dwc2: gadget: Do not halt endpoint if active
The gadget API function usb_ep_set_halt() expects the gadget to return
-EAGAIN if the ep is active. Add support for this behavior.

Otherwise this may break mass storage protocol if a STALL is attempted
on the endpoint.

Change-Id: I935ca97dfc5f6a97c2aeaef0afab97d7a0324a3a
Signed-off-by: Vahram Aharonyan <vahrama@synopsys.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 51da43b555)
2017-01-03 18:48:36 +08:00
John Youn
0138d6e488 UPSTREAM: usb: dwc2: Proper cleanup on dr_mode failure
Cleanup in probe if we fail to get dr_mode.

Change-Id: I8b2f1cf210b9baa6fc81bddd9b64be1bf5e657fb
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit a6ef3e0254)
2017-01-03 18:48:35 +08:00
Sevak Arakelyan
970b192ff5 UPSTREAM: usb: dwc2: Fixed SOF interrupt enabling/disabling
In case of DDMA mode we don't need to get an SOF interrupt so disable
the unmasking of SOF interrupt in DDMA mode.

Change-Id: I8a58bf26e8c9493a39e3f8ba6da1204d13b52127
Signed-off-by: Sevak Arakelyan <sevaka@synopsys.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 907a444718)
2017-01-03 18:48:35 +08:00
Vardan Mikayelyan
4b13398a4c UPSTREAM: usb: dwc2: host: Setting qtd to NULL after freeing it
This is safety change added while doing slub debugging.

Affected functions:
dwc2_hcd_qtd_unlink_and_free()
_dwc2_hcd_urb_enqueue()

Change-Id: Ie541e0390fd5475852ede4216b2b90d7a87f5430
Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit b0d659022e)
2017-01-03 18:48:34 +08:00
Vardan Mikayelyan
83ecfee1ac UPSTREAM: usb: dwc2: gadget: Prevent handling of host interrupts
In host slave mode, the core asserts the rxready, txfifoempty interrupts
that get serviced in the gadget irq handler. Prevent servicing of these
when not in the gadget mode of operation.

Change-Id: I821c48399f876de045649507435bf2a3e9cf4cc5
Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit ee3de8d750)
2017-01-03 18:48:33 +08:00
Vahram Aharonyan
4e026285ea UPSTREAM: usb: dwc2: gadget: Check for ep0 in enable
Replaced the WARN_ON with a check and return of -EINVAL in the
dwc2_hsotg_ep_enable function if ep0 is passed in.

Change-Id: Idf4bf147a52ff9dca294f76263438e41cc511cfc
Signed-off-by: Vahram Aharonyan <vahrama@synopsys.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 8c3d609275)
2017-01-03 18:48:32 +08:00
Przemek Rudy
1f6a1f5c5d UPSTREAM: usb: dwc2: do not override forced dr_mode in gadget setup
The host/device mode set with dr_mode should be kept all the time,
not being changed to OTG in gadget setup (by overriding CFGUSB_FORCEDEVMODE
and CFGUSB_FORCEHOSTMODE bits).

Change-Id: I80037fb325d00cb302c223a65ef3ac628955fe08
Acked-by: John Youn <johnyoun@synopsys.com>
Tested-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Przemek Rudy <prudy1@o2.pl>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit ecd9a7ad45)
2017-01-03 18:48:31 +08:00
John Youn
735f185540 UPSTREAM: usb: dwc2: Fix issues in dwc2_complete_non_isoc_xfer_ddma()
Fixes a static analysis issue in dwc2_complete_non_isoc_xfer_ddma(). The
qtd was being passed to a function after being freed. It was not being
used in the function so this doesn't fix any bugs. But it fixes up the
warning and makes the code safer by setting qtd to NULL and not using it
at all.

Change-Id: I5224d5b7854c23cc0d0931b5a131f93b9a2ce8c8
Reported-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 1fc6598949)
2017-01-03 18:48:30 +08:00
Antti Seppälä
08d26ac585 UPSTREAM: usb: dwc2: Add support for Lantiq ARX and XRX SoCs
Add support for Lantiq ARX and XRX SoC families to the dwc2 driver.

Change-Id: If63c644caae24de6f7230923a63eda40a6b486c2
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Antti Seppälä <a.seppala@gmail.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 6c0c0951bb)
2017-01-03 18:48:29 +08:00
John Youn
7b255fa138 UPSTREAM: usb: dwc2: Move host-specific core functions into hcd.c
Move host core initialization and host channel routines into hcd.c. This
allows these functions to only be compiled in host-enabled driver
configurations (DRD or host-only).

Change-Id: Ib7ed69e977143de58a6055ecf417a48cf603cdff
Tested-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit b02038faa7)
2017-01-03 18:48:28 +08:00
John Youn
7c95a780b8 UPSTREAM: usb: dwc2: Move register save and restore functions
Move the register save and restore functions into the host and gadget
specific files.

Change-Id: If9a11b19ee459d0cd1cd560f0302c83518b3f6af
Tested-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 58e52ff6a6)
2017-01-03 18:48:27 +08:00
Amitoj Kaur Chawla
60e94e7837 UPSTREAM: usb: dwc2: Use kmem_cache_free()
Here, free memory is allocated using kmem_cache_zalloc.  So, use
kmem_cache_free instead of kfree.

This is done using Coccinelle and semantic patch used
is as follows:

//<smpl>
@@
expression x,E,c;
@@
 x =
\(kmem_cache_alloc\|kmem_cache_zalloc\|kmem_cache_alloc_node\)(c,...)
 ... when != x = E
     when != &x
?-kfree(x)
+kmem_cache_free(c,x)
//</smpl>

Change-Id: I41fee7d3451196cc04d99104ecb7f4e7f84df3c9
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Amitoj Kaur Chawla <amitoj1606@gmail.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 9bbe91a1ea)
2017-01-03 18:48:26 +08:00
Douglas Anderson
a9ce138f79 UPSTREAM: usb: dwc2: host: If using uframe scheduler, end splits better
The microframe scheduler figured out exactly how many transfers we need
for a split transaction.  Let's use this knowledge to know when to end
things.

Without this I found that certain devices would just keep responding
with tons of NYET resonses on their INT_IN endpoint.  These would just
keep going and going and eventually we'd decide to terminate the
transfer (because the whole frame changed), but by that time the
scheduler would decide that we "missed" the start of the next transfer.
I can also imagine that if we blow past the end of our scheduled time we
may mess up other things that were scheduled to happen.

No known test cases are improved by this patch except that the scheduler
code doesn't yell about MISSES constantly anymore.

Change-Id: I743b8b121a3c41fdec33b463318f816654aa2bba
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 1479cb698a)
2017-01-03 18:48:25 +08:00
Douglas Anderson
febc1a5eda UPSTREAM: usb: dwc2: host: Totally redo the microframe scheduler
This totally reimplements the microframe scheduler in dwc2 to attempt to
handle periodic splits properly.  The old code didn't even try, so this
was a significant effort since periodic splits are one of the most
complicated things in USB.

I've attempted to keep the old "don't use the microframe" schduler
around for now, but not sure it's needed.  It has also only been lightly
tested.

I think it's pretty certain that this scheduler isn't perfect and might
have some bugs, but it seems much better than what was there before.
With this change my stressful USB test (USB webcam + USB audio + some
keyboards) crackles less.

Change-Id: Ifca7815fdff3301c0897aa4eb55e573384596344
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 9f9f09b048)
2017-01-03 18:48:24 +08:00
Douglas Anderson
704d02125c UPSTREAM: usb: dwc2: host: Properly set even/odd frame
When setting up ISO and INT transfers dwc2 needs to specify whether the
transfer is for an even or an odd frame (or microframe if the controller
is running in high speed mode).

The controller appears to use this as a simple way to figure out if a
transfer should happen right away (in the current microframe) or should
happen at the start of the next microframe.  Said another way:

- If you set "odd" and the current frame number is odd it appears that
  the controller will try to transfer right away.  Same thing if you set
  "even" and the current frame number is even.
- If the oddness you set and the oddness of the frame number are
  _different_, the transfer will be delayed until the frame number
  changes.

As I understand it, the above technique allows you to plan ahead of time
where possible by always working on the next frame.  ...but it still
allows you to properly respond immediately to things that happened in
the previous frame.

The old dwc2_hc_set_even_odd_frame() didn't really handle this concept.
It always looked at the frame number and setup the transfer to happen in
the next frame.  In some cases that meant that certain transactions
would be transferred in the wrong frame.

We'll try our best to set the even / odd to do the transfer in the
scheduled frame.  If that fails then we'll do an ugly "schedule ASAP".
We'll also modify the scheduler code to handle this and not try to
schedule a second transfer for the same frame.

Note that this change relies on the work to redo the microframe
scheduler.  It can work atop ("usb: dwc2: host: Manage frame nums better
in scheduler") but it works even better after ("usb: dwc2: host: Totally
redo the microframe scheduler").

With this change my stressful USB test (USB webcam + USB audio +
keyboards) has less audio crackling than before.

Change-Id: I235e689c89be99a9f6ac406164c88e1d82e87260
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 9cf1a601d2)
2017-01-03 18:48:23 +08:00
Douglas Anderson
1062ece06e UPSTREAM: usb: dwc2: host: Add dwc2_hcd_get_future_frame_number() call
As we start getting more exact about our scheduling it's becoming more
and more important to know exactly how far through the current frame we
are.  This lets us make decisions about whether there's still time left
to start a new transaction in the current frame.

We'll add dwc2_hcd_get_future_frame_number() which will tell you what
the frame number will be a certain number of microseconds (us) from
now.  We can use this information to help decide if there's enough time
left in the frame for a transaction that will take a certain duration.

This is expected to be used by a future change ("usb: dwc2: host:
Properly set even/odd frame").

Change-Id: I3cb39be7281e537696b6378e798c36ccea254739
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit fae4e82609)
2017-01-03 18:48:22 +08:00
Douglas Anderson
0c89d45436 UPSTREAM: usb: dwc2: host: Manage frame nums better in scheduler
The dwc2 scheduler (contained in hcd_queue.c) was a bit confusing in the
way it initted / kept track of which frames a QH was going to be active
in.  Let's clean things up a little bit in preparation for a rewrite of
the microframe scheduler.

Specifically:
* Old code would pick a frame number in dwc2_qh_init() and would try to
  pick it "in a slightly future (micro)frame".  As far as I can tell the
  reason for this was that there was a delay between dwc2_qh_init() and
  when we actually wanted to dwc2_hcd_qh_add().  ...but apparently this
  attempt to be slightly in the future wasn't enough because
  dwc2_hcd_qh_add() then had code to reset things if the frame _wasn't_
  in the future.  There's no reason not to just pick the frame later.
  For non-periodic QH we now pick the frame in dwc2_hcd_qh_add().  For
  periodic QH we pick the frame at dwc2_schedule_periodic() time.
* The old "dwc2_qh_init() actually assigned to "hsotg->frame_number".
  This doesn't seem like a great idea since that variable is supposed to
  be used to keep track of which SOF the interrupt handler has seen.
  Let's be clean: anyone who wants the current frame number (instead of
  the one as of the last interrupt) should ask for it.
* The old code wasn't terribly consistent about trying to use the frame
  that the microframe scheduler assigned to it.  In
  dwc2_sched_periodic_split() when it was scheduling the first frame it
  always "ORed" in 0x7 (!).  Since the frame goes on the wire 1 uFrame
  after next_active_frame it meant that the SSPLIT would always try for
  uFrame 0 and the transaction would happen on the low speed bus during
  uFrame 1.  This is irregardless of what the microframe scheduler
  said.
* The old code assumed it would get called to schedule the next in a
  periodic split very quickly.  That is if next_active_frame was
  0 (transfer on wire in uFrame 1) it assumed it was getting called to
  schedule the next uFrame during uFrame 1 too (so it could queue
  something up for uFrame 2).  It should be possible to actually queue
  something up for uFrame 2 while in uFrame 2 (AKA queue up ASAP).  To
  do this, code needs to look at the previously scheduled frame when
  deciding when to next be active, not look at the current frame number.
* If there was no microframe scheduler, the old code would check for
  whether we should be active using "qh->next_active_frame ==
  frame_number".  This seemed like a race waiting to happen.  ...plus
  there's no way that you wouldn't want to schedule if next_active_frame
  was actually less than frame number.

Note that this change doesn't make 100% sense on its own since it's
expecting some sanity in the frame numbers assigned by the microframe
scheduler and (as per the future patch which rewries it) I think that
the current microframe scheduler is quite insane.  However, it seems
like splitting this up from the microframe scheduler patch makes things
into smaller chunks and hopefully adds to clarity rather than reduces
it.  The two patches could certainly be squashed.  Not that in the very
least, I don't see any obvious bad behavior introduced with just this
patch.

I've attempted to keep the config parameter to disable the microframe
scheduler in tact in this change, though I'm not sure it's worth it.
Obviously the code is touched a lot so it's possible I regressed
something when the microframe scheduler is disabled, though I did some
basic testing and it seemed to work OK.  I'm still not 100% sure why you
wouldn't want the microframe scheduler (presuming it works), so maybe a
future patch (or a future version of this patch?) could remove that
parameter.

Change-Id: I22486b060e24c06868a31ed593a1e38608fe1f02
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit fb616e3f83)
2017-01-03 18:48:21 +08:00
Douglas Anderson
89ae1bbeea UPSTREAM: usb: dwc2: host: Add scheduler logging for missed SOFs
We'll use the new "scheduler verbose debugging" macro to log missed
SOFs.  This is fast enough (assuming you configure it to use the ftrace
buffer) that we can do it without worrying about the speed hit.  The
overhead hit if the scheduler tracing is set to "no_printk" should be
near zero.

Change-Id: I2b4fa9ec5b4ddf15f9ff28d7a876cb4e6341a55d
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 483bb2544c)
2017-01-03 18:48:20 +08:00
Douglas Anderson
9480e38b39 UPSTREAM: usb: dwc2: host: Split code out to make dwc2_do_reserve()
This no-op change splits code out of dwc2_schedule_periodic() into a
dwc2_do_reserve() function.  This makes it a little easier to follow the
logic.

Change-Id: I24cd8d2718b150fdc0b4428e645c545b1d8dbeda
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 2d3f139810)
2017-01-03 18:48:19 +08:00
Douglas Anderson
76e44a44aa UPSTREAM: usb: dwc2: host: Reorder things in hcd_queue.c
This no-op change just reorders a few functions in hcd_queue.c in order
to prepare for future changes.  Motivations here:

The functions dwc2_hcd_qh_free() and dwc2_hcd_qh_create() are exported
functions.  They are not called within the file.  That means that they
should be near the bottom so that they can easily call static helpers.

The function dwc2_qh_init() is only called by dwc2_hcd_qh_create() and
should move near the bottom with it.

The only reason that the dwc2_unreserve_timer_fn() timer function (and
its subroutine dwc2_do_unreserve()) were so high in the file was that
they needed to be above dwc2_qh_init().  Now that dwc2_qh_init() has
been moved down it can be moved down a bit.  A later patch will split
the reserve code out of dwc2_schedule_periodic() and the reserve
function should be near the unreserve function.  The reserve function
needs to be below dwc2_find_uframe() since it calls that.

Change-Id: Ia9a230c8521ca8e98bff606d1863760a62a448d1
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit b951c6c7f8)
2017-01-03 18:48:18 +08:00
Douglas Anderson
b2653b3a2b UPSTREAM: usb: dwc2: host: Rename some fields in struct dwc2_qh
This no-op change just does some renames to simplify a future patch.

1. The "interval" field is renamed to "host_interval" to make it more
   obvious that this interval may be 8 times the interval that the
   device sees (if we're doing split transactions).  A future patch will
   also add the "device_interval" field.
2. The "usecs" field is renamed to "host_us" again to make it more
   obvious that this is the time for the transaction as seen by the
   host.  For split transactions the device may see a much longer
   transaction time.  A future patch will also add "device_us".
3. The "sched_frame" field is renamed to "next_active_frame".  The name
   "sched_frame" kept confusing me because it felt like something more
   permament (the QH's reservation or something).  The name
   "next_active_frame" makes it more obvious that this field is
   constantly changing.

Change-Id: I407af5bc79f46fcc63175603354ce20e8962982c
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit ced9eee122)
2017-01-03 18:48:17 +08:00
Douglas Anderson
7953995914 UPSTREAM: usb: dwc2: host: Use periodic interrupt even with DMA
The old code in dwc2_process_periodic_channels() would only enable the
"periodic empty" interrupt if we weren't using DMA.  That wasn't right
since we can still get into cases where we have small FIFOs even on
systems that have DMA (the rk3288 is a prime example).

Let's always enable/disable the "periodic empty" when appropriate.  As
part of this:

* Always call dwc2_process_periodic_channels() even if there's nothing
  in periodic_sched_assigned (we move the queue empty check so we still
  avoid the extra work).  That will make extra certain that we will
  properly disable the "periodic empty" interrupt even if there's
  nothing queued up.

* Move the enable of "periodic empty" due to non-empty
  periodic_sched_assigned to be for slave mode (non-DMA mode) only.
  Presumably this was the original intention of the check for DMA since
  it seems to match the comments above where in slave mode we leave
  things on the assigned queue.

Note that even before this change slave mode didn't work for me, so I
can't say for sure that my understanding of slave mode is correct.
However, this shouldn't change anything for slave mode so if slave mode
worked for someone in the past it ought to still work.

With this change, I no longer get constant misses reported by my other
debugging code (and with future patches) when I've got:
* Rockchip rk3288 Chromebook, using port ff540000
  -> Pluggable 7-port Hub with Charging (powered)
     -> Microsoft Wireless Keyboard 2000 in port 1.
     -> Das Keyboard in port 2.
     -> Jabra Speaker in port 3
     -> Logitech, Inc. Webcam C600 in port 4
     -> Microsoft Sidewinder X6 Keyboard in port 5

...and I'm playing music on the USB speaker and capturing video from the
webcam.

Change-Id: I9e6a9be0bcd35e4aff4eb8b004a40c31584f02cb
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 4e50e0110c)
2017-01-03 18:48:16 +08:00
Douglas Anderson
8e9fad9adc UPSTREAM: usb: dwc2: host: There's not really a TT for the root hub
I find that when I plug a full speed (NOT high speed) hub into a dwc2
port and then I plug a bunch of devices into that full speed hub that
dwc2 goes bat guano crazy.  Specifically, it just spews errors like this
in the console:
  usb usb1: clear tt 1 (9043) error -22

The specific test case I used looks like this:
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc2/1p, 480M
    |__ Port 1: Dev 17, If 0, Class=Hub, Driver=hub/4p, 12M
        |__ Port 2: Dev 19, If 0, ..., Driver=usbhid, 1.5M
        |__ Port 4: Dev 20, If 0, ..., Driver=usbhid, 12M
        |__ Port 4: Dev 20, If 1, ..., Driver=usbhid, 12M
        |__ Port 4: Dev 20, If 2, ..., Driver=usbhid, 12M

Showing VID/PID:
 Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
 Bus 001 Device 017: ID 03eb:3301 Atmel Corp. at43301 4-Port Hub
 Bus 001 Device 020: ID 045e:0745 Microsoft Corp. Nano Transceiver ...
 Bus 001 Device 019: ID 046d:c404 Logitech, Inc. TrackMan Wheel

I spent a bunch of time trying to figure out why there are errors to
begin with.  I believe that the issue may be a hardware issue where the
transceiver sometimes accidentally sends a PREAMBLE packet if you send a
packet to a full speed device right after one to a low speed device.
Luckily the USB driver retries and the second time things work OK.

In any case, things kinda seem work despite the errors, except for the
"clear tt" spew mucking up my console.  Chalk it up for a win for
retries and robust protocols.

So getting back to the "clear tt" problem, it appears that we get those
because there's not actually a TT here to clear.  It's my understanding
that when dwc2 operates in low speed or full speed mode that there's no
real TT out there.  That makes all these attempts to "clear the TT"
somewhat meaningless and also causes the spew in the log.

Let's just skip all the useless TT clears.  Eventually we should root
cause the errors, but even if we do this is still a proper fix and is
likely to avoid the "clear tt" error in the future.

Note that hooking up a Full Speed USB Audio Device (Jabra 510) to this
same hub with the keyboard / trackball shows that even audio works over
this janky connection.  As a point to note, this particular change (skip
bogus TT clears) compared to just commenting out the dev_err() in
hub_tt_work() actually produces better audio.

Note: don't ask me where I got a full speed USB hub or whether the
massive amount of dust that accumulated on it while it was in my junk
box affected its funtionality.  Just smile and nod.

Change-Id: I58e40aa7ce25ef3138ed03913b27a19218b5bdbd
Acked-by: John Youn <johnyoun@synopsys.com>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit d82a810eed)
2017-01-03 18:48:16 +08:00
Douglas Anderson
3c10e18d74 UPSTREAM: usb: dwc2: host: Properly set the HFIR
According to the most up to date version of the dwc2 databook, the FRINT
field of the HFIR register should be programmed to:
* 125 us * (PHY clock freq for HS) - 1
* 1000 us * (PHY clock freq for FS/LS) - 1

This is opposed to older versions of the doc that claimed it should be:
* 125 us * (PHY clock freq for HS)
* 1000 us * (PHY clock freq for FS/LS)

In case you didn't spot it, the difference is the "- 1".

Let's add the "- 1" to match the newest user manual.  It's presumed that
the "- 1" should have always been there and that this was always a
documentation error.  If some hardware needs the "- 1" and other
hardware doesn't, we'll have to add a configuration parameter for it in
the future.

I checked things before and after this patch on rk3288 using a Total
Phase Beagle 5000 analyzer.

Before this patch, a low speed mouse shows constant Frame Timing Jitter
errors.  After this patch errors have gone away.

Before this patch SOF packets move forward about 1 us per 4 ms.  After
this patch the SOF packets move backward about 1 us per 255 ms.  Some
specific SOF timestamps from the analyzer are below.

Before:
  6.603.790
  6.603.916
  6.604.041
  6.604.166
  ...
  6.607.541
  6.607.667
  6.607.792
  6.607.917
  ...
  6.611.417
  6.611.543
  6.611.668
  6.611.793

After:
  6.215.159
  6.215.284
  6.215.408
  6.215.533
  6.215.658
  ...
  6.470.658
  6.470.783
  6.470.907
  ...
  6.726.032
  6.726.157
  6.725.281
  6.725.406

Change-Id: Id431ef8fc208e8c73c22358422faf1016f81896a
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 9ed04d9761)
2017-01-03 18:48:15 +08:00
Douglas Anderson
388ce3e133 UPSTREAM: usb: dwc2: host: Giveback URB in tasklet context
In commit 94dfd7edfd ("USB: HCD: support giveback of URB in tasklet
context") support was added to give back the URB in tasklet context.
Let's take advantage of this in dwc2.

This speeds up the dwc2 interrupt handler considerably.

Note that this requires the change ("usb: dwc2: host: Add a delay before
releasing periodic bandwidth") to come first.

Note that, as per Alan Stern in
<https://patchwork.kernel.org/patch/7555771/>, we also need to make sure
that the extra delay before the device drivers submit more data doesn't
break the scheduler.  At the moment the scheduler is pretty broken (see
future patches) so it's hard to be 100% certain, but I have yet to see
any new breakage introduced by this delay.  ...and speeding up interrupt
processing for dwc2 is a huge deal because it means we've got a better
chance of not missing SOF interrupts.  That means we've got an overall
win here.

Note that when playing USB audio and using a USB webcam and having
several USB keyboards plugged in, the crackling on the USB audio device
is noticably reduced with this patch.

Change-Id: Ieab057cad78d41492a390e9cfff825eed0f728a9
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 8add17cf8e)
2017-01-03 18:48:14 +08:00
Douglas Anderson
c28b62a22f UPSTREAM: usb: dwc2: host: Add a delay before releasing periodic bandwidth
We'd like to be able to use HCD_BH in order to speed up the dwc2 host
interrupt handler quite a bit.  However, according to the kernel doc for
usb_submit_urb() (specifically the part about "Reserved Bandwidth
Transfers"), we need to keep a reservation active as long as a device
driver keeps submitting.  That was easy to do when we gave back the URB
in the interrupt context: we just looked at when our queue was empty and
released the reserved bandwidth then.  ...but now we need a little more
complexity.

We'll follow EHCI's lead in commit 9118f9eb4f ("USB: EHCI: improve
interrupt qh unlink") and add a 5ms delay.  Since we don't have a whole
timer infrastructure in dwc2, we'll just add a timer per QH.  The
overhead for this is very small.

Note that the dwc2 scheduler is pretty broken (see future patches to fix
it).  This patch attempts to replicate all old behavior and just add the
proper delay.

Change-Id: I051d768b1cefdbe8990a2dfae9c68c61ec9eedf0
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 17dd5b642d)
2017-01-03 18:48:12 +08:00
Douglas Anderson
ceb05ec686 UPSTREAM: usb: dwc2: host: Add scheduler tracing
In preparation for future changes to the scheduler let's add some
tracing that makes it easy for us to see what's happening.  By default
this tracing will be off.

By changing "core.h" you can easily trace to ftrace, the console, or
nowhere.

Change-Id: I5a9ba2c44ac5caeecfae5910cc5434941c8d0fb8
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 74fc4a7558)
2017-01-03 18:48:11 +08:00
Douglas Anderson
19aaf10fa9 UPSTREAM: usb: dwc2: host: fix split transfer schedule sequence
We're supposed to keep outstanding splits in order.  Keep track of a
list of the order of splits and process channel interrupts in that
order.

Without this change and the following setup:
* Rockchip rk3288 Chromebook, using port ff540000
  -> Pluggable 7-port Hub with Charging (powered)
     -> Microsoft Wireless Keyboard 2000 in port 1.
     -> Das Keyboard in port 2.

...I find that I get dropped keys on the Microsoft keyboard (I'm sure
there are other combinations that fail, but this documents my test).
Specifically I've been typing "hahahahahahaha" on the keyboard and often
see keys dropped or repeated.

After this change the above setup works properly.  This patch is based
on a previous patch proposed by Yunzhi Li ("usb: dwc2: hcd: fix periodic
transfer schedule sequence")

Change-Id: I1d461d73c21a117de86de2863c0412b4980a16d8
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Yunzhi Li <lyz@rock-chips.com>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Kever Yang <kever.yang@rock-chips.com>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
(cherry picked from commit c9c8ac0150)
2017-01-03 18:48:10 +08:00
Douglas Anderson
c176381322 UPSTREAM: usb: dwc2: host: Always add to the tail of queues
The queues the the dwc2 host controller used are truly queues.  That
means FIFO or first in first out.

Unfortunately though the code was iterating through these queues
starting from the head, some places in the code was adding things to the
queue by adding at the head instead of the tail.  That means last in
first out.  Doh.

Go through and just always add to the tail.

Doing this makes things much happier when I've got:
* 7-port USB 2.0 Single-TT hub
* - Microsoft 2.4 GHz Transceiver v7.0 dongle
* - Jabra speakerphone playing music

Change-Id: Iaaece8906b95cba659dab8b81211d83b23d11308
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 94ef7aee11)
2017-01-03 18:48:09 +08:00
Douglas Anderson
c6e98b18a3 UPSTREAM: usb: dwc2: host: Avoid use of chan->qh after qh freed
When poking around with USB devices with slub_debug enabled, I found
another obvious use after free.  Turns out that in dwc2_hc_n_intr() I
was in a state when the contents of chan->qh was filled with 0x6b,
indicating that chan->qh was freed but chan still had a reference to
it.

Let's make sure that whenever we free qh we also make sure we remove a
reference from its channel.

The bug fixed here doesn't appear to be new--I believe I just got lucky
and happened to see it while stress testing.

Change-Id: I5affca3f0edc051a95c4992ade6b940e07ef3869
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 16e8021881)
2017-01-03 18:48:08 +08:00
Douglas Anderson
3f0d1d69e0 UPSTREAM: usb: dwc2: host: Set host_rx_fifo_size to 525 for rk3066
As documented in dwc2_calculate_dynamic_fifo(), host_rx_fifo_size should
really be:
 2 * ((Largest Packet size / 4) + 1 + 1) + n
 with n = number of host channel.

We have 9 host channels, so
 2 * ((1024/4) + 2) + 9 = 516 + 9 = 525

We've got 960 / 972 total_fifo_size on rk3288 (and presumably on
rk3066) and 525 + 128 + 256 = 909 so we're still under on both ports
even when we increment by 5.

In the future, it would be nice if dwc2_calculate_dynamic_fifo() could
handle the "too small" FIFO case and come up with something more
dynamically.  When we do that we can figure out how to allocate the
extra 48 / 60 bytes of FIFO that we're currently wasting.

NOTE: no known bugs are fixed by this patch, but it seems like a simple
fix and ought to fix someone.

Change-Id: Ia56c4cce7a01f570cce035a5e45c11ca431a797d
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 098c1ef8fe)
2017-01-03 18:48:07 +08:00
Douglas Anderson
567049afec UPSTREAM: usb: dwc2: host: Get aligned DMA in a more supported way
All other host controllers who want aligned buffers for DMA do it a
certain way.  Let's do that too instead of working behind the USB core's
back.  This makes our interrupt handler not take forever and also rips
out a lot of code, simplifying things a bunch.

This also has the side effect of removing the 65535 max transfer size
limit.

NOTE: The actual code to allocate the aligned buffers is ripped almost
completely from the tegra EHCI driver.  At some point in the future we
may want to add this functionality to the USB core to share more code
everywhere.

Change-Id: Id4a2ebf476148b51ed4a514590887678d8901039
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Acked-by: John Youn <johnyoun@synopsys.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: John Youn <johnyoun@synopsys.com>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 3bc04e28a0)
2017-01-03 18:48:06 +08:00
Douglas Anderson
db77a6eb34 UPSTREAM: usb: dwc2: rockchip: Make the max_transfer_size automatic
Previously we needed to set the max_transfer_size to explicitly be 65535
because the old driver would detect that our hardware could support much
bigger transfers and then would try to do them.  This wouldn't work
since the DMA alignment code couldn't support it.

Later in commit e8f8c14d9d ("usb: dwc2: clip max_transfer_size to
65535") upstream added support for clipping this automatically.  Since
that commit it has been OK to just use "-1" (default), but nobody
bothered to change it.

Let's change it to default now for two reasons:
- It's nice to use autodetected params.
- If we can remove the 65535 limit, we can transfer more!

Change-Id: I020c984ac4edf32488743d4daa0e24168f3152c0
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Acked-by: John Youn <johnyoun@synopsys.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 40eed7d783)
2017-01-03 18:48:05 +08:00
Geert Uytterhoeven
5c40bccd6d UPSTREAM: usb: dwc2: USB_DWC2 should depend on HAS_DMA
If NO_DMA=y:

    ERROR: "usb_gadget_map_request" [drivers/usb/dwc2/dwc2.ko] undefined!
    ERROR: "usb_gadget_unmap_request" [drivers/usb/dwc2/dwc2.ko] undefined!
    ERROR: "bad_dma_ops" [drivers/usb/dwc2/dwc2.ko] undefined!

Add a dependency on HAS_DMA to fix this.

Change-Id: I293b13982d0c35afd48aa38c0dec4c31ebfa20ce
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit ee89b641a9)
2017-01-03 18:48:04 +08:00
Tang, Jianqiang
5e15b8c2ed UPSTREAM: usb: dwc2: host: fix the data toggle error in full speed descriptor dma
There will be data toggle error happen for full speed buld-out transfer.
The data toggle bit is saved in qh for non-control transfers, it is wrong
to  check the qtd for that case.

Also fix one static analysis tool issue after fix the data toggle error.

John Youn:
* Added WARN() to warn on improper usage of the
  dwc2_hcd_save_data_toggle() function.

Change-Id: I9d0efcbf96aa65e7255397aa54af15d8b99d06a5
Signed-off-by: Dyson Lee <dyson.lee@intel.com>
Signed-off-by: Tang, Jianqiang <jianqiang.tang@intel.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 62943b7dfa)
2017-01-03 18:48:03 +08:00
Vardan Mikayelyan
b1f6eec761 UPSTREAM: usb: dwc2: host: fix logical omissions in dwc2_process_non_isoc_desc
Fixes memory manipulation issues and makes Host DDMA bulk transfers
work.

dwc2_process_non_isoc_desc() must return non zero value ONLY when
failure happens in one of the queued descriptors. After receiving
non zero value the caller must stop processing of remaining
QTDs and their descriptors from chain.

Commit 26a19ea699 ("usb: dwc2: host: fix use of qtd after
free in desc dma mode") breaks non_isoc transaction completion logic
in Host DDMA mode. There were bugs before that, but after this patch
dwc2_process_non_isoc_desc() returns fail status even if descriptor
was processed normally. This causes break from loop which is processing
remaining descriptors assigned to QTD, which is not correct for QTDs
containing more than one descriptor.

Current dwc2 driver gathers queued BULK URBs until receiving URB
without URB_NO_INTERRUPT flag. Once getting it, SW creates
descriptor chain, stores it in qh structure and passes start
address to HW. Multiple URB data is contained in that chain.
Hence on getting error on descriptor after its processing by HW,
SW should go out of both loops(qh->qtd, qtd->descs) and report
the failure.

Change-Id: Ie23695bcad29c155f3d22ecaba0a1c78ec35aec7
Fixes: 26a19ea699 ("usb: dwc2: host: fix use of qtd after free in desc dma mode")
Cc: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 3142a16b98)
2017-01-03 18:48:02 +08:00
John Youn
2c7b113cd6 UPSTREAM: usb: dwc2: Add extra delay when forcing dr_mode
Fixes an issue found on rockchip rk3036 and rk3188 SOC platforms. For
some reason, the existing msleep(25) is not enough after the force mode.
The following patch was reported to fix the issue.

This does increase the probe delay again slightly, but not up to the
level it was before the original series of patches that this fixes. It
does not cause any other issues when tested on Synopsys HAPS and Altera
socfpga platforms.

Need to revisit this series next release to see if we can address these
issues without having an unconditional delay.

Change-Id: Ie06514eb87b0acc66edca21755069ba69751e6a5
Fixes: 09c96980dc ("usb: dwc2: Add functions to set and clear force mode")
Reported-by: Caesar Wang <caesar.upstream@gmail.com>
Reported-by: Michael Niewoehner <linux@mniewoehner.de>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Caesar Wang <caesar.upstream@gmail.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit bd84f4ae99)
2017-01-03 18:48:01 +08:00
Vegard Nossum
afbc5d8052 UPSTREAM: usb: add HAS_IOMEM dependency to USB_DWC2
drivers/built-in.o: In function `dwc2_driver_probe':
/home/vegard/linux/drivers/usb/dwc2/platform.c:491: undefined reference to `devm_ioremap_resource'

Change-Id: I34a1b15886144ece1dcd0561ed34995599eb2cd7
Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit 89f1ec8ee2)
2017-01-03 18:48:00 +08:00