summaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc2
AgeCommit message (Collapse)Author
2016-04-04usb: dwc2: do not override forced dr_mode in gadget setupPrzemek Rudy
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). 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>
2016-03-04usb: dwc2: Fix issues in dwc2_complete_non_isoc_xfer_ddma()John Youn
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. Reported-by: Felipe Balbi <balbi@kernel.org> Signed-off-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
2016-03-04usb: dwc2: Add support for Lantiq ARX and XRX SoCsAntti Seppälä
Add support for Lantiq ARX and XRX SoC families to the dwc2 driver. 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>
2016-03-04usb: dwc2: Move host-specific core functions into hcd.cJohn Youn
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). 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>
2016-03-04usb: dwc2: Move register save and restore functionsJohn Youn
Move the register save and restore functions into the host and gadget specific files. 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>
2016-03-04usb: dwc2: Use kmem_cache_free()Amitoj Kaur Chawla
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> Acked-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Amitoj Kaur Chawla <amitoj1606@gmail.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
2016-03-04usb: dwc2: host: If using uframe scheduler, end splits betterDouglas Anderson
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. 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-04usb: dwc2: host: Totally redo the microframe schedulerDouglas Anderson
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-04usb: dwc2: host: Properly set even/odd frameDouglas Anderson
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-04usb: dwc2: host: Add dwc2_hcd_get_future_frame_number() callDouglas Anderson
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-04usb: dwc2: host: Manage frame nums better in schedulerDouglas Anderson
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-04usb: dwc2: host: Add scheduler logging for missed SOFsDouglas Anderson
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-04usb: dwc2: host: Split code out to make dwc2_do_reserve()Douglas Anderson
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-04usb: dwc2: host: Reorder things in hcd_queue.cDouglas Anderson
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-04usb: dwc2: host: Rename some fields in struct dwc2_qhDouglas Anderson
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-04usb: dwc2: host: Use periodic interrupt even with DMADouglas Anderson
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-04usb: dwc2: host: There's not really a TT for the root hubDouglas Anderson
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-04usb: dwc2: host: Properly set the HFIRDouglas Anderson
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-04usb: dwc2: host: Giveback URB in tasklet contextDouglas Anderson
In commit 94dfd7edfd5c ("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-04usb: dwc2: host: Add a delay before releasing periodic bandwidthDouglas Anderson
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 9118f9eb4f1e ("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-04usb: dwc2: host: Add scheduler tracingDouglas Anderson
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-04usb: dwc2: host: fix split transfer schedule sequenceDouglas Anderson
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-04usb: dwc2: host: Always add to the tail of queuesDouglas Anderson
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-04usb: dwc2: host: Avoid use of chan->qh after qh freedDouglas Anderson
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-04usb: dwc2: host: Set host_rx_fifo_size to 525 for rk3066Douglas Anderson
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-04usb: dwc2: host: Get aligned DMA in a more supported wayDouglas Anderson
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-04usb: dwc2: rockchip: Make the max_transfer_size automaticDouglas Anderson
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 e8f8c14d9da7 ("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-01Merge 4.5-rc6 into usb-nextGreg Kroah-Hartman
We want the USB fixes in here as well. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-02-20usb: dwc2: USB_DWC2 should depend on HAS_DMAGeert Uytterhoeven
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-17usb: dwc2: USB_DWC2 should depend on HAS_DMAGeert Uytterhoeven
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-17usb: dwc2: host: fix the data toggle error in full speed descriptor dmaTang, Jianqiang
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-17usb: dwc2: host: fix logical omissions in dwc2_process_non_isoc_descVardan Mikayelyan
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 26a19ea699060fde ("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: 26a19ea699060fde ("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-17usb: dwc2: Add extra delay when forcing dr_modeJohn Youn
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: 09c96980dc72 ("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-14usb: add HAS_IOMEM dependency to USB_DWC2Vegard Nossum
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-03usb: dwc2: Fix probe problem on bcm2835John Youn
Fixes an issue found on Raspberry PI platform that prevents probe. Don't skip setting the force mode if it's already set. Fixes: 09c96980dc72 ("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-03Revert "usb: dwc2: Move reset into dwc2_get_hwparams()"John Youn
This reverts commit 263b7fb557f7 ("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>
2015-12-22usb: dwc2: add shutdown callback to platform variantHeiko Stübner
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-22usb: dwc2: gadget: Repair DSTS register decodingMarek Vasut
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-22usb: dwc2: gadget: Remove call to dwc2_hsotg_init()John Youn
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-22usb: dwc2: Remove redundant reset in probeJohn Youn
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-22usb: dwc2: Reduce delay when forcing mode in resetJohn Youn
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-22usb: dwc2: gadget: Replace dwc2_hsotg_corereset()John Youn
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-22usb: dwc2: gadget: Use hw params from coreJohn Youn
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-22usb: dwc2: Improve handling of host and device hwparamsJohn Youn
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-22usb: dwc2: Add functions to set and clear force modeJohn Youn
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-22usb: dwc2: Move reset into dwc2_get_hwparams()John Youn
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-22usb: dwc2: Move mode querying functions into core.hJohn Youn
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-22usb: dwc2: Fix dr_mode validationJohn Youn
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-22usb: dwc2: Add functions to check the HW OTG configJohn Youn
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-22usb: dwc2: Add dwc2_core_reset()John Youn
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>