[U-Boot] [PATCH RFC V1 00/18] Make mv_udc work for i.mx6

Hi Marek,
This series is based on your u-boot-testing/chipidea branch. After this series, nitrogen6x works with tftpboot to transfer files over usb. But I still cannot enable CONFIG_USB_TTY because of link errors.
Do you have a plan for defining the following symbols in general code? setup_ep udc_endpoint_write udc_init udc_startup_events udc_connect udc_unset_nak udc_set_nak udc_unset_nak
Or should usbtty be hacked to use more gadget style functions?
Troy Kisky (18): Add functions for use with i.mx6 otg udc mx6: iomux: add GPR1 defines mx6: define OTG_BASE_ADDR nitrogen6x: add otg usb ethernet gadget support nitrogen6x: add CONFIG_MV_UDC usb: gadget: config: fix unaligned access issues usb: gadget: mv_udc: set udc after controller.udc is initialized usb: gadget: mv_udc: add MX6Q specific reset usb: gadget: ether set wMaxPacketSize usb: gadget: ether: return error from rx_submit if no request usb: gadget: mv_udc: split mv_udc.h file usb: udc: add udc.h include file usb: gadget: mv_udc: fix typo in error message usb: gadget: mv_udc: use static initialization of ops,udc usb: gadget: mv_udc: set is_dualspeed = 1 usb: gadget: mv_udc: fix full speed connections usb: gadget: mv_udc: fix cache issues usb: gadget: mv_udc: clear desc upon ep_disable
arch/arm/cpu/armv7/mx6/soc.c | 70 ++++++++++++++++++ arch/arm/include/asm/arch-mx6/imx-regs.h | 2 + arch/arm/include/asm/arch-mx6/iomux.h | 6 ++ arch/arm/include/asm/arch-mx6/sys_proto.h | 4 + board/boundary/nitrogen6x/nitrogen6x.c | 16 ++++ drivers/serial/usbtty.h | 3 +- drivers/usb/gadget/config.c | 6 +- drivers/usb/gadget/ether.c | 5 +- drivers/usb/gadget/mv_udc.c | 100 ++++++++++++++++++------- drivers/usb/gadget/mv_udc.h | 117 +++++++++++++++++++++++++++++ include/configs/nitrogen6x.h | 7 ++ include/usb/designware_udc.h | 31 -------- include/usb/mpc8xx_udc.h | 19 +---- include/usb/musb_udc.h | 53 -------------- include/usb/mv_udc.h | 118 ------------------------------ include/usb/omap1510_udc.h | 27 +------ include/usb/pxa27x_udc.h | 26 +------ include/usb/udc.h | 60 +++++++++++++++ 18 files changed, 371 insertions(+), 299 deletions(-) create mode 100644 drivers/usb/gadget/mv_udc.h create mode 100644 include/usb/udc.h

Add functions for use with mx6 soc void otg_enable(void); void reset_usb_phy1(void);
Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com --- arch/arm/cpu/armv7/mx6/soc.c | 70 +++++++++++++++++++++++++++++++ arch/arm/include/asm/arch-mx6/sys_proto.h | 4 ++ 2 files changed, 74 insertions(+)
diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index fc436fb..e5a5734 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -28,11 +28,81 @@ #include <asm/io.h> #include <asm/arch/imx-regs.h> #include <asm/arch/clock.h> +#include <asm/arch/crm_regs.h> #include <asm/arch/sys_proto.h> #include <asm/imx-common/boot_mode.h> #include <asm/imx-common/dma.h> #include <stdbool.h>
+#ifdef CONFIG_MV_UDC + +struct set_clr_tog { + u32 val; + u32 set; + u32 clr; + u32 tog; +}; + +struct usbphy { + struct set_clr_tog pwd; + struct set_clr_tog tx; + struct set_clr_tog rx; + struct set_clr_tog ctrl; +}; + +#define BM_USBPHY_CTRL_CLKGATE 0x40000000 + +static void enable_usb_phy1_clk(unsigned char enable) +{ + struct usbphy *phy = (struct usbphy *)USB_PHY0_BASE_ADDR; + + writel(BM_USBPHY_CTRL_CLKGATE, + enable ? &phy->ctrl.clr : &phy->ctrl.set); +} + +#define BM_USBPHY_CTRL_SFTRST 0x80000000 + +void reset_usb_phy1(void) +{ + struct usbphy *phy = (struct usbphy *)USB_PHY0_BASE_ADDR; + + /* Reset USBPHY module */ + writel(BM_USBPHY_CTRL_SFTRST, &phy->ctrl.set); + udelay(10); + + /* Remove CLKGATE and SFTRST */ + writel(BM_USBPHY_CTRL_CLKGATE | BM_USBPHY_CTRL_SFTRST, &phy->ctrl.clr); + udelay(10); + + /* Power up the PHY */ + writel(0, &phy->pwd.val); +} + + +#define BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B 0x00080000 +#define BM_ANADIG_USB1_CHRG_DETECT_EN_B 0x00100000 + +static void set_usb_phy1_clk(void) +{ + struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; + + writel(BM_ANADIG_USB1_CHRG_DETECT_EN_B + | BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B, + &anatop->usb1_chrg_detect_set); + + /* make sure pll is enable here */ + writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS, + &anatop->usb1_pll_480_ctrl_set); +} + +void otg_enable(void) +{ + set_usb_phy1_clk(); + enable_usboh3_clk(1); + enable_usb_phy1_clk(1); +} +#endif + struct scu_regs { u32 ctrl; u32 config; diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h index 38e4e51..8ac57df 100644 --- a/arch/arm/include/asm/arch-mx6/sys_proto.h +++ b/arch/arm/include/asm/arch-mx6/sys_proto.h @@ -56,4 +56,8 @@ int mxs_wait_mask_set(struct mxs_register_32 *reg, int mxs_wait_mask_clr(struct mxs_register_32 *reg, uint32_t mask, unsigned int timeout); + +void otg_enable(void); +void reset_usb_phy1(void); + #endif

Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com --- arch/arm/include/asm/arch-mx6/iomux.h | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/arch/arm/include/asm/arch-mx6/iomux.h b/arch/arm/include/asm/arch-mx6/iomux.h index d67f600..5a2e75f 100644 --- a/arch/arm/include/asm/arch-mx6/iomux.h +++ b/arch/arm/include/asm/arch-mx6/iomux.h @@ -22,6 +22,12 @@ #define MX6_IOMUXC_GPR7 0x020e001c
/* + * IOMUXC_GPR1 bit fields + */ +#define IOMUXC_GPR1_OTG_ID_ENET_RX_ERR (0<<13) +#define IOMUXC_GPR1_OTG_ID_GPIO1 (1<<13) +#define IOMUXC_GPR1_OTG_ID_MASK (1<<13) +/* * IOMUXC_GPR13 bit fields */ #define IOMUXC_GPR13_SDMA_STOP_REQ (1<<30)

Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com --- arch/arm/include/asm/arch-mx6/imx-regs.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index 03abb2a..30a9687 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -181,9 +181,11 @@ #ifdef CONFIG_MX6SL #define USBO2H_PL301_IPS_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x0000) #define USBO2H_USB_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4000) +#define OTG_BASE_ADDR USBO2H_USB_BASE_ADDR #else #define USBOH3_PL301_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x0000) #define USBOH3_USB_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4000) +#define OTG_BASE_ADDR USBOH3_USB_BASE_ADDR #endif
#define ENET_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x8000)

