Re: [PATCH v6 20/22] usb: dwc2: host: Properly set even/odd frame

2016-02-02 Thread Kever Yang

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

2016-02-01 Thread Kever Yang

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

2016-02-01 Thread Kever Yang

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

2016-01-31 Thread Kever Yang

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

2016-01-31 Thread Kever Yang

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

2016-01-31 Thread Kever Yang

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

2016-01-31 Thread Kever Yang

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

2016-01-28 Thread Kever Yang

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

2016-01-27 Thread Kever Yang

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

2016-01-27 Thread Kever Yang

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

2016-01-27 Thread Kever Yang

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

2016-01-27 Thread Kever Yang

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

2016-01-27 Thread Kever Yang

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

2016-01-27 Thread Kever Yang

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

2016-01-27 Thread Kever Yang

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

2015-01-05 Thread Kever Yang

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.

2014-12-03 Thread Kever Yang

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

2014-11-17 Thread Kever Yang
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

2014-11-17 Thread Kever Yang

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

2014-11-17 Thread Kever Yang
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

2014-11-17 Thread Kever Yang


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

2014-11-17 Thread Kever Yang
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

2014-11-12 Thread Kever Yang

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

2014-11-10 Thread Kever Yang
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

2014-11-10 Thread Kever Yang

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

2014-11-05 Thread Kever Yang
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

2014-10-31 Thread Kever Yang
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

2014-10-30 Thread Kever Yang

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

2014-10-30 Thread Kever Yang

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

2014-10-29 Thread Kever Yang
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

2014-10-29 Thread Kever Yang
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

2014-10-29 Thread Kever Yang
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

2014-10-16 Thread Kever Yang

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

2014-10-16 Thread Kever Yang

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

2014-10-15 Thread Kever Yang
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

2014-10-15 Thread Kever Yang
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

2014-10-15 Thread Kever Yang
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

2014-08-07 Thread Kever Yang
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

2014-08-07 Thread 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 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.

2014-08-07 Thread Kever Yang

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

2014-08-07 Thread Kever Yang

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

2014-08-07 Thread 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 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

2014-08-07 Thread Kever Yang
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

2014-08-05 Thread Kever Yang
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

2014-08-05 Thread Kever Yang
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

2014-08-04 Thread Kever Yang

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

2014-08-04 Thread Kever Yang
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

2014-08-04 Thread Kever Yang
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

2014-07-31 Thread Kever Yang
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

2014-07-31 Thread Kever Yang
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

2014-07-31 Thread Kever Yang
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

2014-07-31 Thread 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 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

2014-07-30 Thread Kever Yang
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

2014-07-30 Thread Kever Yang
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

2014-07-30 Thread Kever Yang
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

2014-07-30 Thread Kever Yang
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

2014-07-29 Thread Kever Yang
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

2014-07-29 Thread Kever Yang
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

2014-07-29 Thread Kever Yang
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

2014-07-29 Thread Kever Yang
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

2014-07-29 Thread Kever Yang
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