[PATCH] usb: dwc2: fix the incorrect bitmaps for the ports of multi_tt hub

2018-05-21 Thread William Wu
The dwc2_get_ls_map() use ttport to reference into the
bitmap if we're on a multi_tt hub. But the bitmaps index
from 0 to (hub->maxchild - 1), while the ttport index from
1 to hub->maxchild. This will cause invalid memory access
when the number of ttport is hub->maxchild.

Without this patch, I can easily meet a Kernel panic issue
if connect a low-speed USB mouse with the max port of FE2.1
multi-tt hub (1a40:0201) on rk3288 platform.

Signed-off-by: William Wu 
---
 drivers/usb/dwc2/hcd_queue.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c
index d7c3d6c..9c55d1a 100644
--- a/drivers/usb/dwc2/hcd_queue.c
+++ b/drivers/usb/dwc2/hcd_queue.c
@@ -383,7 +383,7 @@ static unsigned long *dwc2_get_ls_map(struct dwc2_hsotg 
*hsotg,
/* Get the map and adjust if this is a multi_tt hub */
map = qh->dwc_tt->periodic_bitmaps;
if (qh->dwc_tt->usb_tt->multi)
-   map += DWC2_ELEMENTS_PER_LS_BITMAP * qh->ttport;
+   map += DWC2_ELEMENTS_PER_LS_BITMAP * (qh->ttport - 1);
 
return map;
 }
-- 
2.0.0




[PATCH v5 2/2] usb: dwc2: fix isoc split in transfer with no data

2018-05-11 Thread William Wu
If isoc split in transfer with no data (the length of DATA0
packet is zero), we can't simply return immediately. Because
the DATA0 can be the first transaction or the second transaction
for the isoc split in transaction. If the DATA0 packet with no
data is in the first transaction, we can return immediately.
But if the DATA0 packet with no data is in the second transaction
of isoc split in transaction sequence, we need to increase the
qtd->isoc_frame_index and giveback urb to device driver if needed,
otherwise, the MDATA packet will be lost.

A typical test case is that connect the dwc2 controller with an
usb hs Hub (GL852G-12), and plug an usb fs audio device (Plantronics
headset) into the downstream port of Hub. Then use the usb mic
to record, we can find noise when playback.

In the case, the isoc split in transaction sequence like this:

- SSPLIT IN transaction
- CSPLIT IN transaction
  - MDATA packet (176 bytes)
- CSPLIT IN transaction
  - DATA0 packet (0 byte)

This patch use both the length of DATA0 and qtd->isoc_split_offset
to check if the DATA0 is in the second transaction.

Signed-off-by: William Wu 
---
Changes in v5:
- None

Changes in v4:
- None

Changes in v3:
- Remove "qtd->isoc_split_offset = 0" in the if test

Changes in v2:
- Modify the commit message

 drivers/usb/dwc2/hcd_intr.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c
