RE: [PATCH 4/4] usb: renesas_usbhs: add support for USB-DMAC

2015-02-11 Thread yoshihiro shimoda
Hi Geert-san,

 Hi Shimoda-san,
 
 On Mon, Feb 9, 2015 at 9:16 AM, Yoshihiro Shimoda
 yoshihiro.shimoda...@renesas.com wrote:
  Some Renesas SoCs have the USB-DMAC. It is able to terminate transfers
  when a short packet is received, even if less bytes than the transfer
  counter size have been received. Also, it is able to send a short
  packet even if the packet size is not multiples of 8bytes.
 
  Since the previous code has used the interruption of USBHS controller
  when receiving packets even if this driver has used a dmac, a lot of
  interruptions has happened. This patch will reduce such interruptions.
 
  This patch allows to use the USB-DMAC on R-Car H2 and M2.
 
  Signed-off-by: Yoshihiro Shimoda yoshihiro.shimoda...@renesas.com
 
  --- a/drivers/usb/renesas_usbhs/common.c
  +++ b/drivers/usb/renesas_usbhs/common.c
 
  @@ -487,6 +497,15 @@ static struct renesas_usbhs_platform_info 
  *usbhs_parse_dt(struct device *dev)
  if (gpio  0)
  dparam-enable_gpio = gpio;
 
  +   switch (dparam-type) {
  +   case USBHS_TYPE_R8A7790:
  +   case USBHS_TYPE_R8A7791:
  +   dparam-has_usb_dmac = 1;
  +   break;
  +   default:
  +   break;
  +   }
  +
  return info;
   }
 
   struct usbhs_priv *usbhs_pdev_to_priv(struct platform_device *pdev);
  diff --git a/drivers/usb/renesas_usbhs/fifo.c 
  b/drivers/usb/renesas_usbhs/fifo.c
  index 3b77a1b..1e7dc6e 100644
  --- a/drivers/usb/renesas_usbhs/fifo.c
  +++ b/drivers/usb/renesas_usbhs/fifo.c
 
  @@ -847,10 +849,13 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt 
  *pkt, int *is_done)
  usbhs_pipe_is_dcp(pipe))
  goto usbhsf_pio_prepare_push;
 
  -   if (len  0x7) /* 8byte alignment */
  +   /* default: 8byte alignment */
  +   if (!usbhs_get_dparam(priv, has_usb_dmac)  len  0x7)
  goto usbhsf_pio_prepare_push;
 
 So the has_usb_dmac flags indicates that DMA addresses are not limited to
 8-byte alignment.
 
 Can't this be handled by looking at a dma_mask, as set by the DMAC?

Opps, the comment 8byte alignment is wrong.
I will fix the comment.

The USB-DMAC can send a packet that it is not multiples of 8-bytes.
The USB-DMAC needs 32-bytes alignment by the following code.

-   if ((uintptr_t)(pkt-buf + pkt-actual)  0x7) /* 8byte alignment */
+   align_mask = usbhs_get_dparam(priv, has_usb_dmac) ?
+   USBHS_USB_DMAC_XFER_SIZE - 1 : 0x7;
+   if ((uintptr_t)(pkt-buf + pkt-actual)  align_mask)

The previous code will use a dmac if a packet size is multiples of 8-bytes and
it is 8-bytes alignment.

Best regards,
Yoshihiro Shimoda

 Gr{oetje,eeting}s,
 
 Geert
 
 --
 Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- 
 ge...@linux-m68k.org
 
 In personal conversations with technical people, I call myself a hacker. But
 when I'm talking to journalists I just say programmer or something like 
 that.
 -- Linus Torvalds