Dear Troy Kisky,
Please add commit messages. Btw I removed this horrible macro in my patchset.
Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com
arch/arm/include/asm/arch-mx6/imx-regs.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index 03abb2a..30a9687 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -181,9 +181,11 @@ #ifdef CONFIG_MX6SL #define USBO2H_PL301_IPS_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x0000) #define USBO2H_USB_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4000) +#define OTG_BASE_ADDR USBO2H_USB_BASE_ADDR #else #define USBOH3_PL301_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x0000) #define USBOH3_USB_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4000) +#define OTG_BASE_ADDR USBOH3_USB_BASE_ADDR #endif
#define ENET_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x8000)
Best regards, Marek Vasut

Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com --- board/boundary/nitrogen6x/nitrogen6x.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/board/boundary/nitrogen6x/nitrogen6x.c b/board/boundary/nitrogen6x/nitrogen6x.c index 8f0f9b8..a845ee5 100644 --- a/board/boundary/nitrogen6x/nitrogen6x.c +++ b/board/boundary/nitrogen6x/nitrogen6x.c @@ -46,6 +46,7 @@ #include <i2c.h>
DECLARE_GLOBAL_DATA_PTR; +#define GP_USB_OTG_PWR IMX_GPIO_NR(3, 22)
#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ @@ -385,6 +386,13 @@ int board_eth_init(bd_t *bis) free(bus); } #endif + +#ifdef CONFIG_MV_UDC + otg_enable(); + + /* For otg ethernet*/ + usb_eth_initialize(bis); +#endif return 0; }
@@ -733,6 +741,7 @@ int board_early_init_f(void) gpio_direction_input(WL12XX_WL_IRQ_GP); gpio_direction_output(WL12XX_WL_ENABLE_GP, 0); gpio_direction_output(WL12XX_BT_ENABLE_GP, 0); + gpio_direction_output(GP_USB_OTG_PWR, 0); /* OTG power off */
imx_iomux_v3_setup_multiple_pads(wl12xx_pads, ARRAY_SIZE(wl12xx_pads)); setup_buttons(); @@ -754,6 +763,13 @@ int overwrite_console(void)
int board_init(void) { + struct iomuxc_base_regs *const iomuxc_regs + = (struct iomuxc_base_regs *)IOMUXC_BASE_ADDR; + + clrsetbits_le32(&iomuxc_regs->gpr[1], + IOMUXC_GPR1_OTG_ID_MASK, + IOMUXC_GPR1_OTG_ID_GPIO1); + /* address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;

Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com --- include/configs/nitrogen6x.h | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/include/configs/nitrogen6x.h b/include/configs/nitrogen6x.h index aea91bc..40d0191 100644 --- a/include/configs/nitrogen6x.h +++ b/include/configs/nitrogen6x.h @@ -43,6 +43,13 @@ #define CONFIG_BOARD_EARLY_INIT_F #define CONFIG_MISC_INIT_R #define CONFIG_MXC_GPIO +#define CONFIG_MV_UDC +#define CONFIG_USBD_HS +#define CONFIG_USB_REG_BASE OTG_BASE_ADDR +#define CONFIG_USB_GADGET_DUALSPEED +#define CONFIG_USB_ETHER +#define CONFIG_USB_ETH_CDC +#define CONFIG_NETCONSOLE
#define CONFIG_CMD_FUSE #ifdef CONFIG_CMD_FUSE

Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com --- drivers/usb/gadget/config.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c index f9163a8..a4cb5ad 100644 --- a/drivers/usb/gadget/config.c +++ b/drivers/usb/gadget/config.c @@ -22,6 +22,7 @@ */
#include <common.h> +#include <asm/unaligned.h> #include <asm/errno.h> #include <linux/list.h> #include <linux/string.h> @@ -98,7 +99,8 @@ int usb_gadget_config_buf( /* config descriptor first */ if (length < USB_DT_CONFIG_SIZE || !desc) return -EINVAL; - *cp = *config; + /* config need not be aligned */ + memcpy(cp, config, sizeof(*cp));
/* then interface/endpoint/class/vendor/... */ len = usb_descriptor_fillbuf(USB_DT_CONFIG_SIZE + (u8 *)buf, @@ -112,7 +114,7 @@ int usb_gadget_config_buf( /* patch up the config descriptor */ cp->bLength = USB_DT_CONFIG_SIZE; cp->bDescriptorType = USB_DT_CONFIG; - cp->wTotalLength = cpu_to_le16(len); + put_unaligned_le16(len, &cp->wTotalLength); cp->bmAttributes |= USB_CONFIG_ATT_ONE; return len; }

Dear Troy Kisky,
Missing commit message :-(
Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com
drivers/usb/gadget/config.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c index f9163a8..a4cb5ad 100644 --- a/drivers/usb/gadget/config.c +++ b/drivers/usb/gadget/config.c @@ -22,6 +22,7 @@ */
#include <common.h> +#include <asm/unaligned.h> #include <asm/errno.h> #include <linux/list.h> #include <linux/string.h> @@ -98,7 +99,8 @@ int usb_gadget_config_buf( /* config descriptor first */ if (length < USB_DT_CONFIG_SIZE || !desc) return -EINVAL;
- *cp = *config;
/* config need not be aligned */
memcpy(cp, config, sizeof(*cp));
/* then interface/endpoint/class/vendor/... */ len = usb_descriptor_fillbuf(USB_DT_CONFIG_SIZE + (u8 *)buf,
@@ -112,7 +114,7 @@ int usb_gadget_config_buf( /* patch up the config descriptor */ cp->bLength = USB_DT_CONFIG_SIZE; cp->bDescriptorType = USB_DT_CONFIG;
- cp->wTotalLength = cpu_to_le16(len);
- put_unaligned_le16(len, &cp->wTotalLength); cp->bmAttributes |= USB_CONFIG_ATT_ONE; return len;
}
Best regards, Marek Vasut

mvudc_probe initializes controller.udc, so move initialization of local udc variable after this call.
Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com --- drivers/usb/gadget/mv_udc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/gadget/mv_udc.c b/drivers/usb/gadget/mv_udc.c index db30bdd..5ab4656 100644 --- a/drivers/usb/gadget/mv_udc.c +++ b/drivers/usb/gadget/mv_udc.c @@ -471,7 +471,6 @@ static int mvudc_probe(void)
int usb_gadget_register_driver(struct usb_gadget_driver *driver) { - struct mv_udc *udc = controller.udc; int retval; void *ctrl;
@@ -484,6 +483,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) }
if (!mvudc_probe()) { + struct mv_udc *udc = controller.udc; + usb_lowlevel_init(0, &ctrl); /* select ULPI phy */ writel(PTS(PTS_ENABLE) | PFSC, &udc->portsc);

Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com
--- I don't know if this is needed, but it doesn't hurt. --- drivers/usb/gadget/mv_udc.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/usb/gadget/mv_udc.c b/drivers/usb/gadget/mv_udc.c index 5ab4656..033a9f1 100644 --- a/drivers/usb/gadget/mv_udc.c +++ b/drivers/usb/gadget/mv_udc.c @@ -392,6 +392,9 @@ static int mv_pullup(struct usb_gadget *gadget, int is_on) /* RESET */ writel(USBCMD_ITC(MICRO_8FRAME) | USBCMD_RST, &udc->usbcmd); udelay(200); +#if defined(CONFIG_MX6Q) || defined(CONFIG_MX6DL) + reset_usb_phy1(); +#endif
writel((unsigned) epts, &udc->epinitaddr);

set wMaxPacketSize for full speed descriptors
Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com --- drivers/usb/gadget/ether.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index de880ff..e39714b 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -647,6 +647,7 @@ fs_source_desc = {
.bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = __constant_cpu_to_le16(64), };
static struct usb_endpoint_descriptor @@ -656,6 +657,7 @@ fs_sink_desc = {
.bEndpointAddress = USB_DIR_OUT, .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = __constant_cpu_to_le16(64), };
static const struct usb_descriptor_header *fs_eth_function[11] = {

This prevents a crash if tftpboot is given a bad filename.
Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com --- drivers/usb/gadget/ether.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index e39714b..1542ca3 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -2401,7 +2401,8 @@ static int usb_eth_init(struct eth_device *netdev, bd_t *bd) }
packet_received = 0; - rx_submit(dev, dev->rx_req, 0); + if (dev->rx_req) + rx_submit(dev, dev->rx_req, 0); return 0; fail: return -1;

On 7/16/2013 1:47 PM, Troy Kisky wrote:
This prevents a crash if tftpboot is given a bad filename.
Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com
drivers/usb/gadget/ether.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index e39714b..1542ca3 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -2401,7 +2401,8 @@ static int usb_eth_init(struct eth_device *netdev, bd_t *bd) }
packet_received = 0;
- rx_submit(dev, dev->rx_req, 0);
- if (dev->rx_req)
return 0; fail: return -1;rx_submit(dev, dev->rx_req, 0);
This patch is wrong. I will put the check in rx_submit, because this call was not the problem.

Move defines only needed by mv_udc.c to a file in the same directory.
This allows usbtty to compile for mv_udc, but it still doesn't link.
Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com --- drivers/usb/gadget/mv_udc.c | 6 +++ drivers/usb/gadget/mv_udc.h | 117 +++++++++++++++++++++++++++++++++++++++++++ include/usb/mv_udc.h | 118 -------------------------------------------- 3 files changed, 123 insertions(+), 118 deletions(-) create mode 100644 drivers/usb/gadget/mv_udc.h
diff --git a/drivers/usb/gadget/mv_udc.c b/drivers/usb/gadget/mv_udc.c index 033a9f1..8bf7040 100644 --- a/drivers/usb/gadget/mv_udc.c +++ b/drivers/usb/gadget/mv_udc.c @@ -29,10 +29,16 @@ #include <config.h> #include <net.h> #include <malloc.h> +#include <asm/byteorder.h> #include <asm/io.h> +#include <asm/errno.h> #include <linux/types.h> +#include <linux/usb/ch9.h> +#include <linux/usb/gadget.h> #include <usb/mv_udc.h>
+#include "mv_udc.h" + #if CONFIG_USB_MAX_CONTROLLER_COUNT > 1 #error This driver only supports one single controller. #endif diff --git a/drivers/usb/gadget/mv_udc.h b/drivers/usb/gadget/mv_udc.h new file mode 100644 index 0000000..971e0a1 --- /dev/null +++ b/drivers/usb/gadget/mv_udc.h @@ -0,0 +1,117 @@ +/* + * Copyright 2011, Marvell Semiconductor Inc. + * + * Licensed under the GPL-2 or later. + */ +#ifndef __GADGET__MV_UDC_H__ +#define __GADGET__MV_UDC_H__ + +/* Endpoint 0 states */ +#define EP0_IDLE 0 +#define EP0_IN_DATA 1 +#define EP0_OUT_DATA 2 +#define EP0_XFER_COMPLETE 3 + +#define NUM_ENDPOINTS 6 +#define REQ_COUNT 12 + +struct mv_ep { + struct usb_ep ep; + struct usb_request req; + struct list_head queue; + const struct usb_endpoint_descriptor *desc; +}; + +struct mv_udc { + u32 pad0[80]; +#define MICRO_8FRAME 0x8 +#define USBCMD_ITC(x) (((x > 0xff) ? 0xff : x) << 16) +#define USBCMD_FS2 (1 << 15) +#define USBCMD_RST (1 << 1) +#define USBCMD_RUN (1) + u32 usbcmd; /* 0x140 */ +#define STS_SLI (1 << 8) +#define STS_URI (1 << 6) +#define STS_PCI (1 << 2) +#define STS_UEI (1 << 1) +#define STS_UI (1 << 0) + u32 usbsts; /* 0x144 */ + u32 pad1[3]; + u32 devaddr; /* 0x154 */ + u32 epinitaddr; /* 0x158 */ + u32 pad2[10]; +#define PTS_ENABLE 2 +#define PTS(x) ((x & 0x3) << 30) +#define PFSC (1 << 24) + u32 portsc; /* 0x184 */ + u32 pad3[8]; +#define USBMODE_DEVICE 2 + u32 usbmode; /* 0x1a8 */ + u32 epstat; /* 0x1ac */ +#define EPT_TX(x) (1 << ((x & 0xffff) + 16)) +#define EPT_RX(x) (1 << (x & 0xffff)) + u32 epprime; /* 0x1b0 */ + u32 epflush; /* 0x1b4 */ + u32 pad4; + u32 epcomp; /* 0x1bc */ +#define CTRL_TXE (1 << 23) +#define CTRL_TXR (1 << 22) +#define CTRL_RXE (1 << 7) +#define CTRL_RXR (1 << 6) +#define CTRL_TXT_BULK (2 << 18) +#define CTRL_RXT_BULK (2 << 2) + u32 epctrl[16]; /* 0x1c0 */ +}; + +struct mv_drv { + struct usb_gadget gadget; + struct usb_gadget_driver *driver; + struct mv_udc *udc; +}; + +struct ept_queue_head { + unsigned config; + unsigned current; /* read-only */ + + unsigned next; + unsigned info; + unsigned page0; + unsigned page1; + unsigned page2; + unsigned page3; + unsigned page4; + unsigned reserved_0; + + unsigned char setup_data[8]; + + unsigned reserved_1; + unsigned reserved_2; + unsigned reserved_3; + unsigned reserved_4; +}; + +#define CONFIG_MAX_PKT(n) ((n) << 16) +#define CONFIG_ZLT (1 << 29) /* stop on zero-len xfer */ +#define CONFIG_IOS (1 << 15) /* IRQ on setup */ + +struct ept_queue_item { + unsigned next; + unsigned info; + unsigned page0; + unsigned page1; + unsigned page2; + unsigned page3; + unsigned page4; + unsigned reserved; +}; + +#define TERMINATE 1 +#define INFO_BYTES(n) ((n) << 16) +#define INFO_IOC (1 << 15) +#define INFO_ACTIVE (1 << 7) +#define INFO_HALTED (1 << 6) +#define INFO_BUFFER_ERROR (1 << 5) +#define INFO_TX_ERROR (1 << 3) + +extern int usb_lowlevel_init(int index, void **controller); +#endif diff --git a/include/usb/mv_udc.h b/include/usb/mv_udc.h index 221e626..5fe5b7a 100644 --- a/include/usb/mv_udc.h +++ b/include/usb/mv_udc.h @@ -22,130 +22,12 @@ #ifndef __MV_UDC_H__ #define __MV_UDC_H__
-#include <asm/byteorder.h> -#include <asm/errno.h> -#include <linux/usb/ch9.h> -#include <linux/usb/gadget.h> - -/* Endpoint 0 states */ -#define EP0_IDLE 0 -#define EP0_IN_DATA 1 -#define EP0_OUT_DATA 2 -#define EP0_XFER_COMPLETE 3 - - /* Endpoint parameters */ -#define MAX_ENDPOINTS 4 #define EP_MAX_PACKET_SIZE 0x200
#define EP0_MAX_PACKET_SIZE 64 #define UDC_OUT_ENDPOINT 0x02 -#define UDC_OUT_PACKET_SIZE EP_MAX_PACKET_SIZE #define UDC_IN_ENDPOINT 0x01 -#define UDC_IN_PACKET_SIZE EP_MAX_PACKET_SIZE #define UDC_INT_ENDPOINT 0x05 -#define UDC_INT_PACKET_SIZE EP_MAX_PACKET_SIZE -#define UDC_BULK_PACKET_SIZE EP_MAX_PACKET_SIZE - -#define NUM_ENDPOINTS 6 -#define REQ_COUNT 12 -struct mv_ep { - struct usb_ep ep; - struct usb_request req; - struct list_head queue; - const struct usb_endpoint_descriptor *desc; -}; - -struct mv_udc { - u32 pad0[80]; -#define MICRO_8FRAME 0x8 -#define USBCMD_ITC(x) (((x > 0xff) ? 0xff : x) << 16) -#define USBCMD_FS2 (1 << 15) -#define USBCMD_RST (1 << 1) -#define USBCMD_RUN (1) - u32 usbcmd; /* 0x140 */ -#define STS_SLI (1 << 8) -#define STS_URI (1 << 6) -#define STS_PCI (1 << 2) -#define STS_UEI (1 << 1) -#define STS_UI (1 << 0) - u32 usbsts; /* 0x144 */ - u32 pad1[3]; - u32 devaddr; /* 0x154 */ - u32 epinitaddr; /* 0x158 */ - u32 pad2[10]; -#define PTS_ENABLE 2 -#define PTS(x) ((x & 0x3) << 30) -#define PFSC (1 << 24) - u32 portsc; /* 0x184 */ - u32 pad3[8]; -#define USBMODE_DEVICE 2 - u32 usbmode; /* 0x1a8 */ - u32 epstat; /* 0x1ac */ -#define EPT_TX(x) (1 << ((x & 0xffff) + 16)) -#define EPT_RX(x) (1 << (x & 0xffff)) - u32 epprime; /* 0x1b0 */ - u32 epflush; /* 0x1b4 */ - u32 pad4; - u32 epcomp; /* 0x1bc */ -#define CTRL_TXE (1 << 23) -#define CTRL_TXR (1 << 22) -#define CTRL_RXE (1 << 7) -#define CTRL_RXR (1 << 6) -#define CTRL_TXT_BULK (2 << 18) -#define CTRL_RXT_BULK (2 << 2) - u32 epctrl[16]; /* 0x1c0 */ -}; - -struct mv_drv { - struct usb_gadget gadget; - struct usb_gadget_driver *driver; - struct mv_udc *udc; -}; - -struct ept_queue_head { - unsigned config; - unsigned current; /* read-only */ - - unsigned next; - unsigned info; - unsigned page0; - unsigned page1; - unsigned page2; - unsigned page3; - unsigned page4; - unsigned reserved_0; - - unsigned char setup_data[8]; - - unsigned reserved_1; - unsigned reserved_2; - unsigned reserved_3; - unsigned reserved_4; -}; - -#define CONFIG_MAX_PKT(n) ((n) << 16) -#define CONFIG_ZLT (1 << 29) /* stop on zero-len xfer */ -#define CONFIG_IOS (1 << 15) /* IRQ on setup */ - -struct ept_queue_item { - unsigned next; - unsigned info; - unsigned page0; - unsigned page1; - unsigned page2; - unsigned page3; - unsigned page4; - unsigned reserved; -}; - -#define TERMINATE 1 -#define INFO_BYTES(n) ((n) << 16) -#define INFO_IOC (1 << 15) -#define INFO_ACTIVE (1 << 7) -#define INFO_HALTED (1 << 6) -#define INFO_BUFFER_ERROR (1 << 5) -#define INFO_TX_ERROR (1 << 3)
-extern int usb_lowlevel_init(int index, void **controller); #endif /* __MV_UDC_H__ */

Move common defintions to udc.h
Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com --- drivers/serial/usbtty.h | 3 +-- include/usb/designware_udc.h | 31 ----------------------- include/usb/mpc8xx_udc.h | 19 +------------- include/usb/musb_udc.h | 53 -------------------------------------- include/usb/omap1510_udc.h | 27 +++----------------- include/usb/pxa27x_udc.h | 26 +------------------ include/usb/udc.h | 60 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 66 insertions(+), 153 deletions(-) create mode 100644 include/usb/udc.h
diff --git a/drivers/serial/usbtty.h b/drivers/serial/usbtty.h index 4a0bd45..17ee321 100644 --- a/drivers/serial/usbtty.h +++ b/drivers/serial/usbtty.h @@ -29,8 +29,6 @@ #include <usb/mpc8xx_udc.h> #elif defined(CONFIG_OMAP1510) #include <usb/omap1510_udc.h> -#elif defined(CONFIG_MUSB_UDC) -#include <usb/musb_udc.h> #elif defined(CONFIG_CPU_PXA27X) #include <usb/pxa27x_udc.h> #elif defined(CONFIG_DW_UDC) @@ -39,6 +37,7 @@ #include <usb/mv_udc.h> #endif
+#include <usb/udc.h> #include <version.h>
/* If no VendorID/ProductID is defined in config.h, pretend to be Linux diff --git a/include/usb/designware_udc.h b/include/usb/designware_udc.h index 18b7c19..a8aa69c 100644 --- a/include/usb/designware_udc.h +++ b/include/usb/designware_udc.h @@ -190,19 +190,6 @@ struct udcfifo_regs { };
/* - * USBTTY definitions - */ -#define EP0_MAX_PACKET_SIZE 64 -#define UDC_INT_ENDPOINT 1 -#define UDC_INT_PACKET_SIZE 64 -#define UDC_OUT_ENDPOINT 2 -#define UDC_BULK_PACKET_SIZE 64 -#define UDC_BULK_HS_PACKET_SIZE 512 -#define UDC_IN_ENDPOINT 3 -#define UDC_OUT_PACKET_SIZE 64 -#define UDC_IN_PACKET_SIZE 64 - -/* * UDC endpoint definitions */ #define UDC_EP0 0 @@ -210,22 +197,4 @@ struct udcfifo_regs { #define UDC_EP2 2 #define UDC_EP3 3
-/* - * Function declarations - */ - -void udc_irq(void); - -void udc_set_nak(int epid); -void udc_unset_nak(int epid); -int udc_endpoint_write(struct usb_endpoint_instance *endpoint); -int udc_init(void); -void udc_enable(struct usb_device_instance *device); -void udc_disable(void); -void udc_connect(void); -void udc_disconnect(void); -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 /* __DW_UDC_H */ diff --git a/include/usb/mpc8xx_udc.h b/include/usb/mpc8xx_udc.h index 039d245..19681f3 100644 --- a/include/usb/mpc8xx_udc.h +++ b/include/usb/mpc8xx_udc.h @@ -126,11 +126,9 @@
/* UDC device defines */ #define EP0_MAX_PACKET_SIZE EP_MAX_PKT -#define UDC_OUT_ENDPOINT 0x02 + #define UDC_OUT_PACKET_SIZE EP_MIN_PACKET_SIZE -#define UDC_IN_ENDPOINT 0x03 #define UDC_IN_PACKET_SIZE EP_MIN_PACKET_SIZE -#define UDC_INT_ENDPOINT 0x01 #define UDC_INT_PACKET_SIZE UDC_IN_PACKET_SIZE #define UDC_BULK_PACKET_SIZE EP_MIN_PACKET_SIZE
@@ -193,18 +191,3 @@ typedef enum mpc8xx_udc_state{ STATE_READY, }mpc8xx_udc_state_t;
-/* Declarations */ -int udc_init(void); -void udc_irq(void); -int udc_endpoint_write(struct usb_endpoint_instance *endpoint); -void udc_setup_ep(struct usb_device_instance *device, unsigned int ep, - struct usb_endpoint_instance *endpoint); -void udc_connect(void); -void udc_disconnect(void); -void udc_enable(struct usb_device_instance *device); -void udc_disable(void); -void udc_startup_events(struct usb_device_instance *device); - -/* Flow control */ -void udc_set_nak(int epid); -void udc_unset_nak (int epid); diff --git a/include/usb/musb_udc.h b/include/usb/musb_udc.h index be808fd..e69de29 100644 --- a/include/usb/musb_udc.h +++ b/include/usb/musb_udc.h @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2009 Wind River Systems, Inc. - * Tom Rix Tom.Rix@windriver.com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ -#ifndef __MUSB_UDC_H__ -#define __MUSB_UDC_H__ - -#include <usbdevice.h> - -/* UDC level routines */ -void udc_irq(void); -void udc_set_nak(int ep_num); -void udc_unset_nak(int ep_num); -int udc_endpoint_write(struct usb_endpoint_instance *endpoint); -void udc_setup_ep(struct usb_device_instance *device, unsigned int id, - struct usb_endpoint_instance *endpoint); -void udc_connect(void); -void udc_disconnect(void); -void udc_enable(struct usb_device_instance *device); -void udc_disable(void); -void udc_startup_events(struct usb_device_instance *device); -int udc_init(void); - -/* usbtty */ -#ifdef CONFIG_USB_TTY - -#define EP0_MAX_PACKET_SIZE 64 /* MUSB_EP0_FIFOSIZE */ -#define UDC_INT_ENDPOINT 1 -#define UDC_INT_PACKET_SIZE 64 -#define UDC_OUT_ENDPOINT 2 -#define UDC_OUT_PACKET_SIZE 64 -#define UDC_IN_ENDPOINT 3 -#define UDC_IN_PACKET_SIZE 64 -#define UDC_BULK_PACKET_SIZE 64 - -#endif /* CONFIG_USB_TTY */ - -#endif /* __MUSB_UDC_H__ */ diff --git a/include/usb/omap1510_udc.h b/include/usb/omap1510_udc.h index ece0e95..934930b 100644 --- a/include/usb/omap1510_udc.h +++ b/include/usb/omap1510_udc.h @@ -162,32 +162,11 @@ #define UDC_VBUS_MODE (1 << 18)
/* OMAP Endpoint parameters */ -#define EP0_MAX_PACKET_SIZE 64 -#define UDC_OUT_ENDPOINT 2 -#define UDC_OUT_PACKET_SIZE 64 -#define UDC_IN_ENDPOINT 1 -#define UDC_IN_PACKET_SIZE 64 -#define UDC_INT_ENDPOINT 5 #define UDC_INT_PACKET_SIZE 16 #define UDC_BULK_PACKET_SIZE 16
-void udc_irq (void); -/* Flow control */ -void udc_set_nak(int epid); -void udc_unset_nak (int epid); - -/* Higher level functions for abstracting away from specific device */ -int udc_endpoint_write(struct usb_endpoint_instance *endpoint); - -int udc_init (void); - -void udc_enable(struct usb_device_instance *device); -void udc_disable(void); - -void udc_connect(void); -void udc_disconnect(void); - -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); +#define UDC_INT_ENDPOINT 5 +#define UDC_OUT_ENDPOINT 2 +#define UDC_IN_ENDPOINT 1
#endif diff --git a/include/usb/pxa27x_udc.h b/include/usb/pxa27x_udc.h index 11dbb62..cd22617 100644 --- a/include/usb/pxa27x_udc.h +++ b/include/usb/pxa27x_udc.h @@ -35,35 +35,11 @@
/* Endpoint parameters */ #define MAX_ENDPOINTS 4 -#define EP_MAX_PACKET_SIZE 64
#define EP0_MAX_PACKET_SIZE 16 + #define UDC_OUT_ENDPOINT 0x02 -#define UDC_OUT_PACKET_SIZE EP_MAX_PACKET_SIZE #define UDC_IN_ENDPOINT 0x01 -#define UDC_IN_PACKET_SIZE EP_MAX_PACKET_SIZE #define UDC_INT_ENDPOINT 0x05 -#define UDC_INT_PACKET_SIZE EP_MAX_PACKET_SIZE -#define UDC_BULK_PACKET_SIZE EP_MAX_PACKET_SIZE - -void udc_irq(void); -/* Flow control */ -void udc_set_nak(int epid); -void udc_unset_nak(int epid); - -/* Higher level functions for abstracting away from specific device */ -int udc_endpoint_write(struct usb_endpoint_instance *endpoint); - -int udc_init(void); - -void udc_enable(struct usb_device_instance *device); -void udc_disable(void); - -void udc_connect(void); -void udc_disconnect(void); - -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 diff --git a/include/usb/udc.h b/include/usb/udc.h new file mode 100644 index 0000000..73b1184 --- /dev/null +++ b/include/usb/udc.h @@ -0,0 +1,60 @@ +#ifndef USB_UDC_H +#define USB_UDC_H + +#ifndef EP0_MAX_PACKET_SIZE +#define EP0_MAX_PACKET_SIZE 64 +#endif + +#ifndef EP_MAX_PACKET_SIZE +#define EP_MAX_PACKET_SIZE 64 +#endif + +#ifndef UDC_OUT_PACKET_SIZE +#define UDC_OUT_PACKET_SIZE EP_MAX_PACKET_SIZE +#endif + +#ifndef UDC_IN_PACKET_SIZE +#define UDC_IN_PACKET_SIZE EP_MAX_PACKET_SIZE +#endif + +#ifndef UDC_INT_PACKET_SIZE +#define UDC_INT_PACKET_SIZE EP_MAX_PACKET_SIZE +#endif + +#ifndef UDC_BULK_PACKET_SIZE +#define UDC_BULK_PACKET_SIZE EP_MAX_PACKET_SIZE +#endif + +#ifndef UDC_BULK_HS_PACKET_SIZE +#define UDC_BULK_HS_PACKET_SIZE 512 +#endif + +#ifndef UDC_INT_ENDPOINT +#define UDC_INT_ENDPOINT 1 +#endif + +#ifndef UDC_OUT_ENDPOINT +#define UDC_OUT_ENDPOINT 2 +#endif + +#ifndef UDC_IN_ENDPOINT +#define UDC_IN_ENDPOINT 3 +#endif + +/* function declarations */ +int udc_init(void); +void udc_irq(void); +int udc_endpoint_write(struct usb_endpoint_instance *endpoint); +void udc_setup_ep(struct usb_device_instance *device, unsigned int ep, + struct usb_endpoint_instance *endpoint); +void udc_connect(void); +void udc_disconnect(void); +void udc_enable(struct usb_device_instance *device); +void udc_disable(void); +void udc_startup_events(struct usb_device_instance *device); + +/* Flow control */ +void udc_set_nak(int epid); +void udc_unset_nak(int epid); + +#endif

Change 'nfo=' to 'info='
Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com
squash typo --- drivers/usb/gadget/mv_udc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/gadget/mv_udc.c b/drivers/usb/gadget/mv_udc.c index 8bf7040..820a3b8 100644 --- a/drivers/usb/gadget/mv_udc.c +++ b/drivers/usb/gadget/mv_udc.c @@ -210,8 +210,8 @@ static void handle_ep_complete(struct mv_ep *ep) item = items[2 * num + in];
if (item->info & 0xff) - printf("EP%d/%s FAIL nfo=%x pg0=%x\n", - num, in ? "in" : "out", item->info, item->page0); + printf("EP%d/%s FAIL info=%x pg0=%x\n", + num, in ? "in" : "out", item->info, item->page0);
len = (item->info >> 16) & 0x7fff; ep->req.length -= len;

Move the initialization of gadget.ops and udc from code to the static structure.
Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com --- drivers/usb/gadget/mv_udc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/gadget/mv_udc.c b/drivers/usb/gadget/mv_udc.c index 820a3b8..8f3d975 100644 --- a/drivers/usb/gadget/mv_udc.c +++ b/drivers/usb/gadget/mv_udc.c @@ -107,9 +107,11 @@ static struct usb_ep_ops mv_ep_ops = {
static struct mv_ep ep[2 * NUM_ENDPOINTS]; static struct mv_drv controller = { + .udc = (struct mv_udc *)CONFIG_USB_REG_BASE, .gadget = { .ep0 = &ep[0].ep, .name = "mv_udc", + .ops = &mv_udc_ops, }, };
@@ -438,8 +440,6 @@ static int mvudc_probe(void) struct ept_queue_head *head; int i;
- controller.gadget.ops = &mv_udc_ops; - controller.udc = (struct mv_udc *)CONFIG_USB_REG_BASE; epts = memalign(PAGE_SIZE, QH_MAXNUM * sizeof(struct ept_queue_head)); memset(epts, 0, QH_MAXNUM * sizeof(struct ept_queue_head)); for (i = 0; i < 2 * NUM_ENDPOINTS; i++) {

This controller support full and high speed.
Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com --- drivers/usb/gadget/mv_udc.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/usb/gadget/mv_udc.c b/drivers/usb/gadget/mv_udc.c index 8f3d975..5c10a8b 100644 --- a/drivers/usb/gadget/mv_udc.c +++ b/drivers/usb/gadget/mv_udc.c @@ -112,6 +112,7 @@ static struct mv_drv controller = { .ep0 = &ep[0].ep, .name = "mv_udc", .ops = &mv_udc_ops, + .is_dualspeed = 1, }, };

Set maximum packet length in queue header to wMaxPacketSize of endpoint.
Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com --- drivers/usb/gadget/mv_udc.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-)
diff --git a/drivers/usb/gadget/mv_udc.c b/drivers/usb/gadget/mv_udc.c index 5c10a8b..b9ff306 100644 --- a/drivers/usb/gadget/mv_udc.c +++ b/drivers/usb/gadget/mv_udc.c @@ -32,6 +32,7 @@ #include <asm/byteorder.h> #include <asm/io.h> #include <asm/errno.h> +#include <asm/unaligned.h> #include <linux/types.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> @@ -128,7 +129,7 @@ static void mv_ep_free_request(struct usb_ep *ep, struct usb_request *_req) return; }
-static void ep_enable(int num, int in) +static void ep_enable(int num, int in, int maxpacket) { struct ept_queue_head *head; struct mv_udc *udc = controller.udc; @@ -142,7 +143,7 @@ static void ep_enable(int num, int in) n |= (CTRL_RXE | CTRL_RXR | CTRL_RXT_BULK);
if (num != 0) - head->config = CONFIG_MAX_PKT(EP_MAX_PACKET_SIZE) | CONFIG_ZLT; + head->config = CONFIG_MAX_PKT(maxpacket) | CONFIG_ZLT; writel(n, &udc->epctrl[num]); }
@@ -153,8 +154,21 @@ static int mv_ep_enable(struct usb_ep *ep, int num, in; num = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; in = (desc->bEndpointAddress & USB_DIR_IN) != 0; - ep_enable(num, in); mv_ep->desc = desc; + + if (num) { + int max = get_unaligned_le16(&desc->wMaxPacketSize); + + if ((max > 64) && (controller.gadget.speed == USB_SPEED_FULL)) + max = 64; + if (ep->maxpacket != max) { + DBG("%s: from %d to %d\n", __func__, + ep->maxpacket, max); + ep->maxpacket = max; + } + } + ep_enable(num, in, ep->maxpacket); + DBG("%s: num=%d maxpacket=%d\n", __func__, num, ep->maxpacket); return 0; }
@@ -262,7 +276,7 @@ static void handle_setup(void) in = (ep[i].desc->bEndpointAddress & USB_DIR_IN) != 0; if ((num == _num) && (in == _in)) { - ep_enable(num, in); + ep_enable(num, in, ep[i].ep.maxpacket); usb_ep_queue(controller.gadget.ep0, req, 0); break; @@ -344,15 +358,19 @@ void udc_irq(void) DBG("-- suspend --\n");
if (n & STS_PCI) { - DBG("-- portchange --\n"); + int max = 64; + int speed = USB_SPEED_FULL; + bit = (readl(&udc->portsc) >> 26) & 3; + DBG("-- portchange %x %s\n", bit, (bit == 2) ? "High" : "Full"); if (bit == 2) { - controller.gadget.speed = USB_SPEED_HIGH; - for (i = 1; i < NUM_ENDPOINTS && n; i++) - if (ep[i].desc) - ep[i].ep.maxpacket = 512; - } else { - controller.gadget.speed = USB_SPEED_FULL; + speed = USB_SPEED_HIGH; + max = 512; + } + controller.gadget.speed = speed; + for (i = 1; i < NUM_ENDPOINTS && n; i++) { + if (ep[i].ep.maxpacket > max) + ep[i].ep.maxpacket = max; } }

Allow mv_udc to work when cache is enabled by adding flushing and invalidating calls.
Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com --- drivers/usb/gadget/mv_udc.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-)
diff --git a/drivers/usb/gadget/mv_udc.c b/drivers/usb/gadget/mv_udc.c index b9ff306..324a8d1 100644 --- a/drivers/usb/gadget/mv_udc.c +++ b/drivers/usb/gadget/mv_udc.c @@ -131,10 +131,8 @@ static void mv_ep_free_request(struct usb_ep *ep, struct usb_request *_req)
static void ep_enable(int num, int in, int maxpacket) { - struct ept_queue_head *head; struct mv_udc *udc = controller.udc; unsigned n; - head = epts + 2*num + in;
n = readl(&udc->epctrl[num]); if (in) @@ -142,8 +140,12 @@ static void ep_enable(int num, int in, int maxpacket) else n |= (CTRL_RXE | CTRL_RXR | CTRL_RXT_BULK);
- if (num != 0) + if (num != 0) { + struct ept_queue_head *head = epts + 2*num + in; + head->config = CONFIG_MAX_PKT(maxpacket) | CONFIG_ZLT; + flush_cache((unsigned long)head, sizeof(struct ept_queue_head)); + } writel(n, &udc->epctrl[num]); }
@@ -192,25 +194,26 @@ static int mv_ep_queue(struct usb_ep *ep, head = epts + 2 * num + in; phys = (unsigned)req->buf; len = req->length; + flush_cache(phys, len);
item->next = TERMINATE; item->info = INFO_BYTES(len) | INFO_IOC | INFO_ACTIVE; item->page0 = phys; item->page1 = (phys & 0xfffff000) + 0x1000; + flush_cache((unsigned long)item, sizeof(struct ept_queue_item));
head->next = (unsigned) item; head->info = 0;
DBG("ept%d %s queue len %x, buffer %x\n", num, in ? "in" : "out", len, phys); + flush_cache((unsigned long)head, sizeof(struct ept_queue_head));
if (in) bit = EPT_TX(num); else bit = EPT_RX(num);
- flush_cache(phys, len); - flush_cache((unsigned long)item, sizeof(struct ept_queue_item)); writel(bit, &udc->epprime);
return 0; @@ -234,6 +237,13 @@ static void handle_ep_complete(struct mv_ep *ep) ep->req.length -= len; DBG("ept%d %s complete %x\n", num, in ? "in" : "out", len); + if (ep->req.length && !in) { + unsigned start = (unsigned)ep->req.buf & ~0x3f; + unsigned end = ((unsigned)ep->req.buf + ep->req.length + + 0x3f) & ~0x3f; + + invalidate_dcache_range(start, end); + } ep->req.complete(&ep->ep, &ep->req); if (num == 0) { ep->req.length = 0; @@ -255,7 +265,8 @@ static void handle_setup(void) char *buf; head = epts;
- flush_cache((unsigned long)head, sizeof(struct ept_queue_head)); + invalidate_dcache_range((unsigned long)head, (unsigned long)head + + sizeof(struct ept_queue_head)); memcpy(&r, head->setup_data, sizeof(struct usb_ctrlrequest)); writel(EPT_RX(0), &udc->epstat); DBG("handle setup %s, %x, %x index %x value %x\n", reqname(r.bRequest), @@ -335,6 +346,8 @@ static void stop_activity(void) in = (ep[i].desc->bEndpointAddress & USB_DIR_IN) != 0; head = epts + (num * 2) + (in); head->info = INFO_ACTIVE; + flush_cache((unsigned long)head, + sizeof(struct ept_queue_head)); } } } @@ -458,9 +471,11 @@ static int mvudc_probe(void) { struct ept_queue_head *head; int i; + const int qh_size = QH_MAXNUM * sizeof(struct ept_queue_head); + const int item_size = sizeof(struct ept_queue_item);
- epts = memalign(PAGE_SIZE, QH_MAXNUM * sizeof(struct ept_queue_head)); - memset(epts, 0, QH_MAXNUM * sizeof(struct ept_queue_head)); + epts = memalign(PAGE_SIZE, qh_size); + memset(epts, 0, qh_size); for (i = 0; i < 2 * NUM_ENDPOINTS; i++) { /* * For item0 and item1, they are served as ep0 @@ -476,8 +491,11 @@ static int mvudc_probe(void) head->next = TERMINATE; head->info = 0;
- items[i] = memalign(PAGE_SIZE, sizeof(struct ept_queue_item)); + items[i] = memalign(PAGE_SIZE, item_size); + memset(items[i], 0, item_size); + flush_cache((unsigned long)items[i], item_size); } + flush_cache((unsigned long)epts, qh_size);
INIT_LIST_HEAD(&controller.gadget.ep_list); ep[0].ep.maxpacket = 64;

desc is set at ep_enable, so for symmetry, clear it at ep_disable.
Signed-off-by: Troy Kisky troy.kisky@boundarydevices.com --- drivers/usb/gadget/mv_udc.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/usb/gadget/mv_udc.c b/drivers/usb/gadget/mv_udc.c index 324a8d1..5d3cd74 100644 --- a/drivers/usb/gadget/mv_udc.c +++ b/drivers/usb/gadget/mv_udc.c @@ -176,6 +176,9 @@ static int mv_ep_enable(struct usb_ep *ep,
static int mv_ep_disable(struct usb_ep *ep) { + struct mv_ep *mv_ep = container_of(ep, struct mv_ep, ep); + + mv_ep->desc = NULL; return 0; }

Hi Troy,
Hi Marek,
Can you please base the series on top of my series I posted a while ago [1] ? I feel bad about asking you to, but that series was out earlier and I'm planning to apply it for next MW.
btw review would be nice ;-)
This series is based on your u-boot-testing/chipidea branch. After this series, nitrogen6x works with tftpboot to transfer files over usb. But I still cannot enable CONFIG_USB_TTY because of link errors.
Ugh, USB TTY is not compatible with the new code, right? I use either netconsole or the right way would be to port g_serial from Linux 2.6.37 .
Do you have a plan for defining the following symbols in general code? setup_ep udc_endpoint_write udc_init udc_startup_events udc_connect udc_unset_nak udc_set_nak udc_unset_nak
Or should usbtty be hacked to use more gadget style functions?
Troy Kisky (18): Add functions for use with i.mx6 otg udc mx6: iomux: add GPR1 defines mx6: define OTG_BASE_ADDR nitrogen6x: add otg usb ethernet gadget support nitrogen6x: add CONFIG_MV_UDC usb: gadget: config: fix unaligned access issues usb: gadget: mv_udc: set udc after controller.udc is initialized usb: gadget: mv_udc: add MX6Q specific reset usb: gadget: ether set wMaxPacketSize usb: gadget: ether: return error from rx_submit if no request usb: gadget: mv_udc: split mv_udc.h file usb: udc: add udc.h include file usb: gadget: mv_udc: fix typo in error message usb: gadget: mv_udc: use static initialization of ops,udc usb: gadget: mv_udc: set is_dualspeed = 1 usb: gadget: mv_udc: fix full speed connections usb: gadget: mv_udc: fix cache issues usb: gadget: mv_udc: clear desc upon ep_disable
arch/arm/cpu/armv7/mx6/soc.c | 70 ++++++++++++++++++ arch/arm/include/asm/arch-mx6/imx-regs.h | 2 + arch/arm/include/asm/arch-mx6/iomux.h | 6 ++ arch/arm/include/asm/arch-mx6/sys_proto.h | 4 + board/boundary/nitrogen6x/nitrogen6x.c | 16 ++++ drivers/serial/usbtty.h | 3 +- drivers/usb/gadget/config.c | 6 +- drivers/usb/gadget/ether.c | 5 +- drivers/usb/gadget/mv_udc.c | 100 ++++++++++++++++++------- drivers/usb/gadget/mv_udc.h | 117 +++++++++++++++++++++++++++++ include/configs/nitrogen6x.h | 7 ++ include/usb/designware_udc.h | 31 -------- include/usb/mpc8xx_udc.h | 19 +---- include/usb/musb_udc.h | 53 -------------- include/usb/mv_udc.h | 118 ------------------------------ include/usb/omap1510_udc.h | 27 +------ include/usb/pxa27x_udc.h | 26 +------ include/usb/udc.h | 60 +++++++++++++++ 18 files changed, 371 insertions(+), 299 deletions(-) create mode 100644 drivers/usb/gadget/mv_udc.h create mode 100644 include/usb/udc.h
[1] http://patchwork.ozlabs.org/patch/257935/
Best regards, Marek Vasut

On 7/16/2013 8:04 PM, Marek Vasut wrote:
Hi Troy,
Hi Marek,
Can you please base the series on top of my series I posted a while ago [1] ? I feel bad about asking you to, but that series was out earlier and I'm planning to apply it for next MW.
Since it is 17 patches, do you have a branch I can pull from ?
btw review would be nice ;-)
Sure, I'll look through it.
This series is based on your u-boot-testing/chipidea branch. After this series, nitrogen6x works with tftpboot to transfer files over usb. But I still cannot enable CONFIG_USB_TTY because of link errors.
Ugh, USB TTY is not compatible with the new code, right? I use either netconsole or the right way would be to port g_serial from Linux 2.6.37 .
Thanks for the direction.
[1] http://patchwork.ozlabs.org/patch/257935/
Best regards, Marek Vasut

Dear Troy Kisky,
On 7/16/2013 8:04 PM, Marek Vasut wrote:
Hi Troy,
Hi Marek,
Can you please base the series on top of my series I posted a while ago [1] ? I feel bad about asking you to, but that series was out earlier and I'm planning to apply it for next MW.
Since it is 17 patches, do you have a branch I can pull from ?
Use this bundle : http://patchwork.ozlabs.org/bundle/marex/mvudc/
btw review would be nice ;-)
Sure, I'll look through it.
Thanks!
This series is based on your u-boot-testing/chipidea branch. After this series, nitrogen6x works with tftpboot to transfer files over usb. But I still cannot enable CONFIG_USB_TTY because of link errors.
Ugh, USB TTY is not compatible with the new code, right? I use either netconsole or the right way would be to port g_serial from Linux 2.6.37 .
Thanks for the direction.
[1] http://patchwork.ozlabs.org/patch/257935/
Best regards, Marek Vasut
Best regards, Marek Vasut
participants (2)
-
Marek Vasut
-
Troy Kisky