Commit Graph

338 Commits

Author SHA1 Message Date
Douglas Anderson
9f9f09b048 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.

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>
2016-03-04 15:14:45 +02:00
Douglas Anderson
9cf1a601d2 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.

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>
2016-03-04 15:14:44 +02:00
Douglas Anderson
fae4e82609 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").

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>
2016-03-04 15:14:44 +02:00
Douglas Anderson
fb616e3f83 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.

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>
2016-03-04 15:14:44 +02:00
Douglas Anderson
483bb2544c 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.

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>
2016-03-04 15:14:44 +02:00
Douglas Anderson
2d3f139810 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.

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>
2016-03-04 15:14:43 +02:00
Douglas Anderson
b951c6c7f8 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.

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>
2016-03-04 15:14:43 +02:00
Douglas Anderson
ced9eee122 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.

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>
2016-03-04 15:14:43 +02:00
Douglas Anderson
4e50e0110c 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.

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>
2016-03-04 15:14:42 +02:00
Douglas Anderson
d82a810eed 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.

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>
2016-03-04 15:14:42 +02:00
Douglas Anderson
9ed04d9761 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

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>
2016-03-04 15:14:42 +02:00
Douglas Anderson
8add17cf8e 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.

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>
2016-03-04 15:14:41 +02:00
Douglas Anderson
17dd5b642d 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.

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>
2016-03-04 15:14:41 +02:00
Douglas Anderson
74fc4a7558 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.

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>
2016-03-04 15:14:41 +02:00
Douglas Anderson
c9c8ac0150 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")

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>
2016-03-04 15:14:40 +02:00
Douglas Anderson
94ef7aee11 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

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>
2016-03-04 15:14:40 +02:00
Douglas Anderson
16e8021881 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.

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>
2016-03-04 15:14:40 +02:00
Douglas Anderson
098c1ef8fe 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.

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>
2016-03-04 15:14:39 +02:00
Douglas Anderson
3bc04e28a0 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.

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>
2016-03-04 15:14:39 +02:00
Douglas Anderson
40eed7d783 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!

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>
2016-03-04 15:14:39 +02:00
Greg Kroah-Hartman
71e41bbb43 Merge 4.5-rc6 into usb-next
We want the USB fixes in here as well.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-03-01 16:13:54 -08:00
Geert Uytterhoeven
a057c3259a 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.

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-02-20 20:23:02 -08:00
Geert Uytterhoeven
ee89b641a9 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.

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
2016-02-17 10:32:18 +02:00
Tang, Jianqiang
62943b7dfa 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.

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>
2016-02-17 10:32:09 +02:00
Vardan Mikayelyan
3142a16b98 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.

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>
2016-02-17 10:32:01 +02:00
John Youn
bd84f4ae99 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.

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>
2016-02-17 10:31:42 +02:00
Vegard Nossum
89f1ec8ee2 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'

Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-02-14 17:09:56 -08:00
John Youn
192cb07f79 usb: dwc2: Fix probe problem on bcm2835
Fixes an issue found on Raspberry PI platform that prevents probe. Don't
skip setting the force mode if it's already set.