N�r��yb�X��ǧv�^�)޺{.n�+{��^n�r���z���h����G���h�(�階�ݢj���m��z�ޖ���f���h���~�m�

Re: [PATCH 4/4] usb: renesas_usbhs: add support for USB-DMAC

2015-02-10 Thread Geert Uytterhoeven
Hi Shimoda-san,

On Mon, Feb 9, 2015 at 9:16 AM, Yoshihiro Shimoda
yoshihiro.shimoda...@renesas.com wrote:
 Some Renesas SoCs have the USB-DMAC. It is able to terminate transfers
 when a short packet is received, even if less bytes than the transfer
 counter size have been received. Also, it is able to send a short
 packet even if the packet size is not multiples of 8bytes.

 Since the previous code has used the interruption of USBHS controller
 when receiving packets even if this driver has used a dmac, a lot of
 interruptions has happened. This patch will reduce such interruptions.

 This patch allows to use the USB-DMAC on R-Car H2 and M2.

 Signed-off-by: Yoshihiro Shimoda yoshihiro.shimoda...@renesas.com

 --- a/drivers/usb/renesas_usbhs/common.c
 +++ b/drivers/usb/renesas_usbhs/common.c

 @@ -487,6 +497,15 @@ static struct renesas_usbhs_platform_info 
 *usbhs_parse_dt(struct device *dev)
 if (gpio  0)
 dparam-enable_gpio = gpio;

 +   switch (dparam-type) {
 +   case USBHS_TYPE_R8A7790:
 +   case USBHS_TYPE_R8A7791:
 +   dparam-has_usb_dmac = 1;
 +   break;
 +   default:
 +   break;
 +   }
 +
 return info;
  }

  struct usbhs_priv *usbhs_pdev_to_priv(struct platform_device *pdev);
 diff --git a/drivers/usb/renesas_usbhs/fifo.c 
 b/drivers/usb/renesas_usbhs/fifo.c
 index 3b77a1b..1e7dc6e 100644
 --- a/drivers/usb/renesas_usbhs/fifo.c
 +++ b/drivers/usb/renesas_usbhs/fifo.c

 @@ -847,10 +849,13 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt 
 *pkt, int *is_done)
 usbhs_pipe_is_dcp(pipe))
 goto usbhsf_pio_prepare_push;

 -   if (len  0x7) /* 8byte alignment */
 +   /* default: 8byte alignment */
 +   if (!usbhs_get_dparam(priv, has_usb_dmac)  len  0x7)
 goto usbhsf_pio_prepare_push;

So the has_usb_dmac flags indicates that DMA addresses are not limited to
8-byte alignment.

Can't this be handled by looking at a dma_mask, as set by the DMAC?

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say programmer or something like that.
-- Linus Torvalds
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/4] usb: renesas_usbhs: add support for USB-DMAC

2015-02-09 Thread Yoshihiro Shimoda
Some Renesas SoCs have the USB-DMAC. It is able to terminate transfers
when a short packet is received, even if less bytes than the transfer
counter size have been received. Also, it is able to send a short
packet even if the packet size is not multiples of 8bytes.

Since the previous code has used the interruption of USBHS controller
when receiving packets even if this driver has used a dmac, a lot of
interruptions has happened. This patch will reduce such interruptions.

This patch allows to use the USB-DMAC on R-Car H2 and M2.

Signed-off-by: Yoshihiro Shimoda yoshihiro.shimoda...@renesas.com
---
 drivers/usb/renesas_usbhs/common.c |   19 +
 drivers/usb/renesas_usbhs/common.h |7 ++
 drivers/usb/renesas_usbhs/fifo.c   |  164 ++--
 drivers/usb/renesas_usbhs/fifo.h   |1 +
 drivers/usb/renesas_usbhs/pipe.c   |   39 +
 drivers/usb/renesas_usbhs/pipe.h   |1 +
 include/linux/usb/renesas_usbhs.h  |2 +
 7 files changed, 227 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/renesas_usbhs/common.c 
b/drivers/usb/renesas_usbhs/common.c
index 4cf77d3..0f7e850 100644
--- a/drivers/usb/renesas_usbhs/common.c
+++ b/drivers/usb/renesas_usbhs/common.c
@@ -276,6 +276,16 @@ int usbhs_set_device_config(struct usbhs_priv *priv, int 
devnum,
 }
 
 /*
+ * interrupt functions
+ */
+void usbhs_xxxsts_clear(struct usbhs_priv *priv, u16 sts_reg, u16 bit)
+{
+   u16 pipe_mask = (u16)GENMASK(usbhs_get_dparam(priv, pipe_size), 0);
+
+   usbhs_write(priv, sts_reg, ~(1  bit)  pipe_mask);
+}
+
+/*
  * local functions
  */
 static void usbhsc_set_buswait(struct usbhs_priv *priv)
