Re: [PATCH v1 11/29] usb: dwc2: gadget: configure fifos from device tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On 12/21/2014 05:15 PM, Mian Yousaf Kaukab wrote:
> From: Gregory Herrero <gregory.herrero@xxxxxxxxx>
> 
> As fifo size can vary between SOCs, add possibility to configure
> them from device tree. Fifo sizes used by the legacy driver will
> be used If they are not provided by the device tree.
> 
> Signed-off-by: Gregory Herrero <gregory.herrero@xxxxxxxxx>
> Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@xxxxxxxxx>
> ---
>  drivers/usb/dwc2/core.h   | 13 +++++++
>  drivers/usb/dwc2/gadget.c | 88 ++++++++++++++++++++++++++++++++++-------------
>  2 files changed, 77 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
> index fa5ee27..7c0b995 100644
> --- a/drivers/usb/dwc2/core.h
> +++ b/drivers/usb/dwc2/core.h
> @@ -193,6 +193,13 @@ enum dwc2_lx_state {
>  	DWC2_L3,	/* Off state */
>  };
>  
> +/*
> + * Gadget periodic tx fifo sizes as used by legacy driver
> + * EP0 is not included
> + */
> +#define DWC2_G_P_LEGACY_TX_FIFO_SIZE {256, 256, 256, 256, 768, 768, 768, \
> +					   768, 0, 0, 0, 0, 0, 0, 0}
> +
>  /**
>   * struct dwc2_core_params - Parameters for configuring the core
>   *
> @@ -564,6 +571,9 @@ struct dwc2_hw_params {
>   * @last_rst:           Time of last reset
>   * @eps:                The endpoints being supplied to the gadget framework
>   * @g_using_dma:          Indicate if dma usage is enabled
> + * @g_rx_fifo_sz:         Contains rx fifo size value
> + * @g_np_g_tx_fifo_sz:      Contains Non-Periodic tx fifo size value
> + * @g_tx_fifo_sz:         Contains tx fifo size value per endpoints
>   */
>  struct dwc2_hsotg {
>  	struct device *dev;
> @@ -699,6 +709,9 @@ struct dwc2_hsotg {
>  	struct s3c_hsotg_ep *eps_in[MAX_EPS_CHANNELS];
>  	struct s3c_hsotg_ep *eps_out[MAX_EPS_CHANNELS];
>  	u32 g_using_dma;
> +	u32 g_rx_fifo_sz;
> +	u32 g_np_g_tx_fifo_sz;
> +	u32 g_tx_fifo_sz[MAX_EPS_CHANNELS];
>  #endif /* CONFIG_USB_DWC2_PERIPHERAL || CONFIG_USB_DWC2_DUAL_ROLE */
>  };
>  
> diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
> index d06485c..1fe733b 100644
> --- a/drivers/usb/dwc2/gadget.c
> +++ b/drivers/usb/dwc2/gadget.c
> @@ -174,15 +174,14 @@ static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
>  {
>  	unsigned int ep;
>  	unsigned int addr;
> -	unsigned int size;
>  	int timeout;
>  	u32 val;
>  
> -	/* set FIFO sizes to 2048/1024 */
> -
> -	writel(2048, hsotg->regs + GRXFSIZ);
> -	writel((2048 << FIFOSIZE_STARTADDR_SHIFT) |
> -		(1024 << FIFOSIZE_DEPTH_SHIFT), hsotg->regs + GNPTXFSIZ);
> +	/* set RX/NPTX FIFO sizes */
> +	writel(hsotg->g_rx_fifo_sz, hsotg->regs + GRXFSIZ);
> +	writel((hsotg->g_rx_fifo_sz << FIFOSIZE_STARTADDR_SHIFT) |
> +		(hsotg->g_np_g_tx_fifo_sz << FIFOSIZE_DEPTH_SHIFT),
> +		hsotg->regs + GNPTXFSIZ);
>  
>  	/*
>  	 * arange all the rest of the TX FIFOs, as some versions of this
> @@ -192,7 +191,7 @@ static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
>  	 */
>  
>  	/* start at the end of the GNPTXFSIZ, rounded up */
> -	addr = 2048 + 1024;
> +	addr = hsotg->g_rx_fifo_sz + hsotg->g_np_g_tx_fifo_sz;
>  
>  	/*
>  	 * Because we have not enough memory to have each TX FIFO of size at
> @@ -202,25 +201,14 @@ static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
>  	 * given endpoint.
>  	 */
>  

You should also change the comment above since it's not true after your
changes.

> -	/* 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++) {
> +	for (ep = 1; ep < MAX_EPS_CHANNELS; ep++) {
> +		if (!hsotg->g_tx_fifo_sz[ep])
> +			continue;
>  		val = addr;
> -		val |= size << FIFOSIZE_DEPTH_SHIFT;
> -		WARN_ONCE(addr + size > hsotg->fifo_mem,
> +		val |= hsotg->g_tx_fifo_sz[ep] << FIFOSIZE_DEPTH_SHIFT;
> +		WARN_ONCE(addr + hsotg->g_tx_fifo_sz[ep] > hsotg->fifo_mem,
>  			  "insufficient fifo memory");
> -		addr += size;
> +		addr += hsotg->g_tx_fifo_sz[ep];
>  
>  		writel(val, hsotg->regs + DPTXFSIZN(ep));
>  	}
> @@ -3495,9 +3483,42 @@ static void s3c_hsotg_delete_debug(struct dwc2_hsotg *hsotg)
>  static void s3c_hsotg_of_probe(struct dwc2_hsotg *hsotg)
>  {
>  	struct device_node *np = hsotg->dev->of_node;
> +	u32 len = 0;
> +	u32 i = 0;
>  
>  	/* Enable dma if requested in device tree */
>  	hsotg->g_using_dma = of_property_read_bool(np, "g-use-dma");
> +
> +	/*
> +	* Register TX periodic fifo size per endpoint.
> +	* EP0 is excluded since it has no fifo configuration.
> +	*/
> +	if (!of_find_property(np, "g-tx-fifo-size", &len))
> +		goto rx_fifo;
> +
> +	len /= sizeof(u32);
> +
> +	/* Read tx fifo sizes other than ep0 */
> +	if (of_property_read_u32_array(np, "g-tx-fifo-size",
> +						&hsotg->g_tx_fifo_sz[1], len))
> +		goto rx_fifo;
> +
> +	/* Add ep0 */
> +	len++;
> +
> +	/* Make remaining TX fifos unavailable */
> +	if (len < MAX_EPS_CHANNELS) {
> +		for (i = len; i < MAX_EPS_CHANNELS; i++)
> +			hsotg->g_tx_fifo_sz[i] = 0;
> +	}
> +
> +rx_fifo:
> +	/* Register RX fifo size */
> +	of_property_read_u32(np, "g-rx-fifo-size", &hsotg->g_rx_fifo_sz);
> +
> +	/* Register NPTX fifo size */
> +	of_property_read_u32(np, "g-np-tx-fifo-size",
> +						&hsotg->g_np_g_tx_fifo_sz);
>  }
>  #else
>  static inline void s3c_hsotg_of_probe(struct dwc2_hsotg *hsotg) { }
> @@ -3517,12 +3538,31 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
>  	int epnum;
>  	int ret;
>  	int i;
> +	u32 p_tx_fifo[] = DWC2_G_P_LEGACY_TX_FIFO_SIZE;
>  
>  	/* Set default UTMI width */
>  	hsotg->phyif = GUSBCFG_PHYIF16;
>  
>  	s3c_hsotg_of_probe(hsotg);
>  
> +	/* Initialize to legacy fifo configuration values */
> +	hsotg->g_rx_fifo_sz = 2048;
> +	hsotg->g_np_g_tx_fifo_sz = 1024;
> +	memcpy(&hsotg->g_tx_fifo_sz[1], p_tx_fifo,
> +					sizeof(p_tx_fifo));
> +	/* Device tree specific probe */
> +	s3c_hsotg_of_probe(hsotg);
> +
> +	/* Dump fifo information */
> +	dev_dbg(dev, "NonPeriodic TXFIFO size: %d\n",
> +			hsotg->g_np_g_tx_fifo_sz);
> +	dev_dbg(dev, "RXFIFO size: %d\n",
> +			hsotg->g_rx_fifo_sz);
> +
> +	for (i = 0; i < MAX_EPS_CHANNELS; i++)
> +		dev_dbg(dev, "Periodic TXFIFO%2d size: %d\n", i,
> +						hsotg->g_tx_fifo_sz[i]);
> +
>  	/*
>  	 * Attempt to find a generic PHY, then look for an old style
>  	 * USB PHY, finally fall back to pdata
> 

Good job. I had a plan to do this in future, but it looks like I don't
have to ;)

Reviewed-by: Robert Baldyga <r.baldyga@xxxxxxxxxxx>

Best regards,
Robert Baldyga
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux