RE: [PATCH 10/11] usb: dwc2/gadget: assign TX FIFO dynamically

From: Paul Zimmerman
Date: Mon Jun 23 2014 - 14:43:59 EST


> From: Robert Baldyga [mailto:r.baldyga@xxxxxxxxxxx]
> Sent: Monday, June 23, 2014 12:51 AM
>
> Because we have not enough memory to have each TX FIFO of size at least 3072
> bytes (the maximum single packet size), we create four FIFOs of lenght 1024,
> and four of length 3072 bytes, and assing them to endpoints dynamically
> according to maxpacket size value of given endpoint.
>
> Signed-off-by: Robert Baldyga <r.baldyga@xxxxxxxxxxx>
> ---
> drivers/usb/dwc2/core.h | 1 +
> drivers/usb/dwc2/gadget.c | 48 +++++++++++++++++++++++++++++++++--------------
> 2 files changed, 35 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
> index 067390e..23f7e86 100644
> --- a/drivers/usb/dwc2/core.h
> +++ b/drivers/usb/dwc2/core.h
> @@ -197,6 +197,7 @@ struct s3c_hsotg {
> int fifo_mem;
> unsigned int dedicated_fifos:1;
> unsigned char num_of_eps;
> + u32 fifo_map;
>
> struct dentry *debug_root;
> struct dentry *debug_file;
> diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
> index 3435711..2a7c014 100644
> --- a/drivers/usb/dwc2/gadget.c
> +++ b/drivers/usb/dwc2/gadget.c
> @@ -184,14 +184,26 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg)
>
> /* start at the end of the GNPTXFSIZ, rounded up */
> addr = 2048 + 1024;
> - size = 768;
>
> /*
> * currently we allocate TX FIFOs for all possible endpoints,
> * and assume that they are all the same size.
> */

I think this comment is no longer correct after this patch, right? In
that case, it should be deleted, or better yet replaced with the text
from the commit message.

--
Paul

> - for (ep = 1; ep <= 15; ep++) {
> + /* 256*4=1024 bytes FIFO length */
> + size = 256;
> + for (ep = 1; ep <= 4; ep++) {
> + val = addr;
> + val |= size << FIFOSIZE_DEPTH_SHIFT;
> + WARN_ONCE(addr + size > hsotg->fifo_mem,
> + "insufficient fifo memory");
> + addr += size;
> +
> + writel(val, hsotg->regs + DPTXFSIZN(ep));
> + }
> + /* 768*4=3072 bytes FIFO length */
> + size = 768;
> + for (ep = 5; ep <= 8; ep++) {
> val = addr;
> val |= size << FIFOSIZE_DEPTH_SHIFT;
> WARN_ONCE(addr + size > hsotg->fifo_mem,
> @@ -2440,6 +2452,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
> u32 epctrl;
> u32 mps;
> int dir_in;
> + int i, val, size;
> int ret = 0;
>
> dev_dbg(hsotg->dev,
> @@ -2512,17 +2525,8 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
> break;
>
> case USB_ENDPOINT_XFER_INT:
> - if (dir_in) {
> - /*
> - * Allocate our TxFNum by simply using the index
> - * of the endpoint for the moment. We could do
> - * something better if the host indicates how
> - * many FIFOs we are expecting to use.
> - */
> -
> + if (dir_in)
> hs_ep->periodic = 1;
> - epctrl |= DXEPCTL_TXFNUM(index);
> - }
>
> epctrl |= DXEPCTL_EPTYPE_INTERRUPT;
> break;
> @@ -2536,8 +2540,24 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
> * if the hardware has dedicated fifos, we must give each IN EP
> * a unique tx-fifo even if it is non-periodic.
> */
> - if (dir_in && hsotg->dedicated_fifos)
> - epctrl |= DXEPCTL_TXFNUM(index);
> + if (dir_in && hsotg->dedicated_fifos) {
> + size = hs_ep->ep.maxpacket*hs_ep->mc;
> + for (i = 1; i < 8; ++i) {
> + if (hsotg->fifo_map & (1<<i))
> + continue;
> + val = readl(hsotg->regs + DPTXFSIZN(i));
> + val = (val >> FIFOSIZE_DEPTH_SHIFT)*4;
> + if (val < size)
> + continue;
> + hsotg->fifo_map |= 1<<i;
> + break;
> + }
> +
> + if (i == 8)
> + return -ENOMEM;
> +
> + epctrl |= DXEPCTL_TXFNUM(i);
> + }
>
> /* for non control endpoints, set PID to D0 */
> if (index)
> --
> 1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/