index ba6229e..9751785 100644
--- a/drivers/usb/dwc2/hcd_intr.c
+++ b/drivers/usb/dwc2/hcd_intr.c
@@ -930,9 +930,8 @@ static int dwc2_xfercomp_isoc_split_in(struct dwc2_hsotg 
*hsotg,
frame_desc = &qtd->urb->iso_descs[qtd->isoc_frame_index];
len = dwc2_get_actual_xfer_length(hsotg, chan, chnum, qtd,
  DWC2_HC_XFER_COMPLETE, NULL);
-   if (!len) {
+   if (!len && !qtd->isoc_split_offset) {
qtd->complete_split = 0;
-   qtd->isoc_split_offset = 0;
return 0;
}
 
-- 
2.0.0




[PATCH v5 1/2] usb: dwc2: alloc dma aligned buffer for isoc split in

2018-05-11 Thread William Wu
The commit 3bc04e28a030 ("usb: dwc2: host: Get aligned DMA in
a more supported way") rips out a lot of code to simply the
allocation of aligned DMA. However, it also introduces a new
issue when use isoc split in transfer.

In my test case, I connect the dwc2 controller with an usb hs
Hub (GL852G-12), and plug an usb fs audio device (Plantronics
headset) into the downstream port of Hub. Then use the usb mic
to record, we can find noise when playback.

It's because that the usb Hub uses an MDATA for the first
transaction and a DATA0 for the second transaction for the isoc
split in transaction. An typical isoc split in transaction sequence
like this:

- SSPLIT IN transaction
- CSPLIT IN transaction
  - MDATA packet
- CSPLIT IN transaction
  - DATA0 packet

The DMA address of MDATA (urb->dma) is always DWORD-aligned, but
the DMA address of DATA0 (urb->dma + qtd->isoc_split_offset) may
not be DWORD-aligned, it depends on the qtd->isoc_split_offset (the
length of MDATA). In my test case, the length of MDATA is usually
unaligned, this cause DATA0 packet transmission error.

This patch use kmem_cache to allocate aligned DMA buf for isoc
split in transaction. Note that according to usb 2.0 spec, the
maximum data payload size is 1023 bytes for each fs isoc ep,
and the maximum allowable interrupt data payload size is 64 bytes
or less for fs interrupt ep. So we set the size of object to be
1024 bytes in the kmem cache.

Signed-off-by: William Wu 
Reviewed-by: Douglas Anderson 
---
Changes in v5:
- freeing order opposite of allocation in dwc2_hcd_remove()
- Add Reviewed-by

Changes in v4:
- get rid of "qh->dw_align_buf_size"
- allocate unaligned_cache for Address DMA mode and Desc DMA mode
- freeing order opposite of allocation
- do dma_map_single() with the size of DWC2_KMEM_UNALIGNED_BUF_SIZE

Changes in v3:
- Modify the commit message
- Use Kmem_cache to allocate aligned DMA buf
- Fix coding style

Changes in v2:
- None

 drivers/usb/dwc2/core.h  |  3 ++
 drivers/usb/dwc2/hcd.c   | 89 +---
 drivers/usb/dwc2/hcd.h   |  8 
 drivers/usb/dwc2/hcd_intr.c  |  8 
 drivers/usb/dwc2/hcd_queue.c |  3 ++
 5 files changed, 106 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index d83be56..c1983f8 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -915,6 +915,7 @@ struct dwc2_hregs_backup {
  * @frame_list_sz:  Frame list size
  * @desc_gen_cache: Kmem cache for generic descriptors
  * @desc_hsisoc_cache:  Kmem cache for hs isochronous descriptors
+ * @unaligned_cache:Kmem cache for DMA mode to handle non-aligned buf
  *
  * These are for peripheral mode:
  *
@@ -1059,6 +1060,8 @@ struct dwc2_hsotg {
u32 frame_list_sz;
struct kmem_cache *desc_gen_cache;
struct kmem_cache *desc_hsisoc_cache;
+   struct kmem_cache *unaligned_cache;
+#define DWC2_KMEM_UNALIGNED_BUF_SIZE 1024
 
 #endif /* CONFIG_USB_DWC2_HOST || CONFIG_USB_DWC2_DUAL_ROLE */
 
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 190f959..4e631ba 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -1562,11 +1562,20 @@ static void dwc2_hc_start_transfer(struct dwc2_hsotg 
*hsotg,
}
 
if (hsotg->params.host_dma) {
-   dwc2_writel((u32)chan->xfer_dma,
-   hsotg->regs + HCDMA(chan->hc_num));
+   dma_addr_t dma_addr;
+
+   if (chan->align_buf) {
+   if (dbg_hc(chan))
+   dev_vdbg(hsotg->dev, "align_buf\n");
+   dma_addr = chan->align_buf;
+   } else {
+   dma_addr = chan->xfer_dma;
+   }
+   dwc2_writel((u32)dma_addr, hsotg->regs + HCDMA(chan->hc_num));
+
if (dbg_hc(chan))
dev_vdbg(hsotg->dev, "Wrote %08lx to HCDMA(%d)\n",
-(unsigned long)chan->xfer_dma, chan->hc_num);
+(unsigned long)dma_addr, chan->hc_num);
}
 
/* Start the split */
@@ -2620,6 +2629,35 @@ static void dwc2_hc_init_xfer(struct dwc2_hsotg *hsotg,
}
 }
 
+static int dwc2_alloc_split_dma_aligned_buf(struct dwc2_hsotg *hsotg,
+   struct dwc2_qh *qh,
+   struct dwc2_host_chan *chan)
+{
+   if (!hsotg->unaligned_cache ||
+   chan->max_packet > DWC2_KMEM_UNALIGNED_BUF_SIZE)
+   return -ENOMEM;
+
+   if (!qh->dw_align_buf) {
+   qh->dw_align_buf = kmem_cache_alloc(hsotg->unaligned_cache,
+   GFP_ATOMIC | GFP_DMA);
+   if (!qh->dw_align_buf)
+  

[PATCH v5 0/2] usb: dwc2: fix isoc split in transfer issue

2018-05-11 Thread William Wu
This patch fix dma unaligned problem and data lost problem for
isoc split in transfer.

Test on rk3288 platform, use an usb hs Hub (GL852G-12) and an usb
fs audio device (Plantronics headset) to capture and playback.

William Wu (2):
  usb: dwc2: alloc dma aligned buffer for isoc split in
  usb: dwc2: fix isoc split in transfer with no data

 drivers/usb/dwc2/core.h  |  3 ++
 drivers/usb/dwc2/hcd.c   | 89 +---
 drivers/usb/dwc2/hcd.h   |  8 
 drivers/usb/dwc2/hcd_intr.c  | 11 +-
 drivers/usb/dwc2/hcd_queue.c |  3 ++
 5 files changed, 107 insertions(+), 7 deletions(-)

-- 
2.0.0




[PATCH v4 1/2] usb: dwc2: alloc dma aligned buffer for isoc split in

2018-05-09 Thread William Wu
The commit 3bc04e28a030 ("usb: dwc2: host: Get aligned DMA in
a more supported way") rips out a lot of code to simply the
allocation of aligned DMA. However, it also introduces a new
issue when use isoc split in transfer.

In my test case, I connect the dwc2 controller with an usb hs
Hub (GL852G-12), and plug an usb fs audio device (Plantronics
headset) into the downstream port of Hub. Then use the usb mic
to record, we can find noise when playback.

It's because that the usb Hub uses an MDATA for the first
transaction and a DATA0 for the second transaction for the isoc
split in transaction. An typical isoc split in transaction sequence
like this:

- SSPLIT IN transaction
- CSPLIT IN transaction
  - MDATA packet
- CSPLIT IN transaction
  - DATA0 packet

The DMA address of MDATA (urb->dma) is always DWORD-aligned, but
the DMA address of DATA0 (urb->dma + qtd->isoc_split_offset) may
not be DWORD-aligned, it depends on the qtd->isoc_split_offset (the
length of MDATA). In my test case, the length of MDATA is usually
unaligned, this cause DATA0 packet transmission error.

This patch use kmem_cache to allocate aligned DMA buf for isoc
split in transaction. Note that according to usb 2.0 spec, the
maximum data payload size is 1023 bytes for each fs isoc ep,
and the maximum allowable interrupt data payload size is 64 bytes
or less for fs interrupt ep. So we set the size of object to be
1024 bytes in the kmem cache.

Signed-off-by: William Wu 
---
Changes in v4:
- get rid of "qh->dw_align_buf_size"
- allocate unaligned_cache for Address DMA mode and Desc DMA mode
- freeing order opposite of allocation
- do dma_map_single() with the size of DWC2_KMEM_UNALIGNED_BUF_SIZE

Changes in v3:
- Modify the commit message
- Use Kmem_cache to allocate aligned DMA buf
- Fix coding style

Changes in v2:
- None

 drivers/usb/dwc2/core.h  |  3 ++
 drivers/usb/dwc2/hcd.c   | 87 ++--
 drivers/usb/dwc2/hcd.h   |  8 
 drivers/usb/dwc2/hcd_intr.c  |  8 
 drivers/usb/dwc2/hcd_queue.c |  3 ++
 5 files changed, 105 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index d83be56..c1983f8 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -915,6 +915,7 @@ struct dwc2_hregs_backup {
  * @frame_list_sz:  Frame list size
  * @desc_gen_cache: Kmem cache for generic descriptors
  * @desc_hsisoc_cache:  Kmem cache for hs isochronous descriptors
+ * @unaligned_cache:Kmem cache for DMA mode to handle non-aligned buf
  *
  * These are for peripheral mode:
  *
@@ -1059,6 +1060,8 @@ struct dwc2_hsotg {
u32 frame_list_sz;
struct kmem_cache *desc_gen_cache;
struct kmem_cache *desc_hsisoc_cache;
+   struct kmem_cache *unaligned_cache;
+#define DWC2_KMEM_UNALIGNED_BUF_SIZE 1024
 
 #endif /* CONFIG_USB_DWC2_HOST || CONFIG_USB_DWC2_DUAL_ROLE */
 
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 190f959..64666cf 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -1562,11 +1562,20 @@ static void dwc2_hc_start_transfer(struct dwc2_hsotg 
*hsotg,
}
 
if (hsotg->params.host_dma) {
-   dwc2_writel((u32)chan->xfer_dma,
-   hsotg->regs + HCDMA(chan->hc_num));
+   dma_addr_t dma_addr;
+
+   if (chan->align_buf) {
+   if (dbg_hc(chan))
+   dev_vdbg(hsotg->dev, "align_buf\n");
+   dma_addr = chan->align_buf;
+   } else {
+   dma_addr = chan->xfer_dma;
+   }
+   dwc2_writel((u32)dma_addr, hsotg->regs + HCDMA(chan->hc_num));
+
if (dbg_hc(chan))
dev_vdbg(hsotg->dev, "Wrote %08lx to HCDMA(%d)\n",
-(unsigned long)chan->xfer_dma, chan->hc_num);
+(unsigned long)dma_addr, chan->hc_num);
}
 
/* Start the split */
@@ -2620,6 +2629,35 @@ static void dwc2_hc_init_xfer(struct dwc2_hsotg *hsotg,
}
 }
 
+static int dwc2_alloc_split_dma_aligned_buf(struct dwc2_hsotg *hsotg,
+   struct dwc2_qh *qh,
+   struct dwc2_host_chan *chan)
+{
+   if (!hsotg->unaligned_cache ||
+   chan->max_packet > DWC2_KMEM_UNALIGNED_BUF_SIZE)
+   return -ENOMEM;
+
+   if (!qh->dw_align_buf) {
+   qh->dw_align_buf = kmem_cache_alloc(hsotg->unaligned_cache,
+   GFP_ATOMIC | GFP_DMA);
+   if (!qh->dw_align_buf)
+   return -ENOMEM;
+   }
+
+   qh->dw_align_buf_dma = dma_map_single(hsotg->dev, qh->dw_align_buf,
+ DWC2

[PATCH v4 2/2] usb: dwc2: fix isoc split in transfer with no data

2018-05-09 Thread William Wu
If isoc split in transfer with no data (the length of DATA0
packet is zero), we can't simply return immediately. Because
the DATA0 can be the first transaction or the second transaction
for the isoc split in transaction. If the DATA0 packet with no
data is in the first transaction, we can return immediately.
But if the DATA0 packet with no data is in the second transaction
of isoc split in transaction sequence, we need to increase the
qtd->isoc_frame_index and giveback urb to device driver if needed,
otherwise, the MDATA packet will be lost.

A typical test case is that connect the dwc2 controller with an
usb hs Hub (GL852G-12), and plug an usb fs audio device (Plantronics
headset) into the downstream port of Hub. Then use the usb mic
to record, we can find noise when playback.

In the case, the isoc split in transaction sequence like this:

- SSPLIT IN transaction
- CSPLIT IN transaction
  - MDATA packet (176 bytes)
- CSPLIT IN transaction
  - DATA0 packet (0 byte)

This patch use both the length of DATA0 and qtd->isoc_split_offset
to check if the DATA0 is in the second transaction.

Signed-off-by: William Wu 
---
Changes in v4:
- None

Changes in v3:
- Remove "qtd->isoc_split_offset = 0" in the if test

Changes in v2:
- Modify the commit message

 drivers/usb/dwc2/hcd_intr.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c
index ba6229e..9751785 100644
--- a/drivers/usb/dwc2/hcd_intr.c
+++ b/drivers/usb/dwc2/hcd_intr.c
@@ -930,9 +930,8 @@ static int dwc2_xfercomp_isoc_split_in(struct dwc2_hsotg 
*hsotg,
frame_desc = &qtd->urb->iso_descs[qtd->isoc_frame_index];
len = dwc2_get_actual_xfer_length(hsotg, chan, chnum, qtd,
  DWC2_HC_XFER_COMPLETE, NULL);
-   if (!len) {
+   if (!len && !qtd->isoc_split_offset) {
qtd->complete_split = 0;
-   qtd->isoc_split_offset = 0;
return 0;
}
 
-- 
2.0.0




[PATCH v4 0/2] usb: dwc2: fix isoc split in transfer issue

2018-05-09 Thread William Wu
This patch fix dma unaligned problem and data lost problem for
isoc split in transfer.

Test on rk3288 platform, use an usb hs Hub (GL852G-12) and an usb
fs audio device (Plantronics headset) to capture and playback.

William Wu (2):
  usb: dwc2: alloc dma aligned buffer for isoc split in
  usb: dwc2: fix isoc split in transfer with no data

 drivers/usb/dwc2/core.h  |  3 ++
 drivers/usb/dwc2/hcd.c   | 87 ++--
 drivers/usb/dwc2/hcd.h   |  8 
 drivers/usb/dwc2/hcd_intr.c  | 11 +-
 drivers/usb/dwc2/hcd_queue.c |  3 ++
 5 files changed, 106 insertions(+), 6 deletions(-)

-- 
2.0.0




[PATCH v3 2/2] usb: dwc2: fix isoc split in transfer with no data

2018-05-07 Thread William Wu
If isoc split in transfer with no data (the length of DATA0
packet is zero), we can't simply return immediately. Because
the DATA0 can be the first transaction or the second transaction
for the isoc split in transaction. If the DATA0 packet with no
data is in the first transaction, we can return immediately.
But if the DATA0 packet with no data is in the second transaction
of isoc split in transaction sequence, we need to increase the
qtd->isoc_frame_index and giveback urb to device driver if needed,
otherwise, the MDATA packet will be lost.

A typical test case is that connect the dwc2 controller with an
usb hs Hub (GL852G-12), and plug an usb fs audio device (Plantronics
headset) into the downstream port of Hub. Then use the usb mic
to record, we can find noise when playback.

In the case, the isoc split in transaction sequence like this:

- SSPLIT IN transaction
- CSPLIT IN transaction
  - MDATA packet (176 bytes)
- CSPLIT IN transaction
  - DATA0 packet (0 byte)

This patch use both the length of DATA0 and qtd->isoc_split_offset
to check if the DATA0 is in the second transaction.

Signed-off-by: William Wu 
---
Changes in v3:
- Remove "qtd->isoc_split_offset = 0" in the if test

Changes in v2:
- Modify the commit message

 drivers/usb/dwc2/hcd_intr.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c
index ba6fd852..3003594 100644
--- a/drivers/usb/dwc2/hcd_intr.c
+++ b/drivers/usb/dwc2/hcd_intr.c
@@ -930,9 +930,8 @@ static int dwc2_xfercomp_isoc_split_in(struct dwc2_hsotg 
*hsotg,
frame_desc = &qtd->urb->iso_descs[qtd->isoc_frame_index];
len = dwc2_get_actual_xfer_length(hsotg, chan, chnum, qtd,
  DWC2_HC_XFER_COMPLETE, NULL);
-   if (!len) {
+   if (!len && !qtd->isoc_split_offset) {
qtd->complete_split = 0;
-   qtd->isoc_split_offset = 0;
return 0;
}
 
-- 
2.0.0




[PATCH v3 1/2] usb: dwc2: alloc dma aligned buffer for isoc split in

2018-05-07 Thread William Wu
The commit 3bc04e28a030 ("usb: dwc2: host: Get aligned DMA in
a more supported way") rips out a lot of code to simply the
allocation of aligned DMA. However, it also introduces a new
issue when use isoc split in transfer.

In my test case, I connect the dwc2 controller with an usb hs
Hub (GL852G-12), and plug an usb fs audio device (Plantronics
headset) into the downstream port of Hub. Then use the usb mic
to record, we can find noise when playback.

It's because that the usb Hub uses an MDATA for the first
transaction and a DATA0 for the second transaction for the isoc
split in transaction. An typical isoc split in transaction sequence
like this:

- SSPLIT IN transaction
- CSPLIT IN transaction
  - MDATA packet
- CSPLIT IN transaction
  - DATA0 packet

The DMA address of MDATA (urb->dma) is always DWORD-aligned, but
the DMA address of DATA0 (urb->dma + qtd->isoc_split_offset) may
not be DWORD-aligned, it depends on the qtd->isoc_split_offset (the
length of MDATA). In my test case, the length of MDATA is usually
unaligned, this cause DATA0 packet transmission error.

This patch use kmem_cache to allocate aligned DMA buf for isoc
split in transaction. Note that according to usb 2.0 spec, the
maximum data payload size is 1023 bytes for each fs isoc ep,
and the maximum allowable interrupt data payload size is 64 bytes
or less for fs interrupt ep. So we set the size of object to be
1024 bytes in the kmem cache.

Signed-off-by: William Wu 
---
Changes in v3:
- Modify the commit message
- Use Kmem_cache to allocate aligned DMA buf
- Fix coding style

Changes in v2:
- None

 drivers/usb/dwc2/core.h  |  3 ++
 drivers/usb/dwc2/hcd.c   | 85 ++--
 drivers/usb/dwc2/hcd.h   | 10 ++
 drivers/usb/dwc2/hcd_intr.c  |  8 +
 drivers/usb/dwc2/hcd_queue.c |  3 ++
 5 files changed, 106 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index d83be56..c1983f8 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -915,6 +915,7 @@ struct dwc2_hregs_backup {
  * @frame_list_sz:  Frame list size
  * @desc_gen_cache: Kmem cache for generic descriptors
  * @desc_hsisoc_cache:  Kmem cache for hs isochronous descriptors
+ * @unaligned_cache:Kmem cache for DMA mode to handle non-aligned buf
  *
  * These are for peripheral mode:
  *
@@ -1059,6 +1060,8 @@ struct dwc2_hsotg {
u32 frame_list_sz;
struct kmem_cache *desc_gen_cache;
struct kmem_cache *desc_hsisoc_cache;
+   struct kmem_cache *unaligned_cache;
+#define DWC2_KMEM_UNALIGNED_BUF_SIZE 1024
 
 #endif /* CONFIG_USB_DWC2_HOST || CONFIG_USB_DWC2_DUAL_ROLE */
 
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 190f959..6f22dee 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -1562,11 +1562,20 @@ static void dwc2_hc_start_transfer(struct dwc2_hsotg 
*hsotg,
}
 
if (hsotg->params.host_dma) {
-   dwc2_writel((u32)chan->xfer_dma,
-   hsotg->regs + HCDMA(chan->hc_num));
+   dma_addr_t dma_addr;
+
+   if (chan->align_buf) {
+   if (dbg_hc(chan))
+   dev_vdbg(hsotg->dev, "align_buf\n");
+   dma_addr = chan->align_buf;
+   } else {
+   dma_addr = chan->xfer_dma;
+   }
+   dwc2_writel((u32)dma_addr, hsotg->regs + HCDMA(chan->hc_num));
+
if (dbg_hc(chan))
dev_vdbg(hsotg->dev, "Wrote %08lx to HCDMA(%d)\n",
-(unsigned long)chan->xfer_dma, chan->hc_num);
+(unsigned long)dma_addr, chan->hc_num);
}
 
/* Start the split */
@@ -2620,6 +2629,37 @@ static void dwc2_hc_init_xfer(struct dwc2_hsotg *hsotg,
}
 }
 
+static int dwc2_alloc_split_dma_aligned_buf(struct dwc2_hsotg *hsotg,
+   struct dwc2_qh *qh,
+   struct dwc2_host_chan *chan)
+{
+   if (!hsotg->unaligned_cache)
+   return -ENOMEM;
+
+   if (!qh->dw_align_buf) {
+   qh->dw_align_buf = kmem_cache_alloc(hsotg->unaligned_cache,
+   GFP_ATOMIC | GFP_DMA);
+   if (!qh->dw_align_buf)
+   return -ENOMEM;
+
+   qh->dw_align_buf_size = min_t(u32, chan->max_packet,
+ DWC2_KMEM_UNALIGNED_BUF_SIZE);
+   }
+
+   qh->dw_align_buf_dma = dma_map_single(hsotg->dev, qh->dw_align_buf,
+ qh->dw_align_buf_size,
+ DMA_FROM_DEVICE);
+
+   if (dma_mapping_error(hsotg->de

[PATCH v3 0/2] usb: dwc2: fix isoc split in transfer issue

2018-05-07 Thread William Wu
This patch fix dma unaligned problem and data lost problem for
isoc split in transfer.

Test on rk3288 platform, use an usb hs Hub (GL852G-12) and an usb
fs audio device (Plantronics headset) to capture and playback.

William Wu (2):
  usb: dwc2: alloc dma aligned buffer for isoc split in
  usb: dwc2: fix isoc split in transfer with no data

 drivers/usb/dwc2/core.h  |  3 ++
 drivers/usb/dwc2/hcd.c   | 85 ++--
 drivers/usb/dwc2/hcd.h   | 10 ++
 drivers/usb/dwc2/hcd_intr.c  | 11 --
 drivers/usb/dwc2/hcd_queue.c |  3 ++
 5 files changed, 107 insertions(+), 5 deletions(-)

-- 
2.0.0




[PATCH v2 2/2] usb: dwc2: fix isoc split in transfer with no data

2018-05-01 Thread William Wu
If isoc split in transfer with no data (the length of DATA0
packet is zero), we can't simply return immediately. Because
the DATA0 can be the first transaction or the second transaction
for the isoc split in transaction. If the DATA0 packet with no
data is in the first transaction, we can return immediately.
But if the DATA0 packet with no data is in the second transaction
of isoc split in transaction sequence, we need to increase the
qtd->isoc_frame_index and giveback urb to device driver if needed,
otherwise, the MDATA packet will be lost.

A typical test case is that connect the dwc2 controller with an
usb hs Hub (GL852G-12), and plug an usb fs audio device (Plantronics
headset) into the downstream port of Hub. Then use the usb mic
to record, we can find noise when playback.

In the case, the isoc split in transaction sequence like this:

- SSPLIT IN transaction
- CSPLIT IN transaction
  - MDATA packet (176 bytes)
- CSPLIT IN transaction
  - DATA0 packet (0 byte)

This patch use both the length of DATA0 and qtd->isoc_split_offset
to check if the DATA0 is in the second transaction.

Signed-off-by: William Wu 
---
Changes in v2:
- Modify the commit message

 drivers/usb/dwc2/hcd_intr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c
index 5e2378f..479f628 100644
--- a/drivers/usb/dwc2/hcd_intr.c
+++ b/drivers/usb/dwc2/hcd_intr.c
@@ -930,7 +930,7 @@ static int dwc2_xfercomp_isoc_split_in(struct dwc2_hsotg 
*hsotg,
frame_desc = &qtd->urb->iso_descs[qtd->isoc_frame_index];
len = dwc2_get_actual_xfer_length(hsotg, chan, chnum, qtd,
  DWC2_HC_XFER_COMPLETE, NULL);
-   if (!len) {
+   if (!len && !qtd->isoc_split_offset) {
qtd->complete_split = 0;
qtd->isoc_split_offset = 0;
return 0;
-- 
2.0.0




[PATCH v2 0/2] usb: dwc2: fix isoc split in transfer issue

2018-05-01 Thread William Wu
This patch fix dma unaligned problem and data lost problem for
isoc split in transfer.

Test on rk3288 platform, use an usb hs Hub (GL852G-12) and an usb
fs audio device (Plantronics headset) to capture and playback.

William Wu (2):
  usb: dwc2: alloc dma aligned buffer for isoc split in
  usb: dwc2: fix isoc split in transfer with no data

 drivers/usb/dwc2/hcd.c   | 63 +---
 drivers/usb/dwc2/hcd.h   | 10 +++
 drivers/usb/dwc2/hcd_intr.c  | 10 ++-
 drivers/usb/dwc2/hcd_queue.c |  8 +-
 4 files changed, 86 insertions(+), 5 deletions(-)

-- 
2.0.0




[PATCH v2 1/2] usb: dwc2: alloc dma aligned buffer for isoc split in

2018-05-01 Thread William Wu
The commit 3bc04e28a030 ("usb: dwc2: host: Get aligned DMA in
a more supported way") rips out a lot of code to simply the
allocation of aligned DMA. However, it also introduces a new
issue when use isoc split in transfer.

In my test case, I connect the dwc2 controller with an usb hs
Hub (GL852G-12), and plug an usb fs audio device (Plantronics
headset) into the downstream port of Hub. Then use the usb mic
to record, we can find noise when playback.

It's because that the usb Hub uses an MDATA for the first
transaction and a DATA0 for the second transaction for the isoc
split in transaction. An typical isoc split in transaction sequence
like this:

- SSPLIT IN transaction
- CSPLIT IN transaction
  - MDATA packet
- CSPLIT IN transaction
  - DATA0 packet

The DMA address of MDATA (urb->dma) is always DWORD-aligned, but
the DMA address of DATA0 (urb->dma + qtd->isoc_split_offset) may
not be DWORD-aligned, it depends on the qtd->isoc_split_offset (the
length of MDATA). In my test case, the length of MDATA is usually
unaligned, this casue DATA0 packet transmission error.

This patch base on the old way of aligned DMA allocation in the
dwc2 driver to get aligned DMA for isoc split in.

Signed-off-by: William Wu 
---
Changes in v2:
- None

 drivers/usb/dwc2/hcd.c   | 63 +---
 drivers/usb/dwc2/hcd.h   | 10 +++
 drivers/usb/dwc2/hcd_intr.c  |  8 ++
 drivers/usb/dwc2/hcd_queue.c |  8 +-
 4 files changed, 85 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 190f959..8c2b35f 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -1562,11 +1562,20 @@ static void dwc2_hc_start_transfer(struct dwc2_hsotg 
*hsotg,
}
 
if (hsotg->params.host_dma) {
-   dwc2_writel((u32)chan->xfer_dma,
-   hsotg->regs + HCDMA(chan->hc_num));
+   dma_addr_t dma_addr;
+
+   if (chan->align_buf) {
+   if (dbg_hc(chan))
+   dev_vdbg(hsotg->dev, "align_buf\n");
+   dma_addr = chan->align_buf;
+   } else {
+   dma_addr = chan->xfer_dma;
+   }
+   dwc2_writel((u32)dma_addr, hsotg->regs + HCDMA(chan->hc_num));
+
if (dbg_hc(chan))
dev_vdbg(hsotg->dev, "Wrote %08lx to HCDMA(%d)\n",
-(unsigned long)chan->xfer_dma, chan->hc_num);
+(unsigned long)dma_addr, chan->hc_num);
}
 
/* Start the split */
@@ -2620,6 +2629,33 @@ static void dwc2_hc_init_xfer(struct dwc2_hsotg *hsotg,
}
 }
 
+static int dwc2_alloc_split_dma_aligned_buf(struct dwc2_hsotg *hsotg,
+   struct dwc2_qh *qh,
+   struct dwc2_host_chan *chan)
+{
+   if (!qh->dw_align_buf) {
+   qh->dw_align_buf = kmalloc(chan->max_packet,
+  GFP_ATOMIC | GFP_DMA);
+   if (!qh->dw_align_buf)
+   return -ENOMEM;
+
+   qh->dw_align_buf_size = chan->max_packet;
+   }
+
+   qh->dw_align_buf_dma = dma_map_single(hsotg->dev, qh->dw_align_buf,
+ qh->dw_align_buf_size,
+ DMA_FROM_DEVICE);
+
+   if (dma_mapping_error(hsotg->dev, qh->dw_align_buf_dma)) {
+   dev_err(hsotg->dev, "can't map align_buf\n");
+   chan->align_buf = 0;
+   return -EINVAL;
+   }
+
+   chan->align_buf = qh->dw_align_buf_dma;
+   return 0;
+}
+
 #define DWC2_USB_DMA_ALIGN 4
 
 struct dma_aligned_buffer {
@@ -2797,6 +2833,27 @@ static int dwc2_assign_and_init_hc(struct dwc2_hsotg 
*hsotg, struct dwc2_qh *qh)
/* Set the transfer attributes */
dwc2_hc_init_xfer(hsotg, chan, qtd);
 
+   /* For non-dword aligned buffers */
+   if (hsotg->params.host_dma > 0 && qh->do_split &&
+   chan->ep_is_in && (chan->xfer_dma & 0x3)) {
+   dev_vdbg(hsotg->dev, "Non-aligned buffer\n");
+   if (dwc2_alloc_split_dma_aligned_buf(hsotg, qh, chan)) {
+   dev_err(hsotg->dev,
+   "%s: Failed to allocate memory to handle 
non-dword aligned buffer\n",
+   __func__);
+   /* Add channel back to free list */
+   chan->align_buf = 0;
+   chan->multi_count = 0;
+   list_add_tail(&chan->hc_list_entry,
+ &hsotg->free_hc_list

[PATCH 1/2] usb: dwc2: alloc dma aligned buffer for isoc split in

2018-04-23 Thread William Wu
The commit 3bc04e28a030 ("usb: dwc2: host: Get aligned DMA in
a more supported way") rips out a lot of code to simply the
allocation of aligned DMA. However, it also introduces a new
issue when use isoc split in transfer.

In my test case, I connect the dwc2 controller with an usb hs
Hub (GL852G-12), and plug an usb fs audio device (Plantronics
headset) into the downstream port of Hub. Then use the usb mic
to record, we can find noise when playback.

It's because that the usb Hub uses an MDATA for the first
transaction and a DATA0 for the second transaction for the isoc
split in transaction. An typical isoc split in transaction sequence
like this:

- SSPLIT IN transaction
- CSPLIT IN transaction
  - MDATA packet
- CSPLIT IN transaction
  - DATA0 packet

The DMA address of MDATA (urb->dma) is always DWORD-aligned, but
the DMA address of DATA0 (urb->dma + qtd->isoc_split_offset) may
not be DWORD-aligned, it depends on the qtd->isoc_split_offset (the
length of MDATA). In my test case, the length of MDATA is usually
unaligned, this casue DATA0 packet transmission error.

This patch base on the old way of aligned DMA allocation in the
dwc2 driver to get aligned DMA for isoc split in.

Signed-off-by: William Wu 
---
 drivers/usb/dwc2/hcd.c   | 63 +---
 drivers/usb/dwc2/hcd.h   | 10 +++
 drivers/usb/dwc2/hcd_intr.c  |  8 ++
 drivers/usb/dwc2/hcd_queue.c |  8 +-
 4 files changed, 85 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 190f959..8c2b35f 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -1562,11 +1562,20 @@ static void dwc2_hc_start_transfer(struct dwc2_hsotg 
*hsotg,
}
 
if (hsotg->params.host_dma) {
-   dwc2_writel((u32)chan->xfer_dma,
-   hsotg->regs + HCDMA(chan->hc_num));
+   dma_addr_t dma_addr;
+
+   if (chan->align_buf) {
+   if (dbg_hc(chan))
+   dev_vdbg(hsotg->dev, "align_buf\n");
+   dma_addr = chan->align_buf;
+   } else {
+   dma_addr = chan->xfer_dma;
+   }
+   dwc2_writel((u32)dma_addr, hsotg->regs + HCDMA(chan->hc_num));
+
if (dbg_hc(chan))
dev_vdbg(hsotg->dev, "Wrote %08lx to HCDMA(%d)\n",
-(unsigned long)chan->xfer_dma, chan->hc_num);
+(unsigned long)dma_addr, chan->hc_num);
}
 
/* Start the split */
@@ -2620,6 +2629,33 @@ static void dwc2_hc_init_xfer(struct dwc2_hsotg *hsotg,
}
 }
 
+static int dwc2_alloc_split_dma_aligned_buf(struct dwc2_hsotg *hsotg,
+   struct dwc2_qh *qh,
+   struct dwc2_host_chan *chan)
+{
+   if (!qh->dw_align_buf) {
+   qh->dw_align_buf = kmalloc(chan->max_packet,
+  GFP_ATOMIC | GFP_DMA);
+   if (!qh->dw_align_buf)
+   return -ENOMEM;
+
+   qh->dw_align_buf_size = chan->max_packet;
+   }
+
+   qh->dw_align_buf_dma = dma_map_single(hsotg->dev, qh->dw_align_buf,
+ qh->dw_align_buf_size,
+ DMA_FROM_DEVICE);
+
+   if (dma_mapping_error(hsotg->dev, qh->dw_align_buf_dma)) {
+   dev_err(hsotg->dev, "can't map align_buf\n");
+   chan->align_buf = 0;
+   return -EINVAL;
+   }
+
+   chan->align_buf = qh->dw_align_buf_dma;
+   return 0;
+}
+
 #define DWC2_USB_DMA_ALIGN 4
 
 struct dma_aligned_buffer {
@@ -2797,6 +2833,27 @@ static int dwc2_assign_and_init_hc(struct dwc2_hsotg 
*hsotg, struct dwc2_qh *qh)
/* Set the transfer attributes */
dwc2_hc_init_xfer(hsotg, chan, qtd);
 
+   /* For non-dword aligned buffers */
+   if (hsotg->params.host_dma > 0 && qh->do_split &&
+   chan->ep_is_in && (chan->xfer_dma & 0x3)) {
+   dev_vdbg(hsotg->dev, "Non-aligned buffer\n");
+   if (dwc2_alloc_split_dma_aligned_buf(hsotg, qh, chan)) {
+   dev_err(hsotg->dev,
+   "%s: Failed to allocate memory to handle 
non-dword aligned buffer\n",
+   __func__);
+   /* Add channel back to free list */
+   chan->align_buf = 0;
+   chan->multi_count = 0;
+   list_add_tail(&chan->hc_list_entry,
+ &hsotg->free_hc_list);
+ 

[PATCH 2/2] usb: dwc2: fix isoc split in transfer with no data

2018-04-23 Thread William Wu
If isoc split in transfer with no data (the length of DATA0
packet is 0), we can't simply return immediately. Because the
DATA0 can be the first transaction or the second transaction for
the isoc split in transaction. If the DATA0 packet with on data
is in the first transaction, we can return immediately. But if
the the DATA0 packet with on data is in the second transaction
of isoc split in transaction sequence, we need to increase the
qtd->isoc_frame_index and giveback urb to device driver if needed,
otherwise, the MDATA packet will be lost.

A typical test case is that connect the dwc2 controller with an
usb hs Hub (GL852G-12), and plug an usb fs audio device (Plantronics
headset) into the downstream port of Hub. Then use the usb mic
to record, we can find noise when playback.

In the case, the isoc split in transaction sequence like this:

- SSPLIT IN transaction
- CSPLIT IN transaction
  - MDATA packet (176 bytes)
- CSPLIT IN transaction
  - DATA0 packet (0 byte)

This patch use both the length of DATA0 and qtd->isoc_split_offset
to check if the DATA0 is in the second transaction.

Signed-off-by: William Wu 
---
 drivers/usb/dwc2/hcd_intr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c
index 5e2378f..479f628 100644
--- a/drivers/usb/dwc2/hcd_intr.c
+++ b/drivers/usb/dwc2/hcd_intr.c
@@ -930,7 +930,7 @@ static int dwc2_xfercomp_isoc_split_in(struct dwc2_hsotg 
*hsotg,
frame_desc = &qtd->urb->iso_descs[qtd->isoc_frame_index];
len = dwc2_get_actual_xfer_length(hsotg, chan, chnum, qtd,
  DWC2_HC_XFER_COMPLETE, NULL);
-   if (!len) {
+   if (!len && !qtd->isoc_split_offset) {
qtd->complete_split = 0;
qtd->isoc_split_offset = 0;
return 0;
-- 
2.0.0




[PATCH 0/2] usb: dwc2: fix isoc split in transfer issue

2018-04-23 Thread William Wu
This patch fix dma unaligned problem and data lost problem for
isoc split in transfer.

Test on rk3288 platform, use an usb hs Hub (GL852G-12) and an usb
fs audio device (Plantronics headset) to capture and playback.

William Wu (2):
  usb: dwc2: alloc dma aligned buffer for isoc split in
  usb: dwc2: fix isoc split in transfer with no data

 drivers/usb/dwc2/hcd.c   | 63 +---
 drivers/usb/dwc2/hcd.h   | 10 +++
 drivers/usb/dwc2/hcd_intr.c  | 10 ++-
 drivers/usb/dwc2/hcd_queue.c |  8 +-
 4 files changed, 86 insertions(+), 5 deletions(-)

-- 
2.0.0




[PATCH] usb: gadget: f_fs: get the correct address of comp_desc

2018-02-05 Thread William Wu
Refer to the USB 3.0 spec '9.6.7 SuperSpeed Endpoint Companion',
the companion descriptor follows the standard endpoint descriptor.
This descriptor is only defined for SuperSpeed endpoints. The
f_fs driver gets the address of the companion descriptor via
'ds + USB_DT_ENDPOINT_SIZE', and actually, the ds variable is
a pointer to the struct usb_endpoint_descriptor, so the offset
of the companion descriptor which we get is USB_DT_ENDPOINT_SIZE *
sizeof(struct usb_endpoint_descriptor), the wrong offset is 63
bytes. This cause out-of-bound with the following error log if
CONFIG_KASAN and CONFIG_SLUB_DEBUG is enabled on Rockchip RK3399
Evaluation Board.

android_work: sent uevent USB_STATE=CONNECTED
configfs-gadget gadget: super-speed config #1: b
==
BUG: KASAN: slab-out-of-bounds in ffs_func_set_alt+0x230/0x398
Read of size 1 at addr ffc0ce2d0b10 by task irq/224-dwc3/364

CPU: 4 PID: 364 Comm: irq/224-dwc3 Not tainted 4.4.112 #6
Hardware name: Rockchip RK3399 Evaluation Board v3 (Android) (DT)
Call trace:
[] dump_backtrace+0x0/0x244
[] show_stack+0x14/0x1c
[] dump_stack+0xa4/0xcc
[] print_address_description+0xa4/0x308
[] kasan_report+0x258/0x29c
[] __asan_load1+0x44/0x4c
[] ffs_func_set_alt+0x230/0x398
[] composite_setup+0xdcc/0x1ac8
[] android_setup+0x124/0x1a0
[] dwc3_ep0_delegate_req+0x48/0x68
[] dwc3_ep0_interrupt+0x758/0x1174
[] dwc3_thread_interrupt+0x204/0xe68
[] irq_thread_fn+0x44/0x94
[] irq_thread+0x128/0x22c
[] kthread+0x11c/0x130
[] ret_from_fork+0x10/0x30

Allocated by task 1:
[] save_stack_trace_tsk+0x0/0x134
[] save_stack_trace+0x14/0x1c
[] kasan_kmalloc.part.3+0x48/0xf4
[] kasan_kmalloc+0x8c/0xa0
[] __kmalloc+0x208/0x268
[] ffs_func_bind+0x4b4/0x918
[] usb_add_function+0xd8/0x1d4
[] configfs_composite_bind+0x48c/0x570
[] udc_bind_to_driver+0x6c/0x170
[] usb_udc_attach_driver+0xa4/0xd0
[] gadget_dev_desc_UDC_store+0xd4/0x120
[] configfs_write_file+0x1a0/0x1f8
[] __vfs_write+0x64/0x174
[] vfs_write+0xe4/0x1e8
[] SyS_write+0x68/0xc8
[] el0_svc_naked+0x24/0x28

Freed by task 0:
(stack is not available)

The buggy address belongs to the object at ffc0ce2d0900
which belongs to the cache kmalloc-1024 of size 1024
The buggy address is located 528 bytes inside of
 1024-byte region [ffc0ce2d0900, ffc0ce2d0d00)
The buggy address belongs to the page:
page:ffbdc338b400 count:1 mapcount:-2145648611 mapping:  (null) 
index:0x0
flags: 0x4080(slab|head)
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffc0ce2d0a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ffc0ce2d0a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 >ffc0ce2d0b00: 00 04 fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 ^
 ffc0ce2d0b80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 ffc0ce2d0c00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
==
Disabling lock debugging due to kernel taint
android_work: sent uevent USB_STATE=CONFIGURED

This patch adds struct usb_endpoint_descriptor * -> u8 * type conversion
for ds variable, then we can get the correct address of comp_desc
with offset USB_DT_ENDPOINT_SIZE bytes.

Signed-off-by: William Wu 
---
 drivers/usb/gadget/function/f_fs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/gadget/function/f_fs.c 
b/drivers/usb/gadget/function/f_fs.c
index 6756472..f13ead0 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -1882,8 +1882,8 @@ static int ffs_func_eps_enable(struct ffs_function *func)
ep->ep->desc = ds;
 
if (needs_comp_desc) {
-   comp_desc = (struct usb_ss_ep_comp_descriptor *)(ds +
-   USB_DT_ENDPOINT_SIZE);
+   comp_desc = (struct usb_ss_ep_comp_descriptor *)
+((u8 *)ds + USB_DT_ENDPOINT_SIZE);
ep->ep->maxburst = comp_desc->bMaxBurst + 1;
ep->ep->comp_desc = comp_desc;
}
-- 
2.0.0




[PATCH 1/3] dt-bindings: phy: phy-rockchip-typec: add usb3 otg reset

2018-01-12 Thread William Wu
This patch adds USB3 OTG reset property for rk3399 Type-C PHY
to hold the USB3 controller in reset state.

Signed-off-by: William Wu 
---
 Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt 
b/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt
index 6ea867e..db2902e 100644
--- a/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt
+++ b/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt
@@ -13,7 +13,7 @@ Required properties:
  - assigned-clock-rates : the phy core clk frequency, shall be: 5000
  - resets : a list of phandle + reset specifier pairs
  - reset-names : string reset name, must be:
-"uphy", "uphy-pipe", "uphy-tcphy"
+"uphy", "uphy-pipe", "uphy-tcphy", "usb3-otg"
  - extcon : extcon specifier for the Power Delivery
 
 Note, there are 2 type-c phys for RK3399, and they are almost identical, except
@@ -56,8 +56,9 @@ Example:
assigned-clock-rates = <5000>;
resets = <&cru SRST_UPHY0>,
 <&cru SRST_UPHY0_PIPE_L00>,
-<&cru SRST_P_UPHY0_TCPHY>;
-   reset-names = "uphy", "uphy-pipe", "uphy-tcphy";
+<&cru SRST_P_UPHY0_TCPHY>,
+<&cru SRST_A_USB3_OTG0>;
+   reset-names = "uphy", "uphy-pipe", "uphy-tcphy", "usb3-otg";
rockchip,typec-conn-dir = <0xe580 0 16>;
rockchip,usb3tousb2-en = <0xe580 3 19>;
rockchip,external-psm = <0xe588 14 30>;
@@ -84,8 +85,9 @@ Example:
assigned-clock-rates = <5000>;
resets = <&cru SRST_UPHY1>,
 <&cru SRST_UPHY1_PIPE_L00>,
-<&cru SRST_P_UPHY1_TCPHY>;
-   reset-names = "uphy", "uphy-pipe", "uphy-tcphy";
+<&cru SRST_P_UPHY1_TCPHY>,
+<&cru SRST_A_USB3_OTG1>;
+   reset-names = "uphy", "uphy-pipe", "uphy-tcphy", "usb3-otg";
rockchip,typec-conn-dir = <0xe58c 0 16>;
rockchip,usb3tousb2-en = <0xe58c 3 19>;
rockchip,external-psm = <0xe594 14 30>;
-- 
2.0.0




[PATCH 2/3] arm64: dts: rockchip: add USB3 OTG reset for Type-C PHY on rk3399

2018-01-12 Thread William Wu
Add USB3 OTG reset for Type-C PHY. It can be used to hold the USB3
OTG controller in reset state before initializing the Type-C PHY.

Signed-off-by: William Wu 
---
 arch/arm64/boot/dts/rockchip/rk3399.dtsi | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index d340b58a..4e89d00 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1377,8 +1377,9 @@
power-domains = <&power RK3399_PD_TCPD0>;
resets = <&cru SRST_UPHY0>,
 <&cru SRST_UPHY0_PIPE_L00>,
-<&cru SRST_P_UPHY0_TCPHY>;
-   reset-names = "uphy", "uphy-pipe", "uphy-tcphy";
+<&cru SRST_P_UPHY0_TCPHY>,
+<&cru SRST_A_USB3_OTG0>;
+   reset-names = "uphy", "uphy-pipe", "uphy-tcphy", "usb3-otg";
rockchip,grf = <&grf>;
rockchip,typec-conn-dir = <0xe580 0 16>;
rockchip,usb3tousb2-en = <0xe580 3 19>;
@@ -1406,8 +1407,9 @@
power-domains = <&power RK3399_PD_TCPD1>;
resets = <&cru SRST_UPHY1>,
 <&cru SRST_UPHY1_PIPE_L00>,
-<&cru SRST_P_UPHY1_TCPHY>;
-   reset-names = "uphy", "uphy-pipe", "uphy-tcphy";
+<&cru SRST_P_UPHY1_TCPHY>,
+<&cru SRST_A_USB3_OTG1>;
+   reset-names = "uphy", "uphy-pipe", "uphy-tcphy", "usb3-otg";
rockchip,grf = <&grf>;
rockchip,typec-conn-dir = <0xe58c 0 16>;
rockchip,usb3tousb2-en = <0xe58c 3 19>;
-- 
2.0.0




[PATCH 3/3] phy: rockchip-typec: reset USB3 controller before initializing PHY

2018-01-12 Thread William Wu
According to the RK3399 TRM, for Type-C USB start-up sequence,
we need to hold the whole USB 3.0 OTG controller in reset state
to keep the PIPE power state in P2 while initializing PHY. This
is because when initialize the Type-C PHY for USB3, we need to
configure the PHY and PMA for the selected mode of operation,
and wait for the PMA and PIPE ready, if the USB3 OTG controller
isn't in P2 state, it may cause waiting timeout.

Without this patch, waiting for the PMA and PIPE ready timeout
issue easily happens when we shutdown the Logic on RK3399 and
do the suspend/resume stress test.

Signed-off-by: William Wu 
---
 drivers/phy/rockchip/phy-rockchip-typec.c | 22 --
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c 
b/drivers/phy/rockchip/phy-rockchip-typec.c
index ee85fa0..68a5840 100644
--- a/drivers/phy/rockchip/phy-rockchip-typec.c
+++ b/drivers/phy/rockchip/phy-rockchip-typec.c
@@ -372,6 +372,7 @@ struct rockchip_typec_phy {
struct reset_control *uphy_rst;
struct reset_control *pipe_rst;
struct reset_control *tcphy_rst;
+   struct reset_control *otg_rst;
struct rockchip_usb3phy_port_cfg port_cfgs;
/* mutex to protect access to individual PHYs */
struct mutex lock;
@@ -841,10 +842,16 @@ static int rockchip_usb3_phy_power_on(struct phy *phy)
if (tcphy->mode == new_mode)
goto unlock_ret;
 
+   ret = reset_control_assert(tcphy->otg_rst);
+   if (ret < 0) {
+   dev_err(tcphy->dev, "failed to assert otg reset: %d\n", ret);
+   goto unlock_ret;
+   }
+
if (tcphy->mode == MODE_DISCONNECT) {
ret = tcphy_phy_init(tcphy, new_mode);
if (ret)
-   goto unlock_ret;
+   goto unlock_deassert;
}
 
/* wait TCPHY for pipe ready */
@@ -852,7 +859,7 @@ static int rockchip_usb3_phy_power_on(struct phy *phy)
regmap_read(tcphy->grf_regs, reg->offset, &val);
if (!(val & BIT(reg->enable_bit))) {
tcphy->mode |= new_mode & (MODE_DFP_USB | MODE_UFP_USB);
-   goto unlock_ret;
+   goto unlock_deassert;
}
usleep_range(10, 20);
}
@@ -862,6 +869,11 @@ static int rockchip_usb3_phy_power_on(struct phy *phy)
 
ret = -ETIMEDOUT;
 
+unlock_deassert:
+   ret = reset_control_deassert(tcphy->otg_rst);
+   if (ret < 0)
+   dev_err(tcphy->dev, "failed to deassert otg reset: %d\n", ret);
+
 unlock_ret:
mutex_unlock(&tcphy->lock);
return ret;
@@ -1066,6 +1078,12 @@ static int tcphy_parse_dt(struct rockchip_typec_phy 
*tcphy,
return PTR_ERR(tcphy->tcphy_rst);
}
 
+   tcphy->otg_rst = devm_reset_control_get(dev, "usb3-otg");
+   if (IS_ERR(tcphy->otg_rst)) {
+   dev_err(dev, "no otg_rst reset control found\n");
+   return PTR_ERR(tcphy->otg_rst);
+   }
+
return 0;
 }
 
-- 
2.0.0




[PATCH 0/3] Reset USB3 controller before initializing Type-C PHY on rk3399

2018-01-12 Thread William Wu
This series adds USB3 OTG controller reset for rk3399 Type-C PHY, and use the
reset to hold the whole USB3 OTG controller in reset state to keep the PIPE
power state in P2 before initializing Type-C PHY, it's useful to avoid waiting
for PHY PMA and PIPE ready timeout.

William Wu (3):
  dt-bindings: phy: phy-rockchip-typec: add usb3 otg reset
  arm64: dts: rockchip: add USB3 OTG reset for Type-C PHY on rk3399
  phy: rockchip-typec: reset USB3 controller before initializing PHY

 .../devicetree/bindings/phy/phy-rockchip-typec.txt | 12 +++-
 arch/arm64/boot/dts/rockchip/rk3399.dtsi   | 10 ++
 drivers/phy/rockchip/phy-rockchip-typec.c  | 22 --
 3 files changed, 33 insertions(+), 11 deletions(-)

-- 
2.0.0




[PATCH] usb: dwc3: core: power on PHYs before initializing core

2018-01-11 Thread William Wu
The dwc3_core_init() gets the PHYs and initializes the PHYs with
the usb_phy_init() and phy_init() functions before initializing
core, and power on the PHYs after core initialization is done.

However, some platforms (e.g. Rockchip RK3399 DWC3 with Type-C
USB3 PHY), it needs to do some special operation while power on
the Type-C PHY before initializing DWC3 core. It's because that
the RK3399 Type-C PHY requires to hold the DWC3 controller in
reset state to keep the PIPE power state in P2 while configuring
the Type-C PHY, otherwise, it may cause waiting for the PIPE ready
timeout. In this case, if we power on the PHYs after the DWC3 core
initialization is done, the core will be reset to uninitialized
state after power on the PHYs.

Fix this by powering on the PHYs before initializing core. And
because the GUID register may also be reset in this case, so we
need to configure the GUID register after powering on the PHYs.

Signed-off-by: William Wu 
---
 drivers/usb/dwc3/core.c | 46 ++
 1 file changed, 22 insertions(+), 24 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index c32d2b9..4f5573f 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -741,12 +741,6 @@ static int dwc3_core_init(struct dwc3 *dwc)
goto err0;
}
 
-   /*
-* Write Linux Version Code to our GUID register so it's easy to figure
-* out which kernel version a bug was found.
-*/
-   dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE);
-
/* Handle USB2.0-only core configuration */
if (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) ==
DWC3_GHWPARAMS3_SSPHY_IFC_DIS) {
@@ -762,34 +756,40 @@ static int dwc3_core_init(struct dwc3 *dwc)
if (ret)
goto err0;
 
+   usb_phy_set_suspend(dwc->usb2_phy, 0);
+   usb_phy_set_suspend(dwc->usb3_phy, 0);
+   ret = phy_power_on(dwc->usb2_generic_phy);
+   if (ret < 0)
+   goto err1;
+
+   ret = phy_power_on(dwc->usb3_generic_phy);
+   if (ret < 0)
+   goto err2;
+
ret = dwc3_phy_setup(dwc);
if (ret)
-   goto err0;
+   goto err3;
+
+   /*
+* Write Linux Version Code to our GUID register so it's easy to figure
+* out which kernel version a bug was found.
+*/
+   dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE);
 
dwc3_core_setup_global_control(dwc);
dwc3_core_num_eps(dwc);
 
ret = dwc3_setup_scratch_buffers(dwc);
if (ret)
-   goto err1;
+   goto err3;
 
/* Adjust Frame Length */
dwc3_frame_length_adjustment(dwc);
 
-   usb_phy_set_suspend(dwc->usb2_phy, 0);
-   usb_phy_set_suspend(dwc->usb3_phy, 0);
-   ret = phy_power_on(dwc->usb2_generic_phy);
-   if (ret < 0)
-   goto err2;
-
-   ret = phy_power_on(dwc->usb3_generic_phy);
-   if (ret < 0)
-   goto err3;
-
ret = dwc3_event_buffers_setup(dwc);
if (ret) {
dev_err(dwc->dev, "failed to setup event buffers\n");
-   goto err4;
+   goto err3;
}
 
/*
@@ -821,17 +821,15 @@ static int dwc3_core_init(struct dwc3 *dwc)
 
return 0;
 
-err4:
+err3:
phy_power_off(dwc->usb3_generic_phy);
 
-err3:
+err2:
phy_power_off(dwc->usb2_generic_phy);
 
-err2:
+err1:
usb_phy_set_suspend(dwc->usb2_phy, 1);
usb_phy_set_suspend(dwc->usb3_phy, 1);
-
-err1:
usb_phy_shutdown(dwc->usb2_phy);
usb_phy_shutdown(dwc->usb3_phy);
phy_exit(dwc->usb2_generic_phy);
-- 
2.0.0




[PATCH] usb: dwc2: host: fix isoc urb actual length

2017-11-06 Thread William Wu
The actual_length in dwc2_hcd_urb structure is used
to indicate the total data length transferred so far,
but in dwc2_update_isoc_urb_state(), it just updates
the actual_length of isoc frame, and don't update the
urb actual_length at the same time, this will cause
device drivers working error which depend on the urb
actual_length.

we can easily find this issue if use an USB camera,
the userspace use libusb to get USB data from kernel
via devio driver.In usb devio driver, processcompl()
function will process urb complete and copy data to
userspace depending on urb actual_length.

Let's update the urb actual_length if the isoc frame
is valid.

Signed-off-by: William Wu 
---
 drivers/usb/dwc2/hcd_intr.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c
index 28a8210..01b1e13 100644
--- a/drivers/usb/dwc2/hcd_intr.c
+++ b/drivers/usb/dwc2/hcd_intr.c
@@ -580,6 +580,7 @@ static enum dwc2_halt_status dwc2_update_isoc_urb_state(
frame_desc->status = 0;
frame_desc->actual_length = dwc2_get_actual_xfer_length(hsotg,
chan, chnum, qtd, halt_status, NULL);
+   urb->actual_length += frame_desc->actual_length;
break;
case DWC2_HC_XFER_FRAME_OVERRUN:
urb->error_count++;
@@ -599,6 +600,7 @@ static enum dwc2_halt_status dwc2_update_isoc_urb_state(
frame_desc->status = -EPROTO;
frame_desc->actual_length = dwc2_get_actual_xfer_length(hsotg,
chan, chnum, qtd, halt_status, NULL);
+   urb->actual_length += frame_desc->actual_length;
 
/* Skip whole frame */
if (chan->qh->do_split &&
-- 
2.0.0




[PATCH v3 0/3] Add usb3 ctrl node on RK3328 SoCs and enable usb3 host on RK3328 evb

2017-08-21 Thread William Wu
This series add support for usb3 controller on RK3328 SoCs.
This series don't include usb3 phy patches, and I will try
to submit usb3 phy patches individually later.

Tested on RK3328 evaluation board.

William Wu (3):
  dt-bindings: usb: add DT binding for RK3328 dwc3 controller
  arm64: dts: rockchip: add usb3 controller node for RK3328 SoCs
  arm64: dts: rockchip: enable usb3 for RK3328 evaluation board

 .../devicetree/bindings/usb/rockchip,dwc3.txt  |  4 +++-
 arch/arm64/boot/dts/rockchip/rk3328-evb.dts|  9 
 arch/arm64/boot/dts/rockchip/rk3328.dtsi   | 27 ++
 3 files changed, 39 insertions(+), 1 deletion(-)

-- 
2.0.0




[PATCH v3 2/3] arm64: dts: rockchip: add usb3 controller node for RK3328 SoCs

2017-08-21 Thread William Wu
RK3328 has one USB 3.0 OTG controller which uses DWC_USB3
core's general architecture. It can act as static xHCI host
controller, static device controller, USB 3.0/2.0 OTG basing
on ID of USB3.0 PHY.

Signed-off-by: William Wu 
---
Changes in v3:
- Move dt-binding changes to a separate patch.

Changes in v2:
- Modify the dwc3 quirk "snps,tx-ipgap-linecheck-dis-quirk" to
  "snps,dis-tx-ipgap-linecheck-quirk"

 arch/arm64/boot/dts/rockchip/rk3328.dtsi | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index e23d936..e121cfd 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -700,6 +700,33 @@
status = "disabled";
};
 
+   usbdrd3: usb@ff60 {
+   compatible = "rockchip,rk3328-dwc3", "rockchip,rk3399-dwc3";
+   clocks = <&cru SCLK_USB3OTG_REF>, <&cru SCLK_USB3OTG_SUSPEND>,
+<&cru ACLK_USB3OTG>;
+   clock-names = "ref_clk", "suspend_clk",
+ "bus_clk";
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges;
+   status = "disabled";
+
+   usbdrd_dwc3: dwc3@ff60 {
+   compatible = "snps,dwc3";
+   reg = <0x0 0xff60 0x0 0x10>;
+   interrupts = ;
+   dr_mode = "otg";
+   phy_type = "utmi_wide";
+   snps,dis_enblslpm_quirk;
+   snps,dis-u2-freeclk-exists-quirk;
+   snps,dis_u2_susphy_quirk;
+   snps,dis_u3_susphy_quirk;
+   snps,dis-del-phy-power-chg-quirk;
+   snps,dis-tx-ipgap-linecheck-quirk;
+   status = "disabled";
+   };
+   };
+
gic: interrupt-controller@ff811000 {
compatible = "arm,gic-400";
#interrupt-cells = <3>;
-- 
2.0.0




[PATCH v3 3/3] arm64: dts: rockchip: enable usb3 for RK3328 evaluation board

2017-08-21 Thread William Wu
Rockchip's RK3328 evaluation board has one USB 3.0 OTG controller,
we enable it and set it act as static xHCI host controller to
support USB 3.0 HOST on RK3328 evaluation board.

Signed-off-by: William Wu 
---
Changes in v3:
- None

Changes in v2:
- None

 arch/arm64/boot/dts/rockchip/rk3328-evb.dts | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts 
b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
index 86605ae..68e1b424 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
@@ -219,3 +219,12 @@
 &usb_host0_ohci {
status = "okay";
 };
+
+&usbdrd3 {
+   status = "okay";
+};
+
+&usbdrd_dwc3 {
+   dr_mode = "host";
+   status = "okay";
+};
-- 
2.0.0




[PATCH v3 1/3] dt-bindings: usb: add DT binding for RK3328 dwc3 controller

2017-08-21 Thread William Wu
Adds the device tree bindings description for RK3328 and
compatible USB DWC3 controller.

Signed-off-by: William Wu 
---
Changes in v3:
- Add this for separate usb dt-bindings patch.

Changes in v2:
- None

 Documentation/devicetree/bindings/usb/rockchip,dwc3.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt 
b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
index 0536a93..d6b2e47 100644
--- a/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
@@ -1,7 +1,9 @@
 Rockchip SuperSpeed DWC3 USB SoC controller
 
 Required properties:
-- compatible:  should contain "rockchip,rk3399-dwc3" for rk3399 SoC
+- compatible:  should be one of the following:
+  - "rockchip,rk3399-dwc3": for rk3399 SoC
+  - "rockchip,rk3328-dwc3", "rockchip,rk3399-dwc3": for rk3328 SoC
 - clocks:  A list of phandle + clock-specifier pairs for the
clocks listed in clock-names
 - clock-names: Should contain the following:
-- 
2.0.0




[PATCH] arm64: dts: rockchip: disable tx ipgap linecheck for rk3399 dwc3

2017-08-17 Thread William Wu
RK3399 USB DWC3 controller has a issue that FS/LS devices not
recognized if inserted through USB 3.0 HUB. It's because that
the inter-packet delay between the SSPLIT token to SETUP token
is about 566ns, more then the USB spec requirement.

This patch adds a quirk "snps,dis-tx-ipgap-linecheck-quirk" to
disable the u2mac linestate check to decrease the SSPLIT token
to SETUP token inter-packet delay from 566ns to 466ns.

Signed-off-by: William Wu 
---
 arch/arm64/boot/dts/rockchip/rk3399.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index 27a4616..69cb311 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -412,6 +412,7 @@
snps,dis-u2-freeclk-exists-quirk;
snps,dis_u2_susphy_quirk;
snps,dis-del-phy-power-chg-quirk;
+   snps,dis-tx-ipgap-linecheck-quirk;
status = "disabled";
};
};
@@ -439,6 +440,7 @@
snps,dis-u2-freeclk-exists-quirk;
snps,dis_u2_susphy_quirk;
snps,dis-del-phy-power-chg-quirk;
+   snps,dis-tx-ipgap-linecheck-quirk;
status = "disabled";
};
};
-- 
2.0.0




[PATCH v2 2/2] arm64: dts: rockchip: enable usb3 for RK3328 evaluation board

2017-08-17 Thread William Wu
Rockchip's RK3328 evaluation board has one USB 3.0 OTG controller,
we enable it and set it act as static xHCI host controller to
support USB 3.0 HOST on RK3328 evaluation board.

Signed-off-by: William Wu 
---
Changes in v2:
- None

 arch/arm64/boot/dts/rockchip/rk3328-evb.dts | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts 
b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
index e7db0dc..fedea73 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
@@ -83,3 +83,12 @@
 &usb_host0_ohci {
status = "okay";
 };
+
+&usbdrd3 {
+   status = "okay";
+};
+
+&usbdrd_dwc3 {
+   dr_mode = "host";
+   status = "okay";
+};
-- 
2.0.0




[PATCH v2 0/2] Add usb3 ctrl node on RK3328 SoCs and enable usb3 host on RK3328 evb

2017-08-17 Thread William Wu
This series add support for usb3 controller on RK3328 SoCs.
This series don't include usb3 phy patches, and I will try
to submit usb3 phy patches individually later.

Tested on RK3328 evaluation board.

William Wu (2):
  arm64: dts: rockchip: add usb3 controller node for RK3328 SoCs
  arm64: dts: rockchip: enable usb3 for RK3328 evaluation board

 .../devicetree/bindings/usb/rockchip,dwc3.txt  |  4 +++-
 arch/arm64/boot/dts/rockchip/rk3328-evb.dts|  9 
 arch/arm64/boot/dts/rockchip/rk3328.dtsi   | 27 ++
 3 files changed, 39 insertions(+), 1 deletion(-)

-- 
2.0.0




[PATCH v2 1/2] arm64: dts: rockchip: add usb3 controller node for RK3328 SoCs

2017-08-17 Thread William Wu
RK3328 has one USB 3.0 OTG controller which uses DWC_USB3
core's general architecture. It can act as static xHCI host
controller, static device controller, USB 3.0/2.0 OTG basing
on ID of USB3.0 PHY.

Signed-off-by: William Wu 
---
Changes in v2:
- Modify the dwc3 quirk "snps,tx-ipgap-linecheck-dis-quirk" to
  "snps,dis-tx-ipgap-linecheck-quirk"

 .../devicetree/bindings/usb/rockchip,dwc3.txt  |  4 +++-
 arch/arm64/boot/dts/rockchip/rk3328.dtsi   | 27 ++
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt 
b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
index 0536a93..d6b2e47 100644
--- a/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
@@ -1,7 +1,9 @@
 Rockchip SuperSpeed DWC3 USB SoC controller
 
 Required properties:
-- compatible:  should contain "rockchip,rk3399-dwc3" for rk3399 SoC
+- compatible:  should be one of the following:
+  - "rockchip,rk3399-dwc3": for rk3399 SoC
+  - "rockchip,rk3328-dwc3", "rockchip,rk3399-dwc3": for rk3328 SoC
 - clocks:  A list of phandle + clock-specifier pairs for the
clocks listed in clock-names
 - clock-names: Should contain the following:
diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index e6da0ce..14bd8f4 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -655,6 +655,33 @@
status = "disabled";
};
 
+   usbdrd3: usb@ff60 {
+   compatible = "rockchip,rk3328-dwc3", "rockchip,rk3399-dwc3";
+   clocks = <&cru SCLK_USB3OTG_REF>, <&cru SCLK_USB3OTG_SUSPEND>,
+<&cru ACLK_USB3OTG>;
+   clock-names = "ref_clk", "suspend_clk",
+ "bus_clk";
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges;
+   status = "disabled";
+
+   usbdrd_dwc3: dwc3@ff60 {
+   compatible = "snps,dwc3";
+   reg = <0x0 0xff60 0x0 0x10>;
+   interrupts = ;
+   dr_mode = "otg";
+   phy_type = "utmi_wide";
+   snps,dis_enblslpm_quirk;
+   snps,dis-u2-freeclk-exists-quirk;
+   snps,dis_u2_susphy_quirk;
+   snps,dis_u3_susphy_quirk;
+   snps,dis-del-phy-power-chg-quirk;
+   snps,dis-tx-ipgap-linecheck-quirk;
+   status = "disabled";
+   };
+   };
+
gic: interrupt-controller@ff811000 {
compatible = "arm,gic-400";
#interrupt-cells = <3>;
-- 
2.0.0




[PATCH 2/2] arm64: dts: rockchip: enable usb3 for RK3328 evaluation board

2017-08-17 Thread William Wu
Rockchip's RK3328 evaluation board has one USB 3.0 OTG controller,
we enable it and set it act as static xHCI host controller to
support USB 3.0 HOST on RK3328 evaluation board.

Signed-off-by: William Wu 
---
 arch/arm64/boot/dts/rockchip/rk3328-evb.dts | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts 
b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
index e7db0dc..fedea73 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
@@ -83,3 +83,12 @@
 &usb_host0_ohci {
status = "okay";
 };
+
+&usbdrd3 {
+   status = "okay";
+};
+
+&usbdrd_dwc3 {
+   dr_mode = "host";
+   status = "okay";
+};
-- 
2.0.0




[PATCH 0/2] Add usb3 ctrl node on RK3328 SoCs and enable usb3 host on RK3328 evb

2017-08-17 Thread William Wu
This series add support for usb3 controller on RK3328 SoCs.
This series don't include usb3 phy patches, and I will try
to submit usb3 phy patches individually later.
Tested on RK3328 evaluation board.

William Wu (2):
  arm64: dts: rockchip: add usb3 controller node for RK3328 SoCs
  arm64: dts: rockchip: enable usb3 for RK3328 evaluation board

 .../devicetree/bindings/usb/rockchip,dwc3.txt  |  4 +++-
 arch/arm64/boot/dts/rockchip/rk3328-evb.dts|  9 
 arch/arm64/boot/dts/rockchip/rk3328.dtsi   | 27 ++
 3 files changed, 39 insertions(+), 1 deletion(-)

-- 
2.0.0




[PATCH 1/2] arm64: dts: rockchip: add usb3 controller node for RK3328 SoCs

2017-08-17 Thread William Wu
RK3328 has one USB 3.0 OTG controller which uses DWC_USB3
core's general architecture. It can act as static xHCI host
controller, static device controller, USB 3.0/2.0 OTG basing
on ID of USB3.0 PHY.

Signed-off-by: William Wu 
---
 .../devicetree/bindings/usb/rockchip,dwc3.txt  |  4 +++-
 arch/arm64/boot/dts/rockchip/rk3328.dtsi   | 27 ++
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt 
b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
index 0536a93..d6b2e47 100644
--- a/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
@@ -1,7 +1,9 @@
 Rockchip SuperSpeed DWC3 USB SoC controller
 
 Required properties:
-- compatible:  should contain "rockchip,rk3399-dwc3" for rk3399 SoC
+- compatible:  should be one of the following:
+  - "rockchip,rk3399-dwc3": for rk3399 SoC
+  - "rockchip,rk3328-dwc3", "rockchip,rk3399-dwc3": for rk3328 SoC
 - clocks:  A list of phandle + clock-specifier pairs for the
clocks listed in clock-names
 - clock-names: Should contain the following:
diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index e6da0ce..4b4953b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -655,6 +655,33 @@
status = "disabled";
};
 
+   usbdrd3: usb@ff60 {
+   compatible = "rockchip,rk3328-dwc3", "rockchip,rk3399-dwc3";
+   clocks = <&cru SCLK_USB3OTG_REF>, <&cru SCLK_USB3OTG_SUSPEND>,
+<&cru ACLK_USB3OTG>;
+   clock-names = "ref_clk", "suspend_clk",
+ "bus_clk";
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges;
+   status = "disabled";
+
+   usbdrd_dwc3: dwc3@ff60 {
+   compatible = "snps,dwc3";
+   reg = <0x0 0xff60 0x0 0x10>;
+   interrupts = ;
+   dr_mode = "otg";
+   phy_type = "utmi_wide";
+   snps,dis_enblslpm_quirk;
+   snps,dis-u2-freeclk-exists-quirk;
+   snps,dis_u2_susphy_quirk;
+   snps,dis_u3_susphy_quirk;
+   snps,dis-del-phy-power-chg-quirk;
+   snps,tx-ipgap-linecheck-dis-quirk;
+   status = "disabled";
+   };
+   };
+
gic: interrupt-controller@ff811000 {
compatible = "arm,gic-400";
#interrupt-cells = <3>;
-- 
2.0.0




[PATCH v2 2/2] arm64: dts: rockchip: enable usb2 for RK3328 evaluation board

2017-06-16 Thread William Wu
Rockchip's RK3328 evaluation board has one usb2 otg controller
and one usb2 host controller which consist of EHCI and OHCI.
Each usb controller connects with one usb2 phy port through
UTMI+ interface. Let's enable them to support usb2 on RK3328
evaluation board.

Signed-off-by: William Wu 
---
Changes in v2:
- None

 arch/arm64/boot/dts/rockchip/rk3328-evb.dts | 25 +
 1 file changed, 25 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts 
b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
index cf27239..da02bb7 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
@@ -55,3 +55,28 @@
 &uart2 {
status = "okay";
 };
+
+&u2phy {
+   status = "okay";
+
+   u2phy_otg: otg-port {
+   status = "okay";
+   };
+
+   u2phy_host: host-port {
+   status = "okay";
+   };
+
+};
+
+&usb20_otg {
+   status = "okay";
+};
+
+&usb_host0_ehci {
+   status = "okay";
+};
+
+&usb_host0_ohci {
+   status = "okay";
+};
-- 
2.0.0




[PATCH v2 1/2] arm64: dts: rockchip: add usb2 nodes for RK3328 SoCs

2017-06-16 Thread William Wu
This patch adds usb2 otg/host controllers and phys nodes
for Rockchip RK3328 SoCs.

Signed-off-by: William Wu 
---
Changes in v2:
- set usb2 otg dr_mode as "otg"

 arch/arm64/boot/dts/rockchip/rk3328.dtsi | 76 
 1 file changed, 76 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index 0be96ce..05ea8f3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -372,6 +372,43 @@
<32768>;
};
 
+   usb2phy_grf: syscon@ff45 {
+   compatible = "rockchip,rk3328-usb2phy-grf", "syscon",
+"simple-mfd";
+   reg = <0x0 0xff45 0x0 0x1>;
+   #address-cells = <1>;
+   #size-cells = <1>;
+
+   u2phy: usb2-phy@100 {
+   compatible = "rockchip,rk3328-usb2phy";
+   reg = <0x100 0x10>;
+   clocks = <&xin24m>;
+   clock-names = "phyclk";
+   #clock-cells = <0>;
+   assigned-clocks = <&cru USB480M>;
+   assigned-clock-parents = <&u2phy>;
+   clock-output-names = "usb480m_phy";
+   status = "disabled";
+
+   u2phy_otg: otg-port {
+   #phy-cells = <0>;
+   interrupts = ,
+,
+;
+   interrupt-names = "otg-bvalid", "otg-id",
+ "linestate";
+   status = "disabled";
+   };
+
+   u2phy_host: host-port {
+   #phy-cells = <0>;
+   interrupts = ;
+   interrupt-names = "linestate";
+   status = "disabled";
+   };
+   };
+   };
+
sdmmc: dwmmc@ff50 {
compatible = "rockchip,rk3328-dw-mshc", 
"rockchip,rk3288-dw-mshc";
reg = <0x0 0xff50 0x0 0x4000>;
@@ -424,6 +461,45 @@
status = "disabled";
};
 
+   usb20_otg: usb@ff58 {
+   compatible = "rockchip,rk3328-usb", "rockchip,rk3066-usb",
+"snps,dwc2";
+   reg = <0x0 0xff58 0x0 0x4>;
+   interrupts = ;
+   clocks = <&cru HCLK_OTG>;
+   clock-names = "otg";
+   dr_mode = "otg";
+   g-np-tx-fifo-size = <16>;
+   g-rx-fifo-size = <280>;
+   g-tx-fifo-size = <256 128 128 64 32 16>;
+   g-use-dma;
+   phys = <&u2phy_otg>;
+   phy-names = "usb2-phy";
+   status = "disabled";
+   };
+
+   usb_host0_ehci: usb@ff5c {
+   compatible = "generic-ehci";
+   reg = <0x0 0xff5c 0x0 0x1>;
+   interrupts = ;
+   clocks = <&cru HCLK_HOST0>, <&u2phy>;
+   clock-names = "usbhost", "utmi";
+   phys = <&u2phy_host>;
+   phy-names = "usb";
+   status = "disabled";
+   };
+
+   usb_host0_ohci: usb@ff5d {
+   compatible = "generic-ohci";
+   reg = <0x0 0xff5d 0x0 0x1>;
+   interrupts = ;
+   clocks = <&cru HCLK_HOST0>, <&u2phy>;
+   clock-names = "usbhost", "utmi";
+   phys = <&u2phy_host>;
+   phy-names = "usb";
+   status = "disabled";
+   };
+
gic: interrupt-controller@ff811000 {
compatible = "arm,gic-400";
#interrupt-cells = <3>;
-- 
2.0.0




[PATCH v2 0/2] Add usb2 nodes on RK3328 SoCs and enable usb2 on RK3328 evb

2017-06-16 Thread William Wu
This series adds support for usb2 on RK3328 SoCs.
Tested on RK3328 evaluation board.

William Wu (2):
  arm64: dts: rockchip: add usb2 nodes for RK3328 SoCs
  arm64: dts: rockchip: enable usb2 for RK3328 evaluation board

 arch/arm64/boot/dts/rockchip/rk3328-evb.dts | 25 ++
 arch/arm64/boot/dts/rockchip/rk3328.dtsi| 76 +
 2 files changed, 101 insertions(+)

-- 
2.0.0




[PATCH 2/2] arm64: dts: rockchip: enable usb2 for RK3328 evaluation board

2017-06-16 Thread William Wu
Rockchip's RK3328 evaluation board has one usb2 otg controller
and one usb2 host controller which consist of EHCI and OHCI.
Each usb controller connects with one usb2 phy port through
UTMI+ interface. Let's enable them to support usb2 on RK3328
evaluation board.

Signed-off-by: William Wu 
---
 arch/arm64/boot/dts/rockchip/rk3328-evb.dts | 25 +
 1 file changed, 25 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts 
b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
index cf27239..da02bb7 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
@@ -55,3 +55,28 @@
 &uart2 {
status = "okay";
 };
+
+&u2phy {
+   status = "okay";
+
+   u2phy_otg: otg-port {
+   status = "okay";
+   };
+
+   u2phy_host: host-port {
+   status = "okay";
+   };
+
+};
+
+&usb20_otg {
+   status = "okay";
+};
+
+&usb_host0_ehci {
+   status = "okay";
+};
+
+&usb_host0_ohci {
+   status = "okay";
+};
-- 
2.0.0




[PATCH 1/2] arm64: dts: rockchip: add usb2 nodes for RK3328 SoCs

2017-06-16 Thread William Wu
This patch adds usb2 otg/host controllers and phys nodes
for Rockchip RK3328 SoCs.

Signed-off-by: William Wu 
---
 arch/arm64/boot/dts/rockchip/rk3328.dtsi | 76 
 1 file changed, 76 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index 0be96ce..c55edb4 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -372,6 +372,43 @@
<32768>;
};
 
+   usb2phy_grf: syscon@ff45 {
+   compatible = "rockchip,rk3328-usb2phy-grf", "syscon",
+"simple-mfd";
+   reg = <0x0 0xff45 0x0 0x1>;
+   #address-cells = <1>;
+   #size-cells = <1>;
+
+   u2phy: usb2-phy@100 {
+   compatible = "rockchip,rk3328-usb2phy";
+   reg = <0x100 0x10>;
+   clocks = <&xin24m>;
+   clock-names = "phyclk";
+   #clock-cells = <0>;
+   assigned-clocks = <&cru USB480M>;
+   assigned-clock-parents = <&u2phy>;
+   clock-output-names = "usb480m_phy";
+   status = "disabled";
+
+   u2phy_otg: otg-port {
+   #phy-cells = <0>;
+   interrupts = ,
+,
+;
+   interrupt-names = "otg-bvalid", "otg-id",
+ "linestate";
+   status = "disabled";
+   };
+
+   u2phy_host: host-port {
+   #phy-cells = <0>;
+   interrupts = ;
+   interrupt-names = "linestate";
+   status = "disabled";
+   };
+   };
+   };
+
sdmmc: dwmmc@ff50 {
compatible = "rockchip,rk3328-dw-mshc", 
"rockchip,rk3288-dw-mshc";
reg = <0x0 0xff50 0x0 0x4000>;
@@ -424,6 +461,45 @@
status = "disabled";
};
 
+   usb20_otg: usb@ff58 {
+   compatible = "rockchip,rk3328-usb", "rockchip,rk3066-usb",
+"snps,dwc2";
+   reg = <0x0 0xff58 0x0 0x4>;
+   interrupts = ;
+   clocks = <&cru HCLK_OTG>;
+   clock-names = "otg";
+   dr_mode = "host";
+   g-np-tx-fifo-size = <16>;
+   g-rx-fifo-size = <280>;
+   g-tx-fifo-size = <256 128 128 64 32 16>;
+   g-use-dma;
+   phys = <&u2phy_otg>;
+   phy-names = "usb2-phy";
+   status = "disabled";
+   };
+
+   usb_host0_ehci: usb@ff5c {
+   compatible = "generic-ehci";
+   reg = <0x0 0xff5c 0x0 0x1>;
+   interrupts = ;
+   clocks = <&cru HCLK_HOST0>, <&u2phy>;
+   clock-names = "usbhost", "utmi";
+   phys = <&u2phy_host>;
+   phy-names = "usb";
+   status = "disabled";
+   };
+
+   usb_host0_ohci: usb@ff5d {
+   compatible = "generic-ohci";
+   reg = <0x0 0xff5d 0x0 0x1>;
+   interrupts = ;
+   clocks = <&cru HCLK_HOST0>, <&u2phy>;
+   clock-names = "usbhost", "utmi";
+   phys = <&u2phy_host>;
+   phy-names = "usb";
+   status = "disabled";
+   };
+
gic: interrupt-controller@ff811000 {
compatible = "arm,gic-400";
#interrupt-cells = <3>;
-- 
2.0.0




[PATCH 0/2] Add usb2 nodes on RK3328 SoCs and enable usb2 on RK3328 evb

2017-06-16 Thread William Wu
This series adds support for usb2 on RK3328 SoCs.
Tested on RK3328 evaluation board.

William Wu (2):
  arm64: dts: rockchip: add usb2 nodes for RK3328 SoCs
  arm64: dts: rockchip: enable usb2 for RK3328 evaluation board

 arch/arm64/boot/dts/rockchip/rk3328-evb.dts | 25 ++
 arch/arm64/boot/dts/rockchip/rk3328.dtsi| 76 +
 2 files changed, 101 insertions(+)

-- 
2.0.0




[PATCH v2 1/2] ARM: dts: rockchip: add usb nodes on rk322x

2017-06-02 Thread William Wu
This patch adds usb otg/host controllers and phys nodes on rk322x.

Signed-off-by: William Wu 
---
 arch/arm/boot/dts/rk322x.dtsi | 138 +-
 1 file changed, 137 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
index df57413..1e0ee4a 100644
--- a/arch/arm/boot/dts/rk322x.dtsi
+++ b/arch/arm/boot/dts/rk322x.dtsi
@@ -210,8 +210,61 @@
};
 
grf: syscon@1100 {
-   compatible = "syscon";
+   compatible = "syscon", "simple-mfd";
reg = <0x1100 0x1000>;
+   #address-cells = <1>;
+   #size-cells = <1>;
+
+   u2phy0: usb2-phy@760 {
+   compatible = "rockchip,rk3228-usb2phy";
+   reg = <0x0760 0x0c>;
+   clocks = <&cru SCLK_OTGPHY0>;
+   clock-names = "phyclk";
+   #clock-cells = <0>;
+   clock-output-names = "usb480m_phy0";
+   status = "disabled";
+
+   u2phy0_otg: otg-port {
+   #phy-cells = <0>;
+   interrupts = ,
+,
+;
+   interrupt-names = "otg-bvalid", "otg-id",
+ "linestate";
+   status = "disabled";
+   };
+
+   u2phy0_host: host-port {
+   #phy-cells = <0>;
+   interrupts = ;
+   interrupt-names = "linestate";
+   status = "disabled";
+   };
+   };
+
+   u2phy1: usb2-phy@800 {
+   compatible = "rockchip,rk3228-usb2phy";
+   reg = <0x0800 0x0c>;
+   clocks = <&cru SCLK_OTGPHY1>;
+   clock-names = "phyclk";
+   #clock-cells = <0>;
+   clock-output-names = "usb480m_phy1";
+   status = "disabled";
+
+   u2phy1_otg: otg-port {
+   #phy-cells = <0>;
+   interrupts = ;
+   interrupt-names = "linestate";
+   status = "disabled";
+   };
+
+   u2phy1_host: host-port {
+   #phy-cells = <0>;
+   interrupts = ;
+   interrupt-names = "linestate";
+   status = "disabled";
+   };
+   };
};
 
uart0: serial@1101 {
@@ -467,6 +520,89 @@
status = "disabled";
};
 
+   usb_otg: usb@3004 {
+   compatible = "rockchip,rk3228-usb", "rockchip,rk3066-usb",
+"snps,dwc2";
+   reg = <0x3004 0x4>;
+   interrupts = ;
+   clocks = <&cru HCLK_OTG>;
+   clock-names = "otg";
+   dr_mode = "otg";
+   g-np-tx-fifo-size = <16>;
+   g-rx-fifo-size = <280>;
+   g-tx-fifo-size = <256 128 128 64 32 16>;
+   g-use-dma;
+   phys = <&u2phy0_otg>;
+   phy-names = "usb2-phy";
+   status = "disabled";
+   };
+
+   usb_host0_ehci: usb@3008 {
+   compatible = "generic-ehci";
+   reg = <0x3008 0x2>;
+   interrupts = ;
+   clocks = <&cru HCLK_HOST0>, <&u2phy0>;
+   clock-names = "usbhost", "utmi";
+   phys = <&u2phy0_host>;
+   phy-names = "usb";
+   status = "disabled";
+   };
+
+   usb_host0_ohci: usb@300a {
+   compatible = "generic-ohci";
+   reg = <0x300a 0x2>;
+   interrupts = ;
+   clocks = <&cru HCLK_HOST0>, <&u2phy0>;
+   clock-names = "usbhost", "utmi";
+   phys = <&u2phy0_host>;
+   phy-names = "usb";
+   status = "disabled";
+   };
+
+   usb_host1_ehci: usb@300c000

[PATCH v2 0/2] Add usb nodes on rk322x SoCs and enable usb on rk3229 evb

2017-06-02 Thread William Wu
This series adds support for usb on rk322x SoCs.

William Wu (2):
  ARM: dts: rockchip: add usb nodes on rk322x
  ARM: dts: rockchip: enable usb for rk3229 evb board

Tested on rk3229 evb board, and depended on the following
patches and config.
[1] https://patchwork.kernel.org/patch/9761507/
[2] https://patchwork.kernel.org/patch/9761511/
[3] https://patchwork.kernel.org/patch/9761515/
[4] https://patchwork.kernel.org/patch/9761519/
[5] enable CONFIG_PHY_ROCKCHIP_INNO_USB2

 arch/arm/boot/dts/rk3229-evb.dts |  74 +
 arch/arm/boot/dts/rk322x.dtsi| 138 ++-
 2 files changed, 211 insertions(+), 1 deletion(-)

-- 
2.0.0




[PATCH v2 2/2] ARM: dts: rockchip: enable usb for rk3229 evb board

2017-06-02 Thread William Wu
Rockchip's rk3229 evaluation board has one usb otg controller
and three usb host controllers. Each usb controller connect
with one usb2 phy port through UTMI+ interface. And the three
usb host interfaces use the same GPIO VBUS drive. Let's enable
them to support usb on rk3229 evb board.

Signed-off-by: William Wu 
---
 arch/arm/boot/dts/rk3229-evb.dts | 74 
 1 file changed, 74 insertions(+)

diff --git a/arch/arm/boot/dts/rk3229-evb.dts b/arch/arm/boot/dts/rk3229-evb.dts
index 275092a..1b55192 100644
--- a/arch/arm/boot/dts/rk3229-evb.dts
+++ b/arch/arm/boot/dts/rk3229-evb.dts
@@ -58,6 +58,17 @@
#clock-cells = <0>;
};
 
+   vcc_host: vcc-host-regulator {
+   compatible = "regulator-fixed";
+   enable-active-high;
+   gpio = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
+   pinctrl-names = "default";
+   pinctrl-0 = <&host_vbus_drv>;
+   regulator-name = "vcc_host";
+   regulator-always-on;
+   regulator-boot-on;
+   };
+
vcc_phy: vcc-phy-regulator {
compatible = "regulator-fixed";
enable-active-high;
@@ -85,6 +96,69 @@
status = "okay";
 };
 
+&pinctrl {
+   usb {
+   host_vbus_drv: host-vbus-drv {
+   rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+   };
+   };
+};
+
 &uart2 {
status = "okay";
 };
+
+&u2phy0 {
+   status = "okay";
+
+   u2phy0_otg: otg-port {
+   status = "okay";
+   };
+
+   u2phy0_host: host-port {
+   phy-supply = <&vcc_host>;
+   status = "okay";
+   };
+};
+
+&u2phy1 {
+   status = "okay";
+
+   u2phy1_otg: otg-port {
+   phy-supply = <&vcc_host>;
+   status = "okay";
+   };
+
+   u2phy1_host: host-port {
+   phy-supply = <&vcc_host>;
+   status = "okay";
+   };
+};
+
+&usb_host0_ehci {
+   status = "okay";
+};
+
+&usb_host0_ohci {
+   status = "okay";
+};
+
+&usb_host1_ehci {
+   status = "okay";
+};
+
+&usb_host1_ohci {
+   status = "okay";
+};
+
+&usb_host2_ehci {
+   status = "okay";
+};
+
+&usb_host2_ohci {
+   status = "okay";
+};
+
+&usb_otg {
+   status = "okay";
+};
-- 
2.0.0




[PATCH 2/2] ARM: dts: rockchip: enable usb for rk3229 evb board

2017-05-30 Thread William Wu
Rockchip's rk3229 evaluation board has one usb otg controller
and three usb host controllers. Each usb controller connect
with one usb2 phy port through UTMI+ interface. And the three
usb host interfaces use the same GPIO VBUS drive. Let's enable
them to support usb on rk3229 evb board.

Signed-off-by: William Wu 
---
 arch/arm/boot/dts/rk3229-evb.dts | 74 
 1 file changed, 74 insertions(+)

diff --git a/arch/arm/boot/dts/rk3229-evb.dts b/arch/arm/boot/dts/rk3229-evb.dts
index 275092a..1b55192 100644
--- a/arch/arm/boot/dts/rk3229-evb.dts
+++ b/arch/arm/boot/dts/rk3229-evb.dts
@@ -58,6 +58,17 @@
#clock-cells = <0>;
};
 
+   vcc_host: vcc-host-regulator {
+   compatible = "regulator-fixed";
+   enable-active-high;
+   gpio = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
+   pinctrl-names = "default";
+   pinctrl-0 = <&host_vbus_drv>;
+   regulator-name = "vcc_host";
+   regulator-always-on;
+   regulator-boot-on;
+   };
+
vcc_phy: vcc-phy-regulator {
compatible = "regulator-fixed";
enable-active-high;
@@ -85,6 +96,69 @@
status = "okay";
 };
 
+&pinctrl {
+   usb {
+   host_vbus_drv: host-vbus-drv {
+   rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+   };
+   };
+};
+
 &uart2 {
status = "okay";
 };
+
+&u2phy0 {
+   status = "okay";
+
+   u2phy0_otg: otg-port {
+   status = "okay";
+   };
+
+   u2phy0_host: host-port {
+   phy-supply = <&vcc_host>;
+   status = "okay";
+   };
+};
+
+&u2phy1 {
+   status = "okay";
+
+   u2phy1_otg: otg-port {
+   phy-supply = <&vcc_host>;
+   status = "okay";
+   };
+
+   u2phy1_host: host-port {
+   phy-supply = <&vcc_host>;
+   status = "okay";
+   };
+};
+
+&usb_host0_ehci {
+   status = "okay";
+};
+
+&usb_host0_ohci {
+   status = "okay";
+};
+
+&usb_host1_ehci {
+   status = "okay";
+};
+
+&usb_host1_ohci {
+   status = "okay";
+};
+
+&usb_host2_ehci {
+   status = "okay";
+};
+
+&usb_host2_ohci {
+   status = "okay";
+};
+
+&usb_otg {
+   status = "okay";
+};
-- 
2.0.0




[PATCH 1/2] ARM: dts: rockchip: add usb nodes on rk322x

2017-05-30 Thread William Wu
This patch adds usb otg/host controllers and phys nodes on rk322x.

Signed-off-by: William Wu 
---
 arch/arm/boot/dts/rk322x.dtsi | 138 +-
 1 file changed, 137 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
index df57413..d4bfd3c 100644
--- a/arch/arm/boot/dts/rk322x.dtsi
+++ b/arch/arm/boot/dts/rk322x.dtsi
@@ -210,8 +210,61 @@
};
 
grf: syscon@1100 {
-   compatible = "syscon";
+   compatible = "syscon", "simple-mfd";
reg = <0x1100 0x1000>;
+   #address-cells = <1>;
+   #size-cells = <1>;
+
+   u2phy0: usb2-phy@760 {
+   compatible = "rockchip,rk322x-usb2phy";
+   reg = <0x0760 0x0c>;
+   clocks = <&cru SCLK_OTGPHY0>;
+   clock-names = "phyclk";
+   #clock-cells = <0>;
+   clock-output-names = "usb480m_phy0";
+   status = "disabled";
+
+   u2phy0_otg: otg-port {
+   #phy-cells = <0>;
+   interrupts = ,
+,
+;
+   interrupt-names = "otg-bvalid", "otg-id",
+ "linestate";
+   status = "disabled";
+   };
+
+   u2phy0_host: host-port {
+   #phy-cells = <0>;
+   interrupts = ;
+   interrupt-names = "linestate";
+   status = "disabled";
+   };
+   };
+
+   u2phy1: usb2-phy@800 {
+   compatible = "rockchip,rk322x-usb2phy";
+   reg = <0x0800 0x0c>;
+   clocks = <&cru SCLK_OTGPHY1>;
+   clock-names = "phyclk";
+   #clock-cells = <0>;
+   clock-output-names = "usb480m_phy1";
+   status = "disabled";
+
+   u2phy1_otg: otg-port {
+   #phy-cells = <0>;
+   interrupts = ;
+   interrupt-names = "linestate";
+   status = "disabled";
+   };
+
+   u2phy1_host: host-port {
+   #phy-cells = <0>;
+   interrupts = ;
+   interrupt-names = "linestate";
+   status = "disabled";
+   };
+   };
};
 
uart0: serial@1101 {
@@ -467,6 +520,89 @@
status = "disabled";
};
 
+   usb_otg: usb@3004 {
+   compatible = "rockchip,rk322x-usb", "rockchip,rk3066-usb",
+"snps,dwc2";
+   reg = <0x3004 0x4>;
+   interrupts = ;
+   clocks = <&cru HCLK_OTG>;
+   clock-names = "otg";
+   dr_mode = "otg";
+   g-np-tx-fifo-size = <16>;
+   g-rx-fifo-size = <280>;
+   g-tx-fifo-size = <256 128 128 64 32 16>;
+   g-use-dma;
+   phys = <&u2phy0_otg>;
+   phy-names = "usb2-phy";
+   status = "disabled";
+   };
+
+   usb_host0_ehci: usb@3008 {
+   compatible = "generic-ehci";
+   reg = <0x3008 0x2>;
+   interrupts = ;
+   clocks = <&cru HCLK_HOST0>, <&u2phy0>;
+   clock-names = "usbhost", "utmi";
+   phys = <&u2phy0_host>;
+   phy-names = "usb";
+   status = "disabled";
+   };
+
+   usb_host0_ohci: usb@300a {
+   compatible = "generic-ohci";
+   reg = <0x300a 0x2>;
+   interrupts = ;
+   clocks = <&cru HCLK_HOST0>, <&u2phy0>;
+   clock-names = "usbhost", "utmi";
+   phys = <&u2phy0_host>;
+   phy-names = "usb";
+   status = "disabled";
+   };
+
+   usb_host1_ehci: usb@300c000

[PATCH 0/2] Add usb nodes on rk322x SoCs and enable usb on rk3229 evb

2017-05-30 Thread William Wu
This series adds support for usb on rk322x SoCs.

William Wu (2):
  ARM: dts: rockchip: add usb nodes on rk322x
  ARM: dts: rockchip: enable usb for rk3229 evb board

Tested on rk3229 evb board, and depended on the following
patches and config.
[1] https://patchwork.kernel.org/patch/9732473/
[2] https://patchwork.kernel.org/patch/9732475/
[3] https://patchwork.kernel.org/patch/9732481/
[4] https://patchwork.kernel.org/patch/9732479/  
[5] enable CONFIG_PHY_ROCKCHIP_INNO_USB2

 arch/arm/boot/dts/rk3229-evb.dts |  74 +
 arch/arm/boot/dts/rk322x.dtsi| 138 ++-
 2 files changed, 211 insertions(+), 1 deletion(-)

-- 
2.0.0




[PATCH] usb: dwc2: resume root hub to handle disconnect of device

2017-05-26 Thread William Wu
When handle disconnect of the hcd during bus_suspend, hcd
needs to resume its root hub, otherwise the root hub will
not disconnect the existing devices under its port.

This issue always happens when connecting with usb devices
which support auto-suspend function (e.g. usb hub).

Signed-off-by: William Wu 
---
 drivers/usb/dwc2/hcd.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 740c7e8..cc84f97 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -1975,11 +1975,13 @@ void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool 
force)
 * Without the extra check here we will end calling disconnect
 * and won't get any future interrupts to handle the connect.
 */
-   if (!force) {
-   hprt0 = dwc2_readl(hsotg->regs + HPRT0);
-   if (!(hprt0 & HPRT0_CONNDET) && (hprt0 & HPRT0_CONNSTS))
-   dwc2_hcd_connect(hsotg);
-   }
+   hprt0 = dwc2_readl(hsotg->regs + HPRT0);
+
+   if (!force && !(hprt0 & HPRT0_CONNDET) &&
+   (hprt0 & HPRT0_CONNSTS))
+   dwc2_hcd_connect(hsotg);
+   else if (hsotg->lx_state != DWC2_L0)
+   usb_hcd_resume_root_hub(hsotg->priv);
 }
 
 /**
-- 
2.0.0




[PATCH] usb: gadget: f_fs: avoid out of bounds access on comp_desc

2017-04-25 Thread William Wu
Companion descriptor is only used for SuperSpeed endpoints,
if the endpoints are HighSpeed or FullSpeed, the Companion
descriptor will not allocated, so we can only access it if
gadget is SuperSpeed.

I can reproduce this issue on Rockchip platform rk3368 SoC
which supports USB 2.0, and use functionfs for ADB. Kernel
build with CONFIG_KASAN=y and CONFIG_SLUB_DEBUG=y report
the following BUG:

==
BUG: KASAN: slab-out-of-bounds in ffs_func_set_alt+0x224/0x3a0 at addr 
ffc0601f6509
Read of size 1 by task swapper/0/0

BUG kmalloc-256 (Not tainted): kasan: bad access detected


Disabling lock debugging due to kernel taint
INFO: Allocated in ffs_func_bind+0x52c/0x99c age=1275 cpu=0 pid=1
alloc_debug_processing+0x128/0x17c
___slab_alloc.constprop.58+0x50c/0x610
__slab_alloc.isra.55.constprop.57+0x24/0x34
__kmalloc+0xe0/0x250
ffs_func_bind+0x52c/0x99c
usb_add_function+0xd8/0x1d4
configfs_composite_bind+0x48c/0x570
udc_bind_to_driver+0x6c/0x170
usb_udc_attach_driver+0xa4/0xd0
gadget_dev_desc_UDC_store+0xcc/0x118
configfs_write_file+0x1a0/0x1f8
__vfs_write+0x64/0x174
vfs_write+0xe4/0x200
SyS_write+0x68/0xc8
el0_svc_naked+0x24/0x28
INFO: Freed in inode_doinit_with_dentry+0x3f0/0x7c4 age=1275 cpu=7 pid=247
...
Call trace:
[] dump_backtrace+0x0/0x230
[] show_stack+0x14/0x1c
[] dump_stack+0xa0/0xc8
[] print_trailer+0x188/0x198
[] object_err+0x3c/0x4c
[] kasan_report+0x324/0x4dc
[] __asan_load1+0x24/0x50
[] ffs_func_set_alt+0x224/0x3a0
[] composite_setup+0xdcc/0x1ac8
[] android_setup+0x124/0x1a0
[] _setup+0x54/0x74
[] handle_ep0+0x3288/0x4390
[] dwc_otg_pcd_handle_out_ep_intr+0x14dc/0x2ae4
[] dwc_otg_pcd_handle_intr+0x1ec/0x298
[] dwc_otg_pcd_irq+0x10/0x20
[] handle_irq_event_percpu+0x124/0x3ac
[] handle_irq_event+0x60/0xa0
[] handle_fasteoi_irq+0x10c/0x1d4
[] generic_handle_irq+0x30/0x40
[] __handle_domain_irq+0xac/0xdc
[] gic_handle_irq+0x64/0xa4
...
Memory state around the buggy address:
  ffc0601f6400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  ffc0601f6480: 00 00 00 00 00 00 00 00 00 00 06 fc fc fc fc fc
 >ffc0601f6500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
   ^
  ffc0601f6580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
  ffc0601f6600: fc fc fc fc fc fc fc fc 00 00 00 00 00 00 00 00
==

Signed-off-by: William Wu 
---
 drivers/usb/gadget/function/f_fs.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/gadget/function/f_fs.c 
b/drivers/usb/gadget/function/f_fs.c
index db6935c..ba73f74 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -1858,12 +1858,12 @@ static int ffs_func_eps_enable(struct ffs_function 
*func)
ep->ep->driver_data = ep;
ep->ep->desc = ds;
 
-   comp_desc = (struct usb_ss_ep_comp_descriptor *)(ds +
-   USB_DT_ENDPOINT_SIZE);
-   ep->ep->maxburst = comp_desc->bMaxBurst + 1;
-
-   if (needs_comp_desc)
+   if (needs_comp_desc) {
+   comp_desc = (struct usb_ss_ep_comp_descriptor *)(ds +
+   USB_DT_ENDPOINT_SIZE);
+   ep->ep->maxburst = comp_desc->bMaxBurst + 1;
ep->ep->comp_desc = comp_desc;
+   }
 
ret = usb_ep_enable(ep->ep);
if (likely(!ret)) {
-- 
2.0.0




[PATCH v3] usb: dwc3: add disable u2mac linestate check quirk

2017-04-19 Thread William Wu
This patch adds a quirk to disable USB 2.0 MAC linestate check
during HS transmit. Refer the dwc3 databook, we can use it for
some special platforms if the linestate not reflect the expected
line state(J) during transmission.

When use this quirk, the controller implements a fixed 40-bit
TxEndDelay after the packet is given on UTMI and ignores the
linestate during the transmit of a token (during token-to-token
and token-to-data IPGAP).

On some rockchip platforms (e.g. rk3399), it requires to disable
the u2mac linestate check to decrease the SSPLIT token to SETUP
token inter-packet delay from 566ns to 466ns, and fix the issue
that FS/LS devices not recognized if inserted through USB 3.0 HUB.

Signed-off-by: William Wu 
---
Changes in v3:
- change quirk name
- only read and write GUCTL1 if dwc3 version >= 2.50a

Changes in v2:
- fix coding style

 Documentation/devicetree/bindings/usb/dwc3.txt |  2 ++
 drivers/usb/dwc3/core.c| 20 ++--
 drivers/usb/dwc3/core.h|  4 
 3 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt 
b/Documentation/devicetree/bindings/usb/dwc3.txt
index f658f39..52fb410 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -45,6 +45,8 @@ Optional properties:
a free-running PHY clock.
  - snps,dis-del-phy-power-chg-quirk: when set core will change PHY power
from P0 to P1/P2/P3 without delay.
+ - snps,dis-tx-ipgap-linecheck-quirk: when set, disable u2mac linestate check
+   during HS transmit.
  - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
utmi_l1_suspend_n, false when asserts utmi_sleep_n
  - snps,hird-threshold: HIRD threshold
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 455d89a..9d5a67c 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -796,13 +796,19 @@ static int dwc3_core_init(struct dwc3 *dwc)
dwc3_writel(dwc->regs, DWC3_GUCTL2, reg);
}
 
-   /*
-* Enable hardware control of sending remote wakeup in HS when
-* the device is in the L1 state.
-*/
-   if (dwc->revision >= DWC3_REVISION_290A) {
+   if (dwc->revision >= DWC3_REVISION_250A) {
reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
-   reg |= DWC3_GUCTL1_DEV_L1_EXIT_BY_HW;
+
+   /*
+* Enable hardware control of sending remote wakeup
+* in HS when the device is in the L1 state.
+*/
+   if (dwc->revision >= DWC3_REVISION_290A)
+   reg |= DWC3_GUCTL1_DEV_L1_EXIT_BY_HW;
+
+   if (dwc->dis_tx_ipgap_linecheck_quirk)
+   reg |= DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS;
+
dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
}
 
@@ -1023,6 +1029,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
"snps,dis-u2-freeclk-exists-quirk");
dwc->dis_del_phy_power_chg_quirk = device_property_read_bool(dev,
"snps,dis-del-phy-power-chg-quirk");
+   dwc->dis_tx_ipgap_linecheck_quirk = device_property_read_bool(dev,
+   "snps,dis-tx-ipgap-linecheck-quirk");
 
dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
"snps,tx_de_emphasis_quirk");
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 981c77f..6f6294d 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -204,6 +204,7 @@
 #define DWC3_GCTL_DSBLCLKGTNG  BIT(0)
 
 /* Global User Control 1 Register */
+#define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS BIT(28)
 #define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW  BIT(24)
 
 /* Global USB2 PHY Configuration Register */
@@ -850,6 +851,8 @@ struct dwc3_scratchpad_array {
  * provide a free-running PHY clock.
  * @dis_del_phy_power_chg_quirk: set if we disable delay phy power
  * change quirk.
+ * @dis_tx_ipgap_linecheck_quirk: set if we disable u2mac linestate
+ * check during HS transmit.
  * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
  * @tx_de_emphasis: Tx de-emphasis value
  * 0   - -6dB de-emphasis
@@ -1004,6 +1007,7 @@ struct dwc3 {
unsigneddis_rxdet_inp3_quirk:1;
unsigneddis_u2_freeclk_exists_quirk:1;
unsigneddis_del_phy_power_chg_quirk:1;
+   unsigneddis_tx_ipgap_linecheck_quirk:1;
 
unsignedtx_de_emphasis_quirk:1;
unsignedtx_de_emphasis:2;
-- 
2.0.0




[PATCH v2] usb: dwc3: add disable u2mac linestate check quirk

2017-04-17 Thread William Wu
This patch adds a quirk to disable USB 2.0 MAC linestate check
during HS transmit. Refer the dwc3 databook, we can use it for
some special platforms if the linestate not reflect the expected
line state(J) during transmission.

When use this quirk, the controller implements a fixed 40-bit
TxEndDelay after the packet is given on UTMI and ignores the
linestate during the transmit of a token (during token-to-token
and token-to-data IPGAP).

On some rockchip platforms (e.g. rk3399), it requires to disable
the u2mac linestate check to decrease the SSPLIT token to SETUP
token inter-packet delay from 566ns to 466ns, and fix the issue
that FS/LS devices not recognized if inserted through USB 3.0 HUB.

Signed-off-by: William Wu 
---
Changes in v2:
- fix coding style

 Documentation/devicetree/bindings/usb/dwc3.txt |  2 ++
 drivers/usb/dwc3/core.c| 14 ++
 drivers/usb/dwc3/core.h|  4 
 3 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt 
b/Documentation/devicetree/bindings/usb/dwc3.txt
index f658f39..6a89f0c 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -45,6 +45,8 @@ Optional properties:
a free-running PHY clock.
  - snps,dis-del-phy-power-chg-quirk: when set core will change PHY power
from P0 to P1/P2/P3 without delay.
+ - snps,tx-ipgap-linecheck-dis-quirk: when set, disable u2mac linestate check
+   during HS transmit.
  - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
utmi_l1_suspend_n, false when asserts utmi_sleep_n
  - snps,hird-threshold: HIRD threshold
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 455d89a..03429c5 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -796,15 +796,19 @@ static int dwc3_core_init(struct dwc3 *dwc)
dwc3_writel(dwc->regs, DWC3_GUCTL2, reg);
}
 
+   reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
+
/*
 * Enable hardware control of sending remote wakeup in HS when
 * the device is in the L1 state.
 */
-   if (dwc->revision >= DWC3_REVISION_290A) {
-   reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
+   if (dwc->revision >= DWC3_REVISION_290A)
reg |= DWC3_GUCTL1_DEV_L1_EXIT_BY_HW;
-   dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
-   }
+
+   if (dwc->tx_ipgap_linecheck_dis_quirk)
+   reg |= DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS;
+
+   dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
 
return 0;
 
@@ -1023,6 +1027,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
"snps,dis-u2-freeclk-exists-quirk");
dwc->dis_del_phy_power_chg_quirk = device_property_read_bool(dev,
"snps,dis-del-phy-power-chg-quirk");
+   dwc->tx_ipgap_linecheck_dis_quirk = device_property_read_bool(dev,
+   "snps,tx-ipgap-linecheck-dis-quirk");
 
dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
"snps,tx_de_emphasis_quirk");
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 981c77f..3c2537b 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -204,6 +204,7 @@
 #define DWC3_GCTL_DSBLCLKGTNG  BIT(0)
 
 /* Global User Control 1 Register */
+#define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS BIT(28)
 #define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW  BIT(24)
 
 /* Global USB2 PHY Configuration Register */
@@ -850,6 +851,8 @@ struct dwc3_scratchpad_array {
  * provide a free-running PHY clock.
  * @dis_del_phy_power_chg_quirk: set if we disable delay phy power
  * change quirk.
+ * @tx_ipgap_linecheck_dis_quirk: set if we disable u2mac linestate
+ * check during HS transmit.
  * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
  * @tx_de_emphasis: Tx de-emphasis value
  * 0   - -6dB de-emphasis
@@ -1004,6 +1007,7 @@ struct dwc3 {
unsigneddis_rxdet_inp3_quirk:1;
unsigneddis_u2_freeclk_exists_quirk:1;
unsigneddis_del_phy_power_chg_quirk:1;
+   unsignedtx_ipgap_linecheck_dis_quirk:1;
 
unsignedtx_de_emphasis_quirk:1;
unsignedtx_de_emphasis:2;
-- 
2.0.0




[PATCH] usb: dwc3: add disable u2mac linestate check quirk

2017-04-17 Thread William Wu
This patch adds a quirk to disable USB 2.0 MAC linestate check
during HS transmit. Refer the dwc3 databook, we can use it for
some special platforms if the linestate not reflect the expected
line state(J) during transmission.

When use this quirk, the controller implements a fixed 40-bit
TxEndDelay after the packet is given on UTMI and ignores the
linestate during the transmit of a token (during token-to-token
and token-to-data IPGAP).

On some rockchip platforms (e.g. rk3399), it requires to disable
the u2mac linestate check to decrease the SSPLIT token to SETUP
token inter-packet delay from 566ns to 466ns, and fix the issue
that FS/LS devices not recognized if inserted through USB 3.0 HUB.

Signed-off-by: William Wu 
---
 Documentation/devicetree/bindings/usb/dwc3.txt |  2 ++
 drivers/usb/dwc3/core.c| 14 ++
 drivers/usb/dwc3/core.h|  4 
 3 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt 
b/Documentation/devicetree/bindings/usb/dwc3.txt
index f658f39..6a89f0c 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -45,6 +45,8 @@ Optional properties:
a free-running PHY clock.
  - snps,dis-del-phy-power-chg-quirk: when set core will change PHY power
from P0 to P1/P2/P3 without delay.
+ - snps,tx-ipgap-linecheck-dis-quirk: when set, disable u2mac linestate check
+   during HS transmit.
  - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
utmi_l1_suspend_n, false when asserts utmi_sleep_n
  - snps,hird-threshold: HIRD threshold
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 455d89a..22e0c35 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -796,15 +796,19 @@ static int dwc3_core_init(struct dwc3 *dwc)
dwc3_writel(dwc->regs, DWC3_GUCTL2, reg);
}
 
+   reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
+
/*
 * Enable hardware control of sending remote wakeup in HS when
 * the device is in the L1 state.
 */
-   if (dwc->revision >= DWC3_REVISION_290A) {
-   reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
+   if (dwc->revision >= DWC3_REVISION_290A)
reg |= DWC3_GUCTL1_DEV_L1_EXIT_BY_HW;
-   dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
-   }
+
+   if (dwc->tx_ipgap_linecheck_dis_quirk)
+   reg |= DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS;
+
+   dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
 
return 0;
 
@@ -1023,6 +1027,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
"snps,dis-u2-freeclk-exists-quirk");
dwc->dis_del_phy_power_chg_quirk = device_property_read_bool(dev,
"snps,dis-del-phy-power-chg-quirk");
+dwc->tx_ipgap_linecheck_dis_quirk = device_property_read_bool(dev,
+   "snps,tx-ipgap-linecheck-dis-quirk");
 
dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
"snps,tx_de_emphasis_quirk");
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 981c77f..3c2537b 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -204,6 +204,7 @@
 #define DWC3_GCTL_DSBLCLKGTNG  BIT(0)
 
 /* Global User Control 1 Register */
+#define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS BIT(28)
 #define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW  BIT(24)
 
 /* Global USB2 PHY Configuration Register */
@@ -850,6 +851,8 @@ struct dwc3_scratchpad_array {
  * provide a free-running PHY clock.
  * @dis_del_phy_power_chg_quirk: set if we disable delay phy power
  * change quirk.
+ * @tx_ipgap_linecheck_dis_quirk: set if we disable u2mac linestate
+ * check during HS transmit.
  * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
  * @tx_de_emphasis: Tx de-emphasis value
  * 0   - -6dB de-emphasis
@@ -1004,6 +1007,7 @@ struct dwc3 {
unsigneddis_rxdet_inp3_quirk:1;
unsigneddis_u2_freeclk_exists_quirk:1;
unsigneddis_del_phy_power_chg_quirk:1;
+   unsignedtx_ipgap_linecheck_dis_quirk:1;
 
unsignedtx_de_emphasis_quirk:1;
unsignedtx_de_emphasis:2;
-- 
2.0.0




[PATCH v2] usb: host: xhci: plat: check hcc_params after add hcd

2017-01-16 Thread William Wu
From: William wu 

The commit 4ac53087d6d4 ("usb: xhci: plat: Create both
HCDs before adding them") move add hcd to the end of
probe, this cause hcc_params uninitiated, because xHCI
driver sets hcc_params in xhci_gen_setup() called from
usb_add_hcd().

This patch checks the Maximum Primary Stream Array Size
in the hcc_params register after add primary hcd.

Signed-off-by: William wu 
---
 drivers/usb/host/xhci-plat.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index ddfab30..f96caeb 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -232,9 +232,6 @@ static int xhci_plat_probe(struct platform_device *pdev)
if (device_property_read_bool(&pdev->dev, "usb3-lpm-capable"))
xhci->quirks |= XHCI_LPM_SUPPORT;
 
-   if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
-   xhci->shared_hcd->can_do_streams = 1;
-
hcd->usb_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
if (IS_ERR(hcd->usb_phy)) {
ret = PTR_ERR(hcd->usb_phy);
@@ -251,6 +248,9 @@ static int xhci_plat_probe(struct platform_device *pdev)
if (ret)
goto disable_usb_phy;
 
+   if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
+   xhci->shared_hcd->can_do_streams = 1;
+
ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
if (ret)
goto dealloc_usb2_hcd;
-- 
2.7.4




[PATCH] usb: host: xhci: plat: check hcc_params after add hcd

2017-01-12 Thread William Wu
From: William wu 

The commit 4ac53087d6d4 ("usb: xhci: plat: Create both
HCDs before adding them") move add hcd to the end of
probe, this cause hcc_params uninitiated, because xHCI
driver sets hcc_params in xhci_gen_setup() called from
usb_add_hcd().

This patch checks the Maximum Primary Stream Array Size
in the hcc_params register after add hcd.

Signed-off-by: William wu 
---
 drivers/usb/host/xhci-plat.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index ddfab30..52ce697 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -232,9 +232,6 @@ static int xhci_plat_probe(struct platform_device *pdev)
if (device_property_read_bool(&pdev->dev, "usb3-lpm-capable"))
xhci->quirks |= XHCI_LPM_SUPPORT;
 
-   if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
-   xhci->shared_hcd->can_do_streams = 1;
-
hcd->usb_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
if (IS_ERR(hcd->usb_phy)) {
ret = PTR_ERR(hcd->usb_phy);
@@ -255,6 +252,9 @@ static int xhci_plat_probe(struct platform_device *pdev)
if (ret)
goto dealloc_usb2_hcd;
 
+   if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
+   xhci->shared_hcd->can_do_streams = 1;
+
return 0;
 
 
-- 
2.7.4




[RESEND PATCH] usb: hcd: initialize hcd->flags to 0 when rm hcd

2017-01-12 Thread William Wu
From: William wu 

On some platforms(e.g. rk3399 board), we can call hcd_add/remove
consecutively without calling usb_put_hcd/usb_create_hcd in between,
so hcd->flags can be stale.

If the HC dies due to whatever reason then without this patch we get
the below error on next hcd_add.

[173.296154] xhci-hcd xhci-hcd.2.auto: HC died; cleaning up
[173.296209] xhci-hcd xhci-hcd.2.auto: xHCI Host Controller
[173.296762] xhci-hcd xhci-hcd.2.auto: new USB bus registered, assigned bus 
number 6
[173.296931] usb usb6: We don't know the algorithms for LPM for this host, 
disabling LPM.
[173.297179] usb usb6: New USB device found, idVendor=1d6b, idProduct=0003
[173.297203] usb usb6: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[173.297222] usb usb6: Product: xHCI Host Controller
[173.297240] usb usb6: Manufacturer: Linux 4.4.21 xhci-hcd
[173.297257] usb usb6: SerialNumber: xhci-hcd.2.auto
[173.298680] hub 6-0:1.0: USB hub found
[173.298749] hub 6-0:1.0: 1 port detected
[173.299382] rockchip-dwc3 usb@fe80: USB HOST connected
[173.395418] hub 5-0:1.0: activate --> -19
[173.603447] irq 228: nobody cared (try booting with the "irqpoll" option)
[173.603493] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.4.21 #9
[173.603513] Hardware name: Google Kevin (DT)
[173.603531] Call trace:
[173.603568] [] dump_backtrace+0x0/0x160
[173.603596] [] show_stack+0x20/0x28
[173.603623] [] dump_stack+0x90/0xb0
[173.603650] [] __report_bad_irq+0x48/0xe8
[173.603674] [] note_interrupt+0x1e8/0x28c
[173.603698] [] handle_irq_event_percpu+0x1d4/0x25c
[173.603722] [] handle_irq_event+0x4c/0x7c
[173.603748] [] handle_fasteoi_irq+0xb4/0x124
[173.603777] [] generic_handle_irq+0x30/0x44
[173.603804] [] __handle_domain_irq+0x90/0xbc
[173.603827] [] gic_handle_irq+0xcc/0x188
...
[173.604500] [] el1_irq+0x80/0xf8
[173.604530] [] cpu_startup_entry+0x38/0x3cc
[173.604558] [] rest_init+0x8c/0x94
[173.604585] [] start_kernel+0x3d0/0x3fc
[173.604607] [<00b16000>] 0xb16000
[173.604622] handlers:
[173.604648] [] usb_hcd_irq
[173.604673] Disabling IRQ #228

Signed-off-by: William wu 
Acked-by: Roger Quadros 
---
 drivers/usb/core/hcd.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 479e223..612fab6 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -3017,6 +3017,7 @@ void usb_remove_hcd(struct usb_hcd *hcd)
}
 
usb_put_invalidate_rhdev(hcd);
+   hcd->flags = 0;
 }
 EXPORT_SYMBOL_GPL(usb_remove_hcd);
 
-- 
2.7.4




[PATCH] usb: hcd: initialize hcd->flags to 0 when rm hcd

2017-01-12 Thread William Wu
From: William wu 

On some platforms(e.g. rk3399 board), we can call hcd_add/remove
consecutively without calling usb_put_hcd/usb_create_hcd in between,
so hcd->flags can be stale.

If the HC dies due to whatever reason then without this patch we get
the below error on next hcd_add.

[173.296154] xhci-hcd xhci-hcd.2.auto: HC died; cleaning up
[173.296209] xhci-hcd xhci-hcd.2.auto: xHCI Host Controller
[173.296762] xhci-hcd xhci-hcd.2.auto: new USB bus registered, assigned bus 
number 6
[173.296931] usb usb6: We don't know the algorithms for LPM for this host, 
disabling LPM.
[173.297179] usb usb6: New USB device found, idVendor=1d6b, idProduct=0003
[173.297203] usb usb6: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[173.297222] usb usb6: Product: xHCI Host Controller
[173.297240] usb usb6: Manufacturer: Linux 4.4.21 xhci-hcd
[173.297257] usb usb6: SerialNumber: xhci-hcd.2.auto
[173.298680] hub 6-0:1.0: USB hub found
[173.298749] hub 6-0:1.0: 1 port detected
[173.299382] rockchip-dwc3 usb@fe80: USB HOST connected
[173.395418] hub 5-0:1.0: activate --> -19
[173.603447] irq 228: nobody cared (try booting with the "irqpoll" option)
[173.603493] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.4.21 #9
[173.603513] Hardware name: Google Kevin (DT)
[173.603531] Call trace:
[173.603568] [] dump_backtrace+0x0/0x160
[173.603596] [] show_stack+0x20/0x28
[173.603623] [] dump_stack+0x90/0xb0
[173.603650] [] __report_bad_irq+0x48/0xe8
[173.603674] [] note_interrupt+0x1e8/0x28c
[173.603698] [] handle_irq_event_percpu+0x1d4/0x25c
[173.603722] [] handle_irq_event+0x4c/0x7c
[173.603748] [] handle_fasteoi_irq+0xb4/0x124
[173.603777] [] generic_handle_irq+0x30/0x44
[173.603804] [] __handle_domain_irq+0x90/0xbc
[173.603827] [] gic_handle_irq+0xcc/0x188
...
[173.604500] [] el1_irq+0x80/0xf8
[173.604530] [] cpu_startup_entry+0x38/0x3cc
[173.604558] [] rest_init+0x8c/0x94
[173.604585] [] start_kernel+0x3d0/0x3fc
[173.604607] [<00b16000>] 0xb16000
[173.604622] handlers:
[173.604648] [] usb_hcd_irq
[173.604673] Disabling IRQ #228

Signed-off-by: William wu 
Signed-off-by: William wu 
---
 drivers/usb/core/hcd.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 479e223..612fab6 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -3017,6 +3017,7 @@ void usb_remove_hcd(struct usb_hcd *hcd)
}
 
usb_put_invalidate_rhdev(hcd);
+   hcd->flags = 0;
 }
 EXPORT_SYMBOL_GPL(usb_remove_hcd);
 
-- 
2.7.4




[PATCH v4 0/2] phy: rockchip-inno-usb2: correct 480MHz clk_ops callbacks and stable time

2016-11-14 Thread William Wu
This series try to correct the 480MHz output clock of USB2 PHY
clk_ops callback and fix the delay time. It aims to make the
480MHz clock gate more sensible and stable.

Tested on rk3366/rk3399 EVB board.

William Wu (2):
  phy: rockchip-inno-usb2: correct clk_ops callback
  phy: rockchip-inno-usb2: correct 480MHz output clock stable time

 drivers/phy/phy-rockchip-inno-usb2.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

-- 
2.0.0




[PATCH v4 2/2] phy: rockchip-inno-usb2: correct 480MHz output clock stable time

2016-11-14 Thread William Wu
We found that the system crashed due to 480MHz output clock of
USB2 PHY was unstable after clock had been enabled by gpu module.

Theoretically, 1 millisecond is a critical value for 480MHz
output clock stable time, so we try to change the delay time
to 1.2 millisecond to avoid this issue.

And the commit ed907fb1d7c3 ("phy: rockchip-inno-usb2: correct
clk_ops callback") used prepare callbacks instead of enable
callbacks to support gate a clk if the operation may sleep. So
we can switch from delay to sleep functions.

Also fix a spelling error from "waitting" to "waiting".

Signed-off-by: William Wu 
Reviewed-by: Douglas Anderson 
---
Changes in v4:
- add Reviewed-by and fix a spelling error

Changes in v3:
- None

Changes in v2:
- None

 drivers/phy/phy-rockchip-inno-usb2.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/phy-rockchip-inno-usb2.c 
b/drivers/phy/phy-rockchip-inno-usb2.c
index 365e077..5d922fc 100644
--- a/drivers/phy/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/phy-rockchip-inno-usb2.c
@@ -165,8 +165,8 @@ static int rockchip_usb2phy_clk480m_prepare(struct clk_hw 
*hw)
if (ret)
return ret;
 
-   /* waitting for the clk become stable */
-   mdelay(1);
+   /* waiting for the clk become stable */
+   usleep_range(1200, 1300);
}
 
return 0;
-- 
2.0.0




[PATCH v4 1/2] phy: rockchip-inno-usb2: correct clk_ops callback

2016-11-14 Thread William Wu
Since we needs to delay ~1ms to wait for 480MHz output clock
of USB2 PHY to become stable after turn on it, the delay time
is pretty long for something that's supposed to be "atomic"
like a clk_enable(). Consider that clk_enable() will disable
interrupt and that a 1ms interrupt latency is not sensible.

The 480MHz output clock should be handled in prepare callbacks
which support gate a clk if the operation may sleep.

Signed-off-by: William Wu 
Reviewed-by: Douglas Anderson 
---
Changes in v4:
- add Reviewed-by

Changes in v3:
- None

Changes in v2:
- None

 drivers/phy/phy-rockchip-inno-usb2.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/phy/phy-rockchip-inno-usb2.c 
b/drivers/phy/phy-rockchip-inno-usb2.c
index ac20310..365e077 100644
--- a/drivers/phy/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/phy-rockchip-inno-usb2.c
@@ -153,7 +153,7 @@ static inline bool property_enabled(struct rockchip_usb2phy 
*rphy,
return tmp == reg->enable;
 }
 
-static int rockchip_usb2phy_clk480m_enable(struct clk_hw *hw)
+static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw)
 {
struct rockchip_usb2phy *rphy =
container_of(hw, struct rockchip_usb2phy, clk480m_hw);
@@ -172,7 +172,7 @@ static int rockchip_usb2phy_clk480m_enable(struct clk_hw 
*hw)
return 0;
 }
 
-static void rockchip_usb2phy_clk480m_disable(struct clk_hw *hw)
+static void rockchip_usb2phy_clk480m_unprepare(struct clk_hw *hw)
 {
struct rockchip_usb2phy *rphy =
container_of(hw, struct rockchip_usb2phy, clk480m_hw);
@@ -181,7 +181,7 @@ static void rockchip_usb2phy_clk480m_disable(struct clk_hw 
*hw)
property_enable(rphy, &rphy->phy_cfg->clkout_ctl, false);
 }
 
-static int rockchip_usb2phy_clk480m_enabled(struct clk_hw *hw)
+static int rockchip_usb2phy_clk480m_prepared(struct clk_hw *hw)
 {
struct rockchip_usb2phy *rphy =
container_of(hw, struct rockchip_usb2phy, clk480m_hw);
@@ -197,9 +197,9 @@ rockchip_usb2phy_clk480m_recalc_rate(struct clk_hw *hw,
 }
 
 static const struct clk_ops rockchip_usb2phy_clkout_ops = {
-   .enable = rockchip_usb2phy_clk480m_enable,
-   .disable = rockchip_usb2phy_clk480m_disable,
-   .is_enabled = rockchip_usb2phy_clk480m_enabled,
+   .prepare = rockchip_usb2phy_clk480m_prepare,
+   .unprepare = rockchip_usb2phy_clk480m_unprepare,
+   .is_prepared = rockchip_usb2phy_clk480m_prepared,
.recalc_rate = rockchip_usb2phy_clk480m_recalc_rate,
 };
 
-- 
2.0.0




[PATCH v3 2/2] phy: rockchip-inno-usb2: correct 480MHz output clock stable time

2016-11-14 Thread William Wu
We found that the system crashed due to 480MHz output clock of
USB2 PHY was unstable after clock had been enabled by gpu module.

Theoretically, 1 millisecond is a critical value for 480MHz
output clock stable time, so we try to change the delay time
to 1.2 millisecond to avoid this issue.

And the commit ed907fb1d7c3 ("phy: rockchip-inno-usb2: correct
clk_ops callback") used prepare callbacks instead of enable
callbacks to support gate a clk if the operation may sleep. So
we can switch from delay to sleep functions.

Signed-off-by: William Wu 
---
Changes in v3:
- fix kbuild test error: too few arguments to function 'usleep_range'

Changes in v2:
- use usleep_range() function instead of mdelay()

 drivers/phy/phy-rockchip-inno-usb2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/phy-rockchip-inno-usb2.c 
b/drivers/phy/phy-rockchip-inno-usb2.c
index 365e077..0e52b25 100644
--- a/drivers/phy/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/phy-rockchip-inno-usb2.c
@@ -166,7 +166,7 @@ static int rockchip_usb2phy_clk480m_prepare(struct clk_hw 
*hw)
return ret;
 
/* waitting for the clk become stable */
-   mdelay(1);
+   usleep_range(1200, 1300);
}
 
return 0;
-- 
2.0.0




[PATCH v3 1/2] phy: rockchip-inno-usb2: correct clk_ops callback

2016-11-14 Thread William Wu
Since we needs to delay ~1ms to wait for 480MHz output clock
of USB2 PHY to become stable after turn on it, the delay time
is pretty long for something that's supposed to be "atomic"
like a clk_enable(). Consider that clk_enable() will disable
interrupt and that a 1ms interrupt latency is not sensible.

The 480MHz output clock should be handled in prepare callbacks
which support gate a clk if the operation may sleep.

Signed-off-by: William Wu 
---
Changes in v3:
- None

Changes in v2:
- None

 drivers/phy/phy-rockchip-inno-usb2.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/phy/phy-rockchip-inno-usb2.c 
b/drivers/phy/phy-rockchip-inno-usb2.c
index ac20310..365e077 100644
--- a/drivers/phy/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/phy-rockchip-inno-usb2.c
@@ -153,7 +153,7 @@ static inline bool property_enabled(struct rockchip_usb2phy 
*rphy,
return tmp == reg->enable;
 }
 
-static int rockchip_usb2phy_clk480m_enable(struct clk_hw *hw)
+static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw)
 {
struct rockchip_usb2phy *rphy =
container_of(hw, struct rockchip_usb2phy, clk480m_hw);
@@ -172,7 +172,7 @@ static int rockchip_usb2phy_clk480m_enable(struct clk_hw 
*hw)
return 0;
 }
 
-static void rockchip_usb2phy_clk480m_disable(struct clk_hw *hw)
+static void rockchip_usb2phy_clk480m_unprepare(struct clk_hw *hw)
 {
struct rockchip_usb2phy *rphy =
container_of(hw, struct rockchip_usb2phy, clk480m_hw);
@@ -181,7 +181,7 @@ static void rockchip_usb2phy_clk480m_disable(struct clk_hw 
*hw)
property_enable(rphy, &rphy->phy_cfg->clkout_ctl, false);
 }
 
-static int rockchip_usb2phy_clk480m_enabled(struct clk_hw *hw)
+static int rockchip_usb2phy_clk480m_prepared(struct clk_hw *hw)
 {
struct rockchip_usb2phy *rphy =
container_of(hw, struct rockchip_usb2phy, clk480m_hw);
@@ -197,9 +197,9 @@ rockchip_usb2phy_clk480m_recalc_rate(struct clk_hw *hw,
 }
 
 static const struct clk_ops rockchip_usb2phy_clkout_ops = {
-   .enable = rockchip_usb2phy_clk480m_enable,
-   .disable = rockchip_usb2phy_clk480m_disable,
-   .is_enabled = rockchip_usb2phy_clk480m_enabled,
+   .prepare = rockchip_usb2phy_clk480m_prepare,
+   .unprepare = rockchip_usb2phy_clk480m_unprepare,
+   .is_prepared = rockchip_usb2phy_clk480m_prepared,
.recalc_rate = rockchip_usb2phy_clk480m_recalc_rate,
 };
 
-- 
2.0.0




[PATCH v3 0/2] phy: rockchip-inno-usb2: correct 480MHz clk_ops callbacks and stable time

2016-11-14 Thread William Wu
This series try to correct the 480MHz output clock of USB2 PHY
clk_ops callback and fix the delay time. It aims to make the
480MHz clock gate more sensible and stable.

Tested on rk3366/rk3399 EVB board.

William Wu (2):
  phy: rockchip-inno-usb2: correct clk_ops callback
  phy: rockchip-inno-usb2: correct 480MHz output clock stable time

 drivers/phy/phy-rockchip-inno-usb2.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

-- 
2.0.0




[PATCH v2 0/2] phy: rockchip-inno-usb2: correct 480MHz clk_ops callbacks and stable time

2016-11-13 Thread William Wu
This series try to correct the 480MHz output clock of USB2 PHY
clk_ops callback and fix the delay time. It aims to make the
480MHz clock more sensible and stable.

Tested on rk3366/rk3399 EVB board.

William Wu (2):
  phy: rockchip-inno-usb2: correct clk_ops callback
  phy: rockchip-inno-usb2: correct 480MHz output clock stable time

 drivers/phy/phy-rockchip-inno-usb2.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

-- 
2.0.0




[PATCH v2 2/2] phy: rockchip-inno-usb2: correct 480MHz output clock stable time

2016-11-13 Thread William Wu
We found that the system crashed due to 480MHz output clock of
USB2 PHY was unstable after clock had been enabled by gpu module.

Theoretically, 1 millisecond is a critical value for 480MHz
output clock stable time, so we try to change the delay time
to 1.2 millisecond to avoid this issue.

And the commit ed907fb1d7c3 ("phy: rockchip-inno-usb2: correct
clk_ops callback") used prepare callbacks instead of enable
callbacks to support gate a clk if the operation may sleep. So
we can switch from delay to sleep functions.

Signed-off-by: William Wu 
---
Changes in v2:
- use usleep_range() function instead of mdelay()

 drivers/phy/phy-rockchip-inno-usb2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/phy-rockchip-inno-usb2.c 
b/drivers/phy/phy-rockchip-inno-usb2.c
index 365e077..578290b 100644
--- a/drivers/phy/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/phy-rockchip-inno-usb2.c
@@ -166,7 +166,7 @@ static int rockchip_usb2phy_clk480m_prepare(struct clk_hw 
*hw)
return ret;
 
/* waitting for the clk become stable */
-   mdelay(1);
+   usleep_range(1200);
}
 
return 0;
-- 
2.0.0




[PATCH v2 1/2] phy: rockchip-inno-usb2: correct clk_ops callback

2016-11-13 Thread William Wu
Since we needs to delay ~1ms to wait for 480MHz output clock
of USB2 PHY to become stable after turn on it, the delay time
is pretty long for something that's supposed to be "atomic"
like a clk_enable(). Consider that clk_enable() will disable
interrupt and that a 1ms interrupt latency is not sensible.

The 480MHz output clock should be handled in prepare callbacks
which support gate a clk if the operation may sleep.

Signed-off-by: William Wu 
---
 drivers/phy/phy-rockchip-inno-usb2.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/phy/phy-rockchip-inno-usb2.c 
b/drivers/phy/phy-rockchip-inno-usb2.c
index ac20310..365e077 100644
--- a/drivers/phy/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/phy-rockchip-inno-usb2.c
@@ -153,7 +153,7 @@ static inline bool property_enabled(struct rockchip_usb2phy 
*rphy,
return tmp == reg->enable;
 }
 
-static int rockchip_usb2phy_clk480m_enable(struct clk_hw *hw)
+static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw)
 {
struct rockchip_usb2phy *rphy =
container_of(hw, struct rockchip_usb2phy, clk480m_hw);
@@ -172,7 +172,7 @@ static int rockchip_usb2phy_clk480m_enable(struct clk_hw 
*hw)
return 0;
 }
 
-static void rockchip_usb2phy_clk480m_disable(struct clk_hw *hw)
+static void rockchip_usb2phy_clk480m_unprepare(struct clk_hw *hw)
 {
struct rockchip_usb2phy *rphy =
container_of(hw, struct rockchip_usb2phy, clk480m_hw);
@@ -181,7 +181,7 @@ static void rockchip_usb2phy_clk480m_disable(struct clk_hw 
*hw)
property_enable(rphy, &rphy->phy_cfg->clkout_ctl, false);
 }
 
-static int rockchip_usb2phy_clk480m_enabled(struct clk_hw *hw)
+static int rockchip_usb2phy_clk480m_prepared(struct clk_hw *hw)
 {
struct rockchip_usb2phy *rphy =
container_of(hw, struct rockchip_usb2phy, clk480m_hw);
@@ -197,9 +197,9 @@ rockchip_usb2phy_clk480m_recalc_rate(struct clk_hw *hw,
 }
 
 static const struct clk_ops rockchip_usb2phy_clkout_ops = {
-   .enable = rockchip_usb2phy_clk480m_enable,
-   .disable = rockchip_usb2phy_clk480m_disable,
-   .is_enabled = rockchip_usb2phy_clk480m_enabled,
+   .prepare = rockchip_usb2phy_clk480m_prepare,
+   .unprepare = rockchip_usb2phy_clk480m_unprepare,
+   .is_prepared = rockchip_usb2phy_clk480m_prepared,
.recalc_rate = rockchip_usb2phy_clk480m_recalc_rate,
 };
 
-- 
2.0.0




[PATCH] phy: rockchip-inno-usb2: correct 480MHz output clock stable time

2016-11-07 Thread William Wu
We found that the system crashed due to 480MHz output clock of
USB2 PHY was unstable after clock had been enabled by gpu module.

Theoretically, 1 millisecond is a critical value for 480MHz
output clock stable time, so we try to change the delay time
to 1.2 millisecond to avoid this issue.

Signed-off-by: William Wu 
---
 drivers/phy/phy-rockchip-inno-usb2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/phy-rockchip-inno-usb2.c 
b/drivers/phy/phy-rockchip-inno-usb2.c
index ecfd7d1..8f2d2b6 100644
--- a/drivers/phy/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/phy-rockchip-inno-usb2.c
@@ -267,7 +267,7 @@ static int rockchip_usb2phy_clk480m_enable(struct clk_hw 
*hw)
return ret;
 
/* waitting for the clk become stable */
-   mdelay(1);
+   udelay(1200);
}
 
return 0;
-- 
2.0.0




[PATCH v3 1/2] phy: rockchip-inno-usb2: support otg-port for rk3399

2016-11-07 Thread William Wu
The rk3399 SoC USB2 PHY is comprised of one Host port and
one OTG port. And OTG port is for USB2.0 part of USB3.0 OTG
controller, as a part to construct a fully feature Type-C
subsystem.

With this patch, we can support OTG port with the following
functions:
- Support BC1.2 charger detect, and use extcon notifier to
  send USB charger types to power driver.
- Support PHY suspend for power management.
- Support OTG Host only mode.

Signed-off-by: William Wu 
---
Changes in v3:
- split the clock fix into a separate patch 

Changes in v2:
- remove wakelock

 drivers/phy/phy-rockchip-inno-usb2.c | 591 +--
 1 file changed, 561 insertions(+), 30 deletions(-)

diff --git a/drivers/phy/phy-rockchip-inno-usb2.c 
b/drivers/phy/phy-rockchip-inno-usb2.c
index ac20310..ecfd7d1 100644
--- a/drivers/phy/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/phy-rockchip-inno-usb2.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -30,11 +31,15 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
+#include 
+#include 
 
 #define BIT_WRITEABLE_SHIFT16
-#define SCHEDULE_DELAY (60 * HZ)
+#define SCHEDULE_DELAY (60 * HZ)
+#define OTG_SCHEDULE_DELAY (2 * HZ)
 
 enum rockchip_usb2phy_port_id {
USB2PHY_PORT_OTG,
@@ -49,6 +54,37 @@ enum rockchip_usb2phy_host_state {
PHY_STATE_FS_LS_ONLINE  = 4,
 };
 
+/**
+ * Different states involved in USB charger detection.
+ * USB_CHG_STATE_UNDEFINED USB charger is not connected or detection
+ * process is not yet started.
+ * USB_CHG_STATE_WAIT_FOR_DCD  Waiting for Data pins contact.
+ * USB_CHG_STATE_DCD_DONE  Data pin contact is detected.
+ * USB_CHG_STATE_PRIMARY_DONE  Primary detection is completed (Detects
+ * between SDP and DCP/CDP).
+ * USB_CHG_STATE_SECONDARY_DONESecondary detection is completed 
(Detects
+ * between DCP and CDP).
+ * USB_CHG_STATE_DETECTED  USB charger type is determined.
+ */
+enum usb_chg_state {
+   USB_CHG_STATE_UNDEFINED = 0,
+   USB_CHG_STATE_WAIT_FOR_DCD,
+   USB_CHG_STATE_DCD_DONE,
+   USB_CHG_STATE_PRIMARY_DONE,
+   USB_CHG_STATE_SECONDARY_DONE,
+   USB_CHG_STATE_DETECTED,
+};
+
+static const unsigned int rockchip_usb2phy_extcon_cable[] = {
+   EXTCON_USB,
+   EXTCON_USB_HOST,
+   EXTCON_CHG_USB_SDP,
+   EXTCON_CHG_USB_CDP,
+   EXTCON_CHG_USB_DCP,
+   EXTCON_CHG_USB_SLOW,
+   EXTCON_NONE,
+};
+
 struct usb2phy_reg {
unsigned intoffset;
unsigned intbitend;
@@ -58,19 +94,55 @@ struct usb2phy_reg {
 };
 
 /**
+ * struct rockchip_chg_det_reg: usb charger detect registers
+ * @cp_det: charging port detected successfully.
+ * @dcp_det: dedicated charging port detected successfully.
+ * @dp_det: assert data pin connect successfully.
+ * @idm_sink_en: open dm sink curren.
+ * @idp_sink_en: open dp sink current.
+ * @idp_src_en: open dm source current.
+ * @rdm_pdwn_en: open dm pull down resistor.
+ * @vdm_src_en: open dm voltage source.
+ * @vdp_src_en: open dp voltage source.
+ * @opmode: utmi operational mode.
+ */
+struct rockchip_chg_det_reg {
+   struct usb2phy_reg  cp_det;
+   struct usb2phy_reg  dcp_det;
+   struct usb2phy_reg  dp_det;
+   struct usb2phy_reg  idm_sink_en;
+   struct usb2phy_reg  idp_sink_en;
+   struct usb2phy_reg  idp_src_en;
+   struct usb2phy_reg  rdm_pdwn_en;
+   struct usb2phy_reg  vdm_src_en;
+   struct usb2phy_reg  vdp_src_en;
+   struct usb2phy_reg  opmode;
+};
+
+/**
  * struct rockchip_usb2phy_port_cfg: usb-phy port configuration.
  * @phy_sus: phy suspend register.
+ * @bvalid_det_en: vbus valid rise detection enable register.
+ * @bvalid_det_st: vbus valid rise detection status register.
+ * @bvalid_det_clr: vbus valid rise detection clear register.
  * @ls_det_en: linestate detection enable register.
  * @ls_det_st: linestate detection state register.
  * @ls_det_clr: linestate detection clear register.
+ * @utmi_avalid: utmi vbus avalid status register.
+ * @utmi_bvalid: utmi vbus bvalid status register.
  * @utmi_ls: utmi linestate state register.
  * @utmi_hstdet: utmi host disconnect register.
  */
 struct rockchip_usb2phy_port_cfg {
struct usb2phy_reg  phy_sus;
+   struct usb2phy_reg  bvalid_det_en;
+   struct usb2phy_reg  bvalid_det_st;
+   struct usb2phy_reg  bvalid_det_clr;
struct usb2phy_reg  ls_det_en;
struct usb2phy_reg  ls_det_st;
struct usb2phy_reg  ls_det_clr;
+   struct usb2phy_reg  utmi_avalid;
+   struct usb2phy_reg  utmi_bvalid;
struct usb2phy_reg  utmi_ls;
struct usb2phy_reg  utmi_hstdet;
 };
@@ -80,31 +152,51 @@ struct rockchip_usb2phy_port_cfg {
  * @reg: the address offset of grf for usb-phy config.
  * @num_ports: specify

[PATCH v3 0/2] support USB2 PHY OTG port for rk3399

2016-11-07 Thread William Wu
This series add support for rk3399 USB2 PHY0 and PHY1 OTG port.
rk3399 has two USB2 PHYs, and each USB2 PHY is comprised of one
Host port and one OTG port. We have supported Host port before,
and try to support OTG port now.

Test on rk3399-evb board.

William Wu (2):
  phy: rockchip-inno-usb2: support otg-port for rk3399
  arm64: dts: rockchip: add usb2-phy otg-port support for rk3399

 arch/arm64/boot/dts/rockchip/rk3399.dtsi |  21 ++
 drivers/phy/phy-rockchip-inno-usb2.c | 591 +--
 2 files changed, 582 insertions(+), 30 deletions(-)

-- 
2.0.0




[PATCH v3 2/2] arm64: dts: rockchip: add usb2-phy otg-port support for rk3399

2016-11-07 Thread William Wu
Add otg-port nodes for both u2phy0 and u2phy1. The otg-port can
be used for USB2.0 part of USB3.0 OTG controller.

Signed-off-by: William Wu 
---
Changes in v3:
- None

Changes in v2:
- None

 arch/arm64/boot/dts/rockchip/rk3399.dtsi | 21 +
 1 file changed, 21 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index b65c193..ea2df51 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1095,6 +1095,17 @@
clock-output-names = "clk_usbphy0_480m";
status = "disabled";
 
+   u2phy0_otg: otg-port {
+   #phy-cells = <0>;
+   interrupts = ,
+,
+;
+   interrupt-names = "otg-bvalid", "otg-id",
+ "linestate";
+   status = "disabled";
+   };
+
+
u2phy0_host: host-port {
#phy-cells = <0>;
interrupts = ;
@@ -1112,6 +1123,16 @@
clock-output-names = "clk_usbphy1_480m";
status = "disabled";
 
+   u2phy1_otg: otg-port {
+   #phy-cells = <0>;
+   interrupts = ,
+,
+;
+   interrupt-names = "otg-bvalid", "otg-id",
+ "linestate";
+   status = "disabled";
+   };
+
u2phy1_host: host-port {
#phy-cells = <0>;
interrupts = ;
-- 
2.0.0




[PATCH v2 1/2] phy: rockchip-inno-usb2: support otg-port for rk3399

2016-11-02 Thread William Wu
The rk3399 SoC USB2 PHY is comprised of one Host port and
one OTG port. And OTG port is for USB2.0 part of USB3.0 OTG
controller, as a part to construct a fully feature Type-C
subsystem.

With this patch, we can support OTG port with the following
functions:
- Support BC1.2 charger detect, and use extcon notifier to
  send USB charger types to power driver.
- Support PHY suspend for power management.
- Support OTG Host only mode.

Also, correct 480MHz output clock stable time. We found that
the system crashed due to 480MHz output clock of USB2 PHY was
unstable after clock had been enabled by gpu module.

Theoretically, 1 millisecond is a critical value for 480 output
clock stable time, so we try changing the delay time to 1.2
millisecond to avoid this issue.

Signed-off-by: William Wu 
---
Changes in v2:
- remove wakelock

 drivers/phy/phy-rockchip-inno-usb2.c | 593 +--
 1 file changed, 562 insertions(+), 31 deletions(-)

diff --git a/drivers/phy/phy-rockchip-inno-usb2.c 
b/drivers/phy/phy-rockchip-inno-usb2.c
index ac20310..8f2d2b6 100644
--- a/drivers/phy/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/phy-rockchip-inno-usb2.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -30,11 +31,15 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
+#include 
+#include 
 
 #define BIT_WRITEABLE_SHIFT16
-#define SCHEDULE_DELAY (60 * HZ)
+#define SCHEDULE_DELAY (60 * HZ)
+#define OTG_SCHEDULE_DELAY (2 * HZ)
 
 enum rockchip_usb2phy_port_id {
USB2PHY_PORT_OTG,
@@ -49,6 +54,37 @@ enum rockchip_usb2phy_host_state {
PHY_STATE_FS_LS_ONLINE  = 4,
 };
 
+/**
+ * Different states involved in USB charger detection.
+ * USB_CHG_STATE_UNDEFINED USB charger is not connected or detection
+ * process is not yet started.
+ * USB_CHG_STATE_WAIT_FOR_DCD  Waiting for Data pins contact.
+ * USB_CHG_STATE_DCD_DONE  Data pin contact is detected.
+ * USB_CHG_STATE_PRIMARY_DONE  Primary detection is completed (Detects
+ * between SDP and DCP/CDP).
+ * USB_CHG_STATE_SECONDARY_DONESecondary detection is completed 
(Detects
+ * between DCP and CDP).
+ * USB_CHG_STATE_DETECTED  USB charger type is determined.
+ */
+enum usb_chg_state {
+   USB_CHG_STATE_UNDEFINED = 0,
+   USB_CHG_STATE_WAIT_FOR_DCD,
+   USB_CHG_STATE_DCD_DONE,
+   USB_CHG_STATE_PRIMARY_DONE,
+   USB_CHG_STATE_SECONDARY_DONE,
+   USB_CHG_STATE_DETECTED,
+};
+
+static const unsigned int rockchip_usb2phy_extcon_cable[] = {
+   EXTCON_USB,
+   EXTCON_USB_HOST,
+   EXTCON_CHG_USB_SDP,
+   EXTCON_CHG_USB_CDP,
+   EXTCON_CHG_USB_DCP,
+   EXTCON_CHG_USB_SLOW,
+   EXTCON_NONE,
+};
+
 struct usb2phy_reg {
unsigned intoffset;
unsigned intbitend;
@@ -58,19 +94,55 @@ struct usb2phy_reg {
 };
 
 /**
+ * struct rockchip_chg_det_reg: usb charger detect registers
+ * @cp_det: charging port detected successfully.
+ * @dcp_det: dedicated charging port detected successfully.
+ * @dp_det: assert data pin connect successfully.
+ * @idm_sink_en: open dm sink curren.
+ * @idp_sink_en: open dp sink current.
+ * @idp_src_en: open dm source current.
+ * @rdm_pdwn_en: open dm pull down resistor.
+ * @vdm_src_en: open dm voltage source.
+ * @vdp_src_en: open dp voltage source.
+ * @opmode: utmi operational mode.
+ */
+struct rockchip_chg_det_reg {
+   struct usb2phy_reg  cp_det;
+   struct usb2phy_reg  dcp_det;
+   struct usb2phy_reg  dp_det;
+   struct usb2phy_reg  idm_sink_en;
+   struct usb2phy_reg  idp_sink_en;
+   struct usb2phy_reg  idp_src_en;
+   struct usb2phy_reg  rdm_pdwn_en;
+   struct usb2phy_reg  vdm_src_en;
+   struct usb2phy_reg  vdp_src_en;
+   struct usb2phy_reg  opmode;
+};
+
+/**
  * struct rockchip_usb2phy_port_cfg: usb-phy port configuration.
  * @phy_sus: phy suspend register.
+ * @bvalid_det_en: vbus valid rise detection enable register.
+ * @bvalid_det_st: vbus valid rise detection status register.
+ * @bvalid_det_clr: vbus valid rise detection clear register.
  * @ls_det_en: linestate detection enable register.
  * @ls_det_st: linestate detection state register.
  * @ls_det_clr: linestate detection clear register.
+ * @utmi_avalid: utmi vbus avalid status register.
+ * @utmi_bvalid: utmi vbus bvalid status register.
  * @utmi_ls: utmi linestate state register.
  * @utmi_hstdet: utmi host disconnect register.
  */
 struct rockchip_usb2phy_port_cfg {
struct usb2phy_reg  phy_sus;
+   struct usb2phy_reg  bvalid_det_en;
+   struct usb2phy_reg  bvalid_det_st;
+   struct usb2phy_reg  bvalid_det_clr;
struct usb2phy_reg  ls_det_en;
struct usb2phy_reg  ls_det_st;
struct usb2phy_reg  ls_det_clr;
+   struct usb2phy_reg  utmi_avalid

[PATCH v2 0/2] support USB2 PHY OTG port for rk3399

2016-11-02 Thread William Wu
This series add support for rk3399 USB2 PHY0 and PHY1 OTG port.
rk3399 has two USB2 PHYs, and each USB2 PHY is comprised of one
Host port and one OTG port. We have supported Host port before,
and try to support OTG port now.

Test on rk3399-evb board.

William Wu (2):
  phy: rockchip-inno-usb2: support otg-port for rk3399
  arm64: dts: rockchip: add usb2-phy otg-port support for rk3399

 arch/arm64/boot/dts/rockchip/rk3399.dtsi |  21 ++
 drivers/phy/phy-rockchip-inno-usb2.c | 593 +--
 2 files changed, 583 insertions(+), 31 deletions(-)

-- 
2.0.0




[PATCH v2 2/2] arm64: dts: rockchip: add usb2-phy otg-port support for rk3399

2016-11-02 Thread William Wu
Add otg-port nodes for both u2phy0 and u2phy1. The otg-port can
be used for USB2.0 part of USB3.0 OTG controller.

Signed-off-by: William Wu 
---
Changes in v2:
- None

 arch/arm64/boot/dts/rockchip/rk3399.dtsi | 21 +
 1 file changed, 21 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index b65c193..ea2df51 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1095,6 +1095,17 @@
clock-output-names = "clk_usbphy0_480m";
status = "disabled";
 
+   u2phy0_otg: otg-port {
+   #phy-cells = <0>;
+   interrupts = ,
+,
+;
+   interrupt-names = "otg-bvalid", "otg-id",
+ "linestate";
+   status = "disabled";
+   };
+
+
u2phy0_host: host-port {
#phy-cells = <0>;
interrupts = ;
@@ -1112,6 +1123,16 @@
clock-output-names = "clk_usbphy1_480m";
status = "disabled";
 
+   u2phy1_otg: otg-port {
+   #phy-cells = <0>;
+   interrupts = ,
+,
+;
+   interrupt-names = "otg-bvalid", "otg-id",
+ "linestate";
+   status = "disabled";
+   };
+
u2phy1_host: host-port {
#phy-cells = <0>;
interrupts = ;
-- 
2.0.0




[PATCH 2/2] arm64: dts: rockchip: add usb2-phy otg-port support for rk3399

2016-11-02 Thread William Wu
Add otg-port nodes for both u2phy0 and u2phy1. The otg-port can
be used for USB2.0 part of USB3.0 OTG controller.

Signed-off-by: William Wu 
---
 arch/arm64/boot/dts/rockchip/rk3399.dtsi | 21 +
 1 file changed, 21 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index b65c193..ea2df51 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1095,6 +1095,17 @@
clock-output-names = "clk_usbphy0_480m";
status = "disabled";
 
+   u2phy0_otg: otg-port {
+   #phy-cells = <0>;
+   interrupts = ,
+,
+;
+   interrupt-names = "otg-bvalid", "otg-id",
+ "linestate";
+   status = "disabled";
+   };
+
+
u2phy0_host: host-port {
#phy-cells = <0>;
interrupts = ;
@@ -1112,6 +1123,16 @@
clock-output-names = "clk_usbphy1_480m";
status = "disabled";
 
+   u2phy1_otg: otg-port {
+   #phy-cells = <0>;
+   interrupts = ,
+,
+;
+   interrupt-names = "otg-bvalid", "otg-id",
+ "linestate";
+   status = "disabled";
+   };
+
u2phy1_host: host-port {
#phy-cells = <0>;
interrupts = ;
-- 
2.0.0




[PATCH 0/2] support USB2 PHY OTG port for rk3399

2016-11-02 Thread William Wu
This series add support for rk3399 USB2 PHY0 and PHY1 OTG port.
rk3399 has two USB2 PHYs, and each USB2 PHY is comprised of one
Host port and one OTG port. We have supported Host port before,
and try to support OTG port now.

Test on rk3399-evb board.

William Wu (2):
  phy: rockchip-inno-usb2: support otg-port for rk3399
  arm64: dts: rockchip: add usb2-phy otg-port support for rk3399

 arch/arm64/boot/dts/rockchip/rk3399.dtsi |  21 ++
 drivers/phy/phy-rockchip-inno-usb2.c | 609 +--
 2 files changed, 599 insertions(+), 31 deletions(-)

-- 
2.0.0




[PATCH 1/2] phy: rockchip-inno-usb2: support otg-port for rk3399

2016-11-02 Thread William Wu
The rk3399 SoC USB2 PHY is comprised of one Host port and
one OTG port. And OTG port is for USB2.0 part of USB3.0 OTG
controller, as a part to construct a fully feature Type-C
subsystem.

With this patch, we can support OTG port with the following
functions:
- Support BC1.2 charger detect, and use extcon notifier to
  send USB charger types to power driver.
- Support PHY suspend for power management.
- Support OTG Host only mode.
- Hold a wakelock when work as SDP(e.g. connect to PC).

Also, correct 480MHz output clock stable time. We found that
the system crashed due to 480MHz output clock of USB2 PHY was
unstable after clock had been enabled by gpu module.

Theoretically, 1 millisecond is a critical value for 480 output
clock stable time, so we try changing the delay time to 1.2
millisecond to avoid this issue.

Signed-off-by: William Wu 
---
 drivers/phy/phy-rockchip-inno-usb2.c | 609 +--
 1 file changed, 578 insertions(+), 31 deletions(-)

diff --git a/drivers/phy/phy-rockchip-inno-usb2.c 
b/drivers/phy/phy-rockchip-inno-usb2.c
index ac20310..352cf87 100644
--- a/drivers/phy/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/phy-rockchip-inno-usb2.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -30,11 +31,16 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 #define BIT_WRITEABLE_SHIFT16
-#define SCHEDULE_DELAY (60 * HZ)
+#define SCHEDULE_DELAY (60 * HZ)
+#define OTG_SCHEDULE_DELAY (2 * HZ)
 
 enum rockchip_usb2phy_port_id {
USB2PHY_PORT_OTG,
@@ -49,6 +55,37 @@ enum rockchip_usb2phy_host_state {
PHY_STATE_FS_LS_ONLINE  = 4,
 };
 
+/**
+ * Different states involved in USB charger detection.
+ * USB_CHG_STATE_UNDEFINED USB charger is not connected or detection
+ * process is not yet started.
+ * USB_CHG_STATE_WAIT_FOR_DCD  Waiting for Data pins contact.
+ * USB_CHG_STATE_DCD_DONE  Data pin contact is detected.
+ * USB_CHG_STATE_PRIMARY_DONE  Primary detection is completed (Detects
+ * between SDP and DCP/CDP).
+ * USB_CHG_STATE_SECONDARY_DONESecondary detection is completed 
(Detects
+ * between DCP and CDP).
+ * USB_CHG_STATE_DETECTED  USB charger type is determined.
+ */
+enum usb_chg_state {
+   USB_CHG_STATE_UNDEFINED = 0,
+   USB_CHG_STATE_WAIT_FOR_DCD,
+   USB_CHG_STATE_DCD_DONE,
+   USB_CHG_STATE_PRIMARY_DONE,
+   USB_CHG_STATE_SECONDARY_DONE,
+   USB_CHG_STATE_DETECTED,
+};
+
+static const unsigned int rockchip_usb2phy_extcon_cable[] = {
+   EXTCON_USB,
+   EXTCON_USB_HOST,
+   EXTCON_CHG_USB_SDP,
+   EXTCON_CHG_USB_CDP,
+   EXTCON_CHG_USB_DCP,
+   EXTCON_CHG_USB_SLOW,
+   EXTCON_NONE,
+};
+
 struct usb2phy_reg {
unsigned intoffset;
unsigned intbitend;
@@ -58,19 +95,55 @@ struct usb2phy_reg {
 };
 
 /**
+ * struct rockchip_chg_det_reg: usb charger detect registers
+ * @cp_det: charging port detected successfully.
+ * @dcp_det: dedicated charging port detected successfully.
+ * @dp_det: assert data pin connect successfully.
+ * @idm_sink_en: open dm sink curren.
+ * @idp_sink_en: open dp sink current.
+ * @idp_src_en: open dm source current.
+ * @rdm_pdwn_en: open dm pull down resistor.
+ * @vdm_src_en: open dm voltage source.
+ * @vdp_src_en: open dp voltage source.
+ * @opmode: utmi operational mode.
+ */
+struct rockchip_chg_det_reg {
+   struct usb2phy_reg  cp_det;
+   struct usb2phy_reg  dcp_det;
+   struct usb2phy_reg  dp_det;
+   struct usb2phy_reg  idm_sink_en;
+   struct usb2phy_reg  idp_sink_en;
+   struct usb2phy_reg  idp_src_en;
+   struct usb2phy_reg  rdm_pdwn_en;
+   struct usb2phy_reg  vdm_src_en;
+   struct usb2phy_reg  vdp_src_en;
+   struct usb2phy_reg  opmode;
+};
+
+/**
  * struct rockchip_usb2phy_port_cfg: usb-phy port configuration.
  * @phy_sus: phy suspend register.
+ * @bvalid_det_en: vbus valid rise detection enable register.
+ * @bvalid_det_st: vbus valid rise detection status register.
+ * @bvalid_det_clr: vbus valid rise detection clear register.
  * @ls_det_en: linestate detection enable register.
  * @ls_det_st: linestate detection state register.
  * @ls_det_clr: linestate detection clear register.
+ * @utmi_avalid: utmi vbus avalid status register.
+ * @utmi_bvalid: utmi vbus bvalid status register.
  * @utmi_ls: utmi linestate state register.
  * @utmi_hstdet: utmi host disconnect register.
  */
 struct rockchip_usb2phy_port_cfg {
struct usb2phy_reg  phy_sus;
+   struct usb2phy_reg  bvalid_det_en;
+   struct usb2phy_reg  bvalid_det_st;
+   struct usb2phy_reg  bvalid_det_clr;
struct usb2phy_reg  ls_det_en;
struct usb2phy_reg  ls_det_st;
struct usb2phy_reg  ls_det_clr

[PATCH v11 5/5] usb: dwc3: rockchip: add devicetree bindings documentation

2016-08-16 Thread William Wu
This patch adds the devicetree documentation required for Rockchip
USB3.0 core wrapper consisting of USB3.0 IP from Synopsys.

It supports DRD mode, and could operate in device mode (SS, HS, FS)
and host mode (SS, HS, FS, LS).

Signed-off-by: William Wu 
Acked-by: Rob Herring 
---
Changes in v11:
- remove required properties "resets" and "reset-names"
- remove optional property "extcon"

Changes in v10:
- None

Changes in v9:
- add required properties "resets" and "reset-names"
- add optional property "extcon"

Changes in v8:
- None

Changes in v7:
- add Acked-by (Rob Herring)

Changes in v6:
- rename bus_clk, and add usbdrd3_1 node as an example (Heiko)

Changes in v5:
- rename clock-names, and remove unnecessary clocks (Heiko)

Changes in v4:
- modify commit log, and add phy documentation location (Sergei)

Changes in v3:
- add dwc3 address (balbi)

Changes in v2:
- add rockchip,dwc3.txt to Documentation/devicetree/bindings/ (balbi, Brian)

 .../devicetree/bindings/usb/rockchip,dwc3.txt  | 59 ++
 1 file changed, 59 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/rockchip,dwc3.txt

diff --git a/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt 
b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
new file mode 100644
index 000..0536a93
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
@@ -0,0 +1,59 @@
+Rockchip SuperSpeed DWC3 USB SoC controller
+
+Required properties:
+- compatible:  should contain "rockchip,rk3399-dwc3" for rk3399 SoC
+- clocks:  A list of phandle + clock-specifier pairs for the
+   clocks listed in clock-names
+- clock-names: Should contain the following:
+  "ref_clk"Controller reference clk, have to be 24 MHz
+  "suspend_clk"Controller suspend clk, have to be 24 MHz or 32 KHz
+  "bus_clk"Master/Core clock, have to be >= 62.5 MHz for SS
+   operation and >= 30MHz for HS operation
+  "grf_clk"Controller grf clk
+
+Required child node:
+A child node must exist to represent the core DWC3 IP block. The name of
+the node is not important. The content of the node is defined in dwc3.txt.
+
+Phy documentation is provided in the following places:
+Documentation/devicetree/bindings/phy/rockchip,dwc3-usb-phy.txt
+
+Example device nodes:
+
+   usbdrd3_0: usb@fe80 {
+   compatible = "rockchip,rk3399-dwc3";
+   clocks = <&cru SCLK_USB3OTG0_REF>, <&cru SCLK_USB3OTG0_SUSPEND>,
+<&cru ACLK_USB3OTG0>, <&cru ACLK_USB3_GRF>;
+   clock-names = "ref_clk", "suspend_clk",
+ "bus_clk", "grf_clk";
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges;
+   status = "disabled";
+   usbdrd_dwc3_0: dwc3@fe80 {
+   compatible = "snps,dwc3";
+   reg = <0x0 0xfe80 0x0 0x10>;
+   interrupts = ;
+   dr_mode = "otg";
+   status = "disabled";
+   };
+   };
+
+   usbdrd3_1: usb@fe90 {
+   compatible = "rockchip,rk3399-dwc3";
+   clocks = <&cru SCLK_USB3OTG1_REF>, <&cru SCLK_USB3OTG1_SUSPEND>,
+<&cru ACLK_USB3OTG1>, <&cru ACLK_USB3_GRF>;
+   clock-names = "ref_clk", "suspend_clk",
+ "bus_clk", "grf_clk";
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges;
+   status = "disabled";
+   usbdrd_dwc3_1: dwc3@fe90 {
+   compatible = "snps,dwc3";
+   reg = <0x0 0xfe90 0x0 0x10>;
+   interrupts = ;
+   dr_mode = "otg";
+   status = "disabled";
+   };
+   };
-- 
1.9.1




[PATCH v11 0/5] support rockchip dwc3 driver

2016-08-16 Thread William Wu
This series add support for rockchip DWC3 driver,
and add additional optional properties for specific
platforms (e.g., rockchip rk3399 platform).

The DesignWare USB3 integrated in rockchip SoCs is
a configurable IP Core which can be instantiated as
Dual-Role Device (DRD), Host Only (XHCI) and Peripheral
Only configurations.

The current driver supports Host only and Peripheral Only,
for now, and we can add support for DRD after dwc3 driver
adds generic handling of DRD.

William Wu (5):
  usb: dwc3: of-simple: add compatible for rockchip rk3399
  usb: dwc3: add dis_u2_freeclk_exists_quirk
  usb: dwc3: make usb2 phy utmi interface configurable
  usb: dwc3: add dis_del_phy_power_chg_quirk
  usb: dwc3: rockchip: add devicetree bindings documentation

 Documentation/devicetree/bindings/usb/dwc3.txt |  5 ++
 Documentation/devicetree/bindings/usb/generic.txt  |  6 +++
 .../devicetree/bindings/usb/rockchip,dwc3.txt  | 59 ++
 drivers/usb/dwc3/core.c| 28 ++
 drivers/usb/dwc3/core.h| 20 
 drivers/usb/dwc3/dwc3-of-simple.c  |  1 +
 6 files changed, 119 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/rockchip,dwc3.txt

-- 
1.9.1




[PATCH v11 1/5] usb: dwc3: of-simple: add compatible for rockchip rk3399

2016-08-16 Thread William Wu
Rockchip platform merely enable usb3 clocks and
populate its children. So we can use this generic
glue layer to support Rockchip dwc3.

Signed-off-by: William Wu 
---
Changes in v11:
- add compatible in dwc3-of-simple.c, and remove dwc3-rockchip.c (balbi)

Changes in v10:
- None

Changes in v9:
- remove compatible from dwc3-of-simple.c, and add a new glue layer 
dwc3-rockchip.c

Changes in v8:
- None

Changes in v7:
- None

Changes in v6:
- None

Changes in v5:
- change compatible from "rockchip,dwc3" to "rockchip,rk3399-dwc3" (Heiko)

Changes in v4:
- None

Changes in v3:
- None

Changes in v2:
- sort the list of_dwc3_simple_match (Doug)

 drivers/usb/dwc3/dwc3-of-simple.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/usb/dwc3/dwc3-of-simple.c 
b/drivers/usb/dwc3/dwc3-of-simple.c
index e56d59b..283f998 100644
--- a/drivers/usb/dwc3/dwc3-of-simple.c
+++ b/drivers/usb/dwc3/dwc3-of-simple.c
@@ -162,6 +162,7 @@ static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = {
 
 static const struct of_device_id of_dwc3_simple_match[] = {
{ .compatible = "qcom,dwc3" },
+   { .compatible = "rockchip,rk3399-dwc3" },
{ .compatible = "xlnx,zynqmp-dwc3" },
{ /* Sentinel */ }
 };
-- 
1.9.1




[PATCH v11 2/5] usb: dwc3: add dis_u2_freeclk_exists_quirk

2016-08-16 Thread William Wu
Add a quirk to clear the GUSB2PHYCFG.U2_FREECLK_EXISTS bit,
which specifies whether the USB2.0 PHY provides a free-running
PHY clock, which is active when the clock control input is active.

Signed-off-by: William Wu 
Acked-by: Rob Herring 
---
Changes in v11:
- None

Changes in v10:
- None

Changes in v9:
- None

Changes in v8:
- add Acked-by (Rob Herring)

Changes in v7:
- None

Changes in v6:
- use '-' instead of '_' in dts (Rob Herring)

Changes in v5:
- None

Changes in v4:
- rebase on top of balbi testing/next, remove pdata (balbi)

Changes in v3:
- None

Changes in v2:
- None

 Documentation/devicetree/bindings/usb/dwc3.txt | 3 +++
 drivers/usb/dwc3/core.c| 5 +
 drivers/usb/dwc3/core.h| 5 +
 3 files changed, 13 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt 
b/Documentation/devicetree/bindings/usb/dwc3.txt
index 7d7ce08..020b0e9 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -39,6 +39,9 @@ Optional properties:
disabling the suspend signal to the PHY.
  - snps,dis_rxdet_inp3_quirk: when set core will disable receiver detection
in PHY P3 power state.
+ - snps,dis-u2-freeclk-exists-quirk: when set, clear the u2_freeclk_exists
+   in GUSB2PHYCFG, specify that USB2 PHY doesn't provide
+   a free-running PHY clock.
  - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
utmi_l1_suspend_n, false when asserts utmi_sleep_n
  - snps,hird-threshold: HIRD threshold
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 35d0924..14316e5 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -500,6 +500,9 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
if (dwc->dis_enblslpm_quirk)
reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
 
+   if (dwc->dis_u2_freeclk_exists_quirk)
+   reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS;
+
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
 
return 0;
@@ -924,6 +927,8 @@ static int dwc3_probe(struct platform_device *pdev)
"snps,dis_enblslpm_quirk");
dwc->dis_rxdet_inp3_quirk = device_property_read_bool(dev,
"snps,dis_rxdet_inp3_quirk");
+   dwc->dis_u2_freeclk_exists_quirk = device_property_read_bool(dev,
+   "snps,dis-u2-freeclk-exists-quirk");
 
dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
"snps,tx_de_emphasis_quirk");
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 1a6cc48..08ed9e0 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -199,6 +199,7 @@
 
 /* Global USB2 PHY Configuration Register */
 #define DWC3_GUSB2PHYCFG_PHYSOFTRST(1 << 31)
+#define DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS (1 << 30)
 #define DWC3_GUSB2PHYCFG_SUSPHY(1 << 6)
 #define DWC3_GUSB2PHYCFG_ULPI_UTMI (1 << 4)
 #define DWC3_GUSB2PHYCFG_ENBLSLPM  (1 << 8)
@@ -803,6 +804,9 @@ struct dwc3_scratchpad_array {
  * @dis_u2_susphy_quirk: set if we disable usb2 suspend phy
  * @dis_enblslpm_quirk: set if we clear enblslpm in GUSB2PHYCFG,
  *  disabling the suspend signal to the PHY.
+ * @dis_u2_freeclk_exists_quirk : set if we clear u2_freeclk_exists
+ * in GUSB2PHYCFG, specify that USB2 PHY doesn't
+ * provide a free-running PHY clock.
  * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
  * @tx_de_emphasis: Tx de-emphasis value
  * 0   - -6dB de-emphasis
@@ -946,6 +950,7 @@ struct dwc3 {
unsigneddis_u2_susphy_quirk:1;
unsigneddis_enblslpm_quirk:1;
unsigneddis_rxdet_inp3_quirk:1;
+   unsigneddis_u2_freeclk_exists_quirk:1;
 
unsignedtx_de_emphasis_quirk:1;
unsignedtx_de_emphasis:2;
-- 
1.9.1




[PATCH v11 3/5] usb: dwc3: make usb2 phy utmi interface configurable

2016-08-16 Thread William Wu
Support to configure the UTMI+ PHY with an 8- or 16-bit
interface via DT. The UTMI+ PHY interface is a hardware
capability, and it's platform dependent. Normally, the
PHYIF can be configured during coreconsultant.

But for some specific USB cores(e.g. rk3399 SoC DWC3),
the default PHYIF configuration value is false, so we
need to reconfigure it by software.

Signed-off-by: William Wu 
Acked-by: Rob Herring 
---
Changes in v11:
- None

Changes in v10:
- None

Changes in v9:
- None

Changes in v8:
- configure utmi interface via phy_type property in DT (Heiko, Rob Herring)
- add Acked-by (Rob Herring)
- modify commit message (Rob Herring)

Changes in v7:
- remove quirk and use only one property to configure utmi (Heiko, Rob Herring)

Changes in v6:
- use '-' instead of '_' in dts (Rob Herring)

Changes in v5:
- None

Changes in v4:
- rebase on top of balbi testing/next, remove pdata (balbi)

Changes in v3:
- None

Changes in v2:
- add a quirk for phyif_utmi (balbi)

 Documentation/devicetree/bindings/usb/generic.txt |  6 ++
 drivers/usb/dwc3/core.c   | 18 ++
 drivers/usb/dwc3/core.h   | 12 
 3 files changed, 36 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/generic.txt 
b/Documentation/devicetree/bindings/usb/generic.txt
index bba8257..bfadeb1 100644
--- a/Documentation/devicetree/bindings/usb/generic.txt
+++ b/Documentation/devicetree/bindings/usb/generic.txt
@@ -11,6 +11,11 @@ Optional properties:
"peripheral" and "otg". In case this attribute isn't
passed via DT, USB DRD controllers should default to
OTG.
+ - phy_type: tells USB controllers that we want to configure the core to 
support
+   a UTMI+ PHY with an 8- or 16-bit interface if UTMI+ is
+   selected. Valid arguments are "utmi" and "utmi_wide".
+   In case this isn't passed via DT, USB controllers should
+   default to HW capability.
  - otg-rev: tells usb driver the release number of the OTG and EH supplement
with which the device and its descriptors are compliant,
in binary-coded decimal (i.e. 2.0 is 0200H). This
@@ -34,6 +39,7 @@ dwc3@4a03 {
usb-phy = <&usb2_phy>, <&usb3,phy>;
maximum-speed = "super-speed";
dr_mode = "otg";
+   phy_type = "utmi_wide";
otg-rev = <0x0200>;
adp-disable;
 };
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 14316e5..cdac019 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -485,6 +485,23 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
break;
}
 
+   switch (dwc->hsphy_mode) {
+   case USBPHY_INTERFACE_MODE_UTMI:
+   reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
+  DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
+   reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_8_BIT) |
+  DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_8_BIT);
+   break;
+   case USBPHY_INTERFACE_MODE_UTMIW:
+   reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
+  DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
+   reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_16_BIT) |
+  DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_16_BIT);
+   break;
+   default:
+   break;
+   }
+
/*
 * Above 1.94a, it is recommended to set DWC3_GUSB2PHYCFG_SUSPHY to
 * '0' during coreConsultant configuration. So default value will
@@ -891,6 +908,7 @@ static int dwc3_probe(struct platform_device *pdev)
 
dwc->maximum_speed = usb_get_maximum_speed(dev);
dwc->dr_mode = usb_get_dr_mode(dev);
+   dwc->hsphy_mode = of_usb_get_phy_mode(dev->of_node);
 
dwc->has_lpm_erratum = device_property_read_bool(dev,
"snps,has-lpm-erratum");
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 08ed9e0..cc4f551 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -203,6 +203,14 @@
 #define DWC3_GUSB2PHYCFG_SUSPHY(1 << 6)
 #define DWC3_GUSB2PHYCFG_ULPI_UTMI (1 << 4)
 #define DWC3_GUSB2PHYCFG_ENBLSLPM  (1 << 8)
+#define DWC3_GUSB2PHYCFG_PHYIF(n)  (n << 3)
+#define DWC3_GUSB2PHYCFG_PHYIF_MASKDWC3_GUSB2PHYCFG_PHYIF(1)
+#define DWC3_GUSB2PHYCFG_USBTRDTIM(n)  (n << 10)
+#define DWC3_GUSB2PHYCFG_USBTRDTIM_MASKDWC3_GUSB2PHYCFG_USBTRDTIM(0xf)
+#define USBTRDTIM_UTMI_8_BIT   9
+#define USBTRDTIM_UTMI_16_BIT  5
+#define UTMI_PHYIF_16_BIT  1
+#define UTMI_PHYIF_8_BIT   0
 
 /* Global US

[PATCH v11 4/5] usb: dwc3: add dis_del_phy_power_chg_quirk

2016-08-16 Thread William Wu
Add a quirk to clear the GUSB3PIPECTL.DELAYP1TRANS bit,
which specifies whether disable delay PHY power change
from P0 to P1/P2/P3 when link state changing from U0
to U1/U2/U3 respectively.

Signed-off-by: William Wu 
Acked-by: Rob Herring 
---
Changes in v11:
- None

Changes in v10:
- None

Changes in v9:
- None

Changes in v8:
- add Acked-by (Rob Herring)

Changes in v7:
- None

Changes in v6:
- use '-' instead of '_' in dts (Rob Herring)

Changes in v5:
- None

Changes in v4:
- rebase on top of balbi testing/next, remove pdata (balbi)

Changes in v3:
- None

Changes in v2:
- None

 Documentation/devicetree/bindings/usb/dwc3.txt | 2 ++
 drivers/usb/dwc3/core.c| 5 +
 drivers/usb/dwc3/core.h| 3 +++
 3 files changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt 
b/Documentation/devicetree/bindings/usb/dwc3.txt
index 020b0e9..e96bfc2 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -42,6 +42,8 @@ Optional properties:
  - snps,dis-u2-freeclk-exists-quirk: when set, clear the u2_freeclk_exists
in GUSB2PHYCFG, specify that USB2 PHY doesn't provide
a free-running PHY clock.
+ - snps,dis-del-phy-power-chg-quirk: when set core will change PHY power
+   from P0 to P1/P2/P3 without delay.
  - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
utmi_l1_suspend_n, false when asserts utmi_sleep_n
  - snps,hird-threshold: HIRD threshold
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index cdac019..e887b38 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -448,6 +448,9 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
if (dwc->dis_u3_susphy_quirk)
reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
 
+   if (dwc->dis_del_phy_power_chg_quirk)
+   reg &= ~DWC3_GUSB3PIPECTL_DEPOCHANGE;
+
dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
 
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
@@ -947,6 +950,8 @@ static int dwc3_probe(struct platform_device *pdev)
"snps,dis_rxdet_inp3_quirk");
dwc->dis_u2_freeclk_exists_quirk = device_property_read_bool(dev,
"snps,dis-u2-freeclk-exists-quirk");
+   dwc->dis_del_phy_power_chg_quirk = device_property_read_bool(dev,
+   "snps,dis-del-phy-power-chg-quirk");
 
dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
"snps,tx_de_emphasis_quirk");
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index cc4f551..3d94acd 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -818,6 +818,8 @@ struct dwc3_scratchpad_array {
  * @dis_u2_freeclk_exists_quirk : set if we clear u2_freeclk_exists
  * in GUSB2PHYCFG, specify that USB2 PHY doesn't
  * provide a free-running PHY clock.
+ * @dis_del_phy_power_chg_quirk: set if we disable delay phy power
+ * change quirk.
  * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
  * @tx_de_emphasis: Tx de-emphasis value
  * 0   - -6dB de-emphasis
@@ -963,6 +965,7 @@ struct dwc3 {
unsigneddis_enblslpm_quirk:1;
unsigneddis_rxdet_inp3_quirk:1;
unsigneddis_u2_freeclk_exists_quirk:1;
+   unsigneddis_del_phy_power_chg_quirk:1;
 
unsignedtx_de_emphasis_quirk:1;
unsignedtx_de_emphasis:2;
-- 
1.9.1




[PATCH v10 5/5] usb: dwc3: add rockchip specific glue layer

2016-08-15 Thread William Wu
Add rockchip specific glue layer to support USB3 Peripheral mode
and Host mode on rockchip platforms (e.g. rk3399).

The DesignWare USB3 integrated in rockchip SoCs is a configurable
IP Core which can be instantiated as Dual-Role Device (DRD), Host
Only (XHCI) and Peripheral Only configurations.

We use extcon notifier to manage usb cable detection and mode switch.
Enable DWC3 PM runtime auto suspend to allow core enter runtime_suspend
if USB cable is dettached. For host mode, it requires to keep whole
DWC3 controller in reset state to hold pipe power state in P2 before
initializing PHY. And it need to reconfigure USB PHY interface of DWC3
core after deassert DWC3 controller reset.

The current driver supports Host only and Peripheral Only well, for
now, we will add support for OTG after we have it all stabilized.

Signed-off-by: William Wu 
---
Changes in v10:
- fix building error

Changes in v9:
- Add a new dwc3-rockchip.c driver for rk3399, rather than use dwc3-of-simple.c

 drivers/usb/dwc3/Kconfig |   9 +
 drivers/usb/dwc3/Makefile|   1 +
 drivers/usb/dwc3/core.c  |   2 +-
 drivers/usb/dwc3/core.h  |   1 +
 drivers/usb/dwc3/dwc3-rockchip.c | 441 +++
 5 files changed, 453 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/dwc3/dwc3-rockchip.c

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index a64ce1c..3d5ec30 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -96,6 +96,15 @@ config USB_DWC3_OF_SIMPLE
 Currently supports Xilinx and Qualcomm DWC USB3 IP.
 Say 'Y' or 'M' if you have one such device.
 
+config USB_DWC3_ROCKCHIP
+   tristate "Rockchip Platforms"
+   depends on EXTCON && (ARCH_ROCKCHIP || COMPILE_TEST)
+   depends on OF
+   default USB_DWC3
+   help
+ Support of USB2/3 functionality in Rockchip platforms.
+ say 'Y' or 'M' if you have one such device.
+
 config USB_DWC3_ST
tristate "STMicroelectronics Platforms"
depends on ARCH_STI && OF
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index 22420e1..86fc4fd 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -38,4 +38,5 @@ obj-$(CONFIG_USB_DWC3_EXYNOS) += dwc3-exynos.o
 obj-$(CONFIG_USB_DWC3_PCI) += dwc3-pci.o
 obj-$(CONFIG_USB_DWC3_KEYSTONE)+= dwc3-keystone.o
 obj-$(CONFIG_USB_DWC3_OF_SIMPLE)   += dwc3-of-simple.o
+obj-$(CONFIG_USB_DWC3_ROCKCHIP)+= dwc3-rockchip.o
 obj-$(CONFIG_USB_DWC3_ST)  += dwc3-st.o
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index e887b38..3da6215 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -405,7 +405,7 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
  * initialized. The PHY interfaces and the PHYs get initialized together with
  * the core in dwc3_core_init.
  */
-static int dwc3_phy_setup(struct dwc3 *dwc)
+int dwc3_phy_setup(struct dwc3 *dwc)
 {
u32 reg;
int ret;
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 3d94acd..79403ff 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -1123,6 +1123,7 @@ struct dwc3_gadget_ep_cmd_params {
 /* prototypes */
 void dwc3_set_mode(struct dwc3 *dwc, u32 mode);
 u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type);
+int dwc3_phy_setup(struct dwc3 *dwc);
 
 /* check whether we are on the DWC_usb31 core */
 static inline bool dwc3_is_usb31(struct dwc3 *dwc)
diff --git a/drivers/usb/dwc3/dwc3-rockchip.c b/drivers/usb/dwc3/dwc3-rockchip.c
new file mode 100644
index 000..eeae1a9
--- /dev/null
+++ b/drivers/usb/dwc3/dwc3-rockchip.c
@@ -0,0 +1,441 @@
+/**
+ * dwc3-rockchip.c - Rockchip Specific Glue layer
+ *
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ *
+ * Authors: William Wu 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2  of
+ * the License as published by the Free Software Foundation.
+ *
+ * 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 
+#include 
+
+#include "core.h"
+#include "io.h"
+
+#define DWC3_ROCKCHIP_AUTOSUSPEND_DELAY  500 /* ms */
+
+struct dwc3_rockchip {
+   int num_clocks;
+   struct device   *dev;
+   struct clk  **clks;
+   struct dwc3 *dwc;
+   struct reset_control*otg_rst;
+   struct extcon_dev   *edev;
+   struct notifier_bloc

[PATCH v10 4/5] usb: dwc3: rockchip: add devicetree bindings documentation

2016-08-15 Thread William Wu
This patch adds the devicetree documentation required for Rockchip
USB3.0 core wrapper consisting of USB3.0 IP from Synopsys.

It supports DRD mode, and could operate in device mode (SS, HS, FS)
and host mode (SS, HS, FS, LS).

Signed-off-by: William Wu 
Acked-by: Rob Herring 
---
Changes in v10:
- None

Changes in v9:
- add required properties "resets" and "reset-names"
- add optional property "extcon"

Changes in v8:
- None

Changes in v7:
- add Acked-by (Rob Herring)

Changes in v6:
- rename bus_clk, and add usbdrd3_1 node as an example (Heiko)

Changes in v5:
- rename clock-names, and remove unnecessary clocks (Heiko)

Changes in v4:
- modify commit log, and add phy documentation location (Sergei)

Changes in v3:
- add dwc3 address (balbi)

Changes in v2:
- add rockchip,dwc3.txt to Documentation/devicetree/bindings/ (balbi, Brian)

 .../devicetree/bindings/usb/rockchip,dwc3.txt  | 71 ++
 1 file changed, 71 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/rockchip,dwc3.txt

diff --git a/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt 
b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
new file mode 100644
index 000..3a79be8
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
@@ -0,0 +1,71 @@
+Rockchip SuperSpeed DWC3 USB SoC controller
+
+Required properties:
+- compatible:  should contain "rockchip,rk3399-dwc3" for rk3399 SoC
+- clocks:  A list of phandle + clock-specifier pairs for the
+   clocks listed in clock-names
+- clock-names: Should contain the following:
+  "ref_clk"Controller reference clk, have to be 24 MHz
+  "suspend_clk"Controller suspend clk, have to be 24 MHz or 32 KHz
+  "bus_clk"Master/Core clock, have to be >= 62.5 MHz for SS
+   operation and >= 30MHz for HS operation
+  "grf_clk"Controller grf clk
+- resets:  List of phandle and reset specifier pairs. Should contain
+   softreset line of the DWC3 controller
+- reset-names: List of reset signal names. Names should contain "usb3-otg"
+   for DWC3 controller reset.
+
+Optional properties:
+- extcon:  Phandles to external connector devices, which provide
+   "EXTCON_USB" and "EXTCON_USB_HOST" cable events.
+
+Required child node:
+A child node must exist to represent the core DWC3 IP block. The name of
+the node is not important. The content of the node is defined in dwc3.txt.
+
+Phy documentation is provided in the following places:
+Documentation/devicetree/bindings/phy/rockchip,dwc3-usb-phy.txt
+
+Example device nodes:
+
+   usbdrd3_0: usb@fe80 {
+   compatible = "rockchip,rk3399-dwc3";
+   clocks = <&cru SCLK_USB3OTG0_REF>, <&cru SCLK_USB3OTG0_SUSPEND>,
+<&cru ACLK_USB3OTG0>, <&cru ACLK_USB3_GRF>;
+   clock-names = "ref_clk", "suspend_clk",
+ "bus_clk", "grf_clk";
+   resets = <&cru SRST_A_USB3_OTG0>;
+   reset-names = "usb3-otg";
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges;
+   status = "disabled";
+   usbdrd_dwc3_0: dwc3@fe80 {
+   compatible = "snps,dwc3";
+   reg = <0x0 0xfe80 0x0 0x10>;
+   interrupts = ;
+   dr_mode = "otg";
+   status = "disabled";
+   };
+   };
+
+   usbdrd3_1: usb@fe90 {
+   compatible = "rockchip,rk3399-dwc3";
+   clocks = <&cru SCLK_USB3OTG1_REF>, <&cru SCLK_USB3OTG1_SUSPEND>,
+<&cru ACLK_USB3OTG1>, <&cru ACLK_USB3_GRF>;
+   clock-names = "ref_clk", "suspend_clk",
+ "bus_clk", "grf_clk";
+   resets = <&cru SRST_A_USB3_OTG1>;
+   reset-names = "usb3-otg";
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges;
+   status = "disabled";
+   usbdrd_dwc3_1: dwc3@fe90 {
+   compatible = "snps,dwc3";
+   reg = <0x0 0xfe90 0x0 0x10>;
+   interrupts = ;
+   dr_mode = "otg";
+   status = "disabled";
+   };
+   };
-- 
1.9.1




[PATCH v10 3/5] usb: dwc3: add dis_del_phy_power_chg_quirk

2016-08-15 Thread William Wu
Add a quirk to clear the GUSB3PIPECTL.DELAYP1TRANS bit,
which specifies whether disable delay PHY power change
from P0 to P1/P2/P3 when link state changing from U0
to U1/U2/U3 respectively.

Signed-off-by: William Wu 
Acked-by: Rob Herring 
---
Changes in v10:
- None

Changes in v9:
- None

Changes in v8:
- add Acked-by (Rob Herring)

Changes in v7:
- None

Changes in v6:
- use '-' instead of '_' in dts (Rob Herring)

Changes in v5:
- None

Changes in v4:
- rebase on top of balbi testing/next, remove pdata (balbi)

Changes in v3:
- None

Changes in v2:
- None

 Documentation/devicetree/bindings/usb/dwc3.txt | 2 ++
 drivers/usb/dwc3/core.c| 5 +
 drivers/usb/dwc3/core.h| 3 +++
 3 files changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt 
b/Documentation/devicetree/bindings/usb/dwc3.txt
index 020b0e9..e96bfc2 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -42,6 +42,8 @@ Optional properties:
  - snps,dis-u2-freeclk-exists-quirk: when set, clear the u2_freeclk_exists
in GUSB2PHYCFG, specify that USB2 PHY doesn't provide
a free-running PHY clock.
+ - snps,dis-del-phy-power-chg-quirk: when set core will change PHY power
+   from P0 to P1/P2/P3 without delay.
  - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
utmi_l1_suspend_n, false when asserts utmi_sleep_n
  - snps,hird-threshold: HIRD threshold
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index cdac019..e887b38 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -448,6 +448,9 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
if (dwc->dis_u3_susphy_quirk)
reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
 
+   if (dwc->dis_del_phy_power_chg_quirk)
+   reg &= ~DWC3_GUSB3PIPECTL_DEPOCHANGE;
+
dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
 
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
@@ -947,6 +950,8 @@ static int dwc3_probe(struct platform_device *pdev)
"snps,dis_rxdet_inp3_quirk");
dwc->dis_u2_freeclk_exists_quirk = device_property_read_bool(dev,
"snps,dis-u2-freeclk-exists-quirk");
+   dwc->dis_del_phy_power_chg_quirk = device_property_read_bool(dev,
+   "snps,dis-del-phy-power-chg-quirk");
 
dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
"snps,tx_de_emphasis_quirk");
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index cc4f551..3d94acd 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -818,6 +818,8 @@ struct dwc3_scratchpad_array {
  * @dis_u2_freeclk_exists_quirk : set if we clear u2_freeclk_exists
  * in GUSB2PHYCFG, specify that USB2 PHY doesn't
  * provide a free-running PHY clock.
+ * @dis_del_phy_power_chg_quirk: set if we disable delay phy power
+ * change quirk.
  * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
  * @tx_de_emphasis: Tx de-emphasis value
  * 0   - -6dB de-emphasis
@@ -963,6 +965,7 @@ struct dwc3 {
unsigneddis_enblslpm_quirk:1;
unsigneddis_rxdet_inp3_quirk:1;
unsigneddis_u2_freeclk_exists_quirk:1;
+   unsigneddis_del_phy_power_chg_quirk:1;
 
unsignedtx_de_emphasis_quirk:1;
unsignedtx_de_emphasis:2;
-- 
1.9.1




[PATCH v10 2/5] usb: dwc3: make usb2 phy utmi interface configurable

2016-08-15 Thread William Wu
Support to configure the UTMI+ PHY with an 8- or 16-bit
interface via DT. The UTMI+ PHY interface is a hardware
capability, and it's platform dependent. Normally, the
PHYIF can be configured during coreconsultant.

But for some specific USB cores(e.g. rk3399 SoC DWC3),
the default PHYIF configuration value is false, so we
need to reconfigure it by software.

Signed-off-by: William Wu 
Acked-by: Rob Herring 
---
Changes in v10:
- None

Changes in v9:
- None

Changes in v8:
- configure utmi interface via phy_type property in DT (Heiko, Rob Herring)
- add Acked-by (Rob Herring)
- modify commit message (Rob Herring)

Changes in v7:
- remove quirk and use only one property to configure utmi (Heiko, Rob Herring)

Changes in v6:
- use '-' instead of '_' in dts (Rob Herring)

Changes in v5:
- None

Changes in v4:
- rebase on top of balbi testing/next, remove pdata (balbi)

Changes in v3:
- None

Changes in v2:
- add a quirk for phyif_utmi (balbi)

 Documentation/devicetree/bindings/usb/generic.txt |  6 ++
 drivers/usb/dwc3/core.c   | 18 ++
 drivers/usb/dwc3/core.h   | 12 
 3 files changed, 36 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/generic.txt 
b/Documentation/devicetree/bindings/usb/generic.txt
index bba8257..bfadeb1 100644
--- a/Documentation/devicetree/bindings/usb/generic.txt
+++ b/Documentation/devicetree/bindings/usb/generic.txt
@@ -11,6 +11,11 @@ Optional properties:
"peripheral" and "otg". In case this attribute isn't
passed via DT, USB DRD controllers should default to
OTG.
+ - phy_type: tells USB controllers that we want to configure the core to 
support
+   a UTMI+ PHY with an 8- or 16-bit interface if UTMI+ is
+   selected. Valid arguments are "utmi" and "utmi_wide".
+   In case this isn't passed via DT, USB controllers should
+   default to HW capability.
  - otg-rev: tells usb driver the release number of the OTG and EH supplement
with which the device and its descriptors are compliant,
in binary-coded decimal (i.e. 2.0 is 0200H). This
@@ -34,6 +39,7 @@ dwc3@4a03 {
usb-phy = <&usb2_phy>, <&usb3,phy>;
maximum-speed = "super-speed";
dr_mode = "otg";
+   phy_type = "utmi_wide";
otg-rev = <0x0200>;
adp-disable;
 };
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 14316e5..cdac019 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -485,6 +485,23 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
break;
}
 
+   switch (dwc->hsphy_mode) {
+   case USBPHY_INTERFACE_MODE_UTMI:
+   reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
+  DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
+   reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_8_BIT) |
+  DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_8_BIT);
+   break;
+   case USBPHY_INTERFACE_MODE_UTMIW:
+   reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
+  DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
+   reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_16_BIT) |
+  DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_16_BIT);
+   break;
+   default:
+   break;
+   }
+
/*
 * Above 1.94a, it is recommended to set DWC3_GUSB2PHYCFG_SUSPHY to
 * '0' during coreConsultant configuration. So default value will
@@ -891,6 +908,7 @@ static int dwc3_probe(struct platform_device *pdev)
 
dwc->maximum_speed = usb_get_maximum_speed(dev);
dwc->dr_mode = usb_get_dr_mode(dev);
+   dwc->hsphy_mode = of_usb_get_phy_mode(dev->of_node);
 
dwc->has_lpm_erratum = device_property_read_bool(dev,
"snps,has-lpm-erratum");
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 08ed9e0..cc4f551 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -203,6 +203,14 @@
 #define DWC3_GUSB2PHYCFG_SUSPHY(1 << 6)
 #define DWC3_GUSB2PHYCFG_ULPI_UTMI (1 << 4)
 #define DWC3_GUSB2PHYCFG_ENBLSLPM  (1 << 8)
+#define DWC3_GUSB2PHYCFG_PHYIF(n)  (n << 3)
+#define DWC3_GUSB2PHYCFG_PHYIF_MASKDWC3_GUSB2PHYCFG_PHYIF(1)
+#define DWC3_GUSB2PHYCFG_USBTRDTIM(n)  (n << 10)
+#define DWC3_GUSB2PHYCFG_USBTRDTIM_MASKDWC3_GUSB2PHYCFG_USBTRDTIM(0xf)
+#define USBTRDTIM_UTMI_8_BIT   9
+#define USBTRDTIM_UTMI_16_BIT  5
+#define UTMI_PHYIF_16_BIT  1
+#define UTMI_PHYIF_8_BIT   0
 
 /* Global USB2 PHY Vendor Control Reg

[PATCH v10 1/5] usb: dwc3: add dis_u2_freeclk_exists_quirk

2016-08-15 Thread William Wu
Add a quirk to clear the GUSB2PHYCFG.U2_FREECLK_EXISTS bit,
which specifies whether the USB2.0 PHY provides a free-running
PHY clock, which is active when the clock control input is active.

Signed-off-by: William Wu 
Acked-by: Rob Herring 
---
Changes in v10:
- None

Changes in v9:
- None

Changes in v8:
- add Acked-by (Rob Herring)

Changes in v7:
- None

Changes in v6:
- use '-' instead of '_' in dts (Rob Herring)

Changes in v5:
- None

Changes in v4:
- rebase on top of balbi testing/next, remove pdata (balbi)

Changes in v3:
- None

Changes in v2:
- None

 Documentation/devicetree/bindings/usb/dwc3.txt | 3 +++
 drivers/usb/dwc3/core.c| 5 +
 drivers/usb/dwc3/core.h| 5 +
 3 files changed, 13 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt 
b/Documentation/devicetree/bindings/usb/dwc3.txt
index 7d7ce08..020b0e9 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -39,6 +39,9 @@ Optional properties:
disabling the suspend signal to the PHY.
  - snps,dis_rxdet_inp3_quirk: when set core will disable receiver detection
in PHY P3 power state.
+ - snps,dis-u2-freeclk-exists-quirk: when set, clear the u2_freeclk_exists
+   in GUSB2PHYCFG, specify that USB2 PHY doesn't provide
+   a free-running PHY clock.
  - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
utmi_l1_suspend_n, false when asserts utmi_sleep_n
  - snps,hird-threshold: HIRD threshold
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 35d0924..14316e5 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -500,6 +500,9 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
if (dwc->dis_enblslpm_quirk)
reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
 
+   if (dwc->dis_u2_freeclk_exists_quirk)
+   reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS;
+
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
 
return 0;
@@ -924,6 +927,8 @@ static int dwc3_probe(struct platform_device *pdev)
"snps,dis_enblslpm_quirk");
dwc->dis_rxdet_inp3_quirk = device_property_read_bool(dev,
"snps,dis_rxdet_inp3_quirk");
+   dwc->dis_u2_freeclk_exists_quirk = device_property_read_bool(dev,
+   "snps,dis-u2-freeclk-exists-quirk");
 
dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
"snps,tx_de_emphasis_quirk");
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 1a6cc48..08ed9e0 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -199,6 +199,7 @@
 
 /* Global USB2 PHY Configuration Register */
 #define DWC3_GUSB2PHYCFG_PHYSOFTRST(1 << 31)
+#define DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS (1 << 30)
 #define DWC3_GUSB2PHYCFG_SUSPHY(1 << 6)
 #define DWC3_GUSB2PHYCFG_ULPI_UTMI (1 << 4)
 #define DWC3_GUSB2PHYCFG_ENBLSLPM  (1 << 8)
@@ -803,6 +804,9 @@ struct dwc3_scratchpad_array {
  * @dis_u2_susphy_quirk: set if we disable usb2 suspend phy
  * @dis_enblslpm_quirk: set if we clear enblslpm in GUSB2PHYCFG,
  *  disabling the suspend signal to the PHY.
+ * @dis_u2_freeclk_exists_quirk : set if we clear u2_freeclk_exists
+ * in GUSB2PHYCFG, specify that USB2 PHY doesn't
+ * provide a free-running PHY clock.
  * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
  * @tx_de_emphasis: Tx de-emphasis value
  * 0   - -6dB de-emphasis
@@ -946,6 +950,7 @@ struct dwc3 {
unsigneddis_u2_susphy_quirk:1;
unsigneddis_enblslpm_quirk:1;
unsigneddis_rxdet_inp3_quirk:1;
+   unsigneddis_u2_freeclk_exists_quirk:1;
 
unsignedtx_de_emphasis_quirk:1;
unsignedtx_de_emphasis:2;
-- 
1.9.1




[PATCH v10 0/5] support rockchip dwc3 driver

2016-08-15 Thread William Wu
This series add support for rockchip DWC3 driver,
and add additional optional properties for specific
platforms (e.g., rockchip rk3399 platform).

And because rockchip DWC3 need additional handling of
cable events and mode switch to support DRD mode, so
we add a new dwc3-rockchip driver, rather than use the
generic of glue layer which merely enable some clocks
and populate its children.

William Wu (5):
  usb: dwc3: add dis_u2_freeclk_exists_quirk
  usb: dwc3: make usb2 phy utmi interface configurable
  usb: dwc3: add dis_del_phy_power_chg_quirk
  usb: dwc3: rockchip: add devicetree bindings documentation
  usb: dwc3: add rockchip specific glue layer

 Documentation/devicetree/bindings/usb/dwc3.txt |   5 +
 Documentation/devicetree/bindings/usb/generic.txt  |   6 +
 .../devicetree/bindings/usb/rockchip,dwc3.txt  |  71 
 drivers/usb/dwc3/Kconfig   |   9 +
 drivers/usb/dwc3/Makefile  |   1 +
 drivers/usb/dwc3/core.c|  30 +-
 drivers/usb/dwc3/core.h|  21 +
 drivers/usb/dwc3/dwc3-rockchip.c   | 441 +
 8 files changed, 583 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
 create mode 100644 drivers/usb/dwc3/dwc3-rockchip.c

-- 
1.9.1




[PATCH v9 5/5] usb: dwc3: add rockchip specific glue layer

2016-08-15 Thread William Wu
Add rockchip specific glue layer to support USB3 Peripheral mode
and Host mode on rockchip platforms (e.g. rk3399).

The DesignWare USB3 integrated in rockchip SoCs is a configurable
IP Core which can be instantiated as Dual-Role Device (DRD), Host
Only (XHCI) and Peripheral Only configurations.

We use extcon notifier to manage usb cable detection and mode switch.
Enable DWC3 PM runtime auto suspend to allow core enter runtime_suspend
if USB cable is dettached. For host mode, it requires to keep whole
DWC3 controller in reset state to hold pipe power state in P2 before
initializing PHY. And it need to reconfigure USB PHY interface of DWC3
core after deassert DWC3 controller reset.

The current driver supports Host only and Peripheral Only well, for
now, we will add support for OTG after we have it all stabilized.

Signed-off-by: William Wu 
---
 drivers/usb/dwc3/Kconfig |   9 +
 drivers/usb/dwc3/Makefile|   1 +
 drivers/usb/dwc3/core.c  |   2 +-
 drivers/usb/dwc3/core.h  |   1 +
 drivers/usb/dwc3/dwc3-rockchip.c | 441 +++
 5 files changed, 453 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/dwc3/dwc3-rockchip.c

diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index a64ce1c..3d5ec30 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -96,6 +96,15 @@ config USB_DWC3_OF_SIMPLE
 Currently supports Xilinx and Qualcomm DWC USB3 IP.
 Say 'Y' or 'M' if you have one such device.
 
+config USB_DWC3_ROCKCHIP
+   tristate "Rockchip Platforms"
+   depends on EXTCON && (ARCH_ROCKCHIP || COMPILE_TEST)
+   depends on OF
+   default USB_DWC3
+   help
+ Support of USB2/3 functionality in Rockchip platforms.
+ say 'Y' or 'M' if you have one such device.
+
 config USB_DWC3_ST
tristate "STMicroelectronics Platforms"
depends on ARCH_STI && OF
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index 22420e1..86fc4fd 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -38,4 +38,5 @@ obj-$(CONFIG_USB_DWC3_EXYNOS) += dwc3-exynos.o
 obj-$(CONFIG_USB_DWC3_PCI) += dwc3-pci.o
 obj-$(CONFIG_USB_DWC3_KEYSTONE)+= dwc3-keystone.o
 obj-$(CONFIG_USB_DWC3_OF_SIMPLE)   += dwc3-of-simple.o
+obj-$(CONFIG_USB_DWC3_ROCKCHIP)+= dwc3-rockchip.o
 obj-$(CONFIG_USB_DWC3_ST)  += dwc3-st.o
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index e887b38..3da6215 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -405,7 +405,7 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
  * initialized. The PHY interfaces and the PHYs get initialized together with
  * the core in dwc3_core_init.
  */
-static int dwc3_phy_setup(struct dwc3 *dwc)
+int dwc3_phy_setup(struct dwc3 *dwc)
 {
u32 reg;
int ret;
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 3d94acd..79403ff 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -1123,6 +1123,7 @@ struct dwc3_gadget_ep_cmd_params {
 /* prototypes */
 void dwc3_set_mode(struct dwc3 *dwc, u32 mode);
 u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type);
+int dwc3_phy_setup(struct dwc3 *dwc);
 
 /* check whether we are on the DWC_usb31 core */
 static inline bool dwc3_is_usb31(struct dwc3 *dwc)
diff --git a/drivers/usb/dwc3/dwc3-rockchip.c b/drivers/usb/dwc3/dwc3-rockchip.c
new file mode 100644
index 000..632bbb9
--- /dev/null
+++ b/drivers/usb/dwc3/dwc3-rockchip.c
@@ -0,0 +1,441 @@
+/**
+ * dwc3-rockchip.c - Rockchip Specific Glue layer
+ *
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ *
+ * Authors: William Wu 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2  of
+ * the License as published by the Free Software Foundation.
+ *
+ * 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 
+#include 
+
+#include "core.h"
+#include "io.h"
+
+#define DWC3_ROCKCHIP_AUTOSUSPEND_DELAY  500 /* ms */
+
+struct dwc3_rockchip {
+   int num_clocks;
+   struct device   *dev;
+   struct clk  **clks;
+   struct dwc3 *dwc;
+   struct reset_control*otg_rst;
+   struct extcon_dev   *edev;
+   struct notifier_block   device_nb;
+   struct notifier_block   host_nb;
+   struct work_struct  otg_work;
+};
+
+static int dwc3_rockchip_device_

[PATCH v9 4/5] usb: dwc3: rockchip: add devicetree bindings documentation

2016-08-15 Thread William Wu
This patch adds the devicetree documentation required for Rockchip
USB3.0 core wrapper consisting of USB3.0 IP from Synopsys.

It supports DRD mode, and could operate in device mode (SS, HS, FS)
and host mode (SS, HS, FS, LS).

Signed-off-by: William Wu 
Acked-by: Rob Herring 
---
Changes in v9:
- add required properties "resets" and "reset-names"
- add optional property "extcon"

Changes in v8:
- None

Changes in v7:
- add Acked-by (Rob Herring)

Changes in v6:
- rename bus_clk, and add usbdrd3_1 node as an example (Heiko)

Changes in v5:
- rename clock-names, and remove unnecessary clocks (Heiko)

Changes in v4:
- modify commit log, and add phy documentation location (Sergei)

Changes in v3:
- add dwc3 address (balbi)

Changes in v2:
- add rockchip,dwc3.txt to Documentation/devicetree/bindings/ (balbi, Brian)

 .../devicetree/bindings/usb/rockchip,dwc3.txt  | 71 ++
 1 file changed, 71 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/rockchip,dwc3.txt

diff --git a/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt 
b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
new file mode 100644
index 000..3a79be8
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
@@ -0,0 +1,71 @@
+Rockchip SuperSpeed DWC3 USB SoC controller
+
+Required properties:
+- compatible:  should contain "rockchip,rk3399-dwc3" for rk3399 SoC
+- clocks:  A list of phandle + clock-specifier pairs for the
+   clocks listed in clock-names
+- clock-names: Should contain the following:
+  "ref_clk"Controller reference clk, have to be 24 MHz
+  "suspend_clk"Controller suspend clk, have to be 24 MHz or 32 KHz
+  "bus_clk"Master/Core clock, have to be >= 62.5 MHz for SS
+   operation and >= 30MHz for HS operation
+  "grf_clk"Controller grf clk
+- resets:  List of phandle and reset specifier pairs. Should contain
+   softreset line of the DWC3 controller
+- reset-names: List of reset signal names. Names should contain "usb3-otg"
+   for DWC3 controller reset.
+
+Optional properties:
+- extcon:  Phandles to external connector devices, which provide
+   "EXTCON_USB" and "EXTCON_USB_HOST" cable events.
+
+Required child node:
+A child node must exist to represent the core DWC3 IP block. The name of
+the node is not important. The content of the node is defined in dwc3.txt.
+
+Phy documentation is provided in the following places:
+Documentation/devicetree/bindings/phy/rockchip,dwc3-usb-phy.txt
+
+Example device nodes:
+
+   usbdrd3_0: usb@fe80 {
+   compatible = "rockchip,rk3399-dwc3";
+   clocks = <&cru SCLK_USB3OTG0_REF>, <&cru SCLK_USB3OTG0_SUSPEND>,
+<&cru ACLK_USB3OTG0>, <&cru ACLK_USB3_GRF>;
+   clock-names = "ref_clk", "suspend_clk",
+ "bus_clk", "grf_clk";
+   resets = <&cru SRST_A_USB3_OTG0>;
+   reset-names = "usb3-otg";
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges;
+   status = "disabled";
+   usbdrd_dwc3_0: dwc3@fe80 {
+   compatible = "snps,dwc3";
+   reg = <0x0 0xfe80 0x0 0x10>;
+   interrupts = ;
+   dr_mode = "otg";
+   status = "disabled";
+   };
+   };
+
+   usbdrd3_1: usb@fe90 {
+   compatible = "rockchip,rk3399-dwc3";
+   clocks = <&cru SCLK_USB3OTG1_REF>, <&cru SCLK_USB3OTG1_SUSPEND>,
+<&cru ACLK_USB3OTG1>, <&cru ACLK_USB3_GRF>;
+   clock-names = "ref_clk", "suspend_clk",
+ "bus_clk", "grf_clk";
+   resets = <&cru SRST_A_USB3_OTG1>;
+   reset-names = "usb3-otg";
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges;
+   status = "disabled";
+   usbdrd_dwc3_1: dwc3@fe90 {
+   compatible = "snps,dwc3";
+   reg = <0x0 0xfe90 0x0 0x10>;
+   interrupts = ;
+   dr_mode = "otg";
+   status = "disabled";
+   };
+   };
-- 
1.9.1




[PATCH v9 2/5] usb: dwc3: make usb2 phy utmi interface configurable

2016-08-15 Thread William Wu
Support to configure the UTMI+ PHY with an 8- or 16-bit
interface via DT. The UTMI+ PHY interface is a hardware
capability, and it's platform dependent. Normally, the
PHYIF can be configured during coreconsultant.

But for some specific USB cores(e.g. rk3399 SoC DWC3),
the default PHYIF configuration value is false, so we
need to reconfigure it by software.

Signed-off-by: William Wu 
Acked-by: Rob Herring 
---
Changes in v9:
- None

Changes in v8:
- configure utmi interface via phy_type property in DT (Heiko, Rob Herring)
- add Acked-by (Rob Herring)
- modify commit message (Rob Herring)

Changes in v7:
- remove quirk and use only one property to configure utmi (Heiko, Rob Herring)

Changes in v6:
- use '-' instead of '_' in dts (Rob Herring)

Changes in v5:
- None

Changes in v4:
- rebase on top of balbi testing/next, remove pdata (balbi)

Changes in v3:
- None

Changes in v2:
- add a quirk for phyif_utmi (balbi)

 Documentation/devicetree/bindings/usb/generic.txt |  6 ++
 drivers/usb/dwc3/core.c   | 18 ++
 drivers/usb/dwc3/core.h   | 12 
 3 files changed, 36 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/generic.txt 
b/Documentation/devicetree/bindings/usb/generic.txt
index bba8257..bfadeb1 100644
--- a/Documentation/devicetree/bindings/usb/generic.txt
+++ b/Documentation/devicetree/bindings/usb/generic.txt
@@ -11,6 +11,11 @@ Optional properties:
"peripheral" and "otg". In case this attribute isn't
passed via DT, USB DRD controllers should default to
OTG.
+ - phy_type: tells USB controllers that we want to configure the core to 
support
+   a UTMI+ PHY with an 8- or 16-bit interface if UTMI+ is
+   selected. Valid arguments are "utmi" and "utmi_wide".
+   In case this isn't passed via DT, USB controllers should
+   default to HW capability.
  - otg-rev: tells usb driver the release number of the OTG and EH supplement
with which the device and its descriptors are compliant,
in binary-coded decimal (i.e. 2.0 is 0200H). This
@@ -34,6 +39,7 @@ dwc3@4a03 {
usb-phy = <&usb2_phy>, <&usb3,phy>;
maximum-speed = "super-speed";
dr_mode = "otg";
+   phy_type = "utmi_wide";
otg-rev = <0x0200>;
adp-disable;
 };
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 14316e5..cdac019 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -485,6 +485,23 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
break;
}
 
+   switch (dwc->hsphy_mode) {
+   case USBPHY_INTERFACE_MODE_UTMI:
+   reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
+  DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
+   reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_8_BIT) |
+  DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_8_BIT);
+   break;
+   case USBPHY_INTERFACE_MODE_UTMIW:
+   reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
+  DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
+   reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_16_BIT) |
+  DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_16_BIT);
+   break;
+   default:
+   break;
+   }
+
/*
 * Above 1.94a, it is recommended to set DWC3_GUSB2PHYCFG_SUSPHY to
 * '0' during coreConsultant configuration. So default value will
@@ -891,6 +908,7 @@ static int dwc3_probe(struct platform_device *pdev)
 
dwc->maximum_speed = usb_get_maximum_speed(dev);
dwc->dr_mode = usb_get_dr_mode(dev);
+   dwc->hsphy_mode = of_usb_get_phy_mode(dev->of_node);
 
dwc->has_lpm_erratum = device_property_read_bool(dev,
"snps,has-lpm-erratum");
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 08ed9e0..cc4f551 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -203,6 +203,14 @@
 #define DWC3_GUSB2PHYCFG_SUSPHY(1 << 6)
 #define DWC3_GUSB2PHYCFG_ULPI_UTMI (1 << 4)
 #define DWC3_GUSB2PHYCFG_ENBLSLPM  (1 << 8)
+#define DWC3_GUSB2PHYCFG_PHYIF(n)  (n << 3)
+#define DWC3_GUSB2PHYCFG_PHYIF_MASKDWC3_GUSB2PHYCFG_PHYIF(1)
+#define DWC3_GUSB2PHYCFG_USBTRDTIM(n)  (n << 10)
+#define DWC3_GUSB2PHYCFG_USBTRDTIM_MASKDWC3_GUSB2PHYCFG_USBTRDTIM(0xf)
+#define USBTRDTIM_UTMI_8_BIT   9
+#define USBTRDTIM_UTMI_16_BIT  5
+#define UTMI_PHYIF_16_BIT  1
+#define UTMI_PHYIF_8_BIT   0
 
 /* Global USB2 PHY Vendor Control Register */
 #define DWC3_GUSB2PHY

[PATCH v9 3/5] usb: dwc3: add dis_del_phy_power_chg_quirk

2016-08-15 Thread William Wu
Add a quirk to clear the GUSB3PIPECTL.DELAYP1TRANS bit,
which specifies whether disable delay PHY power change
from P0 to P1/P2/P3 when link state changing from U0
to U1/U2/U3 respectively.

Signed-off-by: William Wu 
Acked-by: Rob Herring 
---
Changes in v9:
- None

Changes in v8:
- add Acked-by (Rob Herring)

Changes in v7:
- None

Changes in v6:
- use '-' instead of '_' in dts (Rob Herring)

Changes in v5:
- None

Changes in v4:
- rebase on top of balbi testing/next, remove pdata (balbi)

Changes in v3:
- None

Changes in v2:
- None

 Documentation/devicetree/bindings/usb/dwc3.txt | 2 ++
 drivers/usb/dwc3/core.c| 5 +
 drivers/usb/dwc3/core.h| 3 +++
 3 files changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt 
b/Documentation/devicetree/bindings/usb/dwc3.txt
index 020b0e9..e96bfc2 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -42,6 +42,8 @@ Optional properties:
  - snps,dis-u2-freeclk-exists-quirk: when set, clear the u2_freeclk_exists
in GUSB2PHYCFG, specify that USB2 PHY doesn't provide
a free-running PHY clock.
+ - snps,dis-del-phy-power-chg-quirk: when set core will change PHY power
+   from P0 to P1/P2/P3 without delay.
  - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
utmi_l1_suspend_n, false when asserts utmi_sleep_n
  - snps,hird-threshold: HIRD threshold
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index cdac019..e887b38 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -448,6 +448,9 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
if (dwc->dis_u3_susphy_quirk)
reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
 
+   if (dwc->dis_del_phy_power_chg_quirk)
+   reg &= ~DWC3_GUSB3PIPECTL_DEPOCHANGE;
+
dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
 
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
@@ -947,6 +950,8 @@ static int dwc3_probe(struct platform_device *pdev)
"snps,dis_rxdet_inp3_quirk");
dwc->dis_u2_freeclk_exists_quirk = device_property_read_bool(dev,
"snps,dis-u2-freeclk-exists-quirk");
+   dwc->dis_del_phy_power_chg_quirk = device_property_read_bool(dev,
+   "snps,dis-del-phy-power-chg-quirk");
 
dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
"snps,tx_de_emphasis_quirk");
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index cc4f551..3d94acd 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -818,6 +818,8 @@ struct dwc3_scratchpad_array {
  * @dis_u2_freeclk_exists_quirk : set if we clear u2_freeclk_exists
  * in GUSB2PHYCFG, specify that USB2 PHY doesn't
  * provide a free-running PHY clock.
+ * @dis_del_phy_power_chg_quirk: set if we disable delay phy power
+ * change quirk.
  * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
  * @tx_de_emphasis: Tx de-emphasis value
  * 0   - -6dB de-emphasis
@@ -963,6 +965,7 @@ struct dwc3 {
unsigneddis_enblslpm_quirk:1;
unsigneddis_rxdet_inp3_quirk:1;
unsigneddis_u2_freeclk_exists_quirk:1;
+   unsigneddis_del_phy_power_chg_quirk:1;
 
unsignedtx_de_emphasis_quirk:1;
unsignedtx_de_emphasis:2;
-- 
1.9.1




[PATCH v9 0/5] support rockchip dwc3 driver

2016-08-15 Thread William Wu
This series add support for rockchip DWC3 driver,
and add additional optional properties for specific
platforms (e.g., rockchip rk3399 platform).

And because rockchip DWC3 need additional handling of
cable events and mode switch to support DRD mode, so
we add a new dwc3-rockchip driver, but not use the
generic of glue layer which merely enable some clocks
and populate its children.

William Wu (5):
  usb: dwc3: add dis_u2_freeclk_exists_quirk
  usb: dwc3: make usb2 phy utmi interface configurable
  usb: dwc3: add dis_del_phy_power_chg_quirk
  usb: dwc3: rockchip: add devicetree bindings documentation
  usb: dwc3: add rockchip specific glue layer

 Documentation/devicetree/bindings/usb/dwc3.txt |   5 +
 Documentation/devicetree/bindings/usb/generic.txt  |   6 +
 .../devicetree/bindings/usb/rockchip,dwc3.txt  |  71 
 drivers/usb/dwc3/Kconfig   |   9 +
 drivers/usb/dwc3/Makefile  |   1 +
 drivers/usb/dwc3/core.c|  30 +-
 drivers/usb/dwc3/core.h|  21 +
 drivers/usb/dwc3/dwc3-rockchip.c   | 441 +
 8 files changed, 583 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
 create mode 100644 drivers/usb/dwc3/dwc3-rockchip.c

-- 
1.9.1




[PATCH v9 1/5] usb: dwc3: add dis_u2_freeclk_exists_quirk

2016-08-15 Thread William Wu
Add a quirk to clear the GUSB2PHYCFG.U2_FREECLK_EXISTS bit,
which specifies whether the USB2.0 PHY provides a free-running
PHY clock, which is active when the clock control input is active.

Signed-off-by: William Wu 
Acked-by: Rob Herring 
---
Changes in v9:
- None

Changes in v8:
- add Acked-by (Rob Herring)

Changes in v7:
- None

Changes in v6:
- use '-' instead of '_' in dts (Rob Herring)

Changes in v5:
- None

Changes in v4:
- rebase on top of balbi testing/next, remove pdata (balbi)

Changes in v3:
- None

Changes in v2:
- None

 Documentation/devicetree/bindings/usb/dwc3.txt | 3 +++
 drivers/usb/dwc3/core.c| 5 +
 drivers/usb/dwc3/core.h| 5 +
 3 files changed, 13 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt 
b/Documentation/devicetree/bindings/usb/dwc3.txt
index 7d7ce08..020b0e9 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -39,6 +39,9 @@ Optional properties:
disabling the suspend signal to the PHY.
  - snps,dis_rxdet_inp3_quirk: when set core will disable receiver detection
in PHY P3 power state.
+ - snps,dis-u2-freeclk-exists-quirk: when set, clear the u2_freeclk_exists
+   in GUSB2PHYCFG, specify that USB2 PHY doesn't provide
+   a free-running PHY clock.
  - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
utmi_l1_suspend_n, false when asserts utmi_sleep_n
  - snps,hird-threshold: HIRD threshold
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 35d0924..14316e5 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -500,6 +500,9 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
if (dwc->dis_enblslpm_quirk)
reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
 
+   if (dwc->dis_u2_freeclk_exists_quirk)
+   reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS;
+
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
 
return 0;
@@ -924,6 +927,8 @@ static int dwc3_probe(struct platform_device *pdev)
"snps,dis_enblslpm_quirk");
dwc->dis_rxdet_inp3_quirk = device_property_read_bool(dev,
"snps,dis_rxdet_inp3_quirk");
+   dwc->dis_u2_freeclk_exists_quirk = device_property_read_bool(dev,
+   "snps,dis-u2-freeclk-exists-quirk");
 
dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
"snps,tx_de_emphasis_quirk");
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 1a6cc48..08ed9e0 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -199,6 +199,7 @@
 
 /* Global USB2 PHY Configuration Register */
 #define DWC3_GUSB2PHYCFG_PHYSOFTRST(1 << 31)
+#define DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS (1 << 30)
 #define DWC3_GUSB2PHYCFG_SUSPHY(1 << 6)
 #define DWC3_GUSB2PHYCFG_ULPI_UTMI (1 << 4)
 #define DWC3_GUSB2PHYCFG_ENBLSLPM  (1 << 8)
@@ -803,6 +804,9 @@ struct dwc3_scratchpad_array {
  * @dis_u2_susphy_quirk: set if we disable usb2 suspend phy
  * @dis_enblslpm_quirk: set if we clear enblslpm in GUSB2PHYCFG,
  *  disabling the suspend signal to the PHY.
+ * @dis_u2_freeclk_exists_quirk : set if we clear u2_freeclk_exists
+ * in GUSB2PHYCFG, specify that USB2 PHY doesn't
+ * provide a free-running PHY clock.
  * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
  * @tx_de_emphasis: Tx de-emphasis value
  * 0   - -6dB de-emphasis
@@ -946,6 +950,7 @@ struct dwc3 {
unsigneddis_u2_susphy_quirk:1;
unsigneddis_enblslpm_quirk:1;
unsigneddis_rxdet_inp3_quirk:1;
+   unsigneddis_u2_freeclk_exists_quirk:1;
 
unsignedtx_de_emphasis_quirk:1;
unsignedtx_de_emphasis:2;
-- 
1.9.1




[PATCH v8 0/5] support rockchip dwc3 driver

2016-08-03 Thread William Wu
This series add support for rockchip dwc3 driver,
and add additional optional properties for specific
platforms (e.g., rockchip rk3399 platform).

William Wu (5):
  usb: dwc3: of-simple: add compatible for rockchip rk3399
  usb: dwc3: add dis_u2_freeclk_exists_quirk
  usb: dwc3: make usb2 phy utmi interface configurable
  usb: dwc3: add dis_del_phy_power_chg_quirk
  usb: dwc3: rockchip: add devicetree bindings documentation

 Documentation/devicetree/bindings/usb/dwc3.txt |  5 ++
 Documentation/devicetree/bindings/usb/generic.txt  |  6 +++
 .../devicetree/bindings/usb/rockchip,dwc3.txt  | 59 ++
 drivers/usb/dwc3/core.c| 28 ++
 drivers/usb/dwc3/core.h| 20 
 drivers/usb/dwc3/dwc3-of-simple.c  |  1 +
 6 files changed, 119 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/rockchip,dwc3.txt

-- 
1.9.1




[PATCH v8 4/5] usb: dwc3: add dis_del_phy_power_chg_quirk

2016-08-03 Thread William Wu
Add a quirk to clear the GUSB3PIPECTL.DELAYP1TRANS bit,
which specifies whether disable delay PHY power change
from P0 to P1/P2/P3 when link state changing from U0
to U1/U2/U3 respectively.

Signed-off-by: William Wu 
Acked-by: Rob Herring 
---
Changes in v8:
- add Acked-by (Rob Herring)

Changes in v7:
- None

Changes in v6:
- use '-' instead of '_' in dts (Rob Herring)

Changes in v5:
- None

Changes in v4:
- rebase on top of balbi testing/next, remove pdata (balbi)

Changes in v3:
- None

Changes in v2:
- None

 Documentation/devicetree/bindings/usb/dwc3.txt | 2 ++
 drivers/usb/dwc3/core.c| 5 +
 drivers/usb/dwc3/core.h| 3 +++
 3 files changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt 
b/Documentation/devicetree/bindings/usb/dwc3.txt
index 020b0e9..e96bfc2 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -42,6 +42,8 @@ Optional properties:
  - snps,dis-u2-freeclk-exists-quirk: when set, clear the u2_freeclk_exists
in GUSB2PHYCFG, specify that USB2 PHY doesn't provide
a free-running PHY clock.
+ - snps,dis-del-phy-power-chg-quirk: when set core will change PHY power
+   from P0 to P1/P2/P3 without delay.
  - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
utmi_l1_suspend_n, false when asserts utmi_sleep_n
  - snps,hird-threshold: HIRD threshold
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index edbca03..b5e0ccc 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -448,6 +448,9 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
if (dwc->dis_u3_susphy_quirk)
reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
 
+   if (dwc->dis_del_phy_power_chg_quirk)
+   reg &= ~DWC3_GUSB3PIPECTL_DEPOCHANGE;
+
dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
 
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
@@ -947,6 +950,8 @@ static int dwc3_probe(struct platform_device *pdev)
"snps,dis_rxdet_inp3_quirk");
dwc->dis_u2_freeclk_exists_quirk = device_property_read_bool(dev,
"snps,dis-u2-freeclk-exists-quirk");
+   dwc->dis_del_phy_power_chg_quirk = device_property_read_bool(dev,
+   "snps,dis-del-phy-power-chg-quirk");
 
dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
"snps,tx_de_emphasis_quirk");
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index ff5a83a..e57e4e2 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -814,6 +814,8 @@ struct dwc3_scratchpad_array {
  * @dis_u2_freeclk_exists_quirk : set if we clear u2_freeclk_exists
  * in GUSB2PHYCFG, specify that USB2 PHY doesn't
  * provide a free-running PHY clock.
+ * @dis_del_phy_power_chg_quirk: set if we disable delay phy power
+ * change quirk.
  * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
  * @tx_de_emphasis: Tx de-emphasis value
  * 0   - -6dB de-emphasis
@@ -959,6 +961,7 @@ struct dwc3 {
unsigneddis_enblslpm_quirk:1;
unsigneddis_rxdet_inp3_quirk:1;
unsigneddis_u2_freeclk_exists_quirk:1;
+   unsigneddis_del_phy_power_chg_quirk:1;
 
unsignedtx_de_emphasis_quirk:1;
unsignedtx_de_emphasis:2;
-- 
1.9.1




[PATCH v8 2/5] usb: dwc3: add dis_u2_freeclk_exists_quirk

2016-08-03 Thread William Wu
Add a quirk to clear the GUSB2PHYCFG.U2_FREECLK_EXISTS bit,
which specifies whether the USB2.0 PHY provides a free-running
PHY clock, which is active when the clock control input is active.

Signed-off-by: William Wu 
Acked-by: Rob Herring 
---
Changes in v8:
- add Acked-by (Rob Herring)

Changes in v7:
- None

Changes in v6:
- use '-' instead of '_' in dts (Rob Herring)

Changes in v5:
- None

Changes in v4:
- rebase on top of balbi testing/next, remove pdata (balbi)

Changes in v3:
- None

Changes in v2:
- None

 Documentation/devicetree/bindings/usb/dwc3.txt | 3 +++
 drivers/usb/dwc3/core.c| 5 +
 drivers/usb/dwc3/core.h| 5 +
 3 files changed, 13 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt 
b/Documentation/devicetree/bindings/usb/dwc3.txt
index 7d7ce08..020b0e9 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -39,6 +39,9 @@ Optional properties:
disabling the suspend signal to the PHY.
  - snps,dis_rxdet_inp3_quirk: when set core will disable receiver detection
in PHY P3 power state.
+ - snps,dis-u2-freeclk-exists-quirk: when set, clear the u2_freeclk_exists
+   in GUSB2PHYCFG, specify that USB2 PHY doesn't provide
+   a free-running PHY clock.
  - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
utmi_l1_suspend_n, false when asserts utmi_sleep_n
  - snps,hird-threshold: HIRD threshold
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 9466431..0b7bfd2 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -500,6 +500,9 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
if (dwc->dis_enblslpm_quirk)
reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
 
+   if (dwc->dis_u2_freeclk_exists_quirk)
+   reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS;
+
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
 
return 0;
@@ -924,6 +927,8 @@ static int dwc3_probe(struct platform_device *pdev)
"snps,dis_enblslpm_quirk");
dwc->dis_rxdet_inp3_quirk = device_property_read_bool(dev,
"snps,dis_rxdet_inp3_quirk");
+   dwc->dis_u2_freeclk_exists_quirk = device_property_read_bool(dev,
+   "snps,dis-u2-freeclk-exists-quirk");
 
dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
"snps,tx_de_emphasis_quirk");
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 45d6de5..f321a5c 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -199,6 +199,7 @@
 
 /* Global USB2 PHY Configuration Register */
 #define DWC3_GUSB2PHYCFG_PHYSOFTRST(1 << 31)
+#define DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS (1 << 30)
 #define DWC3_GUSB2PHYCFG_SUSPHY(1 << 6)
 #define DWC3_GUSB2PHYCFG_ULPI_UTMI (1 << 4)
 #define DWC3_GUSB2PHYCFG_ENBLSLPM  (1 << 8)
@@ -799,6 +800,9 @@ struct dwc3_scratchpad_array {
  * @dis_u2_susphy_quirk: set if we disable usb2 suspend phy
  * @dis_enblslpm_quirk: set if we clear enblslpm in GUSB2PHYCFG,
  *  disabling the suspend signal to the PHY.
+ * @dis_u2_freeclk_exists_quirk : set if we clear u2_freeclk_exists
+ * in GUSB2PHYCFG, specify that USB2 PHY doesn't
+ * provide a free-running PHY clock.
  * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
  * @tx_de_emphasis: Tx de-emphasis value
  * 0   - -6dB de-emphasis
@@ -942,6 +946,7 @@ struct dwc3 {
unsigneddis_u2_susphy_quirk:1;
unsigneddis_enblslpm_quirk:1;
unsigneddis_rxdet_inp3_quirk:1;
+   unsigneddis_u2_freeclk_exists_quirk:1;
 
unsignedtx_de_emphasis_quirk:1;
unsignedtx_de_emphasis:2;
-- 
1.9.1




[PATCH v8 3/5] usb: dwc3: make usb2 phy utmi interface configurable

2016-08-03 Thread William Wu
Support to configure the UTMI+ PHY with an 8- or 16-bit
interface via DT. The UTMI+ PHY interface is a hardware
capability, and it's platform dependent. Normally, the
PHYIF can be configured during coreconsultant.

But for some specific USB cores(e.g. rk3399 SoC DWC3),
the default PHYIF configuration value is false, so we
need to reconfigure it by software.

Signed-off-by: William Wu 
Acked-by: Rob Herring 
---
Changes in v8:
- configure utmi interface via phy_type property in DT (Heiko, Rob Herring)
- add Acked-by (Rob Herring)
- modify commit message (Rob Herring)

Changes in v7:
- remove quirk and use only one property to configure utmi (Heiko, Rob Herring)

Changes in v6:
- use '-' instead of '_' in dts (Rob Herring)

Changes in v5:
- None

Changes in v4:
- rebase on top of balbi testing/next, remove pdata (balbi)

Changes in v3:
- None

Changes in v2:
- add a quirk for phyif_utmi (balbi)

 Documentation/devicetree/bindings/usb/generic.txt |  6 ++
 drivers/usb/dwc3/core.c   | 18 ++
 drivers/usb/dwc3/core.h   | 12 
 3 files changed, 36 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/generic.txt 
b/Documentation/devicetree/bindings/usb/generic.txt
index bba8257..bfadeb1 100644
--- a/Documentation/devicetree/bindings/usb/generic.txt
+++ b/Documentation/devicetree/bindings/usb/generic.txt
@@ -11,6 +11,11 @@ Optional properties:
"peripheral" and "otg". In case this attribute isn't
passed via DT, USB DRD controllers should default to
OTG.
+ - phy_type: tells USB controllers that we want to configure the core to 
support
+   a UTMI+ PHY with an 8- or 16-bit interface if UTMI+ is
+   selected. Valid arguments are "utmi" and "utmi_wide".
+   In case this isn't passed via DT, USB controllers should
+   default to HW capability.
  - otg-rev: tells usb driver the release number of the OTG and EH supplement
with which the device and its descriptors are compliant,
in binary-coded decimal (i.e. 2.0 is 0200H). This
@@ -34,6 +39,7 @@ dwc3@4a03 {
usb-phy = <&usb2_phy>, <&usb3,phy>;
maximum-speed = "super-speed";
dr_mode = "otg";
+   phy_type = "utmi_wide";
otg-rev = <0x0200>;
adp-disable;
 };
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 0b7bfd2..edbca03 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -485,6 +485,23 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
break;
}
 
+   switch (dwc->hsphy_mode) {
+   case USBPHY_INTERFACE_MODE_UTMI:
+   reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
+  DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
+   reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_8_BIT) |
+  DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_8_BIT);
+   break;
+   case USBPHY_INTERFACE_MODE_UTMIW:
+   reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
+  DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
+   reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_16_BIT) |
+  DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_16_BIT);
+   break;
+   default:
+   break;
+   }
+
/*
 * Above 1.94a, it is recommended to set DWC3_GUSB2PHYCFG_SUSPHY to
 * '0' during coreConsultant configuration. So default value will
@@ -891,6 +908,7 @@ static int dwc3_probe(struct platform_device *pdev)
 
dwc->maximum_speed = usb_get_maximum_speed(dev);
dwc->dr_mode = usb_get_dr_mode(dev);
+   dwc->hsphy_mode = of_usb_get_phy_mode(dev->of_node);
 
dwc->has_lpm_erratum = device_property_read_bool(dev,
"snps,has-lpm-erratum");
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index f321a5c..ff5a83a 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -203,6 +203,14 @@
 #define DWC3_GUSB2PHYCFG_SUSPHY(1 << 6)
 #define DWC3_GUSB2PHYCFG_ULPI_UTMI (1 << 4)
 #define DWC3_GUSB2PHYCFG_ENBLSLPM  (1 << 8)
+#define DWC3_GUSB2PHYCFG_PHYIF(n)  (n << 3)
+#define DWC3_GUSB2PHYCFG_PHYIF_MASKDWC3_GUSB2PHYCFG_PHYIF(1)
+#define DWC3_GUSB2PHYCFG_USBTRDTIM(n)  (n << 10)
+#define DWC3_GUSB2PHYCFG_USBTRDTIM_MASKDWC3_GUSB2PHYCFG_USBTRDTIM(0xf)
+#define USBTRDTIM_UTMI_8_BIT   9
+#define USBTRDTIM_UTMI_16_BIT  5
+#define UTMI_PHYIF_16_BIT  1
+#define UTMI_PHYIF_8_BIT   0
 
 /* Global USB2 PHY Vendor Control Register */
 #define DWC3_GUSB2PHYACC_NEWREGREQ (

[PATCH v8 1/5] usb: dwc3: of-simple: add compatible for rockchip rk3399

2016-08-03 Thread William Wu
Rockchip platform merely enable usb3 clocks and
populate its children. So we can use this generic
glue layer to support Rockchip dwc3.

Signed-off-by: William Wu 
---
Changes in v8:
- None

Changes in v7:
- None

Changes in v6:
- None

Changes in v5:
- change compatible from "rockchip,dwc3" to "rockchip,rk3399-dwc3" (Heiko)

Changes in v4:
- None

Changes in v3:
- None

Changes in v2:
- sort the list of_dwc3_simple_match (Doug)

 drivers/usb/dwc3/dwc3-of-simple.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/usb/dwc3/dwc3-of-simple.c 
b/drivers/usb/dwc3/dwc3-of-simple.c
index 9743353..05c9349 100644
--- a/drivers/usb/dwc3/dwc3-of-simple.c
+++ b/drivers/usb/dwc3/dwc3-of-simple.c
@@ -161,6 +161,7 @@ static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = {
 
 static const struct of_device_id of_dwc3_simple_match[] = {
{ .compatible = "qcom,dwc3" },
+   { .compatible = "rockchip,rk3399-dwc3" },
{ .compatible = "xlnx,zynqmp-dwc3" },
{ /* Sentinel */ }
 };
-- 
1.9.1




[PATCH v8 5/5] usb: dwc3: rockchip: add devicetree bindings documentation

2016-08-03 Thread William Wu
This patch adds the devicetree documentation required for Rockchip
USB3.0 core wrapper consisting of USB3.0 IP from Synopsys.

It supports DRD mode, and could operate in device mode (SS, HS, FS)
and host mode (SS, HS, FS, LS).

Signed-off-by: William Wu 
Acked-by: Rob Herring 
---
Changes in v8:
- None

Changes in v7:
- add Acked-by (Rob Herring)

Changes in v6:
- rename bus_clk, and add usbdrd3_1 node as an example (Heiko)

Changes in v5:
- rename clock-names, and remove unnecessary clocks (Heiko)

Changes in v4:
- modify commit log, and add phy documentation location (Sergei)

Changes in v3:
- add dwc3 address (balbi)

Changes in v2:
- add rockchip,dwc3.txt to Documentation/devicetree/bindings/ (balbi, Brian)

 .../devicetree/bindings/usb/rockchip,dwc3.txt  | 59 ++
 1 file changed, 59 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/rockchip,dwc3.txt

diff --git a/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt 
b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
new file mode 100644
index 000..0536a93
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
@@ -0,0 +1,59 @@
+Rockchip SuperSpeed DWC3 USB SoC controller
+
+Required properties:
+- compatible:  should contain "rockchip,rk3399-dwc3" for rk3399 SoC
+- clocks:  A list of phandle + clock-specifier pairs for the
+   clocks listed in clock-names
+- clock-names: Should contain the following:
+  "ref_clk"Controller reference clk, have to be 24 MHz
+  "suspend_clk"Controller suspend clk, have to be 24 MHz or 32 KHz
+  "bus_clk"Master/Core clock, have to be >= 62.5 MHz for SS
+   operation and >= 30MHz for HS operation
+  "grf_clk"Controller grf clk
+
+Required child node:
+A child node must exist to represent the core DWC3 IP block. The name of
+the node is not important. The content of the node is defined in dwc3.txt.
+
+Phy documentation is provided in the following places:
+Documentation/devicetree/bindings/phy/rockchip,dwc3-usb-phy.txt
+
+Example device nodes:
+
+   usbdrd3_0: usb@fe80 {
+   compatible = "rockchip,rk3399-dwc3";
+   clocks = <&cru SCLK_USB3OTG0_REF>, <&cru SCLK_USB3OTG0_SUSPEND>,
+<&cru ACLK_USB3OTG0>, <&cru ACLK_USB3_GRF>;
+   clock-names = "ref_clk", "suspend_clk",
+ "bus_clk", "grf_clk";
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges;
+   status = "disabled";
+   usbdrd_dwc3_0: dwc3@fe80 {
+   compatible = "snps,dwc3";
+   reg = <0x0 0xfe80 0x0 0x10>;
+   interrupts = ;
+   dr_mode = "otg";
+   status = "disabled";
+   };
+   };
+
+   usbdrd3_1: usb@fe90 {
+   compatible = "rockchip,rk3399-dwc3";
+   clocks = <&cru SCLK_USB3OTG1_REF>, <&cru SCLK_USB3OTG1_SUSPEND>,
+<&cru ACLK_USB3OTG1>, <&cru ACLK_USB3_GRF>;
+   clock-names = "ref_clk", "suspend_clk",
+ "bus_clk", "grf_clk";
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges;
+   status = "disabled";
+   usbdrd_dwc3_1: dwc3@fe90 {
+   compatible = "snps,dwc3";
+   reg = <0x0 0xfe90 0x0 0x10>;
+   interrupts = ;
+   dr_mode = "otg";
+   status = "disabled";
+   };
+   };
-- 
1.9.1




[PATCH v7 5/5] usb: dwc3: rockchip: add devicetree bindings documentation

2016-07-14 Thread William Wu
This patch adds the devicetree documentation required for Rockchip
USB3.0 core wrapper consisting of USB3.0 IP from Synopsys.

It supports DRD mode, and could operate in device mode (SS, HS, FS)
and host mode (SS, HS, FS, LS).

Signed-off-by: William Wu 
Acked-by: Rob Herring 
---
Changes in v7:
- add Acked-by (Rob Herring)

Changes in v6:
- rename bus_clk, and add usbdrd3_1 node as an example (Heiko)

Changes in v5:
- rename clock-names, and remove unnecessary clocks (Heiko)

Changes in v4:
- modify commit log, and add phy documentation location (Sergei)

Changes in v3:
- add dwc3 address (balbi)

Changes in v2:
- add rockchip,dwc3.txt to Documentation/devicetree/bindings/ (balbi, Brian)

 .../devicetree/bindings/usb/rockchip,dwc3.txt  | 59 ++
 1 file changed, 59 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/rockchip,dwc3.txt

diff --git a/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt 
b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
new file mode 100644
index 000..0536a93
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt
@@ -0,0 +1,59 @@
+Rockchip SuperSpeed DWC3 USB SoC controller
+
+Required properties:
+- compatible:  should contain "rockchip,rk3399-dwc3" for rk3399 SoC
+- clocks:  A list of phandle + clock-specifier pairs for the
+   clocks listed in clock-names
+- clock-names: Should contain the following:
+  "ref_clk"Controller reference clk, have to be 24 MHz
+  "suspend_clk"Controller suspend clk, have to be 24 MHz or 32 KHz
+  "bus_clk"Master/Core clock, have to be >= 62.5 MHz for SS
+   operation and >= 30MHz for HS operation
+  "grf_clk"Controller grf clk
+
+Required child node:
+A child node must exist to represent the core DWC3 IP block. The name of
+the node is not important. The content of the node is defined in dwc3.txt.
+
+Phy documentation is provided in the following places:
+Documentation/devicetree/bindings/phy/rockchip,dwc3-usb-phy.txt
+
+Example device nodes:
+
+   usbdrd3_0: usb@fe80 {
+   compatible = "rockchip,rk3399-dwc3";
+   clocks = <&cru SCLK_USB3OTG0_REF>, <&cru SCLK_USB3OTG0_SUSPEND>,
+<&cru ACLK_USB3OTG0>, <&cru ACLK_USB3_GRF>;
+   clock-names = "ref_clk", "suspend_clk",
+ "bus_clk", "grf_clk";
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges;
+   status = "disabled";
+   usbdrd_dwc3_0: dwc3@fe80 {
+   compatible = "snps,dwc3";
+   reg = <0x0 0xfe80 0x0 0x10>;
+   interrupts = ;
+   dr_mode = "otg";
+   status = "disabled";
+   };
+   };
+
+   usbdrd3_1: usb@fe90 {
+   compatible = "rockchip,rk3399-dwc3";
+   clocks = <&cru SCLK_USB3OTG1_REF>, <&cru SCLK_USB3OTG1_SUSPEND>,
+<&cru ACLK_USB3OTG1>, <&cru ACLK_USB3_GRF>;
+   clock-names = "ref_clk", "suspend_clk",
+ "bus_clk", "grf_clk";
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges;
+   status = "disabled";
+   usbdrd_dwc3_1: dwc3@fe90 {
+   compatible = "snps,dwc3";
+   reg = <0x0 0xfe90 0x0 0x10>;
+   interrupts = ;
+   dr_mode = "otg";
+   status = "disabled";
+   };
+   };
-- 
1.9.1




[PATCH v7 0/5] support rockchip dwc3 driver

2016-07-14 Thread William Wu
This series add support for rockchip dwc3 driver,
and add additional optional properties for specific
platforms (e.g., rockchip rk3399 platform).

William Wu (5):
  usb: dwc3: of-simple: add compatible for rockchip rk3399
  usb: dwc3: add dis_u2_freeclk_exists_quirk
  usb: dwc3: make usb2 phy utmi interface configurable in DT
  usb: dwc3: add dis_del_phy_power_chg_quirk
  usb: dwc3: rockchip: add devicetree bindings documentation

 Documentation/devicetree/bindings/usb/dwc3.txt |  8 +++
 .../devicetree/bindings/usb/rockchip,dwc3.txt  | 59 ++
 drivers/usb/dwc3/core.c| 35 +
 drivers/usb/dwc3/core.h| 18 +++
 drivers/usb/dwc3/dwc3-of-simple.c  |  1 +
 5 files changed, 121 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/rockchip,dwc3.txt

-- 
1.9.1




  1   2   >