Re: [PATCH v6 20/22] usb: dwc2: host: Properly set even/odd frame
Doug, Thanks for your detail debug information, pls add my Reviewed-by for this patch. Thanks, - Kever On 02/03/2016 06:47 AM, Doug Anderson wrote: Kever, On Mon, Feb 1, 2016 at 11:46 PM, Kever Yang wrote: Doug, On 01/29/2016 10:20 AM, Douglas Anderson wrote: 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. Seems this really help for your case? Yes, I believe it does. Of course my test case is pretty "black box" for the most part in that I play music on youtube while having a webcam open and several USB input devices connected. I then try to decide whether I hear more static or less static. ...clearly a less subjective test would be better... * I tried with http://crosreview.com/325451 (see below) and I hear more static with "use_old = true" than with "use_old = "false". * I tried with this entire patch reverted and I hear about the same static as with "use_old = true". Note that counting reported MISS lines from my logging also shows that the new code is better... Do you check if the transfer can happen right in the current frame? I know it's quite difficult to check it, but this changes what I know for the dwc core schedule the transaction. Yes. I just tried again, too. I coded up <https://chromium-review.googlesource.com/325451> and included it. I then opened up a USB webcam. With things set to the old way: 115.355370 QH=dc6ba8c0 next(0) fn=10cb, sch=10ca=>10cb (+1) miss=0 115.355373 QH=dc6ba8c0 IMM ready fn=10cb, nxt=10cb 115.355518 QH=dc6ba8c0 next(0) fn=10cc, sch=10cb=>10cc (+1) miss=0 115.355522 QH=dc6ba8c0 IMM ready fn=10cc, nxt=10cc 115.355637 QH=dc6ba8c0 next(0) fn=10cd, sch=10cc=>10cd (+1) miss=0 115.355641 QH=dc6ba8c0 IMM ready fn=10cd, nxt=10cd 115.355857 QH=dc6ba8c0 next(0) fn=10ce, sch=10cd=>10ce (+1) miss=0 115.355859 QH=dc6ba8c0 IMM ready fn=10ce, nxt=10ce 115.355867 QH=dc6ba8c0, wire=10cf, old_wire=10d0, EO diff (use OLD) 115.355870 QH=dc6ba8c0 EO MISS w/ old (10ce != 10cf) 115.356037 QH=dc6ba8c0 next(0) fn=10d0, sch=10cf=>10d0 (+1) miss=1 MISS 115.356039 QH=dc6ba8c0 IMM ready fn=10d0, nxt=10d0 115.356169 QH=dc6ba8c0 next(0) fn=10d1, sch=10d0=>10d1 (+1) miss=0 115.356170 QH=dc6ba8c0 IMM ready fn=10d1, nxt=10d1 115.356269 QH=dc6ba8c0 next(0) fn=10d2, sch=10d1=>10d2 (+1) miss=0 115.356273 QH=dc6ba8c0 IMM ready fn=10d2, nxt=10d2 115.356404 QH=dc6ba8c0 next(0) fn=10d3, sch=10d2=>10d3 (+1) miss=0 115.356407 QH=dc6ba8c0 IMM ready fn=10d3, nxt=10d3 With the new way: 87.814741 QH=e2fd7880 next(0) fn=32e4, sch=32e3=>32e4 (+1) miss=0 87.814744 QH=e2fd7880 IMM ready fn=32e4, nxt=32e4 87.814858 QH=e2fd7880 next(0) fn=32e5, sch=32e4=>32e5 (+1) miss=0 87.814862 QH=e2fd7880 IMM ready fn=32e5, nxt=32e5 87.815010 QH=e2fd7880 next(0) fn=32e6, sch=32e5=>32e6 (+1) miss=0 87.815012 QH=e2fd7880 IMM ready fn=32e6, nxt=32e6 87.815220 QH=e2fd7880 next(0) fn=32e8, sch=32e6=>32e7 (+1) miss=0 87.815222 QH=e2fd7880 IMM ready fn=32e8, nxt=32e7 87.815230 QH=e2fd7880, wi
Re: [PATCH v6 20/22] usb: dwc2: host: Properly set even/odd frame
Doug, On 01/29/2016 10:20 AM, Douglas Anderson wrote: 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. Seems this really help for your case? Do you check if the transfer can happen right in the current frame? I know it's quite difficult to check it, but this changes what I know for the dwc core schedule the transaction. In dwc_otgbook, Interrupt OUT Transactions(also similar for Int IN, Iso IN/OUT) in DMA Mode, the normal Interrupt OUT operation says: The DWC_otg host attempts to send out the OUT token in the beginning of next odd frame/microframe. So I'm confuse about if the dwc core can do the transaction at the same frame of host channel initialized or not. Thanks, - Kever Signed-off-by: Douglas Anderson Tested-by: Heiko Stuebner Tested-by: Stefan Wahren --- Changes in v6: - Add Heiko's Tested-by. - Add Stefan's Tested-by. Changes in v5: None Changes in v4: - Properly set even/odd frame new for v4. Changes in v3: None Changes in v2: None drivers/usb/dwc2/core.c | 92 +++- drivers/usb/dwc2/hcd_queue.c | 11 +- 2 files changed, 100 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index a5db20f12ee4..c143f26bd9d9 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -1703,9 +1703,97 @@ static void dwc2_hc_set_even_odd_frame(struct dwc2_hsotg *hsotg, { if (chan->ep_type == USB_ENDPOINT_XFER_INT || chan->ep_type == USB_ENDPOINT_XFER_ISOC) { - /* 1 if _next_ frame is odd, 0 if it's even */ - if (!(dwc2_hcd_get_frame_number(hsotg) & 0x1)) + int host_speed; + int xfer_ns; + int xfer_us; + int bytes_in_fifo; + u16 fifo_space; + u16 frame_number; + u16 wire_frame; + + /* +* Try to figure out if we're an even or odd frame. If we set +* even and the current frame number is even the the transfer +* will happen immediately. Similar if both are odd. If one is +* even and the other is odd then the transfer will happen when +* the frame number ticks. +* +* There's a bit of a balancing act to get this right. +* Sometimes we may want to send data in the current frame (AK +* right away). We might want to do this if the frame number +* _just_ ticked, but we might also want to do this in order +* to continue a split transaction that happened late in a +* microframe (so we didn't know to queue the next transfer +* until the frame number had ticked). The problem is that we +* need a lot of knowledge to know if there's actually still +* time to send things or if it would be better to wait until +* the next frame. +* +* We can look at how much time is left in the current frame +* and make a guess about whether we'll have time to transfer. +* We'll do that. +*/ + +
Re: [PATCH v6 18/22] usb: dwc2: host: Schedule periodic right away if it's time
Doug, On 02/02/2016 08:36 AM, Doug Anderson wrote: Kever, On Sun, Jan 31, 2016 at 8:36 PM, Doug Anderson wrote: Kever, On Sun, Jan 31, 2016 at 7:32 PM, Kever Yang wrote: Doug, On 02/01/2016 06:09 AM, Doug Anderson wrote: Kever, On Sun, Jan 31, 2016 at 1:36 AM, Kever Yang wrote: Doug, On 01/29/2016 10:20 AM, Douglas Anderson wrote: In dwc2_hcd_qh_deactivate() we will put some things on the periodic_sched_ready list. These things won't be taken off the ready list until the next SOF, which might be a little late. Let's put them on right away. Signed-off-by: Douglas Anderson Tested-by: Heiko Stuebner Tested-by: Stefan Wahren --- Changes in v6: - Add Heiko's Tested-by. - Add Stefan's Tested-by. Changes in v5: None Changes in v4: - Schedule periodic right away if it's time new for v4. Changes in v3: None Changes in v2: None drivers/usb/dwc2/hcd_queue.c | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c index 9b3c435339ee..3abb34a5fc5b 100644 --- a/drivers/usb/dwc2/hcd_queue.c +++ b/drivers/usb/dwc2/hcd_queue.c @@ -1080,12 +1080,26 @@ void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, * Note: we purposely use the frame_number from the "hsotg" structure * since we know SOF interrupt will handle future frames. */ - if (dwc2_frame_num_le(qh->next_active_frame, hsotg->frame_number)) + if (dwc2_frame_num_le(qh->next_active_frame, hsotg->frame_number)) { + enum dwc2_transaction_type tr_type; + + /* +* We're bypassing the SOF handler which is normally what puts +* us on the ready list because we're in a hurry and need to +* try to catch up. +*/ + dwc2_sch_vdbg(hsotg, "QH=%p IMM ready fn=%04x, nxt=%04x\n", + qh, frame_number, qh->next_active_frame); list_move_tail(&qh->qh_list_entry, &hsotg->periodic_sched_ready); - else + + tr_type = dwc2_hcd_select_transactions(hsotg); Do we need to add select_transactions call here? If we get into this function in interrupt and once we put the qh in ready queue, the qh can be handled in this frame again by the later function call of dwc_hcd_select_transactions, so what we need to to here is put it in ready list instead of inactive queue, and wait for the schedule. I'm not sure I understand. Can you restate? I'll try to explain more in the meantime... Both before and after my change, this function would place something on the ready queue if the next_active_frame <= the frame number as of last SOF interrupt (aka hsotg->frame_number). Otherwise it goes on the inactive queue. Assuming that the previous change ("usb: dwc2: host: Manage frame nums better in scheduler") worked properly then next_active_frame shouldn't be less than (hsotg->frame_number - 1). Remember that next_active_frame is always 1 before the wire frame, so if "next_active_frame == hsotg->frame_number - 1" it means that we need to get the transfer on the wire _right away_. If "next_active_frame == hsotg->frame_number" the transfer doesn't need to go on the wire right away, but since dwc2 can be prepped one frame in advance it doesn't hurt to give it to the hardware right away if there's space. As I understand it, if we stick something on the ready queue it won't generally get looked at until the next SOF interrupt. That means we'll be too late if "next_active_frame == hsotg->frame_number - 1" and we'll possibly be too late (depending on interrupt latency) if "next_active_frame == hsotg->frame_number" I understand this patch and agree with your point of schedule the periodic right away instead of at least next frame. My point is, there are only two call to dwc2_hcd_qh_deactivate(), from dwc2_hcd_urb_dequeue() and dwc2_release_channel(), we don't need to do the schedule for dequeue, and there is one dwc2_hcd_select_transactions() call at the end of dwc2_release_channel(), maybe we don't need another dwc2_hcd_select_transactions() here. I think the duration from this point to the function call of dwc2_hcd_select_transactions() in dwc2_release_channel() will be the main factor for us to decide if we need to add a function call of dwc2_hcd_select_transactions() here. Oh, now I get what you're saying! A) You've got dwc2_release_channel() -> dwc2_deactivate_qh() -> dwc2_hcd_qh_deactivate() ...and always in that case we'll do a select / queue, so we don't need it there. B) You've got dwc2_hcd_urb_dequeue() -> dwc2_hcd_qh_deactivate() ...but why don't we need it for dw
Re: [PATCH v6 18/22] usb: dwc2: host: Schedule periodic right away if it's time
Doug, On 02/01/2016 06:09 AM, Doug Anderson wrote: Kever, On Sun, Jan 31, 2016 at 1:36 AM, Kever Yang wrote: Doug, On 01/29/2016 10:20 AM, Douglas Anderson wrote: In dwc2_hcd_qh_deactivate() we will put some things on the periodic_sched_ready list. These things won't be taken off the ready list until the next SOF, which might be a little late. Let's put them on right away. Signed-off-by: Douglas Anderson Tested-by: Heiko Stuebner Tested-by: Stefan Wahren --- Changes in v6: - Add Heiko's Tested-by. - Add Stefan's Tested-by. Changes in v5: None Changes in v4: - Schedule periodic right away if it's time new for v4. Changes in v3: None Changes in v2: None drivers/usb/dwc2/hcd_queue.c | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c index 9b3c435339ee..3abb34a5fc5b 100644 --- a/drivers/usb/dwc2/hcd_queue.c +++ b/drivers/usb/dwc2/hcd_queue.c @@ -1080,12 +1080,26 @@ void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, * Note: we purposely use the frame_number from the "hsotg" structure * since we know SOF interrupt will handle future frames. */ - if (dwc2_frame_num_le(qh->next_active_frame, hsotg->frame_number)) + if (dwc2_frame_num_le(qh->next_active_frame, hsotg->frame_number)) { + enum dwc2_transaction_type tr_type; + + /* +* We're bypassing the SOF handler which is normally what puts +* us on the ready list because we're in a hurry and need to +* try to catch up. +*/ + dwc2_sch_vdbg(hsotg, "QH=%p IMM ready fn=%04x, nxt=%04x\n", + qh, frame_number, qh->next_active_frame); list_move_tail(&qh->qh_list_entry, &hsotg->periodic_sched_ready); - else + + tr_type = dwc2_hcd_select_transactions(hsotg); Do we need to add select_transactions call here? If we get into this function in interrupt and once we put the qh in ready queue, the qh can be handled in this frame again by the later function call of dwc_hcd_select_transactions, so what we need to to here is put it in ready list instead of inactive queue, and wait for the schedule. I'm not sure I understand. Can you restate? I'll try to explain more in the meantime... Both before and after my change, this function would place something on the ready queue if the next_active_frame <= the frame number as of last SOF interrupt (aka hsotg->frame_number). Otherwise it goes on the inactive queue. Assuming that the previous change ("usb: dwc2: host: Manage frame nums better in scheduler") worked properly then next_active_frame shouldn't be less than (hsotg->frame_number - 1). Remember that next_active_frame is always 1 before the wire frame, so if "next_active_frame == hsotg->frame_number - 1" it means that we need to get the transfer on the wire _right away_. If "next_active_frame == hsotg->frame_number" the transfer doesn't need to go on the wire right away, but since dwc2 can be prepped one frame in advance it doesn't hurt to give it to the hardware right away if there's space. As I understand it, if we stick something on the ready queue it won't generally get looked at until the next SOF interrupt. That means we'll be too late if "next_active_frame == hsotg->frame_number - 1" and we'll possibly be too late (depending on interrupt latency) if "next_active_frame == hsotg->frame_number" I understand this patch and agree with your point of schedule the periodic right away instead of at least next frame. My point is, there are only two call to dwc2_hcd_qh_deactivate(), from dwc2_hcd_urb_dequeue() and dwc2_release_channel(), we don't need to do the schedule for dequeue, and there is one dwc2_hcd_select_transactions() call at the end of dwc2_release_channel(), maybe we don't need another dwc2_hcd_select_transactions() here. I think the duration from this point to the function call of dwc2_hcd_select_transactions() in dwc2_release_channel() will be the main factor for us to decide if we need to add a function call of dwc2_hcd_select_transactions() here. Thanks, - Kever Note that before my series, there were more places than just the SOF interrupt that would update hsotg->frame_number (see "usb: dwc2: host: Manage frame nums better in scheduler" for fix). Also before my series (specially "usb: dwc2: host: Manage frame nums better in scheduler") we used the actual current frame number when doing comparisons. Also before my series (specifically "usb: dwc2: host: Properly set even/odd frame") we didn't really place things in the frame that
Re: [PATCH v6 18/22] usb: dwc2: host: Schedule periodic right away if it's time
Doug, On 01/29/2016 10:20 AM, Douglas Anderson wrote: In dwc2_hcd_qh_deactivate() we will put some things on the periodic_sched_ready list. These things won't be taken off the ready list until the next SOF, which might be a little late. Let's put them on right away. Signed-off-by: Douglas Anderson Tested-by: Heiko Stuebner Tested-by: Stefan Wahren --- Changes in v6: - Add Heiko's Tested-by. - Add Stefan's Tested-by. Changes in v5: None Changes in v4: - Schedule periodic right away if it's time new for v4. Changes in v3: None Changes in v2: None drivers/usb/dwc2/hcd_queue.c | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c index 9b3c435339ee..3abb34a5fc5b 100644 --- a/drivers/usb/dwc2/hcd_queue.c +++ b/drivers/usb/dwc2/hcd_queue.c @@ -1080,12 +1080,26 @@ void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, * Note: we purposely use the frame_number from the "hsotg" structure * since we know SOF interrupt will handle future frames. */ - if (dwc2_frame_num_le(qh->next_active_frame, hsotg->frame_number)) + if (dwc2_frame_num_le(qh->next_active_frame, hsotg->frame_number)) { + enum dwc2_transaction_type tr_type; + + /* +* We're bypassing the SOF handler which is normally what puts +* us on the ready list because we're in a hurry and need to +* try to catch up. +*/ + dwc2_sch_vdbg(hsotg, "QH=%p IMM ready fn=%04x, nxt=%04x\n", + qh, frame_number, qh->next_active_frame); list_move_tail(&qh->qh_list_entry, &hsotg->periodic_sched_ready); - else + + tr_type = dwc2_hcd_select_transactions(hsotg); Do we need to add select_transactions call here? If we get into this function in interrupt and once we put the qh in ready queue, the qh can be handled in this frame again by the later function call of dwc_hcd_select_transactions, so what we need to to here is put it in ready list instead of inactive queue, and wait for the schedule. Thanks, - Kever + if (tr_type != DWC2_TRANSACTION_NONE) + dwc2_hcd_queue_transactions(hsotg, tr_type); + } else { list_move_tail(&qh->qh_list_entry, &hsotg->periodic_sched_inactive); + } } /** -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 11/22] usb: dwc2: host: There's not really a TT for the root hub
Doug, Reviewed-by: Kever Yang Thanks, - Kever On 01/29/2016 10:20 AM, Douglas Anderson wrote: 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. Signed-off-by: Douglas Anderson --- Changes in v6: - There's not really a TT for the root hub new for v6 Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: None drivers/usb/dwc2/hcd_intr.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c index 5d25a5ec9736..fe44870f84eb 100644 --- a/drivers/usb/dwc2/hcd_intr.c +++ b/drivers/usb/dwc2/hcd_intr.c @@ -87,6 +87,7 @@ static void dwc2_hc_handle_tt_clear(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan, struct dwc2_qtd *qtd) { + struct usb_device *root_hub = dwc2_hsotg_to_hcd(hsotg)->self.root_hub; struct urb *usb_urb; if (!chan->qh) @@ -102,6 +103,15 @@ static void dwc2_hc_handle_tt_clear(struct dwc2_hsotg *hsotg, if (!usb_urb || !usb_urb->dev || !usb_urb->dev->tt) return; + /* +* The root hub doesn't really have a TT, but Linux thinks it +* does because how could you have a "high speed hub" that +* directly talks directly to low speed devices without a TT? +* It's all lies. Lies, I tell you. +*/ + if (usb_urb->dev->tt->hub == root_hub) + return; + if (qtd->urb->status != -EPIPE && qtd->urb->status != -EREMOTEIO) { chan->qh->tt_buffer_dirty = 1; if (usb_hub_clear_tt_buffer(usb_urb)) -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 10/22] usb: dwc2: host: Properly set the HFIR
Doug, On 01/29/2016 10:20 AM, Douglas Anderson wrote: 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 I got 3 version of dwc_otg databook, 2.74a, 2.94a and 3.10a, all the doc describe the FrInt as: * 125 us * (PHY clock freq for HS) * 1000 us * (PHY clock freq for FS/LS) Maybe John can help to check the design. There are some feature different in new and old version, but not sure if this is one of then. The doc says If no value is programmed, the corecalculates the value based on the PHY clock specified in the FS/LS PHY Clock select field of Host configuration register(HCFG.FLSLPclkSel), does this work? Thanks, - Kever 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 Signed-off-by: Douglas Anderson Tested-by: Heiko Stuebner --- Changes in v6: - Incorporated Properly set the HFIR patch to big series in v6 - Add Heiko's Tested-by. Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: None drivers/usb/dwc2/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index ed73b26818c0..a5db20f12ee4 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -2245,10 +2245,10 @@ u32 dwc2_calc_frame_interval(struct dwc2_hsotg *hsotg) if ((hprt0 & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT == HPRT0_SPD_HIGH_SPEED) /* High speed case */ - return 125 * clock; + return 125 * clock - 1; else /* FS/LS case */ - return 1000 * clock; + return 1000 * clock - 1; } /** -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 03/21] usb: dwc2: host: Set host_rx_fifo_size to 528 for rk3066
Hi Doug, On 01/28/2016 03:44 AM, Doug Anderson wrote: If it's all the same to you, I'll probably change it back to 525 and then increase the periodic FIFO size by 3 DWORDS in the next patch. 12 bytes may not be much, but might as well make use of them to improve performance / compatibility? Presumably you're also OK with the next patch in the series: ("usb: dwc2: host: Set host_perio_tx_fifo_size to 304 for rk3066")? I'm OK for change in this patch, but I think we don't need next patch, pls see the reply in another mail. Thank, - Kever -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 04/21] usb: dwc2: host: Set host_perio_tx_fifo_size to 304 for rk3066
Hi Doug, We are in HOST mode, we only need to receive data from USB camera with RX FIFO, and no need to use TX FIFO for USB webcam, right? :) Any way, I think we need to NAK this patch after look into the design of dwc2 controller. Because all the dwc2 controller inside the Rockchip chips don't support the thresholding FIFO mode, in this case, there is no more transaction before a whole packet is send out and the dwc2 only care if the available FIFO is enough for next packet or not. So, the addition 48 words won't help to shorten the latency for data prepare in this case. Thanks, - Kever On 01/28/2016 11:28 AM, Doug Anderson wrote: Kever, On Wed, Jan 27, 2016 at 7:10 PM, Kever Yang wrote: Hi Doug, We are using the minimum FIFO size mode for TX now, which only equal to one max packet size. The addition FIFO size may help shorten the inter-packet data prepare latency when the bus/DRAM is busy. For the actual usage in TX, we have very little change to use the period TX FIFO with more than one max packet size in host mode. So far as I know, usb audio use the isochronous tx FIFO, but this king of device won't have much data payload and won't, I haven't see a usb audio have more data than 1024byte/ms. So I suggest we assign this 48 words to host_nperio_tx_fifi_size instead if we have to do this. Because we are using device base on bulk transaction like U-disk very frequently. Try using a USB webcam. With that plus a USB audio device it's easy to overwhelm the periodic TX FIFO. If we overwhelm the periodic TX FIFO we might actually fail to transmit ISO or INT packets at the scheduled time. That seems more serious of a problem to try to fix than eeking out a tiny bit performance on a USB disk. ...but of course, it all depends on what you consider important. ;) We could split the difference, I suppose and put half on each? -Doug -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 08/21] usb: dwc2: host: Add scheduler tracing
Hi Doug, Very good idea here, I used to add some local patch and with USB analyzer to debug this part of code, and we can use more tools with your patch now, I can try kernelshark next time. Do you consider to add tracing for qtd? Then we can track the whole lift cycle of urb in dwc2 driver. For this patch: Reviewed-by: Kever Yang Thanks, - Kever On 01/23/2016 02:18 AM, Douglas Anderson wrote: 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. Signed-off-by: Douglas Anderson --- Changes in v5: None Changes in v4: - Retooled scheduler tracing a bit, so left off John's Ack from v3. Changes in v3: None Changes in v2: None drivers/usb/dwc2/core.h | 20 drivers/usb/dwc2/hcd.h | 5 + drivers/usb/dwc2/hcd_intr.c | 6 +- drivers/usb/dwc2/hcd_queue.c | 24 +++- 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 538cf38af0e4..18f9e4045643 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -44,6 +44,26 @@ #include #include "hw.h" +/* + * Suggested defines for tracers: + * - no_printk:Disable tracing + * - pr_info: Print this info to the console + * - trace_printk: Print this info to trace buffer (good for verbose logging) + */ + +#define DWC2_TRACE_SCHEDULER no_printk +#define DWC2_TRACE_SCHEDULER_VBno_printk + +/* Detailed scheduler tracing, but won't overwhelm console */ +#define dwc2_sch_dbg(hsotg, fmt, ...) \ + DWC2_TRACE_SCHEDULER(pr_fmt("%s: SCH: " fmt), \ +dev_name(hsotg->dev), ##__VA_ARGS__) + +/* Verbose scheduler tracing */ +#define dwc2_sch_vdbg(hsotg, fmt, ...) \ + DWC2_TRACE_SCHEDULER_VB(pr_fmt("%s: SCH: " fmt), \ + dev_name(hsotg->dev), ##__VA_ARGS__) + static inline u32 dwc2_readl(const void __iomem *addr) { u32 value = __raw_readl(addr); diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h index 1b46e2e617cc..809bc4ff9116 100644 --- a/drivers/usb/dwc2/hcd.h +++ b/drivers/usb/dwc2/hcd.h @@ -563,6 +563,11 @@ static inline u16 dwc2_frame_num_inc(u16 frame, u16 inc) return (frame + inc) & HFNUM_MAX_FRNUM; } +static inline u16 dwc2_frame_num_dec(u16 frame, u16 dec) +{ + return (frame + HFNUM_MAX_FRNUM + 1 - dec) & HFNUM_MAX_FRNUM; +} + static inline u16 dwc2_full_frame_num(u16 frame) { return (frame & HFNUM_MAX_FRNUM) >> 3; diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c index 577c91096a51..5d25a5ec9736 100644 --- a/drivers/usb/dwc2/hcd_intr.c +++ b/drivers/usb/dwc2/hcd_intr.c @@ -138,13 +138,17 @@ static void dwc2_sof_intr(struct dwc2_hsotg *hsotg) while (qh_entry != &hsotg->periodic_sched_inactive) { qh = list_entry(qh_entry, struct dwc2_qh, qh_list_entry); qh_entry = qh_entry->next; - if (dwc2_frame_num_le(qh->sched_frame, hsotg->frame_number)) + if (dwc2_frame_num_le(qh->sched_frame, hsotg->frame_number)) { + dwc2_sch_vdbg(hsotg, "QH=%p ready fn=%04x, sch=%04x\n", + qh, hsotg->frame_number, qh->sched_frame); + /* * Move QH to the ready list to be executed next * (micro)frame */ list_move_tail(&qh->qh_list_entry, &hsotg->periodic_sched_ready); + } } tr_type = dwc2_hcd_select_transactions(hsotg); if (tr_type != DWC2_TRANSACTION_NONE) diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c index bc632a72f611..0e9faa75593c 100644 --- a/drivers/usb/dwc2/hcd_queue.c +++ b/drivers/usb/dwc2/hcd_queue.c @@ -113,6 +113,9 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, qh->sched_frame = dwc2_frame_num_inc(hsotg->frame_number, SCHEDULE_SLOP); qh->interval = urb->interval; + dwc2_sch_dbg(hsotg, "QH=%p init sch=%04x, fn=%04x, int=%#x\n", +qh, qh->sched_frame, hsotg->frame_number, +qh->interval); #if 0 /* Increase interrupt polling rate for debugging */ if (qh->ep_type == USB_ENDPOINT_XFER_INT) @@ -126,6 +129,11 @@ static void dwc2_qh_init(struct dwc2_hsotg
Re: [PATCH v5 05/21] usb: dwc2: host: Avoid use of chan->qh after qh freed
Hi Doug, The NULL pointer bug is one of the most frequent issue we met during hot plug stress test, thanks for this bug fix. Reviewed-by: Kever Yang Thanks, - Kever On 01/23/2016 02:18 AM, Douglas Anderson wrote: 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. Signed-off-by: Douglas Anderson --- Changes in v5: None Changes in v4: - Avoid use of chan->qh after qh freed new for v4. Changes in v3: None Changes in v2: None drivers/usb/dwc2/hcd.c | 8 drivers/usb/dwc2/hcd_intr.c | 10 ++ 2 files changed, 18 insertions(+) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index bc4bdbc1534e..7783c8ba0173 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -164,6 +164,9 @@ static void dwc2_qh_list_free(struct dwc2_hsotg *hsotg, qtd_list_entry) dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh); + if (qh->channel && qh->channel->qh == qh) + qh->channel->qh = NULL; + spin_unlock_irqrestore(&hsotg->lock, flags); dwc2_hcd_qh_free(hsotg, qh); spin_lock_irqsave(&hsotg->lock, flags); @@ -554,7 +557,12 @@ static int dwc2_hcd_endpoint_disable(struct dwc2_hsotg *hsotg, dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh); ep->hcpriv = NULL; + + if (qh->channel && qh->channel->qh == qh) + qh->channel->qh = NULL; + spin_unlock_irqrestore(&hsotg->lock, flags); + dwc2_hcd_qh_free(hsotg, qh); return 0; diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c index 352c98364317..99efc2bd1617 100644 --- a/drivers/usb/dwc2/hcd_intr.c +++ b/drivers/usb/dwc2/hcd_intr.c @@ -1935,6 +1935,16 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum) } dwc2_writel(hcint, hsotg->regs + HCINT(chnum)); + + /* +* If we got an interrupt after someone called +* dwc2_hcd_endpoint_disable() we don't want to crash below +*/ + if (!chan->qh) { + dev_warn(hsotg->dev, "Interrupt on disabled channel\n"); + return; + } + chan->hcint = hcint; hcint &= hcintmsk; -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 04/21] usb: dwc2: host: Set host_perio_tx_fifo_size to 304 for rk3066
Hi Doug, We are using the minimum FIFO size mode for TX now, which only equal to one max packet size. The addition FIFO size may help shorten the inter-packet data prepare latency when the bus/DRAM is busy. For the actual usage in TX, we have very little change to use the period TX FIFO with more than one max packet size in host mode. So far as I know, usb audio use the isochronous tx FIFO, but this king of device won't have much data payload and won't, I haven't see a usb audio have more data than 1024byte/ms. So I suggest we assign this 48 words to host_nperio_tx_fifi_size instead if we have to do this. Because we are using device base on bulk transaction like U-disk very frequently. Thanks, - Kever On 01/23/2016 02:18 AM, Douglas Anderson wrote: Looking at rk3288, there are two dwc2 ports. One has 960 total_fifo_size and the other 972. We're currently assigning 528 + 128 + 256 = 912. That means we're wasting 48 words on one port and 60 words on the other. Since we have one settings block for both ports, let's just eat the 48 words that we know we have and assign them to what's probably the most latency-senstive part of the system: periodic transfers. Presumably other rk3288 parts using the rk3066 settings also have these extra 48 words as well. Note: ideally we'd adjust dwc2_calculate_dynamic_fifo() to handle this more dynamically, but until that's done hardcoding things here seems OK. NOTE: no known use cases are improved by this patch, but in my stressful USB tests I certainly see my periodic FIFO filling up both before and after this change. Presumably there are some USB configurations where the periodic FIFO would have been filled before where it no longer is. Signed-off-by: Douglas Anderson --- Changes in v5: None Changes in v4: - Set host_perio_tx_fifo_size to 304 for rk3066 new for v4. Changes in v3: None Changes in v2: None drivers/usb/dwc2/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index b6d7666e715c..afdcdeee266d 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -128,7 +128,7 @@ static const struct dwc2_core_params params_rk3066 = { .en_multiple_tx_fifo= -1, .host_rx_fifo_size = 528, /* 528 DWORDs */ .host_nperio_tx_fifo_size = 128, /* 128 DWORDs */ - .host_perio_tx_fifo_size= 256, /* 256 DWORDs */ + .host_perio_tx_fifo_size= 304, /* 304 DWORDs */ .max_transfer_size = -1, .max_packet_count = -1, .host_channels = -1, -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 07/21] usb: dwc2: hcd: fix split transfer schedule sequence
Hi Doug, I test this patch with USB 2.0 analyzer, and it make the CSPLIT in the same order with the SSPLIT, so Reviewed-by: Kever Yang Tested-by: Kever Yang Thanks, - Kever On 01/23/2016 02:18 AM, Douglas Anderson wrote: 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 ff54 -> 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") Signed-off-by: Douglas Anderson Signed-off-by: Yunzhi Li --- Changes in v5: - Move list maintenance to hcd.c to avoid gadget-only compile error Changes in v4: - fix split transfer schedule sequence new for v4. Changes in v3: None Changes in v2: None drivers/usb/dwc2/core.c | 2 ++ drivers/usb/dwc2/core.h | 2 ++ drivers/usb/dwc2/hcd.c | 8 drivers/usb/dwc2/hcd.h | 2 ++ drivers/usb/dwc2/hcd_intr.c | 17 + 5 files changed, 31 insertions(+) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 73f2771b7740..ed73b26818c0 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -1676,6 +1676,8 @@ void dwc2_hc_cleanup(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan) chan->xfer_started = 0; + list_del_init(&chan->split_order_list_entry); + /* * Clear channel interrupt enables and any unhandled channel interrupt * conditions diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 7fb6434f4639..538cf38af0e4 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -657,6 +657,7 @@ struct dwc2_hregs_backup { * periodic_sched_ready because it must be rescheduled for * the next frame. Otherwise, the item moves to * periodic_sched_inactive. + * @split_order:List keeping track of channels doing splits, in order. * @periodic_usecs: Total bandwidth claimed so far for periodic transfers. * This value is in microseconds per (micro)frame. The * assumption is that all periodic transfers may occur in @@ -780,6 +781,7 @@ struct dwc2_hsotg { struct list_head periodic_sched_ready; struct list_head periodic_sched_assigned; struct list_head periodic_sched_queued; + struct list_head split_order; u16 periodic_usecs; u16 frame_usecs[8]; u16 frame_number; diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index d2daaea88d91..87ad5bf2d166 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1045,6 +1045,11 @@ static int dwc2_queue_transaction(struct dwc2_hsotg *hsotg, { int retval = 0; + if (chan->do_split) + /* Put ourselves on the list to keep order straight */ + list_move_tail(&chan->split_order_list_entry, + &hsotg->split_order); + if (hsotg->core_params->dma_enable > 0) { if (hsotg->core_params->dma_desc_enable > 0) { if (!chan->xfer_started || @@ -3151,6 +3156,8 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq) INIT_LIST_HEAD(&hsotg->periodic_sched_assigned); INIT_LIST_HEAD(&hsotg->periodic_sched_queued); + INIT_LIST_HEAD(&hsotg->split_order); + /* * Create a host channel descriptor for each host channel implemented * in the controller. Initialize the channel descriptor array. @@ -3164,6 +3171,7 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq) if (channel == NULL) goto error3; channel->hc_num = i; + INIT_LIST_HEAD(&channel->split_order_list_entry); hsotg->hc_ptr_array[i] = channel; } diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h index 42f2e4e233da..1b46e2e617cc 100644 --- a/drivers/usb/dwc2/hcd.h +++ b/drivers/usb/dwc2/hcd.h @@ -106,6 +106,7 @@ struct dwc2_qh; * @hc_list_entry: For linking to list of host channels * @desc_list_addr: Current QH's descriptor list DMA address * @desc_list_sz: Current QH's descriptor list size + * @split_order_list_entry: List entry for keeping track of the order of splits * * T
Re: [PATCH v5 06/21] usb: dwc2: host: Always add to the tail of queues
Hi Doug, This is obviously a bug in dwc2 driver which not meet the usb 2.0 spec, and this patch can fix it. Reviewed-by: Kever Yang Thanks, - Kever On 01/23/2016 02:18 AM, Douglas Anderson wrote: 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 Signed-off-by: Douglas Anderson --- Changes in v5: None Changes in v4: - Always add to the tail of queues new for v4. Changes in v3: None Changes in v2: None drivers/usb/dwc2/hcd.c | 11 ++- drivers/usb/dwc2/hcd_ddma.c | 4 ++-- drivers/usb/dwc2/hcd_intr.c | 4 ++-- drivers/usb/dwc2/hcd_queue.c | 6 -- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 7783c8ba0173..d2daaea88d91 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -969,7 +969,8 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions( * periodic assigned schedule */ qh_ptr = qh_ptr->next; - list_move(&qh->qh_list_entry, &hsotg->periodic_sched_assigned); + list_move_tail(&qh->qh_list_entry, + &hsotg->periodic_sched_assigned); ret_val = DWC2_TRANSACTION_PERIODIC; } @@ -1002,8 +1003,8 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions( * non-periodic active schedule */ qh_ptr = qh_ptr->next; - list_move(&qh->qh_list_entry, - &hsotg->non_periodic_sched_active); + list_move_tail(&qh->qh_list_entry, + &hsotg->non_periodic_sched_active); if (ret_val == DWC2_TRANSACTION_NONE) ret_val = DWC2_TRANSACTION_NON_PERIODIC; @@ -1176,8 +1177,8 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg) * Move the QH from the periodic assigned schedule to * the periodic queued schedule */ - list_move(&qh->qh_list_entry, - &hsotg->periodic_sched_queued); + list_move_tail(&qh->qh_list_entry, + &hsotg->periodic_sched_queued); /* done queuing high bandwidth */ hsotg->queuing_high_bandwidth = 0; diff --git a/drivers/usb/dwc2/hcd_ddma.c b/drivers/usb/dwc2/hcd_ddma.c index 36606fc33c0d..16b261cfa92d 100644 --- a/drivers/usb/dwc2/hcd_ddma.c +++ b/drivers/usb/dwc2/hcd_ddma.c @@ -1327,8 +1327,8 @@ void dwc2_hcd_complete_xfer_ddma(struct dwc2_hsotg *hsotg, dwc2_hcd_qh_unlink(hsotg, qh); } else { /* Keep in assigned schedule to continue transfer */ - list_move(&qh->qh_list_entry, - &hsotg->periodic_sched_assigned); + list_move_tail(&qh->qh_list_entry, + &hsotg->periodic_sched_assigned); /* * If channel has been halted during giveback of urb * then prevent any new scheduling. diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c index 99efc2bd1617..2c521c00e5e0 100644 --- a/drivers/usb/dwc2/hcd_intr.c +++ b/drivers/usb/dwc2/hcd_intr.c @@ -143,7 +143,7 @@ static void dwc2_sof_intr(struct dwc2_hsotg *hsotg) * Move QH to the ready list to be executed next * (micro)frame */ - list_move(&qh->qh_list_entry, + list_move_tail(&qh->qh_list_entry, &hsotg->periodic_sched_ready); } tr_type = dwc2_hcd_select_transactions(hsotg); @@ -794,7 +794,7 @@ static void dwc2_halt_channel(struct dwc2_hsotg *hsotg, * halt to be queued when the periodic schedule is * processed. */ - list_move(&chan->qh->qh_list_entry, + list_move_tail(&chan->qh->qh_list_entry, &hsotg->periodic_sched_assigned); /* diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd
Re: [PATCH v5 03/21] usb: dwc2: host: Set host_rx_fifo_size to 528 for rk3066
Hi Doug, On 01/23/2016 02:18 AM, Douglas Anderson wrote: 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. Since we have space, Kever Yang suggests bumping by 8. He says this will meet INCR16 access and next fifo type can start with a aligned address. I have double check this feature, the INCR16 is actually a burst 16 on to the bus, the aligned problem only happen on the DRAM access, and it's OK for internal RAM access via internal DMA. Bump to 8 looks much better when we check the FIFO setting if we have enough memory, right? :) rk3066/rk3188/rk3288 have the same hw config for dwc2 controller, so this patch should works on those files. Reviewed-by: Kever Yang ...so let's bump up by 8. 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. Signed-off-by: Douglas Anderson --- Changes in v5: None Changes in v4: - Set host_rx_fifo_size to 528 for rk3066 new for v4. Changes in v3: None Changes in v2: None drivers/usb/dwc2/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 5008a467ce06..b6d7666e715c 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -126,7 +126,7 @@ static const struct dwc2_core_params params_rk3066 = { .speed = -1, .enable_dynamic_fifo= 1, .en_multiple_tx_fifo= -1, - .host_rx_fifo_size = 520, /* 520 DWORDs */ + .host_rx_fifo_size = 528, /* 528 DWORDs */ .host_nperio_tx_fifo_size = 128, /* 128 DWORDs */ .host_perio_tx_fifo_size= 256, /* 256 DWORDs */ .max_transfer_size = -1, -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3] usb: dwc2: add bus suspend/resume for dwc2
Hi Paul, I think you need this patch to fix the problem: usb: dwc2: resume root hub when device detect with suspend state https://patchwork.kernel.org/patch/5325111/ Thanks, - Kever On 01/06/2015 09:23 AM, Paul Zimmerman wrote: From: Kever Yang [mailto:kever.y...@rock-chips.com] Sent: Wednesday, November 12, 2014 4:42 PM On 11/13/2014 07:22 AM, Doug Anderson wrote: Kever, On Mon, Nov 10, 2014 at 5:09 AM, Kever Yang wrote: Hcd controller needs bus_suspend/resume, dwc2 controller make root hub generate suspend/resume signal with hprt0 register when work in host mode. After the root hub enter suspend, we can make controller enter low power state with PCGCTL register. We also update the lx_state for hsotg state. This patch has tested on rk3288 with suspend/resume. Signed-off-by: Kever Yang Acked-by: Paul Zimmerman --- Changes in v3: - remove CONFIG_PM macro for bus_suspend/resume - add PCGCTL operation for no device connect case Changes in v2: - update commit message - make dwc2 suspend/resume sourcecode work drivers/usb/dwc2/hcd.c | 88 +++--- 1 file changed, 77 insertions(+), 11 deletions(-) I would certainly appreciate confirmation, but my inclination is to NAK this change due to the fact that it regresses functionality. I haven't done any serious review of it, but I've been testing it and it appears to break hotplug. Said another way, I did this: 1. Without this patch, I booted with a USB stick in. It was detected. I unplugged it, waited 5 seconds, and then plugged it back in. The USB stick was redetcted. 2. With this patch, I did the same thing. The USB not redected after plugging it back in. With this patch, the dwc2 hcd/root hub will be auto suspend after device on port is disconnected, and it can't detect the device connect any more, I think that's the problem. I will figure out how to make dwc2 detect the device connect after auto suspend, or disable the auto suspend feature for the dwc2 hcd. Kever, This patch has made it into Linus' kernel as commit 0cf884e819e0, and it breaks disconnect/connect on at least the Altera SOCFPGA platform. I haven't been able to test it on any other platforms. You need to submit a patch to either fix this, or to only enable this feature for the Rock-chip platform. Otherwise the patch has to be reverted. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] phy: add Rockchip RK3288 USB2 PHY driver.
Hi Roy, Why you send two patches with different commit message but the same change, you should use V2 for a new patch. On 12/03/2014 09:46 PM, LiYunzhi wrote: From: lyz You don't need the From for the patches from yourself. Add a driver for the Rockchip SoC internal USB2.0 PHY. This driver currently support RK3288. Signed-off-by: lyz Remember to use you Full name here for From/Signed-off-by or all the kind of signature. --- .../devicetree/bindings/phy/rockchip-usb-phy.txt | 17 ++ The document should be in a separate patch, so please split this into two patches. drivers/phy/Kconfig| 7 + drivers/phy/Makefile | 1 + drivers/phy/phy-rockchip-usb.c | 179 + 4 files changed, 204 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt create mode 100644 drivers/phy/phy-rockchip-usb.c diff --git a/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt new file mode 100644 index 000..18ccc2f --- /dev/null +++ b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt @@ -0,0 +1,17 @@ +ROCKCHIP USB2 PHY + +Required properties: + - compatible: rockchip,rk3288-usb-phy + - rockchip,grf : phandle to the syscon managing the "general + register files" + - #phy-cells: must be 1 +Refer to phy/phy-bindings.txt for the generic PHY binding +properties + +Example: + + usbphy: phy { + #phy-cells = <1>; + compatible = "rockchip,rk3288-usb-phy"; + rockchip,grf = <&grf>; + }; diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 2a436e6..54ab088 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -218,6 +218,13 @@ config PHY_QCOM_IPQ806X_SATA depends on OF select GENERIC_PHY +config PHY_ROCKCHIP_RK3288_USB2 + tristate "Rockchip USB2 RK3288 PHY Driver" + depends on ARCH_ROCKCHIP && OF + select GENERIC_PHY + help + Enable this to support the Rockchip USB 2.0 PHY. + config PHY_ST_SPEAR1310_MIPHY tristate "ST SPEAR1310-MIPHY driver" select GENERIC_PHY diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index c4590fc..f4f2f79 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -25,6 +25,7 @@ phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2)+= phy-s5pv210-usb2.o obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o +obj-$(CONFIG_PHY_ROCKCHIP_RK3288_USB2) += phy-rockchip-usb.o Add this after 'CONFIG_PHY_QCOM_IPQ806X_SATA'. obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o diff --git a/drivers/phy/phy-rockchip-usb.c b/drivers/phy/phy-rockchip-usb.c new file mode 100644 index 000..2586b76 --- /dev/null +++ b/drivers/phy/phy-rockchip-usb.c @@ -0,0 +1,179 @@ +/* + * Rockchip usb PHY driver + * + * Copyright (C) 2014 Roy Li + * Copyright (C) 2014 ROCKCHIP, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ROCKCHIP_RK3288_UOC(n) (0x320 + n * 0x14) + +#define SIDDQ_MSK (1 << (13 + 16)) +#define SIDDQ_ON (1 << 13) +#define SIDDQ_OFF (0 << 13) + +enum rk3288_phy_id { + RK3288_OTG, + RK3288_HOST0, + RK3288_HOST1, + RK3288_NUM_PHYS, +}; + +struct rockchip_usb_phy { + struct regmap *reg_base; + unsigned int reg_offset; + struct clk *clk; + struct phy *phy; +}; + +static int rockchip_usb_phy_power(struct rockchip_usb_phy *phy, + bool siddq) +{ + return regmap_write(phy->reg_base, phy->reg_offset, + SIDDQ_MSK | (siddq ? SIDDQ_ON : SIDDQ_OFF)); +} + +static int rockchip_usb_phy_power_off(struct phy *_phy) +{ + struct rockchip_usb_phy *phy = phy_get_drvdata(_phy); + int ret = 0; + + /* Power down usb phy analog blocks by set siddq 1*/ + ret = rockchip_usb_phy_power(phy, 1); Use a MACRO like ON/OFF instead of 1/0? and then we don't need the comment anymore. + if (ret) + return ret; + + clk_disabl
[PATCH v2] usb: dwc2: resume root hub when device detect with suspend state
After we implement the bus_suspend/resume, auto suspend id enabled. The root hub will be auto suspend if there is no device connected, we need to resume the root hub when a device connect detect. This patch tested on rk3288. Signed-off-by: Roy Li Signed-off-by: Kever Yang --- Changes in v2: - add definition for hcd structure - remove check for bus->root_hub drivers/usb/dwc2/hcd_intr.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c index 551ba87..680206f 100644 --- a/drivers/usb/dwc2/hcd_intr.c +++ b/drivers/usb/dwc2/hcd_intr.c @@ -329,6 +329,7 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg) { u32 hprt0; u32 hprt0_modify; + struct usb_hcd *hcd = (struct usb_hcd *)hsotg->priv; dev_vdbg(hsotg->dev, "--Port Interrupt--\n"); @@ -354,6 +355,10 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg) hsotg->flags.b.port_connect_status = 1; hprt0_modify |= HPRT0_CONNDET; + /* resume root hub? */ + if (hcd->state == HC_STATE_SUSPENDED) + usb_hcd_resume_root_hub(hcd); + /* * The Hub driver asserts a reset when it sees port connect * status change flag -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] usb: dwc2: resume root hub when device detect with suspend state
Hi Julius, On 11/18/2014 05:21 AM, Julius Werner wrote: On Mon, Nov 17, 2014 at 5:14 AM, Kever Yang wrote: After we implement the bus_suspend/resume, auto suspend id enabled. The root hub will be auto suspend if there is no device connected, we need to resume the root hub when a device connect detect. This patch tested on rk3288. Signed-off-by: Roy Li Signed-off-by: Kever Yang --- drivers/usb/dwc2/hcd_intr.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c index 551ba87..c8299fd 100644 --- a/drivers/usb/dwc2/hcd_intr.c +++ b/drivers/usb/dwc2/hcd_intr.c @@ -355,6 +355,13 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg) hprt0_modify |= HPRT0_CONNDET; /* +* Check if root hub is in suspend state +* if root hub in suspend, resume it. +*/ + if ((bus->root_hub) && (hcd->state == HC_STATE_SUSPENDED)) What is bus->root_hub checking for? Is there any chance that this could be NULL here? I add bus->root_hub check because the _dwc2_hcd_start check this before it call the usb_hcd_resume_root_hub. I think we don't need this check for the root_hub must be there if we register the HCD success, right? I will remove this in next version. + usb_hcd_resume_root_hub(hcd); + + /* * The Hub driver asserts a reset when it sees port connect * status change flag */ -- 1.9.1 Seems sensible in general. Does this actually fix the problem Doug was reporting? Yes, this fix the problem Doug reported with my dwc2 hcd suspend/resume patch. - Kever -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] usb: dwc2: resume root hub when device detect with suspend state
This patch is no complete, Sorry for that, I will upload a new version tomorrow. - Kever On 11/17/2014 09:14 PM, Kever Yang wrote: After we implement the bus_suspend/resume, auto suspend id enabled. The root hub will be auto suspend if there is no device connected, we need to resume the root hub when a device connect detect. This patch tested on rk3288. Signed-off-by: Roy Li Signed-off-by: Kever Yang --- drivers/usb/dwc2/hcd_intr.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c index 551ba87..c8299fd 100644 --- a/drivers/usb/dwc2/hcd_intr.c +++ b/drivers/usb/dwc2/hcd_intr.c @@ -355,6 +355,13 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg) hprt0_modify |= HPRT0_CONNDET; /* +* Check if root hub is in suspend state +* if root hub in suspend, resume it. +*/ + if ((bus->root_hub) && (hcd->state == HC_STATE_SUSPENDED)) + usb_hcd_resume_root_hub(hcd); + + /* * The Hub driver asserts a reset when it sees port connect * status change flag */ -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3] usb: dwc2: add bus suspend/resume for dwc2
On 11/14/2014 11:55 PM, Alan Stern wrote: On Thu, 13 Nov 2014, Julius Werner wrote: Another thing might be that the port connect interrupt does not correctly resume the root hub. I don't really know many details about how that works, and it seems pretty complicated. But I can see that all other HCDs seem to call usb_hcd_resume_root_hub() from their interrupt handlers, which we don't. There's also a That's how a root hub sends a wakeup request to the kernel. The controller issues an interrupt, and when the HCD's interrupt handler sees that the root hub is suspended, it calls usb_hcd_resume_root_hub() instead of trying to query the hardware (because in general you _can't_ query the hardware while it's in a low-power state). Thanks Alan and Julius, just like what you have mentioned, the dwc2 miss the usb_hcd_resume_root_hub() when root hub is suspended and device connect detected. I have send another patch for that, hope it did the right thing. - Kever -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] usb: dwc2: resume root hub when device detect with suspend state
After we implement the bus_suspend/resume, auto suspend id enabled. The root hub will be auto suspend if there is no device connected, we need to resume the root hub when a device connect detect. This patch tested on rk3288. Signed-off-by: Roy Li Signed-off-by: Kever Yang --- drivers/usb/dwc2/hcd_intr.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c index 551ba87..c8299fd 100644 --- a/drivers/usb/dwc2/hcd_intr.c +++ b/drivers/usb/dwc2/hcd_intr.c @@ -355,6 +355,13 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg) hprt0_modify |= HPRT0_CONNDET; /* +* Check if root hub is in suspend state +* if root hub in suspend, resume it. +*/ + if ((bus->root_hub) && (hcd->state == HC_STATE_SUSPENDED)) + usb_hcd_resume_root_hub(hcd); + + /* * The Hub driver asserts a reset when it sees port connect * status change flag */ -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3] usb: dwc2: add bus suspend/resume for dwc2
Doug, On 11/13/2014 07:22 AM, Doug Anderson wrote: Kever, On Mon, Nov 10, 2014 at 5:09 AM, Kever Yang wrote: Hcd controller needs bus_suspend/resume, dwc2 controller make root hub generate suspend/resume signal with hprt0 register when work in host mode. After the root hub enter suspend, we can make controller enter low power state with PCGCTL register. We also update the lx_state for hsotg state. This patch has tested on rk3288 with suspend/resume. Signed-off-by: Kever Yang Acked-by: Paul Zimmerman --- Changes in v3: - remove CONFIG_PM macro for bus_suspend/resume - add PCGCTL operation for no device connect case Changes in v2: - update commit message - make dwc2 suspend/resume sourcecode work drivers/usb/dwc2/hcd.c | 88 +++--- 1 file changed, 77 insertions(+), 11 deletions(-) I would certainly appreciate confirmation, but my inclination is to NAK this change due to the fact that it regresses functionality. I haven't done any serious review of it, but I've been testing it and it appears to break hotplug. Said another way, I did this: 1. Without this patch, I booted with a USB stick in. It was detected. I unplugged it, waited 5 seconds, and then plugged it back in. The USB stick was redetcted. 2. With this patch, I did the same thing. The USB not redected after plugging it back in. With this patch, the dwc2 hcd/root hub will be auto suspend after device on port is disconnected, and it can't detect the device connect any more, I think that's the problem. I will figure out how to make dwc2 detect the device connect after auto suspend, or disable the auto suspend feature for the dwc2 hcd. - Kever -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3] usb: dwc2: add bus suspend/resume for dwc2
Hcd controller needs bus_suspend/resume, dwc2 controller make root hub generate suspend/resume signal with hprt0 register when work in host mode. After the root hub enter suspend, we can make controller enter low power state with PCGCTL register. We also update the lx_state for hsotg state. This patch has tested on rk3288 with suspend/resume. Signed-off-by: Kever Yang Acked-by: Paul Zimmerman --- Changes in v3: - remove CONFIG_PM macro for bus_suspend/resume - add PCGCTL operation for no device connect case Changes in v2: - update commit message - make dwc2 suspend/resume sourcecode work drivers/usb/dwc2/hcd.c | 88 +++--- 1 file changed, 77 insertions(+), 11 deletions(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 0a0e6f0..7480078 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1471,6 +1471,30 @@ static void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) } } +static void dwc2_port_resume(struct dwc2_hsotg *hsotg) +{ + u32 hprt0; + + /* After clear the Stop PHY clock bit, we should wait for a moment +* for PLL work stable with clock output. +*/ + writel(0, hsotg->regs + PCGCTL); + usleep_range(2000, 4000); + + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_RES; + writel(hprt0, hsotg->regs + HPRT0); + hprt0 &= ~HPRT0_SUSP; + /* according to USB2.0 Spec 7.1.7.7, the host must send the resume +* signal for at least 20ms +*/ + usleep_range(2, 25000); + + hprt0 &= ~HPRT0_RES; + writel(hprt0, hsotg->regs + HPRT0); + hsotg->lx_state = DWC2_L0; +} + /* Handles hub class-specific requests */ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, u16 wvalue, u16 windex, char *buf, u16 wlength) @@ -1516,17 +1540,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, case USB_PORT_FEAT_SUSPEND: dev_dbg(hsotg->dev, "ClearPortFeature USB_PORT_FEAT_SUSPEND\n"); - writel(0, hsotg->regs + PCGCTL); - usleep_range(2, 4); - - hprt0 = dwc2_read_hprt0(hsotg); - hprt0 |= HPRT0_RES; - writel(hprt0, hsotg->regs + HPRT0); - hprt0 &= ~HPRT0_SUSP; - usleep_range(10, 15); - - hprt0 &= ~HPRT0_RES; - writel(hprt0, hsotg->regs + HPRT0); + dwc2_port_resume(hsotg); break; case USB_PORT_FEAT_POWER: @@ -2299,6 +2313,55 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd) usleep_range(1000, 3000); } +static int _dwc2_hcd_suspend(struct usb_hcd *hcd) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + u32 hprt0; + + if (!((hsotg->op_state == OTG_STATE_B_HOST) || + (hsotg->op_state == OTG_STATE_A_HOST))) + return 0; + + /* TODO: We get into suspend from 'on' state, maybe we need to do +* something if we get here from DWC2_L1(LPM sleep) state one day. +*/ + if (hsotg->lx_state != DWC2_L0) + return 0; + + hprt0 = dwc2_read_hprt0(hsotg); + if (hprt0 & HPRT0_CONNSTS) { + dwc2_port_suspend(hsotg, 1); + } else { + u32 pcgctl = readl(hsotg->regs + PCGCTL); + + pcgctl |= PCGCTL_STOPPCLK; + writel(pcgctl, hsotg->regs + PCGCTL); + } + + return 0; +} + +static int _dwc2_hcd_resume(struct usb_hcd *hcd) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + u32 hprt0; + + if (!((hsotg->op_state == OTG_STATE_B_HOST) || + (hsotg->op_state == OTG_STATE_A_HOST))) + return 0; + + if (hsotg->lx_state != DWC2_L2) + return 0; + + hprt0 = dwc2_read_hprt0(hsotg); + if ((hprt0 & HPRT0_CONNSTS) && (hprt0 & HPRT0_SUSP)) + dwc2_port_resume(hsotg); + else + writel(0, hsotg->regs + PCGCTL); + + return 0; +} + /* Returns the current frame number */ static int _dwc2_hcd_get_frame_number(struct usb_hcd *hcd) { @@ -2669,6 +2732,9 @@ static struct hc_driver dwc2_hc_driver = { .hub_status_data = _dwc2_hcd_hub_status_data, .hub_control = _dwc2_hcd_hub_control, .clear_tt_buffer_complete = _dwc2_hcd_clear_tt_buffer_complete, + + .bus_suspend = _dwc2_hcd_suspend, + .bus_resume = _dwc2_hcd_resume, }; /* -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] usb: dwc2: add bus suspend/resume for dwc2
Hi Julius, On 11/07/2014 06:11 AM, Julius Werner wrote: On Wed, Nov 5, 2014 at 5:30 PM, Kever Yang wrote: Hcd controller needs bus_suspend/resume, dwc2 controller make root hub generate suspend/resume signal with hprt0 register when work in host mode. After the root hub enter suspend, we can make controller enter low power state with PCGCTL register. You say you do this, but I don't actually see you doing it (for the not-connected case)? Agree to add PCGCTL operation for the not-connected case. We also update the lx_state for hsotg state. This patch has tested on rk3288 with suspend/resume. Signed-off-by: Kever Yang --- Changes in v2: - update commit message - make dwc2 suspend/resume sourcecode work drivers/usb/dwc2/hcd.c | 78 +++--- 1 file changed, 67 insertions(+), 11 deletions(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 0a0e6f0..01a415b 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1471,6 +1471,30 @@ static void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) } } +static void dwc2_port_resume(struct dwc2_hsotg *hsotg) +{ + u32 hprt0; + + /* After clear the Stop PHY clock bit, we should wait for a moment +* for PLL work stable with clock output. +*/ + writel(0, hsotg->regs + PCGCTL); + usleep_range(2000, 4000); + + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_RES; + writel(hprt0, hsotg->regs + HPRT0); + hprt0 &= ~HPRT0_SUSP; + /* according to USB2.0 Spec 7.1.7.7, the host must send the resume +* signal for at least 20ms +*/ + usleep_range(2, 25000); + + hprt0 &= ~HPRT0_RES; + writel(hprt0, hsotg->regs + HPRT0); + hsotg->lx_state = DWC2_L0; +} + /* Handles hub class-specific requests */ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, u16 wvalue, u16 windex, char *buf, u16 wlength) @@ -1516,17 +1540,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, case USB_PORT_FEAT_SUSPEND: dev_dbg(hsotg->dev, "ClearPortFeature USB_PORT_FEAT_SUSPEND\n"); - writel(0, hsotg->regs + PCGCTL); - usleep_range(2, 4); - - hprt0 = dwc2_read_hprt0(hsotg); - hprt0 |= HPRT0_RES; - writel(hprt0, hsotg->regs + HPRT0); - hprt0 &= ~HPRT0_SUSP; - usleep_range(10, 15); - - hprt0 &= ~HPRT0_RES; - writel(hprt0, hsotg->regs + HPRT0); I'm curious why this didn't change lx_state back to DWC2_L0 before... Paul, do you know? + dwc2_port_resume(hsotg); break; case USB_PORT_FEAT_POWER: @@ -2299,6 +2313,44 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd) usleep_range(1000, 3000); } +static int _dwc2_hcd_suspend(struct usb_hcd *hcd) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + u32 hprt0; + + if (!((hsotg->op_state == OTG_STATE_B_HOST) || + (hsotg->op_state == OTG_STATE_A_HOST))) + return 0; + + if (hsotg->lx_state != DWC2_L0) What if the port is in L1 state? I don't think the driver supports LPM right now, but the DWC2_L1 enum is defined so it may one day in the future. Let's maybe at least add a TODO. Added + return 0; In your original ChromiumOS version of this patch, you also set PCGCTL_STOPPCLK here if the port was not connected. Is there a reason that changed (does it not actually save power or something)? + + hprt0 = dwc2_read_hprt0(hsotg); + if (hprt0 & HPRT0_CONNSTS) + dwc2_port_suspend(hsotg, 1); The contract for bus_suspend() is that it will suspend all ports not yet suspended, keep track of those ports and then only resume those in bus_resume() (compare, for example, how XHCI keeps track of that with xhci_bus_state.bus_suspended in xhci_bus_suspend/resume()). So you need something here to remember whether this function suspended the port or whether it had already been suspended, and then only resume the port in bus_resume() in the former case. In fact, the dwc2 controller only support one port, so the hprt0 is the only one port we need to care. Note that dwc2_port_suspend() changes lx_state to DWC_L2 (at least in the version I'm looking at right now), so you can't just rely on that unless you explicitly set it back to something else here. + + return 0; +} + +static int _dwc2_hcd_resume(struct usb_hcd *hcd) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + u32 hprt0; + + if (!((hsotg->op_state =
[PATCH v2] usb: dwc2: add bus suspend/resume for dwc2
Hcd controller needs bus_suspend/resume, dwc2 controller make root hub generate suspend/resume signal with hprt0 register when work in host mode. After the root hub enter suspend, we can make controller enter low power state with PCGCTL register. We also update the lx_state for hsotg state. This patch has tested on rk3288 with suspend/resume. Signed-off-by: Kever Yang --- Changes in v2: - update commit message - make dwc2 suspend/resume sourcecode work drivers/usb/dwc2/hcd.c | 78 +++--- 1 file changed, 67 insertions(+), 11 deletions(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 0a0e6f0..01a415b 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1471,6 +1471,30 @@ static void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) } } +static void dwc2_port_resume(struct dwc2_hsotg *hsotg) +{ + u32 hprt0; + + /* After clear the Stop PHY clock bit, we should wait for a moment +* for PLL work stable with clock output. +*/ + writel(0, hsotg->regs + PCGCTL); + usleep_range(2000, 4000); + + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_RES; + writel(hprt0, hsotg->regs + HPRT0); + hprt0 &= ~HPRT0_SUSP; + /* according to USB2.0 Spec 7.1.7.7, the host must send the resume +* signal for at least 20ms +*/ + usleep_range(2, 25000); + + hprt0 &= ~HPRT0_RES; + writel(hprt0, hsotg->regs + HPRT0); + hsotg->lx_state = DWC2_L0; +} + /* Handles hub class-specific requests */ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, u16 wvalue, u16 windex, char *buf, u16 wlength) @@ -1516,17 +1540,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, case USB_PORT_FEAT_SUSPEND: dev_dbg(hsotg->dev, "ClearPortFeature USB_PORT_FEAT_SUSPEND\n"); - writel(0, hsotg->regs + PCGCTL); - usleep_range(2, 4); - - hprt0 = dwc2_read_hprt0(hsotg); - hprt0 |= HPRT0_RES; - writel(hprt0, hsotg->regs + HPRT0); - hprt0 &= ~HPRT0_SUSP; - usleep_range(10, 15); - - hprt0 &= ~HPRT0_RES; - writel(hprt0, hsotg->regs + HPRT0); + dwc2_port_resume(hsotg); break; case USB_PORT_FEAT_POWER: @@ -2299,6 +2313,44 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd) usleep_range(1000, 3000); } +static int _dwc2_hcd_suspend(struct usb_hcd *hcd) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + u32 hprt0; + + if (!((hsotg->op_state == OTG_STATE_B_HOST) || + (hsotg->op_state == OTG_STATE_A_HOST))) + return 0; + + if (hsotg->lx_state != DWC2_L0) + return 0; + + hprt0 = dwc2_read_hprt0(hsotg); + if (hprt0 & HPRT0_CONNSTS) + dwc2_port_suspend(hsotg, 1); + + return 0; +} + +static int _dwc2_hcd_resume(struct usb_hcd *hcd) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + u32 hprt0; + + if (!((hsotg->op_state == OTG_STATE_B_HOST) || + (hsotg->op_state == OTG_STATE_A_HOST))) + return 0; + + if (hsotg->lx_state != DWC2_L2) + return 0; + + hprt0 = dwc2_read_hprt0(hsotg); + if ((hprt0 & HPRT0_CONNSTS) && (hprt0 & HPRT0_SUSP)) + dwc2_port_resume(hsotg); + + return 0; +} + /* Returns the current frame number */ static int _dwc2_hcd_get_frame_number(struct usb_hcd *hcd) { @@ -2669,6 +2721,10 @@ static struct hc_driver dwc2_hc_driver = { .hub_status_data = _dwc2_hcd_hub_status_data, .hub_control = _dwc2_hcd_hub_control, .clear_tt_buffer_complete = _dwc2_hcd_clear_tt_buffer_complete, +#ifdef CONFIG_PM + .bus_suspend = _dwc2_hcd_suspend, + .bus_resume = _dwc2_hcd_resume, +#endif }; /* -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] usb: dwc2: add bus suspend/resume for dwc2
This patch adds suspend/resume for dwc2 hcd controller. Signed-off-by: Kever Yang --- drivers/usb/dwc2/hcd.c | 74 ++ 1 file changed, 63 insertions(+), 11 deletions(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index fa49c72..df68449 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1473,6 +1473,29 @@ static void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) } } +static void dwc2_port_resume(struct dwc2_hsotg *hsotg) +{ + u32 hprt0; + + /* After clear the Stop PHY clock bit, we should wait for a moment +* for PLL work stable with clock output. +*/ + writel(0, hsotg->regs + PCGCTL); + usleep_range(2000, 4000); + + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_RES; + writel(hprt0, hsotg->regs + HPRT0); + hprt0 &= ~HPRT0_SUSP; + /* according to USB2.0 Spec 7.1.7.7, the host most send the resume +* signal for at least 20ms +*/ + usleep_range(2, 25000); + + hprt0 &= ~HPRT0_RES; + writel(hprt0, hsotg->regs + HPRT0); +} + /* Handles hub class-specific requests */ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, u16 wvalue, u16 windex, char *buf, u16 wlength) @@ -1518,17 +1541,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, case USB_PORT_FEAT_SUSPEND: dev_dbg(hsotg->dev, "ClearPortFeature USB_PORT_FEAT_SUSPEND\n"); - writel(0, hsotg->regs + PCGCTL); - usleep_range(2, 4); - - hprt0 = dwc2_read_hprt0(hsotg); - hprt0 |= HPRT0_RES; - writel(hprt0, hsotg->regs + HPRT0); - hprt0 &= ~HPRT0_SUSP; - usleep_range(10, 15); - - hprt0 &= ~HPRT0_RES; - writel(hprt0, hsotg->regs + HPRT0); + dwc2_port_resume(hsotg); break; case USB_PORT_FEAT_POWER: @@ -2301,6 +2314,42 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd) usleep_range(1000, 3000); } +static int _dwc2_hcd_suspend(struct usb_hcd *hcd) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + u32 hprt0; + + if (hsotg->op_state != OTG_STATE_B_HOST) + return 0; + + if (hsotg->lx_state != DWC2_L0) + return 0; + + hprt0 = dwc2_read_hprt0(hsotg); + if (hprt0 & HPRT0_CONNSTS) + dwc2_port_suspend(hsotg, 1); + + return 0; +} + +static int _dwc2_hcd_resume(struct usb_hcd *hcd) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + u32 hprt0; + + if (hsotg->op_state != OTG_STATE_B_HOST) + return 0; + + if (hsotg->lx_state != DWC2_L2) + return 0; + + hprt0 = dwc2_read_hprt0(hsotg); + if ((hprt0 | HPRT0_CONNSTS) && (hprt0 | HPRT0_SUSP)) + dwc2_port_resume(hsotg); + + return 0; +} + /* Returns the current frame number */ static int _dwc2_hcd_get_frame_number(struct usb_hcd *hcd) { @@ -2671,6 +2720,9 @@ static struct hc_driver dwc2_hc_driver = { .hub_status_data = _dwc2_hcd_hub_status_data, .hub_control = _dwc2_hcd_hub_control, .clear_tt_buffer_complete = _dwc2_hcd_clear_tt_buffer_complete, + + .bus_suspend = _dwc2_hcd_suspend, + .bus_resume = _dwc2_hcd_resume, }; /* -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv6 1/8] usb: dwc2: Update the gadget driver to use common dwc2_hsotg structure
Hi Dinh On 10/29/2014 07:25 AM, dingu...@opensource.altera.com wrote: From: Dinh Nguyen Adds the gadget data structure and appropriate data structure pointers to the common dwc2_hsotg data structure. To keep the driver data dereference code looking clean, the gadget variable declares are only available for peripheral and dual-role mode. This is needed so that the dwc2_hsotg data structure can be used by the hcd and gadget drivers. Updates gadget.c to use the dwc2_hsotg data structure and gadget pointers that have been moved into the common dwc2_hsotg structure. Are we still need so much s3c prefix? Can we replace all the s3c into dwc2? - Kever -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv6 6/8] usb: dwc2: gadget: Do not fail probe if there isn't a clock node
Hi Dinh, On 10/29/2014 07:25 AM, dingu...@opensource.altera.com wrote: From: Dinh Nguyen Since the dwc2 hcd driver is currently not looking for a clock node during init, we should not completely fail if there isn't a clock provided. For dual-role mode, we will only fail init for a non-clock node error. We then update the HCD to only call gadget funtions if there is a proper clock node. We have to add clock management for hcd, and I think it is better to do it before more Socs use this driver, isn't it? I have do something in my RFC patches, but I think I still do it in a wrong way. Can we just handle all the clock thing in platform? Balbi suggested in my patch that we can "hide" clk_enable()/disable() under ->runtime_resume()/->runtime_suspend() and linux driver model. Can this be in platform driver? - Kever -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH v2 2/2] usb: dwc2: move the clock management from gadget to platform
This patch move clock management out of gadget into platform, make both hcd and gadget can use the clock. Signed-off-by: Kever Yang --- Changes in v2: - move all the clock operation into platform drivers/usb/dwc2/gadget.c | 24 ++-- drivers/usb/dwc2/platform.c | 32 2 files changed, 22 insertions(+), 34 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 6ffbfc2..0b108ee 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2852,8 +2852,6 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, hsotg->gadget.dev.of_node = hsotg->dev->of_node; hsotg->gadget.speed = USB_SPEED_UNKNOWN; - clk_enable(hsotg->clk); - ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); if (ret) { @@ -2903,8 +2901,6 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); - clk_disable(hsotg->clk); - return 0; } @@ -2936,10 +2932,8 @@ static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) spin_lock_irqsave(&hsotg->lock, flags); if (is_on) { s3c_hsotg_phy_enable(hsotg); - clk_enable(hsotg->clk); s3c_hsotg_core_init(hsotg); } else { - clk_disable(hsotg->clk); s3c_hsotg_phy_disable(hsotg); } @@ -3408,20 +3402,12 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) hsotg->phyif = GUSBCFG_PHYIF8; } - hsotg->clk = devm_clk_get(dev, "otg"); - if (IS_ERR(hsotg->clk)) { - dev_err(dev, "cannot get otg clock\n"); - return PTR_ERR(hsotg->clk); - } - hsotg->gadget.max_speed = USB_SPEED_HIGH; hsotg->gadget.ops = &s3c_hsotg_gadget_ops; hsotg->gadget.name = dev_name(dev); /* reset the system */ - clk_prepare_enable(hsotg->clk); - /* regulators */ for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++) @@ -3431,7 +3417,7 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) hsotg->supplies); if (ret) { dev_err(dev, "failed to request supplies: %d\n", ret); - goto err_clk; + goto out; } ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), @@ -3510,9 +3496,7 @@ err_ep_mem: kfree(eps); err_supplies: s3c_hsotg_phy_disable(hsotg); -err_clk: - clk_disable_unprepare(hsotg->clk); - +out: return ret; } EXPORT_SYMBOL_GPL(dwc2_gadget_init); @@ -3532,8 +3516,6 @@ int s3c_hsotg_remove(struct dwc2_hsotg *hsotg) usb_gadget_unregister_driver(hsotg->driver); } - clk_disable_unprepare(hsotg->clk); - return 0; } EXPORT_SYMBOL_GPL(s3c_hsotg_remove); @@ -3560,7 +3542,6 @@ int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); - clk_disable(hsotg->clk); } return ret; @@ -3576,7 +3557,6 @@ int s3c_hsotg_resume(struct dwc2_hsotg *hsotg) dev_info(hsotg->dev, "resuming usb gadget %s\n", hsotg->driver->driver.name); - clk_enable(hsotg->clk); ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); } diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 77c8417..356e378 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -122,6 +123,7 @@ static int dwc2_driver_remove(struct platform_device *dev) dwc2_hcd_remove(hsotg); s3c_hsotg_remove(hsotg); + clk_disable_unprepare(hsotg->clk); return 0; } @@ -216,24 +218,28 @@ static int dwc2_driver_probe(struct platform_device *dev) hsotg->dr_mode = of_usb_get_dr_mode(dev->dev.of_node); spin_lock_init(&hsotg->lock); - retval = dwc2_gadget_init(hsotg, irq); - if (retval) { - /* -* We will not fail the driver initialization for dual-role -* if no clock node is supplied. However, all gadget -* functionality will be disabled if a clock node is not -* provided. Host functionality will continue. -* TO-DO: make clock node a requirement for the HCD. -*/ - if (
[RFC PATCH v2 0/2] add power manage for dwc2 hcd
This patchset add clock manage and suspend/resume for dwc2. Based on Dinh's patch "usb: dwc2: Add support for dual role". Because the system suspend/resume on my platform still not ready, and the 'suspend' can't be used in power/control node, and the auto suspend seems not work, could anyone told me how to test the usb suspend/resume API easily? Changes in v2: - remove the clock from hcd - adjust the delay time when resume - move all the clock operation into platform Kever Yang (2): usb: dwc2: add bus suspend/resume for dwc2 usb: dwc2: move the clock management from gadget to platform drivers/usb/dwc2/gadget.c | 24 ++- drivers/usb/dwc2/hcd.c | 75 ++--- drivers/usb/dwc2/platform.c | 32 +++ 3 files changed, 86 insertions(+), 45 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH v2 1/2] usb: dwc2: add bus suspend/resume for dwc2
This patch adds suspend/resume for dwc2 hcd controller. Signed-off-by: Kever Yang --- Changes in v2: - remove the clock from hcd - adjust the delay time when resume drivers/usb/dwc2/hcd.c | 75 ++ 1 file changed, 64 insertions(+), 11 deletions(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index fa49c72..76984da 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1473,6 +1473,30 @@ static void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) } } +static void dwc2_port_resume(struct dwc2_hsotg *hsotg) +{ + u32 hprt0; + + /* After clear the Stop PHY clock bit, we should wait for a moment +* for clock stable, but I still didn't know how long it should take. +* I will update it in next version. +*/ + writel(0, hsotg->regs + PCGCTL); + usleep_range(2, 4); + + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_RES; + writel(hprt0, hsotg->regs + HPRT0); + hprt0 &= ~HPRT0_SUSP; + /* according to USB2.0 Spec 7.1.7.7, the host most send the resume +* signal for at least 20ms +*/ + usleep_range(2, 25000); + + hprt0 &= ~HPRT0_RES; + writel(hprt0, hsotg->regs + HPRT0); +} + /* Handles hub class-specific requests */ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, u16 wvalue, u16 windex, char *buf, u16 wlength) @@ -1518,17 +1542,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, case USB_PORT_FEAT_SUSPEND: dev_dbg(hsotg->dev, "ClearPortFeature USB_PORT_FEAT_SUSPEND\n"); - writel(0, hsotg->regs + PCGCTL); - usleep_range(2, 4); - - hprt0 = dwc2_read_hprt0(hsotg); - hprt0 |= HPRT0_RES; - writel(hprt0, hsotg->regs + HPRT0); - hprt0 &= ~HPRT0_SUSP; - usleep_range(10, 15); - - hprt0 &= ~HPRT0_RES; - writel(hprt0, hsotg->regs + HPRT0); + dwc2_port_resume(hsotg); break; case USB_PORT_FEAT_POWER: @@ -2301,6 +2315,42 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd) usleep_range(1000, 3000); } +static int _dwc2_hcd_suspend(struct usb_hcd *hcd) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + u32 hprt0; + + if (hsotg->op_state != OTG_STATE_B_HOST) + return 0; + + if (hsotg->lx_state != DWC2_L0) + return 0; + + hprt0 = dwc2_read_hprt0(hsotg); + if (hprt0 & HPRT0_CONNSTS) + dwc2_port_suspend(hsotg, 1); + + return 0; +} + +static int _dwc2_hcd_resume(struct usb_hcd *hcd) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + u32 hprt0; + + if (hsotg->op_state != OTG_STATE_B_HOST) + return 0; + + if (hsotg->lx_state != DWC2_L2) + return 0; + + hprt0 = dwc2_read_hprt0(hsotg); + if ((hprt0 | HPRT0_CONNSTS) && (hprt0 | HPRT0_SUSP)) + dwc2_port_resume(hsotg); + + return 0; +} + /* Returns the current frame number */ static int _dwc2_hcd_get_frame_number(struct usb_hcd *hcd) { @@ -2671,6 +2721,9 @@ static struct hc_driver dwc2_hc_driver = { .hub_status_data = _dwc2_hcd_hub_status_data, .hub_control = _dwc2_hcd_hub_control, .clear_tt_buffer_complete = _dwc2_hcd_clear_tt_buffer_complete, + + .bus_suspend = _dwc2_hcd_suspend, + .bus_resume = _dwc2_hcd_resume, }; /* -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 2/2] usb: dwc2: add bus suspend/resume for dwc2
Hi Felipe, On 10/16/2014 06:30 AM, Felipe Balbi wrote: On Wed, Oct 15, 2014 at 10:46:18PM -0700, Kever Yang wrote: This patch add suspend/resume for dwc2 hcd controller. adds Signed-off-by: Kever Yang --- drivers/usb/dwc2/hcd.c | 71 ++ 1 file changed, 60 insertions(+), 11 deletions(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index fddd923..c1801d8 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1474,6 +1474,23 @@ static void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) } } +static void dwc2_port_resume(struct dwc2_hsotg *hsotg) +{ + u32 hprt0; + + writel(0, hsotg->regs + PCGCTL); + usleep_range(2, 4); why this usleep_range() ? Is it documented somewhere ? How about adding a comment explaining why you need to wait at least 20ms ? This is a straight copy of CLEAR_FEATURE(PORT_SUSPEND) code in dwc2_hcd_hub_control(), maybe Paul knows the detail? I will check with USB2.0 spec and DWC databook to figure out how long the delay it should be. + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_RES; + writel(hprt0, hsotg->regs + HPRT0); + hprt0 &= ~HPRT0_SUSP; + usleep_range(10, 15); and another one here, why ? + hprt0 &= ~HPRT0_RES; + writel(hprt0, hsotg->regs + HPRT0); +} + /* Handles hub class-specific requests */ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, u16 wvalue, u16 windex, char *buf, u16 wlength) @@ -1519,17 +1536,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, case USB_PORT_FEAT_SUSPEND: dev_dbg(hsotg->dev, "ClearPortFeature USB_PORT_FEAT_SUSPEND\n"); - writel(0, hsotg->regs + PCGCTL); - usleep_range(2, 4); - - hprt0 = dwc2_read_hprt0(hsotg); - hprt0 |= HPRT0_RES; - writel(hprt0, hsotg->regs + HPRT0); - hprt0 &= ~HPRT0_SUSP; - usleep_range(10, 15); - - hprt0 &= ~HPRT0_RES; - writel(hprt0, hsotg->regs + HPRT0); + dwc2_port_resume(hsotg); break; case USB_PORT_FEAT_POWER: @@ -2304,6 +2311,45 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd) usleep_range(1000, 3000); } +static int _dwc2_hcd_suspend(struct usb_hcd *hcd) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + u32 hprt0; + + if (hsotg->op_state != OTG_STATE_B_HOST) + return 0; + + if (hsotg->lx_state != DWC2_L0) + return 0; + + hprt0 = dwc2_read_hprt0(hsotg); + if (hprt0 | HPRT0_CONNSTS) did you mean: if (hprt0 & HPRT0_CONNSTS) ?? + dwc2_port_suspend(hsotg, 1); always 1 ? + clk_disable(hsotg->clk); this I keep getting wrong, but if ->bus_suspend() is really the one used for actual system sleep, then you might want to fiddle with the clocks only from the parent platform glue. I haven't really read the code to make sure, however, so this might be a completely bogus comment :-) + return 0; +} + +static int _dwc2_hcd_resume(struct usb_hcd *hcd) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + u32 hprt0; + + if (hsotg->op_state != OTG_STATE_B_HOST) + return 0; + + if (hsotg->lx_state != DWC2_L2) + return 0; + + clk_enable(hsotg->clk); + + hprt0 = dwc2_read_hprt0(hsotg); + if (hprt0 | HPRT0_CONNSTS | HPRT0_SUSP) and here: if ((hprt0 & HPRT0_CONNSTS) && (hprt0 & HPRT0_SUSP)) ??? -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 1/2] usb: dwc2: add clock manage for hcd
Hi Felipe, Thank for comment. On 10/16/2014 06:23 AM, Felipe Balbi wrote: Hi, On Wed, Oct 15, 2014 at 10:46:17PM -0700, Kever Yang wrote: This patch move clock init out of gadget into platform, make both hcd and gadget can use the clock Signed-off-by: Kever Yang --- drivers/usb/dwc2/gadget.c | 16 ++-- drivers/usb/dwc2/hcd.c | 3 +++ drivers/usb/dwc2/platform.c | 30 ++ 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index fa49c72..fddd923 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -2266,6 +2267,7 @@ static int _dwc2_hcd_start(struct usb_hcd *hcd) spin_lock_irqsave(&hsotg->lock, flags); hcd->state = HC_STATE_RUNNING; + clk_enable(hsotg->clk); with this you're moving clk_enable() from gadget to HCD. You might want to leave this completely to the glue; at least for now. No, I moving devm_clk_get/clk_prerare_enable/clk_disable_unprepare to platform, but not effect clk_enable/disable in the gadget. I send this patch for comments if we can do it in this way. If not, how should we manage clock in hcd and gadget? - Kever -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 1/2] usb: dwc2: add clock manage for hcd
This patch move clock init out of gadget into platform, make both hcd and gadget can use the clock Signed-off-by: Kever Yang --- drivers/usb/dwc2/gadget.c | 16 ++-- drivers/usb/dwc2/hcd.c | 3 +++ drivers/usb/dwc2/platform.c | 30 ++ 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 6ffbfc2..1943e52 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3408,20 +3408,12 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) hsotg->phyif = GUSBCFG_PHYIF8; } - hsotg->clk = devm_clk_get(dev, "otg"); - if (IS_ERR(hsotg->clk)) { - dev_err(dev, "cannot get otg clock\n"); - return PTR_ERR(hsotg->clk); - } - hsotg->gadget.max_speed = USB_SPEED_HIGH; hsotg->gadget.ops = &s3c_hsotg_gadget_ops; hsotg->gadget.name = dev_name(dev); /* reset the system */ - clk_prepare_enable(hsotg->clk); - /* regulators */ for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++) @@ -3431,7 +3423,7 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) hsotg->supplies); if (ret) { dev_err(dev, "failed to request supplies: %d\n", ret); - goto err_clk; + goto out; } ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), @@ -3510,9 +3502,7 @@ err_ep_mem: kfree(eps); err_supplies: s3c_hsotg_phy_disable(hsotg); -err_clk: - clk_disable_unprepare(hsotg->clk); - +out: return ret; } EXPORT_SYMBOL_GPL(dwc2_gadget_init); @@ -3532,8 +3522,6 @@ int s3c_hsotg_remove(struct dwc2_hsotg *hsotg) usb_gadget_unregister_driver(hsotg->driver); } - clk_disable_unprepare(hsotg->clk); - return 0; } EXPORT_SYMBOL_GPL(s3c_hsotg_remove); diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index fa49c72..fddd923 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -2266,6 +2267,7 @@ static int _dwc2_hcd_start(struct usb_hcd *hcd) spin_lock_irqsave(&hsotg->lock, flags); hcd->state = HC_STATE_RUNNING; + clk_enable(hsotg->clk); if (dwc2_is_device_mode(hsotg)) { spin_unlock_irqrestore(&hsotg->lock, flags); @@ -2297,6 +2299,7 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd) spin_lock_irqsave(&hsotg->lock, flags); dwc2_hcd_stop(hsotg); spin_unlock_irqrestore(&hsotg->lock, flags); + clk_disable(hsotg->clk); usleep_range(1000, 3000); } diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 77c8417..16cdd1f 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -122,6 +123,7 @@ static int dwc2_driver_remove(struct platform_device *dev) dwc2_hcd_remove(hsotg); s3c_hsotg_remove(hsotg); + clk_disable_unprepare(hsotg->clk); return 0; } @@ -216,24 +218,28 @@ static int dwc2_driver_probe(struct platform_device *dev) hsotg->dr_mode = of_usb_get_dr_mode(dev->dev.of_node); spin_lock_init(&hsotg->lock); - retval = dwc2_gadget_init(hsotg, irq); - if (retval) { - /* -* We will not fail the driver initialization for dual-role -* if no clock node is supplied. However, all gadget -* functionality will be disabled if a clock node is not -* provided. Host functionality will continue. -* TO-DO: make clock node a requirement for the HCD. -*/ - if (!IS_ERR(hsotg->clk)) - return retval; + hsotg->clk = devm_clk_get(dev, "otg"); + if (IS_ERR(hsotg->clk)) { + dev_err(dev, "cannot get otg clock\n"); + return PTR_ERR(hsotg->clk); } + + clk_prepare_enable(hsotg->clk); + + retval = dwc2_gadget_init(hsotg, irq); + if (retval) + goto out; + retval = dwc2_hcd_init(hsotg, irq, params); if (retval) - return retval; + goto out; platform_set_drvdata(dev, hsotg); +out: + if (IS_ERR(retval)) + clk_disable_unprepare(hsotg->clk); + return retval; } -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 2/2] usb: dwc2: add bus suspend/resume for dwc2
This patch add suspend/resume for dwc2 hcd controller. Signed-off-by: Kever Yang --- drivers/usb/dwc2/hcd.c | 71 ++ 1 file changed, 60 insertions(+), 11 deletions(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index fddd923..c1801d8 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1474,6 +1474,23 @@ static void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) } } +static void dwc2_port_resume(struct dwc2_hsotg *hsotg) +{ + u32 hprt0; + + writel(0, hsotg->regs + PCGCTL); + usleep_range(2, 4); + + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_RES; + writel(hprt0, hsotg->regs + HPRT0); + hprt0 &= ~HPRT0_SUSP; + usleep_range(10, 15); + + hprt0 &= ~HPRT0_RES; + writel(hprt0, hsotg->regs + HPRT0); +} + /* Handles hub class-specific requests */ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, u16 wvalue, u16 windex, char *buf, u16 wlength) @@ -1519,17 +1536,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, case USB_PORT_FEAT_SUSPEND: dev_dbg(hsotg->dev, "ClearPortFeature USB_PORT_FEAT_SUSPEND\n"); - writel(0, hsotg->regs + PCGCTL); - usleep_range(2, 4); - - hprt0 = dwc2_read_hprt0(hsotg); - hprt0 |= HPRT0_RES; - writel(hprt0, hsotg->regs + HPRT0); - hprt0 &= ~HPRT0_SUSP; - usleep_range(10, 15); - - hprt0 &= ~HPRT0_RES; - writel(hprt0, hsotg->regs + HPRT0); + dwc2_port_resume(hsotg); break; case USB_PORT_FEAT_POWER: @@ -2304,6 +2311,45 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd) usleep_range(1000, 3000); } +static int _dwc2_hcd_suspend(struct usb_hcd *hcd) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + u32 hprt0; + + if (hsotg->op_state != OTG_STATE_B_HOST) + return 0; + + if (hsotg->lx_state != DWC2_L0) + return 0; + + hprt0 = dwc2_read_hprt0(hsotg); + if (hprt0 | HPRT0_CONNSTS) + dwc2_port_suspend(hsotg, 1); + + clk_disable(hsotg->clk); + return 0; +} + +static int _dwc2_hcd_resume(struct usb_hcd *hcd) +{ + struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + u32 hprt0; + + if (hsotg->op_state != OTG_STATE_B_HOST) + return 0; + + if (hsotg->lx_state != DWC2_L2) + return 0; + + clk_enable(hsotg->clk); + + hprt0 = dwc2_read_hprt0(hsotg); + if (hprt0 | HPRT0_CONNSTS | HPRT0_SUSP) + dwc2_port_resume(hsotg); + + return 0; +} + /* Returns the current frame number */ static int _dwc2_hcd_get_frame_number(struct usb_hcd *hcd) { @@ -2674,6 +2720,9 @@ static struct hc_driver dwc2_hc_driver = { .hub_status_data = _dwc2_hcd_hub_status_data, .hub_control = _dwc2_hcd_hub_control, .clear_tt_buffer_complete = _dwc2_hcd_clear_tt_buffer_complete, + + .bus_suspend = _dwc2_hcd_suspend, + .bus_resume = _dwc2_hcd_resume, }; /* -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 0/2] add power manage for dwc2 hcd
This patchset add clock manage and suspend/resume for dwc2. Based on Dinh's patch "usb: dwc2: Add support for dual role". Kever Yang (2): usb: dwc2: add clock manage for hcd usb: dwc2: add bus suspend/resume for dwc2 drivers/usb/dwc2/gadget.c | 16 ++ drivers/usb/dwc2/hcd.c | 74 ++--- drivers/usb/dwc2/platform.c | 30 ++ 3 files changed, 83 insertions(+), 37 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 2/4] usb: dwc2: add compatible data for rockchip soc
This patch add compatible data for dwc2 controller found on rk3066, rk3188 and rk3288 processors from rockchip. Signed-off-by: Kever Yang Acked-by: Paul Zimmerman --- Changes in v5: - max_transfer_size change to 65535 to met the requirement of header file Changes in v4: - max_transfer_size change to 65536, this should be enough for most transfer, the hardware auto-detect will set this to 0x7 which may make dma_alloc_coherent fail when non-dword aligned buf from driver like usbnet happen. Changes in v3: None Changes in v2: - set most parameters as driver auto-detect drivers/usb/dwc2/platform.c | 29 + 1 file changed, 29 insertions(+) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index a10e7a3..2f859bd 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -75,6 +75,34 @@ static const struct dwc2_core_params params_bcm2835 = { .uframe_sched = 0, }; +static const struct dwc2_core_params params_rk3066 = { + .otg_cap= 2,/* non-HNP/non-SRP */ + .otg_ver= -1, + .dma_enable = -1, + .dma_desc_enable= 0, + .speed = -1, + .enable_dynamic_fifo= 1, + .en_multiple_tx_fifo= -1, + .host_rx_fifo_size = 520, /* 520 DWORDs */ + .host_nperio_tx_fifo_size = 128, /* 128 DWORDs */ + .host_perio_tx_fifo_size= 256, /* 256 DWORDs */ + .max_transfer_size = 65535, + .max_packet_count = -1, + .host_channels = -1, + .phy_type = -1, + .phy_utmi_width = -1, + .phy_ulpi_ddr = -1, + .phy_ulpi_ext_vbus = -1, + .i2c_enable = -1, + .ulpi_fs_ls = -1, + .host_support_fs_ls_low_power = -1, + .host_ls_low_power_phy_clk = -1, + .ts_dline = -1, + .reload_ctl = -1, + .ahbcfg = 0x7, /* INCR16 */ + .uframe_sched = -1, +}; + /** * dwc2_driver_remove() - Called when the DWC_otg core is unregistered with the * DWC_otg driver @@ -97,6 +125,7 @@ static int dwc2_driver_remove(struct platform_device *dev) static const struct of_device_id dwc2_of_match_table[] = { { .compatible = "brcm,bcm2835-usb", .data = ¶ms_bcm2835 }, + { .compatible = "rockchip,rk3066-usb", .data = ¶ms_rk3066 }, { .compatible = "snps,dwc2", .data = NULL }, {}, }; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 0/4] Patches to add support for Rockchip dwc2 controller
These patches to add support for dwc2 controller found in Rockchip processors rk3066, rk3188 and rk3288, and enable dts for rk3288 evb. Changes in v5: - max_transfer_size change to 65535 to met the requirement of header file - change the sort order of dwc2 in rk3288.dtsi - don't enable otg port for evb Changes in v4: - max_transfer_size change to 65536, this should be enough for most transfer, the hardware auto-detect will set this to 0x7 which may make dma_alloc_coherent fail when non-dword aligned buf from driver like usbnet happen. - remove EHCI and HSIC dts patch for Doug had post it seprately. Changes in v3: - EHCI and HSIC move new for version 3. - Rebase Changes in v2: - Split out dr_mode and rk3288 bindings. - add compatible "snps,dwc2" bingding info - set most parameters as driver auto-detect - evb patch added in version 2 Kever Yang (4): Documentation: dt-bindings: add dt binding info for Rockchip dwc2 usb: dwc2: add compatible data for rockchip soc ARM: dts: add rk3288 dwc2 controller support ARM: dts: Enable USB host1(dwc) on rk3288-evb Documentation/devicetree/bindings/usb/dwc2.txt | 3 +++ arch/arm/boot/dts/rk3288-evb.dtsi | 4 arch/arm/boot/dts/rk3288.dtsi | 20 ++ drivers/usb/dwc2/platform.c| 29 ++ 4 files changed, 56 insertions(+) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] usb: dwc2: Read GNPTXFSIZ when in forced HOST mode.
Doug: On 08/08/2014 03:48 AM, Doug Anderson wrote: The documentation for GNPTXFSIZ says that "For host mode, this field is always valid." Since we're already switching to host mode for HPTXFSIZ, let's also read GNPTXFSIZ in host mode. On an rk3288 SoC, without this change we see this at bootup: dwc2 ff58.usb: gnptxfsiz=00100400 dwc2 ff58.usb: 128 invalid for host_nperio_tx_fifo_size. Check HW configuration. After this change we see: dwc2 ff58.usb: gnptxfsiz=04000400 Yeap, that is the problem cause the log you shown in rk3288-evb and further more cause fifo setting fail. I was plan to commit this patch just the same as you did. It's great that you also find out the problem and send this patch. Signed-off-by: Doug Anderson --- drivers/usb/dwc2/core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 27d2c9b..c184ed43 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -2674,23 +2674,23 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) hwcfg2 = readl(hsotg->regs + GHWCFG2); hwcfg3 = readl(hsotg->regs + GHWCFG3); hwcfg4 = readl(hsotg->regs + GHWCFG4); - gnptxfsiz = readl(hsotg->regs + GNPTXFSIZ); grxfsiz = readl(hsotg->regs + GRXFSIZ); dev_dbg(hsotg->dev, "hwcfg1=%08x\n", hwcfg1); dev_dbg(hsotg->dev, "hwcfg2=%08x\n", hwcfg2); dev_dbg(hsotg->dev, "hwcfg3=%08x\n", hwcfg3); dev_dbg(hsotg->dev, "hwcfg4=%08x\n", hwcfg4); - dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz); dev_dbg(hsotg->dev, "grxfsiz=%08x\n", grxfsiz); - /* Force host mode to get HPTXFSIZ exact power on value */ + /* Force host mode to get HPTXFSIZ / GNPTXFSIZ exact power on value */ gusbcfg = readl(hsotg->regs + GUSBCFG); gusbcfg |= GUSBCFG_FORCEHOSTMODE; writel(gusbcfg, hsotg->regs + GUSBCFG); usleep_range(10, 15); + gnptxfsiz = readl(hsotg->regs + GNPTXFSIZ); hptxfsiz = readl(hsotg->regs + HPTXFSIZ); + dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz); dev_dbg(hsotg->dev, "hptxfsiz=%08x\n", hptxfsiz); gusbcfg = readl(hsotg->regs + GUSBCFG); gusbcfg &= ~GUSBCFG_FORCEHOSTMODE; There may be a potential problem still need to fix, the grxfsiz may have being changed, the bootrom and uboot will change this value if they use the dwc2 controller. The way we get the register value here can not make sure this is the power-on value which we actually need. Let me do more test for that, and maybe we need another patch. Anyway, this patch works and reasonable. Reviewed-by: Kever Yang -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 2/4] usb: dwc2: add compatible data for rockchip soc
Paul, On 08/08/2014 02:26 AM, Paul Zimmerman wrote: From: Kever Yang [mailto:kever.y...@gmail.com] On Behalf Of Kever Yang Sent: Thursday, August 07, 2014 2:35 AM This patch add compatible data for dwc2 controller found on rk3066, rk3188 and rk3288 processors from rockchip. Signed-off-by: Kever Yang Acked-by: Paul Zimmerman --- Changes in v4: - max_transfer_size change to 65536, this should be enough for most transfer, the hardware auto-detect will set this to 0x7 which may make dma_alloc_coherent fail when non-dword aligned buf from driver like usbnet happen. Hi Kever, Did you test this change thoroughly? I have vague memories of any value above 65535 causing problems, at least on my hardware. And I see it is set to 65535 in both pci.c and platform.c. I could be wrong, but I thought I should mention it. I test it on rk3288 evb, it works find with 65536, I'm sorry for didn't mention it in my patch. The problem in my platform is if the value use hardware auto-detect, it will be 0x7, and that will cause the dma_alloc_coherent fail in hcd driver. The value less than 0x7 should be fine for hardware, but for the software, it depends on how we use it. What kind of problem did you met? Software problem or hardware problem? Maybe I should pay more attention for this value. :) -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 0/4] Patches to add support for Rockchip dwc2 controller
These patches to add support for dwc2 controller found in Rockchip processors rk3066, rk3188 and rk3288, and enable dts for rk3288 evb. Changes in v4: - max_transfer_size change to 65536, this should be enough for most transfer, the hardware auto-detect will set this to 0x7 which may make dma_alloc_coherent fail when non-dword aligned buf from driver like usbnet happen. - remove EHCI and HSIC dts patch for Doug had post it seprately. Changes in v3: - EHCI and HSIC move new for version 3. - Rebase Changes in v2: - Split out dr_mode and rk3288 bindings. - add compatible "snps,dwc2" bingding info - set most parameters as driver auto-detect - evb patch added in version 2 Kever Yang (4): Documentation: dt-bindings: add dt binding info for Rockchip dwc2 usb: dwc2: add compatible data for rockchip soc ARM: dts: add rk3288 dwc2 controller support ARM: dts: Enable USB otg and host1(dwc) on rk3288-evb Documentation/devicetree/bindings/usb/dwc2.txt | 3 +++ arch/arm/boot/dts/rk3288-evb.dtsi | 6 ++ arch/arm/boot/dts/rk3288.dtsi | 20 ++ drivers/usb/dwc2/platform.c| 29 ++ 4 files changed, 58 insertions(+) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 2/4] usb: dwc2: add compatible data for rockchip soc
This patch add compatible data for dwc2 controller found on rk3066, rk3188 and rk3288 processors from rockchip. Signed-off-by: Kever Yang Acked-by: Paul Zimmerman --- Changes in v4: - max_transfer_size change to 65536, this should be enough for most transfer, the hardware auto-detect will set this to 0x7 which may make dma_alloc_coherent fail when non-dword aligned buf from driver like usbnet happen. Changes in v3: None Changes in v2: - set most parameters as driver auto-detect drivers/usb/dwc2/platform.c | 29 + 1 file changed, 29 insertions(+) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index a10e7a3..832b103 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -75,6 +75,34 @@ static const struct dwc2_core_params params_bcm2835 = { .uframe_sched = 0, }; +static const struct dwc2_core_params params_rk3066 = { + .otg_cap= 2,/* non-HNP/non-SRP */ + .otg_ver= -1, + .dma_enable = -1, + .dma_desc_enable= 0, + .speed = -1, + .enable_dynamic_fifo= 1, + .en_multiple_tx_fifo= -1, + .host_rx_fifo_size = 520, /* 520 DWORDs */ + .host_nperio_tx_fifo_size = 128, /* 128 DWORDs */ + .host_perio_tx_fifo_size= 256, /* 256 DWORDs */ + .max_transfer_size = 65536, + .max_packet_count = -1, + .host_channels = -1, + .phy_type = -1, + .phy_utmi_width = -1, + .phy_ulpi_ddr = -1, + .phy_ulpi_ext_vbus = -1, + .i2c_enable = -1, + .ulpi_fs_ls = -1, + .host_support_fs_ls_low_power = -1, + .host_ls_low_power_phy_clk = -1, + .ts_dline = -1, + .reload_ctl = -1, + .ahbcfg = 0x7, /* INCR16 */ + .uframe_sched = -1, +}; + /** * dwc2_driver_remove() - Called when the DWC_otg core is unregistered with the * DWC_otg driver @@ -97,6 +125,7 @@ static int dwc2_driver_remove(struct platform_device *dev) static const struct of_device_id dwc2_of_match_table[] = { { .compatible = "brcm,bcm2835-usb", .data = ¶ms_bcm2835 }, + { .compatible = "rockchip,rk3066-usb", .data = ¶ms_rk3066 }, { .compatible = "snps,dwc2", .data = NULL }, {}, }; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 2/2] usb: dwc2: add 'mode' which based on Kconfig select or dts setting
According to the "dr_mode", the otg controller can work as device role and host role. Some boards always want to use host mode and some other boards want to use gadget mode. We use the dts setting to set dwc2's mode, rather than fixing it to whatever hardware says. Signed-off-by: Kever Yang Acked-by: Paul Zimmerman --- Changes in v4: - From Doug's suggestion: -- remove dr_mode init from Kconfig code -- change the commit meesage Changes in v3: - fix the odd spacing in dwc2_hsotg struct - From Jingoo's suggestion: change the commit message - add dr_mode init from Kconfig Changes in v2: - put spaces around '+' operator - expand the comment for dr_mode - handle dr_mode is USB_DR_MODE_OTG drivers/usb/dwc2/core.c | 18 ++ drivers/usb/dwc2/core.h | 5 + drivers/usb/dwc2/platform.c | 4 3 files changed, 27 insertions(+) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 27d2c9b..738bec2 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -118,6 +118,7 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg) { u32 greset; int count = 0; + u32 gusbcfg; dev_vdbg(hsotg->dev, "%s()\n", __func__); @@ -148,6 +149,23 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg) } } while (greset & GRSTCTL_CSFTRST); + if (hsotg->dr_mode == USB_DR_MODE_HOST) { + gusbcfg = readl(hsotg->regs + GUSBCFG); + gusbcfg &= ~GUSBCFG_FORCEDEVMODE; + gusbcfg |= GUSBCFG_FORCEHOSTMODE; + writel(gusbcfg, hsotg->regs + GUSBCFG); + } else if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) { + gusbcfg = readl(hsotg->regs + GUSBCFG); + gusbcfg &= ~GUSBCFG_FORCEHOSTMODE; + gusbcfg |= GUSBCFG_FORCEDEVMODE; + writel(gusbcfg, hsotg->regs + GUSBCFG); + } else if (hsotg->dr_mode == USB_DR_MODE_OTG) { + gusbcfg = readl(hsotg->regs + GUSBCFG); + gusbcfg &= ~GUSBCFG_FORCEHOSTMODE; + gusbcfg &= ~GUSBCFG_FORCEDEVMODE; + writel(gusbcfg, hsotg->regs + GUSBCFG); + } + /* * NOTE: This long sleep is _very_ important, otherwise the core will * not stay in host mode after a connector ID change! diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 1efd10c..52a4fd2 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -501,6 +501,10 @@ struct dwc2_hw_params { * a_peripheral and b_device=>b_host) this may not match * the core, but allows the software to determine * transitions + * @dr_mode:Requested mode of operation, one of following: + * - USB_DR_MODE_PERIPHERAL + * - USB_DR_MODE_HOST + * - USB_DR_MODE_OTG * @queuing_high_bandwidth: True if multiple packets of a high-bandwidth * transfer are in process of being queued * @srp_success:Stores status of SRP request in the case of a FS PHY @@ -592,6 +596,7 @@ struct dwc2_hsotg { /** Params to actually use */ struct dwc2_core_params *core_params; enum usb_otg_state op_state; + enum usb_dr_mode dr_mode; unsigned int queuing_high_bandwidth:1; unsigned int srp_success:1; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index a10e7a3..5f0c4bb 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -42,6 +42,8 @@ #include #include +#include + #include "core.h" #include "hcd.h" @@ -171,6 +173,8 @@ static int dwc2_driver_probe(struct platform_device *dev) dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n", (unsigned long)res->start, hsotg->regs); + hsotg->dr_mode = of_usb_get_dr_mode(dev->dev.of_node); + retval = dwc2_hcd_init(hsotg, irq, params); if (retval) return retval; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 0/2] Patches to add dr_mode for dwc2
These two patches enable the dr_mode for the dwc2 usb controller. These are split from the patch series adding rk3288 dwc2 support. Changes in v4: - From Doug's suggestion: -- remove dr_mode init from Kconfig code -- change the commit meesage Changes in v3: - fix the odd spacing in dwc2_hsotg struct - From Jingoo's suggestion: change the commit message - add dr_mode init from Kconfig Changes in v2: - Split out dr_mode and rk3288 bindings. - put spaces around '+' operator - expand the comment for dr_mode - handle dr_mode is USB_DR_MODE_OTG Kever Yang (2): Documentation: dt-bindings: add dt binding info for dwc2 dr_mode usb: dwc2: add 'mode' which based on Kconfig select or dts setting Documentation/devicetree/bindings/usb/dwc2.txt | 2 ++ drivers/usb/dwc2/core.c| 18 ++ drivers/usb/dwc2/core.h| 5 + drivers/usb/dwc2/platform.c| 4 4 files changed, 29 insertions(+) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 2/2] usb: dwc2: add 'mode' which based on Kconfig select or dts setting
Doug, On 08/05/2014 12:34 AM, Doug Anderson wrote: Kever, On Mon, Aug 4, 2014 at 6:45 AM, Kever Yang wrote: According to the "dr_mode", the otg controller can work as device role during firmware period, and work as host role in the kernel, without use of usb_id pin. As the commit "usb: dwc3: set 'mode' based on selected Kconfig choices". I don't think you need to mention firmware / kernel here. Just say that on some boards we always want to use host mode and on other boards we want to use gadget mode. ...and that we don't necessarily have the ID pin hooked up to make this automatic. OK, I'll change this message again, I just don't know how to describe to make everyone understand what I'm doing. Signed-off-by: Kever Yang Normally I'd say that you should have added Paul's "Acked-by" since you fixed his nit and he told you to include his Acked-by when his nit was fixed, but... There are some more changes than Paul's suggestion, so I'm not sure if Paul need more review to give me the "Acked-by", I get it now. --- Changes in v3: - fix the odd spacing in dwc2_hsotg struct - From Jingoo's suggestion: change the commit message You did more than just this. You also added some (incorrect) Kconfig things. See below. Changes in v2: - put spaces around '+' operator - expand the comment for dr_mode - handle dr_mode is USB_DR_MODE_OTG drivers/usb/dwc2/core.c | 18 ++ drivers/usb/dwc2/core.h | 5 + drivers/usb/dwc2/platform.c | 12 3 files changed, 35 insertions(+) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 27d2c9b..738bec2 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -118,6 +118,7 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg) { u32 greset; int count = 0; + u32 gusbcfg; dev_vdbg(hsotg->dev, "%s()\n", __func__); @@ -148,6 +149,23 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg) } } while (greset & GRSTCTL_CSFTRST); + if (hsotg->dr_mode == USB_DR_MODE_HOST) { + gusbcfg = readl(hsotg->regs + GUSBCFG); + gusbcfg &= ~GUSBCFG_FORCEDEVMODE; + gusbcfg |= GUSBCFG_FORCEHOSTMODE; + writel(gusbcfg, hsotg->regs + GUSBCFG); + } else if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) { + gusbcfg = readl(hsotg->regs + GUSBCFG); + gusbcfg &= ~GUSBCFG_FORCEHOSTMODE; + gusbcfg |= GUSBCFG_FORCEDEVMODE; + writel(gusbcfg, hsotg->regs + GUSBCFG); + } else if (hsotg->dr_mode == USB_DR_MODE_OTG) { + gusbcfg = readl(hsotg->regs + GUSBCFG); + gusbcfg &= ~GUSBCFG_FORCEHOSTMODE; + gusbcfg &= ~GUSBCFG_FORCEDEVMODE; + writel(gusbcfg, hsotg->regs + GUSBCFG); + } + /* * NOTE: This long sleep is _very_ important, otherwise the core will * not stay in host mode after a connector ID change! diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 1efd10c..52a4fd2 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -501,6 +501,10 @@ struct dwc2_hw_params { * a_peripheral and b_device=>b_host) this may not match * the core, but allows the software to determine * transitions + * @dr_mode:Requested mode of operation, one of following: + * - USB_DR_MODE_PERIPHERAL + * - USB_DR_MODE_HOST + * - USB_DR_MODE_OTG * @queuing_high_bandwidth: True if multiple packets of a high-bandwidth * transfer are in process of being queued * @srp_success:Stores status of SRP request in the case of a FS PHY @@ -592,6 +596,7 @@ struct dwc2_hsotg { /** Params to actually use */ struct dwc2_core_params *core_params; enum usb_otg_state op_state; + enum usb_dr_mode dr_mode; unsigned int queuing_high_bandwidth:1; unsigned int srp_success:1; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index a10e7a3..4d2c738 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -42,6 +42,8 @@ #include #include +#include + #include "core.h" #include "hcd.h" @@ -171,6 +173,16 @@ static int dwc2_driver_probe(struct platform_device *dev) dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n", (unsigned long)res->start, hsotg->regs); + hsotg->dr_mode = of_usb_get_dr_mode(dev->dev.of_node); + + if (IS_ENABLED(CONFIG_USB_DWC2_HOST)) + hsotg->dr_mode = USB_DR_MODE_HOST; + else if (IS_E
[PATCH v3 0/2] Patches to add dr_mode for dwc2
These two patches enable the dr_mode for the dwc2 usb controller. These are split from the patch series adding rk3288 dwc2 support. Changes in v3: - fix the odd spacing in dwc2_hsotg struct - From Jingoo's suggestion: change the commit message Changes in v2: - Split out dr_mode and rk3288 bindings. - put spaces around '+' operator - expand the comment for dr_mode - handle dr_mode is USB_DR_MODE_OTG Kever Yang (2): Documentation: dt-bindings: add dt binding info for dwc2 dr_mode usb: dwc2: add 'mode' which based on Kconfig select or dts setting Documentation/devicetree/bindings/usb/dwc2.txt | 2 ++ drivers/usb/dwc2/core.c| 18 ++ drivers/usb/dwc2/core.h| 5 + drivers/usb/dwc2/platform.c| 12 4 files changed, 37 insertions(+) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 2/2] usb: dwc2: add 'mode' which based on Kconfig select or dts setting
According to the "dr_mode", the otg controller can work as device role during firmware period, and work as host role in the kernel, without use of usb_id pin. As the commit "usb: dwc3: set 'mode' based on selected Kconfig choices". Signed-off-by: Kever Yang --- Changes in v3: - fix the odd spacing in dwc2_hsotg struct - From Jingoo's suggestion: change the commit message Changes in v2: - put spaces around '+' operator - expand the comment for dr_mode - handle dr_mode is USB_DR_MODE_OTG drivers/usb/dwc2/core.c | 18 ++ drivers/usb/dwc2/core.h | 5 + drivers/usb/dwc2/platform.c | 12 3 files changed, 35 insertions(+) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 27d2c9b..738bec2 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -118,6 +118,7 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg) { u32 greset; int count = 0; + u32 gusbcfg; dev_vdbg(hsotg->dev, "%s()\n", __func__); @@ -148,6 +149,23 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg) } } while (greset & GRSTCTL_CSFTRST); + if (hsotg->dr_mode == USB_DR_MODE_HOST) { + gusbcfg = readl(hsotg->regs + GUSBCFG); + gusbcfg &= ~GUSBCFG_FORCEDEVMODE; + gusbcfg |= GUSBCFG_FORCEHOSTMODE; + writel(gusbcfg, hsotg->regs + GUSBCFG); + } else if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) { + gusbcfg = readl(hsotg->regs + GUSBCFG); + gusbcfg &= ~GUSBCFG_FORCEHOSTMODE; + gusbcfg |= GUSBCFG_FORCEDEVMODE; + writel(gusbcfg, hsotg->regs + GUSBCFG); + } else if (hsotg->dr_mode == USB_DR_MODE_OTG) { + gusbcfg = readl(hsotg->regs + GUSBCFG); + gusbcfg &= ~GUSBCFG_FORCEHOSTMODE; + gusbcfg &= ~GUSBCFG_FORCEDEVMODE; + writel(gusbcfg, hsotg->regs + GUSBCFG); + } + /* * NOTE: This long sleep is _very_ important, otherwise the core will * not stay in host mode after a connector ID change! diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 1efd10c..52a4fd2 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -501,6 +501,10 @@ struct dwc2_hw_params { * a_peripheral and b_device=>b_host) this may not match * the core, but allows the software to determine * transitions + * @dr_mode:Requested mode of operation, one of following: + * - USB_DR_MODE_PERIPHERAL + * - USB_DR_MODE_HOST + * - USB_DR_MODE_OTG * @queuing_high_bandwidth: True if multiple packets of a high-bandwidth * transfer are in process of being queued * @srp_success:Stores status of SRP request in the case of a FS PHY @@ -592,6 +596,7 @@ struct dwc2_hsotg { /** Params to actually use */ struct dwc2_core_params *core_params; enum usb_otg_state op_state; + enum usb_dr_mode dr_mode; unsigned int queuing_high_bandwidth:1; unsigned int srp_success:1; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index a10e7a3..4d2c738 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -42,6 +42,8 @@ #include #include +#include + #include "core.h" #include "hcd.h" @@ -171,6 +173,16 @@ static int dwc2_driver_probe(struct platform_device *dev) dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n", (unsigned long)res->start, hsotg->regs); + hsotg->dr_mode = of_usb_get_dr_mode(dev->dev.of_node); + + if (IS_ENABLED(CONFIG_USB_DWC2_HOST)) + hsotg->dr_mode = USB_DR_MODE_HOST; + else if (IS_ENABLED(CONFIG_USB_DWC2_GADGET)) + hsotg->dr_mode = USB_DR_MODE_PERIPHERAL; + + if (hsotg->dr_mode == USB_DR_MODE_UNKNOWN) + hsotg->dr_mode = USB_DR_MODE_OTG; + retval = dwc2_hcd_init(hsotg, irq, params); if (retval) return retval; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[REPOST PATCH v3 2/5] usb: dwc2: add compatible data for rockchip soc
This patch add compatible data for dwc2 controller found on rk3066, rk3188 and rk3288 processors from rockchip. Signed-off-by: Kever Yang Acked-by: Paul Zimmerman --- Changes in v3: None Changes in v2: - set most parameters as driver auto-detect drivers/usb/dwc2/platform.c | 29 + 1 file changed, 29 insertions(+) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index a10e7a3..b533a0d 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -75,6 +75,34 @@ static const struct dwc2_core_params params_bcm2835 = { .uframe_sched = 0, }; +static const struct dwc2_core_params params_rk3066 = { + .otg_cap= 2,/* non-HNP/non-SRP */ + .otg_ver= -1, + .dma_enable = -1, + .dma_desc_enable= 0, + .speed = -1, + .enable_dynamic_fifo= 1, + .en_multiple_tx_fifo= -1, + .host_rx_fifo_size = 520, /* 520 DWORDs */ + .host_nperio_tx_fifo_size = 128, /* 128 DWORDs */ + .host_perio_tx_fifo_size= 256, /* 256 DWORDs */ + .max_transfer_size = -1, + .max_packet_count = -1, + .host_channels = -1, + .phy_type = -1, + .phy_utmi_width = -1, + .phy_ulpi_ddr = -1, + .phy_ulpi_ext_vbus = -1, + .i2c_enable = -1, + .ulpi_fs_ls = -1, + .host_support_fs_ls_low_power = -1, + .host_ls_low_power_phy_clk = -1, + .ts_dline = -1, + .reload_ctl = -1, + .ahbcfg = 0x7, /* INCR16 */ + .uframe_sched = -1, +}; + /** * dwc2_driver_remove() - Called when the DWC_otg core is unregistered with the * DWC_otg driver @@ -97,6 +125,7 @@ static int dwc2_driver_remove(struct platform_device *dev) static const struct of_device_id dwc2_of_match_table[] = { { .compatible = "brcm,bcm2835-usb", .data = ¶ms_bcm2835 }, + { .compatible = "rockchip,rk3066-usb", .data = ¶ms_rk3066 }, { .compatible = "snps,dwc2", .data = NULL }, {}, }; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[REPOST PATCH v3 0/5] Patches to add support for Rockchip dwc2 controller
These patches to add support for dwc2 controller found in Rockchip processors rk3066, rk3188 and rk3288, and enable dts for rk3288 evb. Reposting series with the proper email address. Changes in v3: - Moved out of pin control and sort by base address - EHCI and HSIC move new for version 3. - Rebase Changes in v2: - Split out dr_mode and rk3288 bindings. - add compatible "snps,dwc2" bingding info - set most parameters as driver auto-detect - change the node name from 'dwc2' to 'usb' - evb patch added in version 2 Doug Anderson (1): ARM: dts: Fix the sort ordering of EHCI and HSIC in rk3288.dtsi Kever Yang (4): Documentation: dt-bindings: add dt binding info for Rockchip dwc2 usb: dwc2: add compatible data for rockchip soc ARM: dts: add rk3288 dwc2 controller support ARM: dts: Enable USB otg and host1(dwc) on rk3288-evb Documentation/devicetree/bindings/usb/dwc2.txt |3 ++ arch/arm/boot/dts/rk3288-evb.dtsi |6 +++ arch/arm/boot/dts/rk3288.dtsi | 61 drivers/usb/dwc2/platform.c| 29 +++ 4 files changed, 78 insertions(+), 21 deletions(-) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 2/5] usb: dwc2: add compatible data for rockchip soc
This patch add compatible data for dwc2 controller found on rk3066, rk3188 and rk3288 processors from rockchip. Signed-off-by: Kever Yang Acked-by: Paul Zimmerman --- Changes in v3: None Changes in v2: - set most parameters as driver auto-detect drivers/usb/dwc2/platform.c | 29 + 1 file changed, 29 insertions(+) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index a10e7a3..b533a0d 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -75,6 +75,34 @@ static const struct dwc2_core_params params_bcm2835 = { .uframe_sched = 0, }; +static const struct dwc2_core_params params_rk3066 = { + .otg_cap= 2,/* non-HNP/non-SRP */ + .otg_ver= -1, + .dma_enable = -1, + .dma_desc_enable= 0, + .speed = -1, + .enable_dynamic_fifo= 1, + .en_multiple_tx_fifo= -1, + .host_rx_fifo_size = 520, /* 520 DWORDs */ + .host_nperio_tx_fifo_size = 128, /* 128 DWORDs */ + .host_perio_tx_fifo_size= 256, /* 256 DWORDs */ + .max_transfer_size = -1, + .max_packet_count = -1, + .host_channels = -1, + .phy_type = -1, + .phy_utmi_width = -1, + .phy_ulpi_ddr = -1, + .phy_ulpi_ext_vbus = -1, + .i2c_enable = -1, + .ulpi_fs_ls = -1, + .host_support_fs_ls_low_power = -1, + .host_ls_low_power_phy_clk = -1, + .ts_dline = -1, + .reload_ctl = -1, + .ahbcfg = 0x7, /* INCR16 */ + .uframe_sched = -1, +}; + /** * dwc2_driver_remove() - Called when the DWC_otg core is unregistered with the * DWC_otg driver @@ -97,6 +125,7 @@ static int dwc2_driver_remove(struct platform_device *dev) static const struct of_device_id dwc2_of_match_table[] = { { .compatible = "brcm,bcm2835-usb", .data = ¶ms_bcm2835 }, + { .compatible = "rockchip,rk3066-usb", .data = ¶ms_rk3066 }, { .compatible = "snps,dwc2", .data = NULL }, {}, }; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 0/5] Patches to add support for Rockchip dwc2 controller
These patches to add support for dwc2 controller found in Rockchip processors rk3066, rk3188 and rk3288, and enable dts for rk3288 evb. Changes in v3: - Moved out of pin control and sort by base address - EHCI and HSIC move new for version 3. - Rebase Changes in v2: - Split out dr_mode and rk3288 bindings. - add compatible "snps,dwc2" bingding info - set most parameters as driver auto-detect - change the node name from 'dwc2' to 'usb' - evb patch added in version 2 Doug Anderson (1): ARM: dts: Fix the sort ordering of EHCI and HSIC in rk3288.dtsi Kever Yang (4): Documentation: dt-bindings: add dt binding info for Rockchip dwc2 usb: dwc2: add compatible data for rockchip soc ARM: dts: add rk3288 dwc2 controller support ARM: dts: Enable USB otg and host1(dwc) on rk3288-evb Documentation/devicetree/bindings/usb/dwc2.txt |3 ++ arch/arm/boot/dts/rk3288-evb.dtsi |6 +++ arch/arm/boot/dts/rk3288.dtsi | 61 drivers/usb/dwc2/platform.c| 29 +++ 4 files changed, 78 insertions(+), 21 deletions(-) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/4] usb: dwc2: add compatible data for rockchip soc
This patch add compatible data for dwc2 controller found on rk3066, rk3188 and rk3288 processors from rockchip. Signed-off-by: Kever Yang --- Changes in v2: - set most parameters as driver auto-detect drivers/usb/dwc2/platform.c | 29 + 1 file changed, 29 insertions(+) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 5f0c4bb..5e610dd 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -77,6 +77,34 @@ static const struct dwc2_core_params params_bcm2835 = { .uframe_sched = 0, }; +static const struct dwc2_core_params params_rk3066 = { + .otg_cap= 2,/* non-HNP/non-SRP */ + .otg_ver= -1, + .dma_enable = -1, + .dma_desc_enable= 0, + .speed = -1, + .enable_dynamic_fifo= 1, + .en_multiple_tx_fifo= -1, + .host_rx_fifo_size = 520, /* 520 DWORDs */ + .host_nperio_tx_fifo_size = 128, /* 128 DWORDs */ + .host_perio_tx_fifo_size= 256, /* 256 DWORDs */ + .max_transfer_size = -1, + .max_packet_count = -1, + .host_channels = -1, + .phy_type = -1, + .phy_utmi_width = -1, + .phy_ulpi_ddr = -1, + .phy_ulpi_ext_vbus = -1, + .i2c_enable = -1, + .ulpi_fs_ls = -1, + .host_support_fs_ls_low_power = -1, + .host_ls_low_power_phy_clk = -1, + .ts_dline = -1, + .reload_ctl = -1, + .ahbcfg = 0x7, /* INCR16 */ + .uframe_sched = -1, +}; + /** * dwc2_driver_remove() - Called when the DWC_otg core is unregistered with the * DWC_otg driver @@ -99,6 +127,7 @@ static int dwc2_driver_remove(struct platform_device *dev) static const struct of_device_id dwc2_of_match_table[] = { { .compatible = "brcm,bcm2835-usb", .data = ¶ms_bcm2835 }, + { .compatible = "rockchip,rk3066-usb", .data = ¶ms_rk3066 }, { .compatible = "snps,dwc2", .data = NULL }, {}, }; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 0/4] Patches to add support for Rockchip dwc2 controller
From: Kever Yang These patches to add support for dwc2 controller found in Rockchip processors rk3066, rk3188 and rk3288, and enable dts for rk3288 evb. Changes in v2: - Split out dr_mode and rk3288 bindings. - add compatible "snps,dwc2" bingding info - set most parameters as driver auto-detect - change the node name from 'dwc2' to 'usb' - evb patch added in version 2 Kever Yang (4): Documentation: dt-bindings: add dt binding info for Rockchip dwc2 usb: dwc2: add compatible data for rockchip soc ARM: dts: add rk3288 dwc2 controller support ARM: dts: Enable USB otg and host1(dwc) on rk3288-evb Documentation/devicetree/bindings/usb/dwc2.txt |3 +++ arch/arm/boot/dts/rk3288-evb.dtsi |6 + arch/arm/boot/dts/rk3288.dtsi | 20 drivers/usb/dwc2/platform.c| 29 4 files changed, 58 insertions(+) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/2] usb: dwc2: add dr_mode support for dwc2
Some devices with A female host port and without use of usb_id pin will need this for the otg controller works as device role during firmware period and works as host role in rich os. Signed-off-by: Kever Yang --- Changes in v2: - put spaces around '+' operator - expand the comment for dr_mode - handle dr_mode is USB_DR_MODE_OTG drivers/usb/dwc2/core.c | 18 ++ drivers/usb/dwc2/core.h |5 + drivers/usb/dwc2/platform.c |4 3 files changed, 27 insertions(+) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 27d2c9b..738bec2 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -118,6 +118,7 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg) { u32 greset; int count = 0; + u32 gusbcfg; dev_vdbg(hsotg->dev, "%s()\n", __func__); @@ -148,6 +149,23 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg) } } while (greset & GRSTCTL_CSFTRST); + if (hsotg->dr_mode == USB_DR_MODE_HOST) { + gusbcfg = readl(hsotg->regs + GUSBCFG); + gusbcfg &= ~GUSBCFG_FORCEDEVMODE; + gusbcfg |= GUSBCFG_FORCEHOSTMODE; + writel(gusbcfg, hsotg->regs + GUSBCFG); + } else if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) { + gusbcfg = readl(hsotg->regs + GUSBCFG); + gusbcfg &= ~GUSBCFG_FORCEHOSTMODE; + gusbcfg |= GUSBCFG_FORCEDEVMODE; + writel(gusbcfg, hsotg->regs + GUSBCFG); + } else if (hsotg->dr_mode == USB_DR_MODE_OTG) { + gusbcfg = readl(hsotg->regs + GUSBCFG); + gusbcfg &= ~GUSBCFG_FORCEHOSTMODE; + gusbcfg &= ~GUSBCFG_FORCEDEVMODE; + writel(gusbcfg, hsotg->regs + GUSBCFG); + } + /* * NOTE: This long sleep is _very_ important, otherwise the core will * not stay in host mode after a connector ID change! diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 1efd10c..a34681c 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -501,6 +501,10 @@ struct dwc2_hw_params { * a_peripheral and b_device=>b_host) this may not match * the core, but allows the software to determine * transitions + * @dr_mode:Requested mode of operation, one of following: + * - USB_DR_MODE_PERIPHERAL + * - USB_DR_MODE_HOST + * - USB_DR_MODE_OTG * @queuing_high_bandwidth: True if multiple packets of a high-bandwidth * transfer are in process of being queued * @srp_success:Stores status of SRP request in the case of a FS PHY @@ -592,6 +596,7 @@ struct dwc2_hsotg { /** Params to actually use */ struct dwc2_core_params *core_params; enum usb_otg_state op_state; + enum usb_dr_modedr_mode; unsigned int queuing_high_bandwidth:1; unsigned int srp_success:1; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index b14668b..669a03a 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -42,6 +42,8 @@ #include #include +#include + #include "core.h" #include "hcd.h" @@ -200,6 +202,8 @@ static int dwc2_driver_probe(struct platform_device *dev) dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n", (unsigned long)res->start, hsotg->regs); + hsotg->dr_mode = of_usb_get_dr_mode(dev->dev.of_node); + retval = dwc2_hcd_init(hsotg, irq, params); if (retval) return retval; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 0/2] Patches to add dr_mode for dwc2
These two patches enable the dr_mode for the dwc2 usb controller. These are split from the patch series adding rk3288 dwc2 support. Changes in v2: - Split out dr_mode and rk3288 bindings. - put spaces around '+' operator - expand the comment for dr_mode - handle dr_mode is USB_DR_MODE_OTG Kever Yang (2): Documentation: dt-bindings: add dt binding info for dwc2 dr_mode usb: dwc2: add dr_mode support for dwc2 Documentation/devicetree/bindings/usb/dwc2.txt |2 ++ drivers/usb/dwc2/core.c| 18 ++ drivers/usb/dwc2/core.h|5 + drivers/usb/dwc2/platform.c|4 4 files changed, 29 insertions(+) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/4] usb: dwc2: add compatible data for rockchip soc
This patch add compatible data for dwc2 controller found on rk3066, rk3188 and rk3288 processors from rockchip. Signed-off-by: Kever Yang --- drivers/usb/dwc2/platform.c | 29 + 1 file changed, 29 insertions(+) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index a10e7a3..cc5983c 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -75,6 +75,34 @@ static const struct dwc2_core_params params_bcm2835 = { .uframe_sched = 0, }; +static const struct dwc2_core_params params_rk3066 = { + .otg_cap= 2,/* no HNP/SRP capable */ + .otg_ver= 0,/* 1.3 */ + .dma_enable = 1, + .dma_desc_enable= 0, + .speed = 0,/* High Speed */ + .enable_dynamic_fifo= 1, + .en_multiple_tx_fifo= 1, + .host_rx_fifo_size = 520, /* 520 DWORDs */ + .host_nperio_tx_fifo_size = 128, /* 128 DWORDs */ + .host_perio_tx_fifo_size= 256, /* 256 DWORDs */ + .max_transfer_size = 65536, + .max_packet_count = 512, + .host_channels = 9, + .phy_type = 1,/* UTMI */ + .phy_utmi_width = 16, /* 8 bits */ + .phy_ulpi_ddr = 0,/* Single */ + .phy_ulpi_ext_vbus = 0, + .i2c_enable = 0, + .ulpi_fs_ls = 0, + .host_support_fs_ls_low_power = 0, + .host_ls_low_power_phy_clk = 0,/* 48 MHz */ + .ts_dline = 0, + .reload_ctl = 1, + .ahbcfg = 0x17, /* dma enable & INCR16 */ + .uframe_sched = 1, +}; + /** * dwc2_driver_remove() - Called when the DWC_otg core is unregistered with the * DWC_otg driver @@ -97,6 +125,7 @@ static int dwc2_driver_remove(struct platform_device *dev) static const struct of_device_id dwc2_of_match_table[] = { { .compatible = "brcm,bcm2835-usb", .data = ¶ms_bcm2835 }, + { .compatible = "rockchip,rk3066-usb", .data = ¶ms_rk3066 }, { .compatible = "snps,dwc2", .data = NULL }, {}, }; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/4] usb: dwc2: add dr_mode support for dwc2
Some devices with A female host port and without use of usb_id pin will need this for the otg controller works as device role during firmware period and works as host role in rich os. Signed-off-by: Kever Yang --- drivers/usb/dwc2/core.c | 13 + drivers/usb/dwc2/core.h |2 ++ drivers/usb/dwc2/platform.c |4 3 files changed, 19 insertions(+) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 27d2c9b..6688951 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -118,6 +118,7 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg) { u32 greset; int count = 0; + u32 gusbcfg; dev_vdbg(hsotg->dev, "%s()\n", __func__); @@ -148,6 +149,18 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg) } } while (greset & GRSTCTL_CSFTRST); + if (hsotg->dr_mode == USB_DR_MODE_HOST) { + gusbcfg = readl(hsotg->regs+GUSBCFG); + gusbcfg &= ~GUSBCFG_FORCEDEVMODE; + gusbcfg |= GUSBCFG_FORCEHOSTMODE; + writel(gusbcfg, hsotg->regs+GUSBCFG); + } else if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) { + gusbcfg = readl(hsotg->regs+GUSBCFG); + gusbcfg &= ~GUSBCFG_FORCEHOSTMODE; + gusbcfg |= GUSBCFG_FORCEDEVMODE; + writel(gusbcfg, hsotg->regs+GUSBCFG); + } + /* * NOTE: This long sleep is _very_ important, otherwise the core will * not stay in host mode after a connector ID change! diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 1efd10c..9fe960b 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -501,6 +501,7 @@ struct dwc2_hw_params { * a_peripheral and b_device=>b_host) this may not match * the core, but allows the software to determine * transitions + * @dr_mode:requested mode of operation * @queuing_high_bandwidth: True if multiple packets of a high-bandwidth * transfer are in process of being queued * @srp_success:Stores status of SRP request in the case of a FS PHY @@ -592,6 +593,7 @@ struct dwc2_hsotg { /** Params to actually use */ struct dwc2_core_params *core_params; enum usb_otg_state op_state; + enum usb_dr_modedr_mode; unsigned int queuing_high_bandwidth:1; unsigned int srp_success:1; diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index cc5983c..a2ac1ea 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -42,6 +42,8 @@ #include #include +#include + #include "core.h" #include "hcd.h" @@ -200,6 +202,8 @@ static int dwc2_driver_probe(struct platform_device *dev) dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n", (unsigned long)res->start, hsotg->regs); + hsotg->dr_mode = of_usb_get_dr_mode(dev->dev.of_node); + retval = dwc2_hcd_init(hsotg, irq, params); if (retval) return retval; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/4] ARM: dts: add rk3288 dwc2 controller support
rk3288 has two kind of usb controller, this add the dwc2 controller for otg and host1. Controller can works with usb PHY default setting and Vbus on. Signed-off-by: Kever Yang --- arch/arm/boot/dts/rk3288.dtsi | 20 1 file changed, 20 insertions(+) diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index abc51f5..4309c4f 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -646,5 +646,25 @@ clock-names = "baudclk", "apb_pclk"; status = "disabled"; }; + + usb_otg: dwc2@ff58 { + compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb", + "snps,dwc2"; + reg = <0xff58 0x4>; + interrupts = ; + clocks = <&cru HCLK_OTG0>; + clock-names = "otg"; + status = "disabled"; + }; + + usb_host1: dwc2@ff54 { + compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb", + "snps,dwc2"; + reg = <0xff54 0x4>; + interrupts = ; + clocks = <&cru HCLK_USBHOST1>; + clock-names = "otg"; + status = "disabled"; + }; }; }; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/4] usb: dwc2: add suport for Rockchip dwc2 controller
This path is to add the support for dwc2 controller found ind Rockchip processors rk3066, rk3188 and rk3288 This patch also add dr_mode for dwc2 driver. Kever Yang (4): Documentation: dt-bindings: add dt binding info for Rockchip dwc2 ARM: dts: add rk3288 dwc2 controller support usb: dwc2: add compatible data for rockchip soc usb: dwc2: add dr_mode support for dwc2 Documentation/devicetree/bindings/usb/dwc2.txt |5 arch/arm/boot/dts/rk3288.dtsi | 20 ++ drivers/usb/dwc2/core.c| 13 ++ drivers/usb/dwc2/core.h|2 ++ drivers/usb/dwc2/platform.c| 33 5 files changed, 73 insertions(+) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/4] Documentation: dt-bindings: add dt binding info for Rockchip dwc2
This add necessary dwc2 binding documentation for Rockchip socs: rk3066, rk3188 and rk3288 add dr_mode as optional properties. Signed-off-by: Kever Yang --- Documentation/devicetree/bindings/usb/dwc2.txt |5 + 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt index aa91034..eb80d7b 100644 --- a/Documentation/devicetree/bindings/usb/dwc2.txt +++ b/Documentation/devicetree/bindings/usb/dwc2.txt @@ -4,6 +4,9 @@ Platform DesignWare HS OTG USB 2.0 controller Required properties: - compatible : One of: - brcm,bcm2835-usb: The DWC2 USB controller instance in the BCM2835 SoC. + - rockchip,rk3066-usb: The DWC2 USB controller instance in the rk3066 Soc; + - "rockchip,rk3188-usb","rockchip,rk3066-usb": for rk3188 Soc; + - "rockchip,rk3288-usb","rockchip,rk3066-usb": for rk3288 Soc; - snps,dwc2: A generic DWC2 USB controller with default parameters. - reg : Should contain 1 register range (address and length) - interrupts : Should contain 1 interrupt @@ -15,6 +18,8 @@ Optional properties: - phys: phy provider specifier - phy-names: shall be "usb2-phy" Refer to phy/phy-bindings.txt for generic phy consumer properties +- dr_mode: shall be one of "host", "peripheral" and "otg" + Refer to usb/generic.txt Example: -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html