@@ -487,6 +497,15 @@ static struct renesas_usbhs_platform_info 
*usbhs_parse_dt(struct device *dev)
if (gpio  0)
dparam-enable_gpio = gpio;
 
+   switch (dparam-type) {
+   case USBHS_TYPE_R8A7790:
+   case USBHS_TYPE_R8A7791:
+   dparam-has_usb_dmac = 1;
+   break;
+   default:
+   break;
+   }
+
return info;
 }
 
diff --git a/drivers/usb/renesas_usbhs/common.h 
b/drivers/usb/renesas_usbhs/common.h
index fc96e92..8c5fc12 100644
--- a/drivers/usb/renesas_usbhs/common.h
+++ b/drivers/usb/renesas_usbhs/common.h
@@ -193,6 +193,7 @@ struct usbhs_priv;
 #define TYPE_BULK  (1  14)
 #define TYPE_INT   (2  14)
 #define TYPE_ISO   (3  14)
+#define BFRE   (1  10)   /* BRDY Interrupt Operation Spec. */
 #define DBLB   (1  9)/* Double Buffer Mode */
 #define SHTNAK (1  7)/* Pipe Disable in Transfer End */
 #define DIR_OUT(1  4)/* Transfer Direction */
@@ -216,6 +217,7 @@ struct usbhs_priv;
 #defineACLRM   (1  9)/* Buffer Auto-Clear Mode */
 #define SQCLR  (1  8)/* Toggle Bit Clear */
 #define SQSET  (1  7)/* Toggle Bit Set */
+#define SQMON  (1  6)/* Toggle Bit Check */
 #define PBUSY  (1  5)/* Pipe Busy */
 #define PID_MASK   (0x3)   /* Response PID */
 #define  PID_NAK   0
@@ -324,6 +326,11 @@ int usbhs_set_device_config(struct usbhs_priv *priv, int 
devnum, u16 upphub,
   u16 hubport, u16 speed);
 
 /*
+ * interrupt functions
+ */
+void usbhs_xxxsts_clear(struct usbhs_priv *priv, u16 sts_reg, u16 bit);
+
+/*
  * data
  */
 struct usbhs_priv *usbhs_pdev_to_priv(struct platform_device *pdev);
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
index 3b77a1b..1e7dc6e 100644
--- a/drivers/usb/renesas_usbhs/fifo.c
+++ b/drivers/usb/renesas_usbhs/fifo.c
@@ -813,7 +813,8 @@ static void xfer_work(struct work_struct *work)
desc-callback  = usbhsf_dma_complete;
desc-callback_param= pipe;
 
-   if (dmaengine_submit(desc)  0) {
+   pkt-cookie = dmaengine_submit(desc);
+   if (pkt-cookie  0) {
dev_err(dev, Failed to submit dma descriptor\n);
return;
}
@@ -838,6 +839,7 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, 
int *is_done)
struct usbhs_fifo *fifo;
int len = pkt-length - pkt-actual;
int ret;
+   uintptr_t align_mask;
 
if (usbhs_pipe_is_busy(pipe))
return 0;
@@ -847,10 +849,13 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, 
int *is_done)
usbhs_pipe_is_dcp(pipe))
goto usbhsf_pio_prepare_push;
 
-   if (len  0x7) /* 8byte alignment */
+   /* default: 8byte alignment */
+   if (!usbhs_get_dparam(priv, has_usb_dmac)  len  0x7)
goto usbhsf_pio_prepare_push;
 
-   if ((uintptr_t)(pkt-buf + pkt-actual)  0x7) /* 8byte alignment */
+   align_mask = usbhs_get_dparam(priv, has_usb_dmac) ?
+   USBHS_USB_DMAC_XFER_SIZE - 1 : 0x7;
+   if ((uintptr_t)(pkt-buf + pkt-actual)  align_mask)
goto