Fixes: 09c96980dc ("usb: dwc2: Add functions to set and clear force mode")
Tested-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Reported-by: Stefan Wahren <stefan.wahren@i2se.com>
Reported-by: Remi Pommarel <repk@triplefau.lt>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Tested-by: Remi Pommarel <repk@triplefau.lt>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
2016-02-03 20:15:49 +02:00
John Youn
03b32e4c9b Revert "usb: dwc2: Move reset into dwc2_get_hwparams()"
This reverts commit 263b7fb557 ("usb: dwc2: Move reset into
dwc2_get_hwparams()") due to regression found on bcm2835 platform. USB
ethernet fails, due to being unable to pick up proper parameters when
performing a plain reset before reading hw params.

Below shows the results of the gnptxfsiz and hptxfsiz with and before
and after reverting this (from Stefan Wahren):

So here is the probe result before Patch 1 is applied:

[    1.283148] dwc2 20980000.usb: Configuration mismatch. dr_mode forced to host
[    1.313894] dwc2 20980000.usb: gnptxfsiz=00201000
[    1.314104] dwc2 20980000.usb: hptxfsiz=00000000
[    1.353908] dwc2 20980000.usb: 256 invalid for host_nperio_tx_fifo_size. Check HW configuration.
[    1.354262] dwc2 20980000.usb: 512 invalid for host_perio_tx_fifo_size. Check HW configuration.
[    1.394249] dwc2 20980000.usb: DWC OTG Controller
[    1.394561] dwc2 20980000.usb: new USB bus registered, assigned bus number 1
[    1.394917] dwc2 20980000.usb: irq 33, io mem 0x00000000

And here is the probe result after Patch 1 is applied:

[    1.280107] dwc2 20980000.usb: Configuration mismatch. dr_mode forced to host
[    1.353949] dwc2 20980000.usb: gnptxfsiz=01001000
[    1.354166] dwc2 20980000.usb: hptxfsiz=02002000
[    1.434301] dwc2 20980000.usb: DWC OTG Controller
[    1.434616] dwc2 20980000.usb: new USB bus registered, assigned bus number 1
[    1.434973] dwc2 20980000.usb: irq 33, io mem 0x00000000

Tested-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Reported-by: Stefan Wahren <stefan.wahren@i2se.com>
Reported-by: Remi Pommarel <repk@triplefau.lt>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Tested-by: Remi Pommarel <repk@triplefau.lt>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
2016-02-03 20:15:19 +02:00
Heiko Stübner
a40a00318c usb: dwc2: add shutdown callback to platform variant
In specific conditions (involving usb hubs) dwc2 devices can create a
lot of interrupts, even to the point of overwhelming devices running
at low frequencies. Some devices need to do special clock handling
at shutdown-time which may bring the system clock below the threshold
of being able to handle the dwc2 interrupts. Disabling dwc2-irqs
in a shutdown callbacks prevents reboots/poweroffs from getting stuck
in such cases.

The hsotg struct already contains an unused irq element, so we can
just use it to store the irq number for the shutdown callback.

Reviewed-by: Douglas Anderson <dianders@chromium.org>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Heiko Stuebner <heiko.stuebner@collabora.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 12:12:51 -06:00
Marek Vasut
6d76c92c2f usb: dwc2: gadget: Repair DSTS register decoding
The "enumspd" field is located in register DSTS[2:1], but the code
which checks the bitfield does not shift the value accordingly. This
in turn causes incorrect detection of gadget link partner speed in
dwc2_hsotg_irq_enumdone() .

Shift the value accordingly to fix the problem with speed detection.

Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 12:03:05 -06:00
John Youn
60c0288c72 usb: dwc2: gadget: Remove call to dwc2_hsotg_init()
Remove call to dwc2_hsotg_init() from dwc2_gadget_init(). The
gadget_init function should not access any device registers because the
mode isn't guaranteed here.

Also, this is already called elsewhere before anything starts on the
gadget so it is not necessary here.

Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 12:02:44 -06:00
John Youn
25362d3183 usb: dwc2: Remove redundant reset in probe
Reset already happens before this so just force the dr_mode.

Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 12:02:34 -06:00
John Youn
97e463886b usb: dwc2: Reduce delay when forcing mode in reset
The delay for force mode is only 25ms according to the databook.

Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 12:01:32 -06:00
John Youn
241729baa9 usb: dwc2: gadget: Replace dwc2_hsotg_corereset()
The dwc2_core_reset() function exists in the core so use that one
instead.

Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 12:01:19 -06:00
John Youn
43e9034904 usb: dwc2: gadget: Use hw params from core
Use the previously cached hw params in the gadget. This saves a reset
and force mode in the gadget initialization during probe and makes
getting the hardware parameters consistent between gadget and host.

Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 12:01:01 -06:00
John Youn
55e1040e42 usb: dwc2: Improve handling of host and device hwparams
Adds separate functions to get the host and device specific hardware
parameters. The functions check whether the parameters need to be read
at all, depending on dr_mode, and forces the mode only if necessary.
This saves some delays during probe. This also adds two device mode
parameters that will be used by the gadget.

Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 12:00:51 -06:00
John Youn
09c96980dc usb: dwc2: Add functions to set and clear force mode
Added functions to set force mode for host and device. These functions
will check the current mode and only force if needed thus avoiding
unnecessary force mode delays. However clearing the mode is currently
done unconditionally and with the delay in place. This is needed during
the connector ID status change interrupt in order to ensure that the
mode has changed properly. This preserves the old behavior only for this
case. The warning comment about this is moved into the clear mode
condition.

Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 12:00:34 -06:00
John Youn
263b7fb557 usb: dwc2: Move reset into dwc2_get_hwparams()
The reset is required to get reset values of the hardware parameters but
the force mode is not. Move the base reset into dwc2_get_hwparams() and
do the reset and force mode afterwards.

Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 11:58:34 -06:00
John Youn
1696d5ab99 usb: dwc2: Move mode querying functions into core.h
These functions should go in core.h where they can be called from core,
device, or host.

Signed-off-by: John Youn <johnyoun@synopsys.com>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 11:57:55 -06:00
John Youn
5268ed9d2e usb: dwc2: Fix dr_mode validation
The dr_mode parameter was being checked against how the dwc2 module
was being configured at compile time. But it wasn't checked against
the hardware capabilities, nor were the hardware capabilities checked
against the compilation parameters.

This commit adds those checks and adjusts dr_mode to an appropriate
value, if needed. If the hardware capabilities and module compilation
do not match then we fail as it wouldn't be possible to run properly.

The hardware, module, and dr_mode, can each be set to host, device,
or otg. Check that all these values are compatible and adjust the
value of dr_mode if possible.

The following table summarizes the behavior:

                     actual
   HW  MOD dr_mode   dr_mode
 ------------------------------
  HST  HST  any    :  HST
  HST  DEV  any    :  ---
  HST  OTG  any    :  HST

  DEV  HST  any    :  ---
  DEV  DEV  any    :  DEV
  DEV  OTG  any    :  DEV

  OTG  HST  any    :  HST
  OTG  DEV  any    :  DEV
  OTG  OTG  any    :  dr_mode

Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 11:57:35 -06:00
John Youn
6bea962053 usb: dwc2: Add functions to check the HW OTG config
Added functions to query the GHWCFG2.OTG_MODE. This tells us whether the
controller hardware is configured for OTG, device-only, or host-only.

Signed-off-by: John Youn <johnyoun@synopsys.com>
Tested-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 11:55:46 -06:00
John Youn
b5d308abef usb: dwc2: Add dwc2_core_reset()
dwc2_core_reset() was previously renamed to
dwc2_core_reset_and_dr_force_mode(). Now add back dwc2_core_reset() which
performs only a basic core reset without forcing the mode.

Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 11:55:32 -06:00
John Youn
6d58f346a6 usb: dwc2: Rename dwc2_core_reset()
Renamed dwc2_core_reset() to dwc2_core_reset_and_force_dr_mode(). This
describes what it is doing more accurately. This is in preparation of
introducing a plain dwc2_core_reset() function that only performs the
reset and doesn't force the mode.

Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 11:55:21 -06:00
John Youn
b8ccc593ee usb: dwc2: Reorder AHBIDLE and CSFTRST in dwc2_core_reset()
According to the databook, the core soft reset should be done before
checking for AHBIDLE. The gadget version of core reset had it correct
but the hcd version did not. This fixes the hcd version.

Signed-off-by: John Youn <johnyoun@synopsys.com>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Tested-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 11:54:45 -06:00
Douglas Anderson
7d56cc2620 usb: dwc2: Avoid more calls to dwc2_core_reset()
Calls to dwc2_core_reset() are currently very slow, taking at least
150ms (possibly more).  It behooves us to take as many of these calls
out as possible.

It turns out that the calls in dwc2_fs_phy_init() and dwc2_hs_phy_init()
should (as documented in the code) only be needed if we need to do a PHY
SELECT.  That means that if we see that we can avoid the PHY SELECT then
we can avoid the reset.

This patch appears to successfully bypass two resets (one per USB
device) on rk3288-based ARM Chromebooks.

Signed-off-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 11:54:30 -06:00
Yunzhi Li
20bde64343 usb: dwc2: reduce dwc2 driver probe time
I found that the probe function of dwc2 driver takes much time
when kernel boot up. There are many long delays in the probe
function these take almost 1 second.

This patch trying to reduce unnecessary delay time.

In dwc2_core_reset() I see it use two at least 20ms delays to
wait AHB idle and core soft reset, but dwc2 data book said that
dwc2 core soft reset and AHB idle just need a few clocks (I think
it refers to AHB clock, and AHB clock run at 150MHz in my RK3288
board), so 20ms is too long, delay 1us for wait AHB idle and soft
reset is enough.

And in dwc2_get_hwparams() it takes 150ms to wait ForceHostMode
and ForceDeviceMode valid but in data book it said software must
wait at least 25ms before the change to take effect, so I reduce
this time to 25ms~50ms. By the way, is there any state bit show
that the force mode take effect ? Could we poll curmod bit for
figuring out if the change take effect ?

It seems that usleep_range() at boot time will pick the longest
value in the range. In dwc2_core_reset() there is a very long
delay takes 200ms, and this function run twice when probe, could
any one tell me is this delay time resonable ?

I have tried this patch in my RK3288-evb board. It works well.

Signed-off-by: Yunzhi Li <lyz@rock-chips.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 11:54:16 -06:00
Douglas Anderson
f619473140 usb: dwc2: Speed dwc2_get_hwparams() on some host-only ports
On some host-only DWC2 ports (like the one in rk3288) when we set
GUSBCFG_FORCEHOSTMODE in GUSBCFG and then read back, we don't see the
bit set.  Presumably that's because the port is always forced to HOST
mode so there's no reason to implement these status bits.

Since we know dwc2_core_reset() is always called before
dwc2_get_hwparams() and we know dwc2_core_reset() should have set
GUSBCFG_FORCEHOSTMODE whenever hsotg->dr_mode == USB_DR_MODE_HOST, we
can just check hsotg->dr_mode to decide that we can skip the delays in
dwc2_get_hwparams().

Signed-off-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 11:53:01 -06:00
Douglas Anderson
0fe239bc19 usb: dwc2: Avoid double-reset at boot time
In (usb: dwc2: reset dwc2 core before dwc2_get_hwparams()) we added an
extra reset to the probe path for the dwc2 USB controllers.  This
allowed proper detection of parameters even if the firmware had already
used the USB part.

Unfortunately, this extra reset is quite slow and is affecting boot
speed.  We can avoid the double-reset by skipping the extra reset that
would happen just after the one we added.  Logic that explains why this
is safe:

* As of the CL mentioned above, we now always call dwc2_core_reset() in
  dwc2_driver_probe() before dwc2_hcd_init().

* The only caller of dwc2_hcd_init() is dwc2_driver_probe(), so we're
  guaranteed that dwc2_core_reset() was called before dwc2_hdc_init().

* dwc2_hdc_init() is the only caller that passes an irq other than -1 to
  dwc2_core_init().  Thus if dwc2_core_init() is called with an irq
  other than -1 we're guaranteed that dwc2_core_reset was called before
  dwc2_core_init().

...this allows us to remove the dwc2_core_reset() in dwc2_core_init() if
irq is not < 0.

Note that since "irq" wasn't used in the function dwc2_core_init()
anyway and since select_phy was always set at exactly the same times we
could avoid the reset, we remove "irq" and rename "select_phy" to
"initial_setup" and adjust the callers accordingly.

Signed-off-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 11:52:08 -06:00
Yunzhi Li
cebfdbf329 usb: dwc2: reset dwc2 core before dwc2_get_hwparams()
We initiate dwc2 usb controller in BIOS, dwc2_core_reset() should
be called before dwc2_get_hwparams() to reset core registers to
default value. Without this the FIFO setting might be incorrect
because calculating FIFO size need power-on value of
GRXFSIZ/GNPTXFSIZ/HPTXFSIZ registers.

This patch could avoid warnning massage like in rk3288 platform:
[    2.074764] dwc2 ff580000.usb: 256 invalid for
host_perio_tx_fifo_size. Check HW configuration.

Signed-off-by: Yunzhi Li <lyz@rock-chips.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 11:51:45 -06:00
Douglas Anderson
991824677f usb: dwc2: Restore GUSBCFG in dwc2_get_hwparams()
Previously dwc2_get_hwparams() was changing GUSBCFG and not putting it
back the way it was (specifically it set and cleared FORCEHOSTMODE).
Since we want to move dwc2_core_reset() _before_ dwc2_get_hwparams() we
should make sure dwc2_get_hwparams() isn't messing with things in a
permanent way.

Since we're now looking at GUSBCFG, it's obvious that we shouldn't need
all the extra delays if FORCEHOSTMODE was already set.  This will avoid
some delays for any ports that have forced host mode.

Signed-off-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 11:51:30 -06:00
Gregory Herrero
3be99cd0e8 usb: dwc2: gadget: don't overwrite DCTL register on NAKEFF interrupts
When receiving GINTSTS_GINNAKEFF or GINTSTS_GOUTNAKEFF interrupt,
DCTL will be overwritten with DCTL_CGOUTNAK or DCTL_CGNPINNAK values.
Instead of overwriting it, write only needed bits.

It could cause an issue if GINTSTS_GINNAKEFF or GINTSTS_GOUTNAKEFF
interrupt is received after dwc2 disabled pullup by writing
DCTL_SFTDISCON bit.
Pullup will then be re-enabled whereas it should not.

Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 11:50:43 -06:00
Du, Changbin
0676c7e734 usb: dwc2: fix transfer stop programming for out endpoint
To stop an out endpoint, software should set sets the Global OUT NAK,
but not the Global Non-periodic IN NAK. This driver bug leads the out-ep
failed be in disabled state with below error.

dwc2_hsotg_ep_stop_xfr: timeout DOEPCTL.EPDisable

Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Du, Changbin <changbin.du@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-22 11:50:03 -06:00
Douglas Anderson
29539019b4 usb: dwc2: host: Clear interrupts before handling them
In general it is wise to clear interrupts before processing them.  If
you don't do that, you can get:
 1. Interrupt happens
 2. You look at system state and process interrupt
 3. A new interrupt happens
 4. You clear interrupt without processing it.

This patch was actually a first attempt to fix missing device insertions
as described in (usb: dwc2: host: Fix missing device insertions) and it
did solve some of the signal bouncing problems but not all of
them (which is why I submitted the other patch).  Specifically, this
patch itself would sometimes change:
 1. hardware sees connect
 2. hardware sees disconnect
 3. hardware sees connect
 4. dwc2_port_intr() - clears connect interrupt
 5. dwc2_handle_common_intr() - calls dwc2_hcd_disconnect()

...to:
 1. hardware sees connect
 2. hardware sees disconnect
 3. dwc2_port_intr() - clears connect interrupt
 4. hardware sees connect
 5. dwc2_handle_common_intr() - calls dwc2_hcd_disconnect()

...but with different timing then sometimes we'd still miss cable
insertions.

In any case, though this patch doesn't fix any (known) problems, it
still seems wise as a general policy to clear interrupt before handling
them.

Note that for dwc2_handle_usb_port_intr(), instead of moving the clear
of PRTINT to the beginning of the function we remove it completely.  The
only way to clear PRTINT is to clear the sources that set it in the
first place.

Signed-off-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-15 09:12:41 -06:00
Douglas Anderson
4a065c7bdb usb: dwc2: host: Add missing spinlock in dwc2_hcd_reset_func()
The dwc2_hcd_reset_func() function is only ever called directly by a
delayed work function.  As such no locks are already held when the
function is called.

Doing a read-modify-write of CPU registers and setting fields in the
main hsotg data structure is a bad idea without locks.  Let's add
locks.

The bug was found by code inspection only.  It turns out that the
dwc2_hcd_reset_func() is only ever called today if the
"host_support_fs_ls_low_power" parameter is enabled and no code in
mainline enables that parameter.  Thus no known issues in mainline are
fixed by this patch, but it's still probably wise to fix the function.

Signed-off-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-15 09:12:41 -06:00
Douglas Anderson
69b76cdff5 usb: dwc2: host: Support immediate retries for split transactions
In some cases, like when you've got a "Microsoft Wireless Keyboard 2000"
connected to dwc2 with a hub, expected that we'll get some transfer
errors sometimes.  The controller is expected to try at least 3 times
before giving up.  See figure "Figure A-67. Normal HS CSPLIT 3 Strikes
Smash" in the USB spec.

The dwc2 controller has a way to support this by using the "EC_MC"
field.  The Raspberry Pi driver has logic for setting this right.  See
fiq_fsm_queue_split_transaction() in their "dwc_otg_hcd.c".  Let's use
the same logic.

After making this change, we no longer get dropped characters from the
above mentioned keyboard.  Other devices on the same bus as the keyboard
also behave more properly.

Thanks for Julius Werner for the expert analysis and suggestions.

Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-15 09:12:41 -06:00
Douglas Anderson
6a6595318a usb: dwc2: host: Fix missing device insertions
If you've got your interrupt signals bouncing a bit as you insert your
USB device, you might end up in a state when the device is connected but
the driver doesn't know it.

Specifically, the observed order is:
 1. hardware sees connect
 2. hardware sees disconnect
 3. hardware sees connect
 4. dwc2_port_intr() - clears connect interrupt
 5. dwc2_handle_common_intr() - calls dwc2_hcd_disconnect()

Now you'll be stuck with the cable plugged in and no further interrupts
coming in but the driver will think we're disconnected.

We'll fix this by checking for the missing connect interrupt and
re-connecting after the disconnect is posted.  We don't skip the
disconnect because if there is a transitory disconnect we really want to
de-enumerate and re-enumerate.

Notes:
1. As part of this change we add a "force" parameter to
   dwc2_hcd_disconnect() so that when we're unloading the module we
   avoid the new behavior.  The need for this was pointed out by John
   Youn.
2. The bit of code needed at the end of dwc2_hcd_disconnect() is
   exactly the same bit of code from dwc2_port_intr().  To avoid
   duplication, we refactor that code out into a new function
   dwc2_hcd_connect().

Signed-off-by: Douglas Anderson <dianders@chromium.org>
Acked-by: John Youn <johnyoun@synopsys.com>
Tested-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-15 09:12:41 -06:00
Zhangfei Gao
37dd9d65cc usb: dwc2: add support of hi6220
Support hisilicon,hi6220-usb for HiKey board

Acked-by: Rob Herring <robh@kernel.org>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-15 09:12:41 -06:00
Gregory Herrero
3b5fcc9ac2 usb: dwc2: host: use kmem cache to allocate descriptors
Kmem caches help to get correct boundary for descriptor buffers
which need to be 512 bytes aligned for dwc2 controller.
Two kmem caches are needed for generic descriptors and for
hs isochronous descriptors which doesn't have same size.

Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-15 09:12:41 -06:00
Mian Yousaf Kaukab
e23b8a54a4 usb: dwc2: host: fix descriptor list address masking
Masks for HCDMA.CTD and HCDMA.DMAAddr are incorrect. As we always
start from first descriptor, no need to mask the address anyway.

Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-15 09:12:41 -06:00
Gregory Herrero
95105a998d usb: dwc2: host: avoid usage of dma_alloc_coherent with irqs disabled
Use Streaming DMA mappings to handle cache coherency of frame list and
descriptor list. Cache are always flushed before controller access it
or before cpu access it.

Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-15 09:12:41 -06:00
Mian Yousaf Kaukab
fbb9e22b15 usb: dwc2: host: enable descriptor dma for fs devices
As descriptor dma mode does not support split transfers, it can't be
enabled for high speed devices. Add a core parameter to enable it for
full speed devices.

Ensure frame list and descriptor list are correctly freed during
disconnect.

Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-15 09:12:41 -06:00
Gregory Herrero
762d3a1a9c usb: dwc2: host: process all completed urbs
Process all completed urbs, if more urbs are complete by the time
driver processes completion interrupt.

Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-15 09:12:41 -06:00
Gregory Herrero
3f808bdae7 usb: dwc2: host: always increment available host channel during release
When releasing a channel, increment hsotg->available_host_channels even
in case a periodic channel is released.

Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-15 09:12:41 -06:00
Gregory Herrero
c17b337c1e usb: dwc2: host: program descriptor for next frame
Isochronous descriptor is currently programmed for the frame
after the last descriptor was programmed.

If the last descriptor frame underrun, then current descriptor must
take this into account and must be programmed on the current frame + 1.
This overrun usually happens when system is loaded and dwc2 can't init
descriptor list in time.

Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-15 09:12:41 -06:00
Gregory Herrero
b9392d9920 usb: dwc2: host: add function to compare frame index
This function allow comparing frame index used for
descriptor list which has 64 entries.

Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-15 09:12:41 -06:00
Gregory Herrero
2b046bc5aa usb: dwc2: host: spinlock release channel
Prevent dwc2 driver from accessing channel while it frees it.

Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-15 09:12:41 -06:00
Gregory Herrero
26a19ea699 usb: dwc2: host: fix use of qtd after free in desc dma mode
When completing non isoc xfer, dwc2_complete_non_isoc_xfer_ddma()
is relying on qtd->n_desc to process the corresponding number of
descriptors.

During the processing of these descriptors, qtd could be unlinked
and freed if xfer is done and urb is no more in progress.

In this case, dwc2_complete_non_isoc_xfer_ddma() will read again
qtd->n_desc whereas qtd has been freed. This will lead to unpredictable
results since qtd->n_desc is no more valid value.

To avoid this error, return a result != 0 in dwc2_process_non_isoc_desc(),
so that dwc2_complete_non_isoc_xfer_ddma() stops desc processing.

This has been seen with Slub debug enabled.

Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-15 09:12:41 -06:00
Gregory Herrero
c503b38153 usb: dwc2: host: rework isochronous halt path
When a channel is halted because of urb dequeue during transfer
completion, no other qtds must be scheduled until halt is done.
Moreover, all in progress qtds must be given back.

Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-15 09:12:41 -06:00
Gregory Herrero
dde4c1bf5d usb: dwc2: host: set active bit in isochronous descriptors
Active bit must be enabled in all scheduled descriptors. Else transfer
never start.
Remove previous code which was not correctly configuring descriptors.
Active bit was set before calling dwc2_fill_host_isoc_dma_desc() which
is erasing dma_desc->status.

Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-15 09:12:41 -06:00
Gregory Herrero
3ac38d260f usb: dwc2: host: ensure filling of isoc desc is correctly done
Increment qtd->isoc_frame_index_last before testing it, else below
check will never be true and IOC (Interrupt On Complete) bit for
last frame will never be set in descriptor status.

  /* Set IOC for each descriptor corresponding to last frame of URB */
  if (qtd->isoc_frame_index_last == qtd->urb->packet_count)
	dma_desc->status |= HOST_DMA_IOC;

Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-12-15 09:12:41 -06:00
Stefan Wahren
f74875dc36 usb: dwc2: fix kernel oops during driver probe
This patch make sure that all necessary members of dwc2_hsotg
are initialized before the irq handler is requested. So
the kernel oops triggered by dwc2_handle_common_intr has
been fixed.

  dwc2 20980000.usb: Configuration mismatch. Forcing host mode
  dwc2 20980000.usb: no platform data or transceiver defined
  Unable to handle kernel paging request at virtual address cc860040
  pgd = c0004000
  [cc860040] *pgd=0b41e811, *pte=00000000, *ppte=00000000
  Internal error: Oops: 7 [#1] ARM
  CPU: 0 PID: 1 Comm: swapper Not tainted 4.3.0-rc3+ #19
  Hardware name: BCM2835
  task: cb494000 ti: cb4d0000 task.ti: cb4d0000
  PC is at dwc2_is_controller_alive+0x18/0x34
  LR is at dwc2_handle_common_intr+0x24/0xb60

Acked-by: John Youn <johnyoun@synopsys.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-11-20 09:29:47 -06:00
Stefan Wahren
8aa90cf2a2 usb: dwc2: make otg clk optional
Fixes commit 09a75e8577
("usb: dwc2: refactor common low-level hw code to platform.c")

The above commit consolidated the low-level phy access into a common
location. This change made the otg clk a requirement and broke some
platforms when it was moved into platform.c.

So make clk handling optional again.

Acked-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Acked-by: John Youn <johnyoun@synopsys.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Fixes: 09a75e8577 ("usb: dwc2: refactor common low-level hw code to platform.c")
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-11-19 14:48:49 -06:00
Stefan Wahren
6c2dad6916 usb: dwc2: Return errors from PHY
When searching for PHYs, any error was treated as if the PHY did not
exist or was not specified. Thus the probe function did not
correctly return error conditions such as -EPROBE_DEFER.

Fixed so that only a non-existing PHY is ignored and any other error
is returned.

Acked-by: Eric Anholt <eric@anholt.net>
Reported-by: Alexander Aring <alex.aring@gmail.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-11-19 14:48:49 -06:00
John Youn
d0464bcf12 usb: dwc2: Make PHY optional
Fixes commit 09a75e8577
("usb: dwc2: refactor common low-level hw code to platform.c")

The above commit consolidated the low-level phy access into a common
location. This change introduced a check from the gadget requiring
that a PHY is specified. This requirement never existed on the host
side and broke some platforms when it was moved into platform.c.

The gadget doesn't require the PHY either so remove the check.

Acked-by: Eric Anholt <eric@anholt.net>
Reported-by: Stefan Wahren <info@lategoodbye.de>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Fixes: 09a75e8577 ("usb: dwc2: refactor common low-level hw code to platform.c")
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-11-19 14:48:49 -06:00
Douglas Anderson
1fb7f12d5b usb: dwc2: host: Fix remote wakeup when not in DWC2_L2
In commit 734643dfbd ("usb: dwc2: host: add flag to reflect bus
state") we changed dwc2_port_suspend() not to set the lx_state
anymore (instead it sets the new bus_suspended variable).  This
introduced a bug where we would fail to detect device insertions if:

1. Plug empty hub into dwc2
2. Plug USB flash drive into the empty hub.
3. Wait a few seconds
4. Unplug USB flash drive
5. Less than 2 seconds after step 4, plug the USB flash drive in again.

The dwc2_hcd_rem_wakeup() function should have been changed to look at
the new bus_suspended variable.

Let's fix it.  Since commit b46146d59f ("usb: dwc2: host: resume root
hub on remote wakeup") talks about needing the root hub resumed if the
bus was suspended, we'll include it in our test.

It appears that the "port_l1_change" should only be set to 1 if we were
in DWC2_L1 (the driver currently never sets this), so we'll update the
former "else" case based on this test.

Fixes: 734643dfbd ("usb: dwc2: host: add flag to reflect bus state")
Acked-by: John Youn <johnyoun@synopsys.com>
Tested-by: Gregory Herrero <gregory.herrero@intel.com>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-11-17 11:35:38 -06:00
Douglas Anderson
f16593034a usb: dwc2: host: Fix ahbcfg for rk3066
The comment for ahbcfg for rk3066 parameters (also used for rk3288)
claimed that ahbcfg was INCR16, but it wasn't.  Since the bits weren't
shifted properly, the 0x7 ended up being masked and we ended up
programming 0x3 for the HBstLen.  Let's set it to INCR16 properly.

As per Wu Liang Feng at Rockchip this may increase transmission
efficiency.  I did blackbox tests with writing 0s to a USB-based SD
reader (forcefully capping CPU Freq to try to measure efficiency):
  cd /sys/devices/system/cpu/cpu0/cpufreq
  echo userspace > scaling_governor
  echo 126000 > scaling_setspeed
  for i in $(seq 10); do
    dd if=/dev/zero of=/dev/sdb bs=1M count=750
  done

With the above tests I found that speeds went from ~15MB/s to ~18MB/s.
Note that most other tests I did (including reading from the same USB
reader) didn't show any difference in performance.

Tested-by: Heiko Stuebner <heiko@sntech.de>
Acked-by: John Youn <johnyoun@synopsys.com>
Reviewed-by: Liangfeng Wu <wulf@rock-chips.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-11-17 11:29:52 -06:00
Doug Anderson
dc87308469 usb: dwc2: host: Fix use after free w/ simultaneous irqs
While plugging / unplugging on a DWC2 host port with "slub_debug=FZPUA"
enabled, I found a crash that was quite obviously a use after free.

It appears that in some cases when we handle the various sub-cases of
HCINT we may end up freeing the QTD.  If there is more than one bit set
in HCINT we may then end up continuing to use the QTD, which is bad.
Let's be paranoid and check for this after each sub-case.  This should
be safe since we officially have the "hsotg->lock" (it was grabbed in
dwc2_handle_hcd_intr).

The specific crash I found was:
 Unable to handle kernel paging request at virtual address 6b6b6b9f

At the time of the crash, the kernel reported:
 (dwc2_hc_nak_intr+0x5c/0x198)
 (dwc2_handle_hcd_intr+0xa84/0xbf8)
 (_dwc2_hcd_irq+0x1c/0x20)
 (usb_hcd_irq+0x34/0x48)

Popping into kgdb found that "*qtd" was filled with "0x6b", AKA qtd had
been freed and filled with slub_debug poison.

kgdb gave a little better stack crawl:
 0 dwc2_hc_nak_intr (hsotg=hsotg@entry=0xec42e058,
     chan=chan@entry=0xec546dc0, chnum=chnum@entry=4,
     qtd=qtd@entry=0xec679600) at drivers/usb/dwc2/hcd_intr.c:1237
 1 dwc2_hc_n_intr (chnum=4, hsotg=0xec42e058) at
     drivers/usb/dwc2/hcd_intr.c:2041
 2 dwc2_hc_intr (hsotg=0xec42e058) at drivers/usb/dwc2/hcd_intr.c:2078
 3 dwc2_handle_hcd_intr (hsotg=0xec42e058) at
     drivers/usb/dwc2/hcd_intr.c:2128
 4 _dwc2_hcd_irq (hcd=<optimized out>) at drivers/usb/dwc2/hcd.c:2837
 5 usb_hcd_irq (irq=<optimized out>, __hcd=<optimized out>) at
     drivers/usb/core/hcd.c:2353

Popping up to frame #1 (dwc2_hc_n_intr) found:
 (gdb) print /x hcint
 $12 = 0x12

AKA:
 #define HCINTMSK_CHHLTD  (1 << 1)
 #define HCINTMSK_NAK     (1 << 4)

Further debugging found that by simulating receiving those two
interrupts at the same time it was trivial to replicate the
use-after-free.  See <http://crosreview.com/305712> for a patch and
instructions.  This lead to getting the following stack crawl of the
actual free:
 0  arch_kgdb_breakpoint () at arch/arm/include/asm/outercache.h:103
 1  kgdb_breakpoint () at kernel/debug/debug_core.c:1054
 2  dwc2_hcd_qtd_unlink_and_free (hsotg=<optimized out>, qh=<optimized
      out>, qtd=0xe4479a00) at drivers/usb/dwc2/hcd.h:488
 3  dwc2_deactivate_qh (free_qtd=<optimized out>, qh=0xe5efa280,
      hsotg=0xed424618) at drivers/usb/dwc2/hcd_intr.c:671
 4  dwc2_release_channel (hsotg=hsotg@entry=0xed424618,
      chan=chan@entry=0xed5be000, qtd=<optimized out>,
      halt_status=<optimized out>) at drivers/usb/dwc2/hcd_intr.c:742
 5  dwc2_halt_channel (hsotg=0xed424618, chan=0xed5be000, qtd=<optimized
      out>, halt_status=<optimized out>) at
      drivers/usb/dwc2/hcd_intr.c:804
 6  dwc2_complete_non_periodic_xfer (chnum=<optimized out>,
      halt_status=<optimized out>, qtd=<optimized out>, chan=<optimized
      out>, hsotg=<optimized out>) at drivers/usb/dwc2/hcd_intr.c:889
 7  dwc2_hc_xfercomp_intr (hsotg=hsotg@entry=0xed424618,
      chan=chan@entry=0xed5be000, chnum=chnum@entry=6,
      qtd=qtd@entry=0xe4479a00) at drivers/usb/dwc2/hcd_intr.c:1065
 8  dwc2_hc_chhltd_intr_dma (qtd=0xe4479a00, chnum=6, chan=0xed5be000,
      hsotg=0xed424618) at drivers/usb/dwc2/hcd_intr.c:1823
 9  dwc2_hc_chhltd_intr (qtd=0xe4479a00, chnum=6, chan=0xed5be000,
      hsotg=0xed424618) at drivers/usb/dwc2/hcd_intr.c:1944
 10 dwc2_hc_n_intr (chnum=6, hsotg=0xed424618) at
      drivers/usb/dwc2/hcd_intr.c:2052
 11 dwc2_hc_intr (hsotg=0xed424618) at drivers/usb/dwc2/hcd_intr.c:2097
 12 dwc2_handle_hcd_intr (hsotg=0xed424618) at
      drivers/usb/dwc2/hcd_intr.c:2147
 13 _dwc2_hcd_irq (hcd=<optimized out>) at drivers/usb/dwc2/hcd.c:2837
 14 usb_hcd_irq (irq=<optimized out>, __hcd=<optimized out>) at
      drivers/usb/core/hcd.c:2353

Though we could add specific code to handle this case, adding the
general purpose code to check for all cases where qtd might be freed
seemed safer.

Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-19 09:22:46 -05:00
Douglas Anderson
4d273c2af0 usb: dwc2: host: Protect PCGCTL with lock in dwc2_port_resume()
From code inspection, it appears to be unsafe to do a read-modify-write
of PCGCTL in dwc2_port_resume().  Let's make sure the spinlock is held
around this operation.

Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-16 14:44:15 -05:00
Marek Szyprowski
09a75e8577 usb: dwc2: refactor common low-level hw code to platform.c
DWC2 module on some platforms needs three additional hardware
resources: phy controller, clock and power supply. All of them must be
enabled/activated to properly initialize and operate. This was initially
handled in s3c-hsotg driver, which has been converted to 'gadget' part
of dwc2 driver. Unfortunately, not all of this code got moved to common
platform code, what resulted in accessing DWC2 registers without
enabling low-level hardware resources. This fails for example on Exynos
SoCs. This patch moves all the code for managing those resources to
common platform.c file and provides convenient wrappers for controlling
them.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Acked-by: John Youn <johnyoun@synopsys.com>
Tested-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-14 08:40:15 -05:00
Marek Szyprowski
758ed196fc usb: dwc2: remove no longer needed init_mutex
init_mutex is a leftover from the time, when s3c-hsotg driver did not
implement proper pull up/down control and emulated it by enabling
enabling/disabling usb phy. Proper pull up/down control has been added
by commit 5b9451f8c4 ("usb: dwc2: gadget:
use soft-disconnect udc feature in pullup() method"), so init_muxtex can
be removed now to avoid potential deadlocks with other locks.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Acked-by: John Youn <johnyoun@synopsys.com>
Tested-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-14 08:39:17 -05:00
Mian Yousaf Kaukab
44e4a60dac usb: dwc2: fix duplicate argument warning
Fix a duplicate argument warning reported by 0-DAY kernel test
infrastructure in the following patch:
77dbf71 usb: dwc2: host: add disconnect interrupt to host only interrupts

Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-13 13:17:42 -05:00
Roman Bacik
ec1f9d9f01 usb: dwc2: gadget: parity fix in isochronous mode
USB OTG driver in isochronous mode has to set the parity of the receiving
microframe. The parity is set to even by default. This causes problems for
an audio gadget, if the host starts transmitting on odd microframes.

This fix uses Incomplete Periodic Transfer interrupt to toggle between
even and odd parity until the Transfer Complete interrupt is received.

Signed-off-by: Roman Bacik <rbacik@broadcom.com>
Reviewed-by: Abhinav Ratna <aratna@broadcom.com>
Reviewed-by: Srinath Mannam <srinath.mannam@broadcom.com>
Signed-off-by: Scott Branden <sbranden@broadcom.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-02 13:10:57 -05:00
Marek Szyprowski
5ee2a003e8 usb: dwc2: fix unbalanced phy control
Even when DWC2 is in (internal) suspended state, it should disable PHY
in suspend and then enable it in resume. This patch fixes unbalanced PHY
control sequence.

Tested-by: John Youn <johnyoun@synopsys.com>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-01 12:40:28 -05:00
Marek Szyprowski
4112905f90 usb: dwc2: remove non-functional clock gating
During typical gadget operation, dwc2 clock was enabled 3 times: from
dwc2_gadget_init(), dwc2_hsotg_udc_start() and dwc2_hsotg_pullup(), and
then disabled in s3c_hsotg_pullup(), s3c_hsotg_udc_stop() and
dwc2_hsotg_remove(). This really makes no sense, so leave clock control
code only in dwc2_gadget_init/remove functions.

Tested-by: John Youn <johnyoun@synopsys.com>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-01 12:40:28 -05:00
Marek Szyprowski
19dadca58a usb: dwc2: remove double call to dwc2_hsotg_of_probe
This patch removes doubled call to dwc2_hsotg_of_probe() function.

Tested-by: John Youn <johnyoun@synopsys.com>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-01 12:40:28 -05:00
Yunzhi Li
44583fecfd usb: dwc2: gadget: fix a memory use-after-free bug
When dwc2_hsotg_handle_unaligned_buf_complete() hs_req->req.buf
already destroyed, in dwc2_hsotg_unmap_dma(), it touches
hs_req->req.dma again, so dwc2_hsotg_unmap_dma() should be called
before dwc2_hsotg_handle_unaligned_buf_complete(). Otherwise, it
will cause a bad_page BUG, when allocate this memory page next
time.

This bug led to the following crash:

BUG: Bad page state in process swapper/0  pfn:2bdbc
[   26.820440] page:eed76780 count:0 mapcount:0 mapping:  (null) index:0x0
[   26.854710] page flags: 0x200(arch_1)
[   26.885836] page dumped because: PAGE_FLAGS_CHECK_AT_PREP flag set
[   26.919179] bad because of flags:
[   26.948917] page flags: 0x200(arch_1)
[   26.979100] Modules linked in:
[   27.008401] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G W3.14.0 #17
[   27.041816] [<c010e1f8>] (unwind_backtrace) from [<c010a704>] (show_stack+0x20/0x24)
[   27.076108] [<c010a704>] (show_stack) from [<c087eea8>] (dump_stack+0x70/0x8c)
[   27.110246] [<c087eea8>] (dump_stack) from [<c01ce0b8>] (bad_page+0xfc/0x12c)
[   27.143958] [<c01ce0b8>] (bad_page) from [<c01ce65c>] (get_page_from_freelist+0x3e4/0x50c)
[   27.179298] [<c01ce65c>] (get_page_from_freelist) from [<c01ce9a0>] (__alloc_pages_nodemask)
[   27.216296] [<c01ce9a0>] (__alloc_pages_nodemask) from [<c01cf00c>] (__get_free_pages+0x20/)
[   27.252326] [<c01cf00c>] (__get_free_pages) from [<c01e5bec>] (kmalloc_order_trace+0x34/0xa)
[   27.288295] [<c01e5bec>] (kmalloc_order_trace) from [<c0203304>] (__kmalloc+0x40/0x1ac)
[   27.323751] [<c0203304>] (__kmalloc) from [<c052abc0>] (dwc2_hsotg_ep_queue.isra.12+0x7c/0x1)
[   27.359937] [<c052abc0>] (dwc2_hsotg_ep_queue.isra.12) from [<c052af88>] (dwc2_hsotg_ep_queue)
[   27.397478] [<c052af88>] (dwc2_hsotg_ep_queue_lock) from [<c0554110>] (rx_submit+0xfc/0x164)
[   27.433619] [<c0554110>] (rx_submit) from [<c05546e8>] (rx_complete+0x22c/0x230)
[   27.468872] [<c05546e8>] (rx_complete) from [<c052b528>] (dwc2_hsotg_complete_request+0xfc/0)
[   27.506240] [<c052b528>] (dwc2_hsotg_complete_request) from [<c052bba0>] (dwc2_hsotg_handle_o)
[   27.545401] [<c052bba0>] (dwc2_hsotg_handle_outdone) from [<c052be70>] (dwc2_hsotg_epint+0x2c)
[   27.583689] [<c052be70>] (dwc2_hsotg_epint) from [<c052c750>] (dwc2_hsotg_irq+0x1dc/0x4ac)
[   27.621041] [<c052c750>] (dwc2_hsotg_irq) from [<c01682e0>] (handle_irq_event_percpu+0x70/0x)
[   27.659066] [<c01682e0>] (handle_irq_event_percpu) from [<c01684ec>] (handle_irq_event+0x4c)
[   27.697322] [<c01684ec>] (handle_irq_event) from [<c016bae0>] (handle_fasteoi_irq+0xc8/0x11)
[   27.735451] [<c016bae0>] (handle_fasteoi_irq) from [<c0167b8c>] (generic_handle_irq+0x30/0x)
[   27.773918] [<c0167b8c>] (generic_handle_irq) from [<c0167ca4>] (__handle_domain_irq+0x84/0)
[   27.812018] [<c0167ca4>] (__handle_domain_irq) from [<c01003b0>] (gic_handle_irq+0x48/0x6c)
[   27.849695] [<c01003b0>] (gic_handle_irq) from [<c010b340>] (__irq_svc+0x40/0x50)
[   27.886907] Exception stack(0xc0d01ee0 to 0xc0d01f28)

Acked-by: John Youn <johnyoun@synopsys.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Jeffy Chen <jeffy.chen@rock-chips.com>
Signed-off-by: Yunzhi Li <lyz@rock-chips.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-01 12:40:27 -05:00
Mian Yousaf Kaukab
21795c826a usb: dwc2: exit hibernation on session request
Controller enters hibernation through suspend interrupt on
disconnection. On connection, session request interrupt is generated.
dwc2 must exit hibernation and restore state from this interrupt
before continuing.

In host mode, exit from hibernation is handled by bus_resume function.

Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Tested-by: Robert Baldyga <r.baldyga@samsung.com>
Tested-by: Dinh Nguyen <dinguyen@opensource.altera.com>
Tested-by: John Youn <johnyoun@synopsys.com>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-01 12:40:27 -05:00
Mian Yousaf Kaukab
8fc37b82a4 usb: dwc2: gadget: handle reset interrupt before endpoint interrupts
If system is loaded, reset, enum-done and setup interrupts can occur
at the same time. Current interrupt handling sequence will handle
setup packet's interrupt before handling reset interrupt. Which will
break the enumeration process. Correct sequence is to handle reset,
enum-done and then any other endpoint interrupts.

Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
Tested-by: Robert Baldyga <r.baldyga@samsung.com>
Tested-by: Dinh Nguyen <dinguyen@opensource.altera.com>
Tested-by: John Youn <johnyoun@synopsys.com>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-01 12:40:27 -05:00
Gregory Herrero
61f7223bf1 usb: dwc2: gadget: exit hibernation before power down
When disconnecting cable, controller will detect a suspend condition
and enter partial power down. If vbus_session is called by the phy
driver during hibernation, make sure controller exit hibernation
before it is accessed.

Signed-off-by: Jianqiang Tang <jianqiang.tang@intel.com>
Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
Tested-by: Robert Baldyga <r.baldyga@samsung.com>
Tested-by: Dinh Nguyen <dinguyen@opensource.altera.com>
Tested-by: John Youn <johnyoun@synopsys.com>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-01 12:40:27 -05:00
Gregory Herrero
1ee6903b8f usb: dwc2: gadget: unmask idstschng interrupt only if controller supports it
idstschng interrupt should not be used when id pin control is
external. This is already handled on dwc2 host part. Fix it on gadget
part as well.

Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
Tested-by: Robert Baldyga <r.baldyga@samsung.com>
Tested-by: Dinh Nguyen <dinguyen@opensource.altera.com>
Tested-by: John Youn <johnyoun@synopsys.com>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-01 12:40:26 -05:00
Mian Yousaf Kaukab
2becdc62a9 usb: dwc2: gadget: only reset core after addressed state
There is a 200ms guard period to avoid unnecessary resets of the dwc2
ip. This delay sometimes prove to be too large when usbcv is run with
an ehci host. dwc2 only needs to be reset after addressed state.
Change the logic to reset ip after addressed state.

Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
Tested-by: Robert Baldyga <r.baldyga@samsung.com>
Tested-by: Dinh Nguyen <dinguyen@opensource.altera.com>
Tested-by: John Youn <johnyoun@synopsys.com>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-01 12:40:26 -05:00
Mian Yousaf Kaukab
5390d438e6 usb: dwc2: gadget: kill ep0 requests before reinitializing core
Make sure there are no requests pending on ep0 before reinitializing
core. Otherwise, dwc2_hsotg_enqueue_setup will fail afterwards.

Also, take hsotg->lock before calling
dwc2_hsotg_core_init_disconnected() from dwc2_conn_id_status_change()
as dwc2_hsotg_complete_request() expect lock to be held.

Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
Tested-by: Robert Baldyga <r.baldyga@samsung.com>
Tested-by: Dinh Nguyen <dinguyen@opensource.altera.com>
Tested-by: John Youn <johnyoun@synopsys.com>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-01 12:40:26 -05:00
Mian Yousaf Kaukab
c524dd5f43 usb: dwc2: gadget: stop current transfer on dequeue
If the request being dequeued is already started, disable endpoint
to stop the transfer and then call dwc2_hsotg_complete_request().
Endpoint will be re-enabled on next call to dwc2_hsotg_start_req().

Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
Tested-by: Robert Baldyga <r.baldyga@samsung.com>
Tested-by: Dinh Nguyen <dinguyen@opensource.altera.com>
Tested-by: John Youn <johnyoun@synopsys.com>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-01 12:40:25 -05:00
Mian Yousaf Kaukab
e525e74339 usb: dwc2: gadget: print complete setup packet
wIndex field was missing. Also print in natural order instead of
Req first, so that its easier to compare for example against
bus analyzer logs.

Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
Tested-by: Robert Baldyga <r.baldyga@samsung.com>
Tested-by: Dinh Nguyen <dinguyen@opensource.altera.com>
Tested-by: John Youn <johnyoun@synopsys.com>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-01 12:40:25 -05:00
Mian Yousaf Kaukab
b2d4c54e51 usb: dwc2: gadget: ignore stall check for ep0
dwc2_hsotg_start_req starts a request only if endpoint is not stalled.
Ignore this check for ep0 as core will clear DOEPCTL0.Stall after
sending stall handshake. Prepare instead for receiving next setup
packet.

Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
Tested-by: Robert Baldyga <r.baldyga@samsung.com>
Tested-by: Dinh Nguyen <dinguyen@opensource.altera.com>
Tested-by: John Youn <johnyoun@synopsys.com>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-01 12:40:25 -05:00
Gregory Herrero
86de489536 usb: dwc2: gadget: abort core init if core_reset fails
No point of continue with initialization if core is not in a sane
state.

Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
Tested-by: Robert Baldyga <r.baldyga@samsung.com>
Tested-by: Dinh Nguyen <dinguyen@opensource.altera.com>
Tested-by: John Youn <johnyoun@synopsys.com>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-01 12:40:24 -05:00
Gregory Herrero
cd0e641c8d usb: dwc2: gadget: set op_state in vbus_session call
Some device may have external id pin control enabled, so op_state
will not be set on id pin interrupt change.
Thus, ensure op_state is set to peripheral during vbus detection.

Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
Tested-by: Robert Baldyga <r.baldyga@samsung.com>
Tested-by: Dinh Nguyen <dinguyen@opensource.altera.com>
Tested-by: John Youn <johnyoun@synopsys.com>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-01 12:40:24 -05:00
Gregory Herrero
77ba9119ad usb: dwc2: gadget: don't modify pullup state in host mode
Modifying the pullup state during host mode trig a new enumeration
of attached device. Thus, avoid modifying pullup in host mode.

Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
Tested-by: Robert Baldyga <r.baldyga@samsung.com>
Tested-by: Dinh Nguyen <dinguyen@opensource.altera.com>
Tested-by: John Youn <johnyoun@synopsys.com>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-01 12:40:24 -05:00
Mian Yousaf Kaukab
857512d0eb usb: dwc2: force dr_mode in case of configuration mismatch
If dual role configuration is not selected, check and force dr_mode
based on the selected configuration.

Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
Tested-by: Robert Baldyga <r.baldyga@samsung.com>
Tested-by: Dinh Nguyen <dinguyen@opensource.altera.com>
Tested-by: John Youn <johnyoun@synopsys.com>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-10-01 12:40:23 -05:00