[U-Boot] [PATCH v2 14/17] SPEAr : USBD driver support added
Tom Rix
tom at bumblecow.com
Mon May 3 02:29:57 CEST 2010
Vipin KUMAR wrote:
> USBD is a Synopsys IP. The earlier driver implements itself as specific to spear
> SoCs. This patch implements this driver as a reusable driver for other platforms
> as well.
Similar comments about 'IP'
Similar comments about Synopsys vs DW
Expand 'USBD' to be 'the usb device on the spear platforms'
'implements itself' -> 'is implementend'
'patch implement' -> 'patch moves .. to a common driver'
>
> Signed-off-by: Vipin Kumar <vipin.kumar at st.com>
> ---
> drivers/serial/usbtty.h | 4 +-
> drivers/usb/gadget/Makefile | 2 +-
> drivers/usb/gadget/{spr_udc.c => designware_udc.c} | 116 +++++++++++---------
> include/configs/spear-common.h | 2 +-
> include/usb/{spr_udc.h => designware_udc.h} | 8 +-
> 5 files changed, 74 insertions(+), 58 deletions(-)
> rename drivers/usb/gadget/{spr_udc.c => designware_udc.c} (91%)
> rename include/usb/{spr_udc.h => designware_udc.h} (98%)
>
> diff --git a/drivers/serial/usbtty.h b/drivers/serial/usbtty.h
> index a23169a..38b407f 100644
> --- a/drivers/serial/usbtty.h
> +++ b/drivers/serial/usbtty.h
> @@ -33,8 +33,8 @@
> #include <usb/musb_udc.h>
> #elif defined(CONFIG_PXA27X)
> #include <usb/pxa27x_udc.h>
> -#elif defined(CONFIG_SPEAR3XX) || defined(CONFIG_SPEAR600)
> -#include <usb/spr_udc.h>
> +#elif defined(CONFIG_DW_UDC)
> +#include <usb/designware_udc.h>
> #endif
>
> #include <version_autogenerated.h>
> diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
> index 1d7362d..3820f36 100644
> --- a/drivers/usb/gadget/Makefile
> +++ b/drivers/usb/gadget/Makefile
> @@ -28,11 +28,11 @@ LIB := $(obj)libusb_gadget.a
> ifdef CONFIG_USB_DEVICE
> COBJS-y += core.o
> COBJS-y += ep0.o
> +COBJS-$(CONFIG_DW_UDC) += designware_udc.o
> COBJS-$(CONFIG_OMAP1510) += omap1510_udc.o
> COBJS-$(CONFIG_OMAP1610) += omap1510_udc.o
> COBJS-$(CONFIG_MPC885_FAMILY) += mpc8xx_udc.o
> COBJS-$(CONFIG_PXA27X) += pxa27x_udc.o
> -COBJS-$(CONFIG_SPEARUDC) += spr_udc.o
> endif
>
> COBJS := $(COBJS-y)
> diff --git a/drivers/usb/gadget/spr_udc.c b/drivers/usb/gadget/designware_udc.c
> similarity index 91%
> rename from drivers/usb/gadget/spr_udc.c
> rename to drivers/usb/gadget/designware_udc.c
> index f2b06d6..e550426 100644
> --- a/drivers/usb/gadget/spr_udc.c
> +++ b/drivers/usb/gadget/designware_udc.c
> @@ -29,14 +29,13 @@
>
> #include <usbdevice.h>
> #include "ep0.h"
> -#include <usb/spr_udc.h>
> +#include <usb/designware_udc.h>
> #include <asm/arch/hardware.h>
> -#include <asm/arch/spr_misc.h>
>
> #define UDC_INIT_MDELAY 80 /* Device settle delay */
>
> /* Some kind of debugging output... */
> -#ifndef DEBUG_SPRUSBTTY
> +#ifndef DEBUG_DWUSBTTY
> #define UDCDBG(str)
> #define UDCDBGA(fmt, args...)
> #else
> @@ -251,7 +250,7 @@ static void usbputpcktofifo(int epNum, u8 *bufp, u32 len)
> }
>
> /*
> - * spear_write_noniso_tx_fifo - Write the next packet to TxFIFO.
> + * dw_write_noniso_tx_fifo - Write the next packet to TxFIFO.
> * @endpoint: Endpoint pointer.
> *
> * If the endpoint has an active tx_urb, then the next packet of data from the
> @@ -263,7 +262,7 @@ static void usbputpcktofifo(int epNum, u8 *bufp, u32 len)
> * transmitted in this packet.
> *
> */
> -static void spear_write_noniso_tx_fifo(struct usb_endpoint_instance
> +static void dw_write_noniso_tx_fifo(struct usb_endpoint_instance
> *endpoint)
> {
> struct urb *urb = endpoint->tx_urb;
> @@ -307,7 +306,7 @@ static void spear_write_noniso_tx_fifo(struct usb_endpoint_instance
> * Handle SETUP USB interrupt.
> * This function implements TRM Figure 14-14.
> */
> -static void spear_udc_setup(struct usb_endpoint_instance *endpoint)
> +static void dw_udc_setup(struct usb_endpoint_instance *endpoint)
> {
> u8 *datap = (u8 *)&ep0_urb->device_request;
> int ep_addr = endpoint->endpoint_address;
> @@ -344,11 +343,11 @@ static void spear_udc_setup(struct usb_endpoint_instance *endpoint)
> endpoint->tx_urb = ep0_urb;
> endpoint->sent = 0;
> /*
> - * Write packet data to the FIFO. spear_write_noniso_tx_fifo
> + * Write packet data to the FIFO. dw_write_noniso_tx_fifo
> * will update endpoint->last with the number of bytes written
> * to the FIFO.
> */
> - spear_write_noniso_tx_fifo(endpoint);
> + dw_write_noniso_tx_fifo(endpoint);
>
> writel(0x0, &inep_regs_p[ep_addr].write_done);
> }
> @@ -361,7 +360,7 @@ static void spear_udc_setup(struct usb_endpoint_instance *endpoint)
> /*
> * Handle endpoint 0 RX interrupt
> */
> -static void spear_udc_ep0_rx(struct usb_endpoint_instance *endpoint)
> +static void dw_udc_ep0_rx(struct usb_endpoint_instance *endpoint)
> {
> u8 dummy[64];
>
> @@ -395,7 +394,7 @@ static void spear_udc_ep0_rx(struct usb_endpoint_instance *endpoint)
> /*
> * Handle endpoint 0 TX interrupt
> */
> -static void spear_udc_ep0_tx(struct usb_endpoint_instance *endpoint)
> +static void dw_udc_ep0_tx(struct usb_endpoint_instance *endpoint)
> {
> struct usb_device_request *request = &ep0_urb->device_request;
> int ep_addr;
> @@ -444,7 +443,7 @@ static void spear_udc_ep0_tx(struct usb_endpoint_instance *endpoint)
> * need a zero-length terminating packet.
> */
> UDCDBG("ACK control read data stage packet");
> - spear_write_noniso_tx_fifo(endpoint);
> + dw_write_noniso_tx_fifo(endpoint);
>
> ep_addr = endpoint->endpoint_address;
> writel(0x0, &inep_regs_p[ep_addr].write_done);
> @@ -452,7 +451,7 @@ static void spear_udc_ep0_tx(struct usb_endpoint_instance *endpoint)
> }
> }
>
> -static struct usb_endpoint_instance *spear_find_ep(int ep)
> +static struct usb_endpoint_instance *dw_find_ep(int ep)
> {
> int i;
>
> @@ -469,11 +468,11 @@ static struct usb_endpoint_instance *spear_find_ep(int ep)
> * The ep argument is a physical endpoint number for a non-ISO IN endpoint
> * in the range 1 to 15.
> */
> -static void spear_udc_epn_rx(int ep)
> +static void dw_udc_epn_rx(int ep)
> {
> int nbytes = 0;
> struct urb *urb;
> - struct usb_endpoint_instance *endpoint = spear_find_ep(ep);
> + struct usb_endpoint_instance *endpoint = dw_find_ep(ep);
>
> if (endpoint) {
> urb = endpoint->rcv_urb;
> @@ -494,20 +493,28 @@ static void spear_udc_epn_rx(int ep)
> * The ep argument is a physical endpoint number for a non-ISO IN endpoint
> * in the range 16 to 30.
> */
> -static void spear_udc_epn_tx(int ep)
> +static void dw_udc_epn_tx(int ep)
> {
> - struct usb_endpoint_instance *endpoint = spear_find_ep(ep);
> + struct usb_endpoint_instance *endpoint = dw_find_ep(ep);
> +
> + if (!endpoint)
> + return;
This is a change not related to the change of 'spear' -> 'dw'
There are a number of other changes.
This patch must be split.
>
> /*
> * We need to transmit a terminating zero-length packet now if
> * we have sent all of the data in this URB and the transfer
> * size was an exact multiple of the packet size.
> */
> - if (endpoint && endpoint->tx_urb && endpoint->tx_urb->actual_length) {
> - if (endpoint->last == endpoint->tx_packetSize) {
> - /* handle zero length packet here */
> - writel(0x0, &inep_regs_p[ep].write_done);
> - }
> + if (endpoint->tx_urb &&
> + (endpoint->last == endpoint->tx_packetSize) &&
> + (endpoint->tx_urb->actual_length - endpoint->sent -
> + endpoint->last == 0)) {
> + /* handle zero length packet here */
> + writel(0x0, &inep_regs_p[ep].write_done);
> +
> + }
> +
> + if (endpoint->tx_urb && endpoint->tx_urb->actual_length) {
> /* retire the data that was just sent */
> usbd_tx_complete(endpoint);
> /*
> @@ -516,7 +523,7 @@ static void spear_udc_epn_tx(int ep)
> */
> if (endpoint->tx_urb && endpoint->tx_urb->actual_length) {
> /* write data to FIFO */
> - spear_write_noniso_tx_fifo(endpoint);
> + dw_write_noniso_tx_fifo(endpoint);
> writel(0x0, &inep_regs_p[ep].write_done);
>
> } else if (endpoint->tx_urb
> @@ -549,8 +556,6 @@ int udc_init(void)
>
> readl(&plug_regs_p->plug_pending);
>
> - udc_disconnect();
> -
This is another change.
> for (i = 0; i < UDC_INIT_MDELAY; i++)
> udelay(1000);
>
> @@ -562,10 +567,9 @@ int udc_init(void)
> writel(~0x0, &udc_regs_p->endp_int_mask);
>
> writel(DEV_CONF_FS_SPEED | DEV_CONF_REMWAKEUP | DEV_CONF_SELFPOW |
> - /* Dev_Conf_SYNCFRAME | */
> DEV_CONF_PHYINT_16, &udc_regs_p->dev_conf);
>
> - writel(0x0, &udc_regs_p->dev_cntl);
> + writel(DEV_CNTL_SD, &udc_regs_p->dev_cntl);
>
> /* Clear all interrupts pending */
> writel(DEV_INT_MSK, &udc_regs_p->dev_int);
> @@ -589,6 +593,9 @@ void udc_setup_ep(struct usb_device_instance *device,
> char *tt;
> u32 endp_intmask;
>
> + if ((ep != 0) && (udc_device->device_state < STATE_ADDRESSED))
> + return;
> +
Here too.
> tt = getenv("usbtty");
> if (!tt)
> tt = "generic";
> @@ -648,9 +655,6 @@ void udc_setup_ep(struct usb_device_instance *device,
> writel(packet_size | ((buffer_size / sizeof(int)) << 16),
> &out_p->endp_maxpacksize);
>
> - writel((packet_size << 19) | ENDP_EPTYPE_CNTL,
> - &udc_regs_p->udc_endp_reg[ep_num]);
> -
> } else if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
> /* Setup the IN endpoint */
> writel(0x0, &in_p->endp_status);
> @@ -709,7 +713,17 @@ void udc_setup_ep(struct usb_device_instance *device,
> /* Turn on the USB connection by enabling the pullup resistor */
> void udc_connect(void)
> {
> - u32 plug_st;
> + u32 plug_st, dev_cntl;
> +
> + dev_cntl = readl(&udc_regs_p->dev_cntl);
> + dev_cntl |= DEV_CNTL_SD;
> + writel(dev_cntl, &udc_regs_p->dev_cntl);
> +
> + udelay(1000);
> +
> + dev_cntl = readl(&udc_regs_p->dev_cntl);
> + dev_cntl &= ~DEV_CNTL_SD;
> + writel(dev_cntl, &udc_regs_p->dev_cntl);
>
> plug_st = readl(&plug_regs_p->plug_state);
> plug_st &= ~(PLUG_STATUS_PHY_RESET | PLUG_STATUS_PHY_MODE);
> @@ -721,6 +735,8 @@ void udc_disconnect(void)
> {
> u32 plug_st;
>
> + writel(DEV_CNTL_SD, &udc_regs_p->dev_cntl);
> +
> plug_st = readl(&plug_regs_p->plug_state);
> plug_st |= (PLUG_STATUS_PHY_RESET | PLUG_STATUS_PHY_MODE);
> writel(plug_st, &plug_regs_p->plug_state);
> @@ -765,7 +781,7 @@ void udc_startup_events(struct usb_device_instance *device)
> * DEVICE_HUB_CONFIGURED and DEVICE_RESET events here.
> * DEVICE_HUB_CONFIGURED causes a transition to the state STATE_POWERED,
> * and DEVICE_RESET causes a transition to the state STATE_DEFAULT.
> - * The SPEAr USB client controller has the capability to detect when the
> + * The DW USB client controller has the capability to detect when the
> * USB cable is connected to a powered USB bus, so we will defer the
> * DEVICE_HUB_CONFIGURED and DEVICE_RESET events until later.
> */
> @@ -776,7 +792,7 @@ void udc_startup_events(struct usb_device_instance *device)
> /*
> * Plug detection interrupt handling
> */
> -void spear_udc_plug_irq(void)
> +void dw_udc_plug_irq(void)
> {
> if (readl(&plug_regs_p->plug_state) & PLUG_STATUS_ATTACHED) {
> /*
> @@ -790,11 +806,6 @@ void spear_udc_plug_irq(void)
> UDCDBG("device attached and powered");
> udc_state_transition(udc_device->device_state, STATE_POWERED);
> } else {
> - /*
> - * USB cable detached
> - * Reset the PHY and switch the mode.
> - */
> - udc_disconnect();
> writel(~0x0, &udc_regs_p->dev_int_mask);
>
> UDCDBG("device detached or unpowered");
> @@ -805,18 +816,23 @@ void spear_udc_plug_irq(void)
> /*
> * Device interrupt handling
> */
> -void spear_udc_dev_irq(void)
> +void dw_udc_dev_irq(void)
> {
> if (readl(&udc_regs_p->dev_int) & DEV_INT_USBRESET) {
> writel(~0x0, &udc_regs_p->endp_int_mask);
>
> - udc_connect();
> -
> writel(readl(&inep_regs_p[0].endp_cntl) | ENDP_CNTL_FLUSH,
> &inep_regs_p[0].endp_cntl);
>
> writel(DEV_INT_USBRESET, &udc_regs_p->dev_int);
>
> + /*
> + * This endpoint0 specific register can be programmed only
> + * after the phy clock is initialized
> + */
> + writel((EP0_MAX_PACKET_SIZE << 19) | ENDP_EPTYPE_CNTL,
> + &udc_regs_p->udc_endp_reg[0]);
> +
> UDCDBG("device reset in progess");
> udc_state_transition(udc_device->device_state, STATE_DEFAULT);
> }
> @@ -870,7 +886,7 @@ void spear_udc_dev_irq(void)
> /*
> * Endpoint interrupt handling
> */
> -void spear_udc_endpoint_irq(void)
> +void dw_udc_endpoint_irq(void)
> {
> while (readl(&udc_regs_p->endp_int) & ENDP0_INT_CTRLOUT) {
>
> @@ -878,13 +894,13 @@ void spear_udc_endpoint_irq(void)
>
> if ((readl(&outep_regs_p[0].endp_status) & ENDP_STATUS_OUTMSK)
> == ENDP_STATUS_OUT_SETUP) {
> - spear_udc_setup(udc_device->bus->endpoint_array + 0);
> + dw_udc_setup(udc_device->bus->endpoint_array + 0);
> writel(ENDP_STATUS_OUT_SETUP,
> &outep_regs_p[0].endp_status);
>
> } else if ((readl(&outep_regs_p[0].endp_status) &
> ENDP_STATUS_OUTMSK) == ENDP_STATUS_OUT_DATA) {
> - spear_udc_ep0_rx(udc_device->bus->endpoint_array + 0);
> + dw_udc_ep0_rx(udc_device->bus->endpoint_array + 0);
> writel(ENDP_STATUS_OUT_DATA,
> &outep_regs_p[0].endp_status);
>
> @@ -897,13 +913,13 @@ void spear_udc_endpoint_irq(void)
> }
>
> if (readl(&udc_regs_p->endp_int) & ENDP0_INT_CTRLIN) {
> - spear_udc_ep0_tx(udc_device->bus->endpoint_array + 0);
> + dw_udc_ep0_tx(udc_device->bus->endpoint_array + 0);
>
> writel(ENDP_STATUS_IN, &inep_regs_p[0].endp_status);
> writel(ENDP0_INT_CTRLIN, &udc_regs_p->endp_int);
> }
>
> - while (readl(&udc_regs_p->endp_int) & ENDP_INT_NONISOOUT_MSK) {
> + if (readl(&udc_regs_p->endp_int) & ENDP_INT_NONISOOUT_MSK) {
> u32 epnum = 0;
> u32 ep_int = readl(&udc_regs_p->endp_int) &
> ENDP_INT_NONISOOUT_MSK;
> @@ -919,7 +935,7 @@ void spear_udc_endpoint_irq(void)
> if ((readl(&outep_regs_p[epnum].endp_status) &
> ENDP_STATUS_OUTMSK) == ENDP_STATUS_OUT_DATA) {
>
> - spear_udc_epn_rx(epnum);
> + dw_udc_epn_rx(epnum);
> writel(ENDP_STATUS_OUT_DATA,
> &outep_regs_p[epnum].endp_status);
> } else if ((readl(&outep_regs_p[epnum].endp_status) &
> @@ -941,7 +957,7 @@ void spear_udc_endpoint_irq(void)
> if (readl(&inep_regs_p[epnum].endp_status) & ENDP_STATUS_IN) {
> writel(ENDP_STATUS_IN,
> &outep_regs_p[epnum].endp_status);
> - spear_udc_epn_tx(epnum);
> + dw_udc_epn_tx(epnum);
>
> writel(ENDP_STATUS_IN,
> &outep_regs_p[epnum].endp_status);
> @@ -963,13 +979,13 @@ void udc_irq(void)
> * host requests.
> */
> while (readl(&plug_regs_p->plug_pending))
> - spear_udc_plug_irq();
> + dw_udc_plug_irq();
>
> while (readl(&udc_regs_p->dev_int))
> - spear_udc_dev_irq();
> + dw_udc_dev_irq();
>
> if (readl(&udc_regs_p->endp_int))
> - spear_udc_endpoint_irq();
> + dw_udc_endpoint_irq();
> }
>
> /* Flow control */
> diff --git a/include/configs/spear-common.h b/include/configs/spear-common.h
> index 99923de..61bc45f 100644
> --- a/include/configs/spear-common.h
> +++ b/include/configs/spear-common.h
> @@ -33,7 +33,7 @@
> #define CONFIG_PHY_RESET_DELAY (10000) /* in usec */
>
> /* USBD driver configuration */
> -#define CONFIG_SPEARUDC
> +#define CONFIG_DW_UDC
> #define CONFIG_USB_DEVICE
> #define CONFIG_USB_TTY
>
> diff --git a/include/usb/spr_udc.h b/include/usb/designware_udc.h
> similarity index 98%
> rename from include/usb/spr_udc.h
> rename to include/usb/designware_udc.h
> index 2c332d5..47509ba 100644
> --- a/include/usb/spr_udc.h
> +++ b/include/usb/designware_udc.h
> @@ -21,8 +21,8 @@
> * MA 02111-1307 USA
> */
>
> -#ifndef __SPR_UDC_H
> -#define __SPR_UDC_H
> +#ifndef __DW_UDC_H
> +#define __DW_UDC_H
>
> /*
> * Defines for USBD
> @@ -116,7 +116,7 @@ struct udc_regs {
> #define DEV_CNTL_TSHLDEN 0x00000080
> #define DEV_CNTL_BURSTEN 0x00000100
> #define DEV_CNTL_DMAMODE 0x00000200
> -#define DEV_CNTL_SOFTDISCONNECT 0x00000400
> +#define DEV_CNTL_SD 0x00000400
The more descriptive 'SOFTDISCONNECT' is preferred to 'SD'
Revert
Tom
> #define DEV_CNTL_SCALEDOWN 0x00000800
> #define DEV_CNTL_BURSTLENU 0x00010000
> #define DEV_CNTL_BURSTLENMSK 0x00ff0000
> @@ -227,4 +227,4 @@ void udc_startup_events(struct usb_device_instance *device);
> void udc_setup_ep(struct usb_device_instance *device, unsigned int ep,
> struct usb_endpoint_instance *endpoint);
>
> -#endif /* __SPR_UDC_H */
> +#endif /* __DW_UDC_H */
More information about the U-Boot
mailing list