[RFC] OMAP3 U-Boot v1 MUSB patch, please review

25 views
Skip to first unread message

Dirk Behme

unread,
Feb 1, 2009, 1:39:23 PM2/1/09
to beagl...@googlegroups.com

After Steve applied the sync patches and merged omap3-dev into
omap3-dev-usb (thanks!), in attachment the diff between these two
branches. Result is a ~37k U-Boot v1 MUSB patch we should clean up now.

Please review and comment.

Review comments should go as patches to omap3-dev-usb. With this, we
will get a clean OMAP3 MUSB patch in omap3-dev-usb we can send to USB
maintainer, later.

Note: Unfortunately, it doesn't apply to any upstream branch, yet.
Upstream mainline has recent USB changes, but no OMAP3 (needed for
config file changes), yet. Upstream u-boot-arm has OMAP3, but not
recent USB changes.

Best regards

Dirk

Changed files:

drivers/serial/usbtty.h
drivers/usb/Makefile
drivers/usb/omap3530_usb.c
drivers/usb/omap3530_usb.h
drivers/usb/twl4030-usb.c
drivers/usb/usbdcore_musb.c
include/configs/omap3_beagle.h
include/configs/omap3_evm.h
include/usbdcore_musb.h
include/usb.h

u-boot-v1-omap3-usb-patch.txt

Jason Kridner

unread,
Feb 1, 2009, 2:52:27 PM2/1/09
to beagl...@googlegroups.com
On Feb 1, 2009, at 12:39 PM, Dirk Behme wrote:

>
> After Steve applied the sync patches and merged omap3-dev into
> omap3-dev-usb (thanks!), in attachment the diff between these two
> branches. Result is a ~37k U-Boot v1 MUSB patch we should clean up
> now.
>
> Please review and comment.
>
> Review comments should go as patches to omap3-dev-usb. With this, we
> will get a clean OMAP3 MUSB patch in omap3-dev-usb we can send to USB
> maintainer, later.

I had not seen any note that [1], [2], and [3] had been applied, but
it appears are merged already on omap3-dev-usb. Were there any
changes made before applying those patches?

[1] http://groups.google.com/group/beagleboard/browse_thread/thread/3684dd45ba5cf190
[2] http://groups.google.com/group/beagleboard/browse_thread/thread/adbbab0be3b8eb62
[3] http://groups.google.com/group/beagleboard/browse_thread/thread/f230b4f8477bbb79

>
>
> Note: Unfortunately, it doesn't apply to any upstream branch, yet.
> Upstream mainline has recent USB changes, but no OMAP3 (needed for
> config file changes), yet. Upstream u-boot-arm has OMAP3, but not
> recent USB changes.
>
> Best regards
>
> Dirk
>
> Changed files:
>
> drivers/serial/usbtty.h
> drivers/usb/Makefile
> drivers/usb/omap3530_usb.c
> drivers/usb/omap3530_usb.h
> drivers/usb/twl4030-usb.c
> drivers/usb/usbdcore_musb.c
> include/configs/omap3_beagle.h
> include/configs/omap3_evm.h
> include/usbdcore_musb.h
> include/usb.h
>
> >
> diff -uprN omap3-dev/drivers/serial/usbtty.h omap3-dev-usb/drivers/
> serial/usbtty.h
> --- omap3-dev/drivers/serial/usbtty.h 2009-02-01 19:17:13.000000000
> +0100
> +++ omap3-dev-usb/drivers/serial/usbtty.h 2009-02-01
> 19:17:43.000000000 +0100
> @@ -27,8 +27,10 @@
> #include <usbdcore.h>
> #if defined(CONFIG_PPC)
> #include <usbdcore_mpc8xx.h>
> -#elif defined(CONFIG_ARM)
> +#elif defined(CONFIG_OMAP1510)
> #include <usbdcore_omap1510.h>
> +#elif defined(CONFIG_MUSB)
> +#include <usbdcore_musb.h>
> #endif
>
> #include <version_autogenerated.h>
> diff -uprN omap3-dev/drivers/usb/Makefile omap3-dev-usb/drivers/usb/
> Makefile
> --- omap3-dev/drivers/usb/Makefile 2009-02-01 19:17:13.000000000 +0100
> +++ omap3-dev-usb/drivers/usb/Makefile 2009-02-01 19:17:43.000000000
> +0100
> @@ -40,6 +40,7 @@ COBJS-$(CONFIG_USB_EHCI_IXP4XX) += usb_e
> COBJS-$(CONFIG_MUSB_HCD) += musb_hcd.o musb_core.o
> COBJS-$(CONFIG_USB_DAVINCI) += davinci_usb.o
> COBJS-$(CONFIG_USB_EHCI_VCT) += usb_ehci_vct.o
> +COBJS-$(CONFIG_USB_OMAP3530) += omap3530_usb.o
>
> # device
> ifdef CONFIG_USB_DEVICE
> @@ -47,6 +48,8 @@ COBJS-y += usbdcore_ep0.o
> COBJS-$(CONFIG_OMAP1510) += usbdcore_omap1510.o
> COBJS-$(CONFIG_OMAP1610) += usbdcore_omap1510.o
> COBJS-$(CONFIG_MPC885_FAMILY) += usbdcore_mpc8xx.o
> +COBJS-$(CONFIG_MUSB) += usbdcore_musb.o
> +COBJS-$(CONFIG_TWL4030_USB) += twl4030-usb.o
> endif
>
> COBJS := $(COBJS-y)
> diff -uprN omap3-dev/drivers/usb/omap3530_usb.c omap3-dev-usb/
> drivers/usb/omap3530_usb.c
> --- omap3-dev/drivers/usb/omap3530_usb.c 1970-01-01
> 01:00:00.000000000 +0100
> +++ omap3-dev-usb/drivers/usb/omap3530_usb.c 2009-02-01
> 19:17:43.000000000 +0100
> @@ -0,0 +1,66 @@
> +/*
> + * TI's OMAP3530 platform specific USB functions.
> + *
> + * Copyright (c) 2008 Texas Instruments
> + *
> + * 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
> + *
> + * Author: Thomas Abraham t-ab...@ti.com, Texas Instruments
> + */
> +
> +#include <common.h>
> +
> +#include "omap3530_usb.h"
> +#include <asm/arch/cpu.h>
> +#include <asm/arch/sys_proto.h>
> +#include <asm/io.h>
> +
> +/* MUSB platform configuration */
> +struct musb_config musb_cfg = {
> + (struct musb_regs *)MENTOR_USB0_BASE,
> + OMAP3530_USB_TIMEOUT,
> + 0
> +};
> +
> +/* MUSB module register overlay */
> +struct omap3530_usb_regs *regs;
> +
> +/*
> + * This function performs OMAP3530 platform specific initialization
> for Mentor
> + * USB OTG controller.
> + */
> +int musb_platform_init(void)
> +{
> + regs = (struct omap3530_usb_regs *)OMAP3530_USB0_BASE;
> + /* Disable force standby */
> + sr32((void *)&regs->forcestdby, 0 , 1 , 0);
> + /* Set configuration for clock and interface clock to be always on
> */
> + writel(0x1008, &regs->sysconfig);
> + /* Configure the PHY as PHY interface is 12-pin, 8-bit SDR ULPI */
> + sr32((void *)&regs->interfsel, 0, 1, 1);
> + return 0;
> +}
> +
> +/*
> + * This function performs OMAP3530 platform specific
> deinitialization for
> + * Mentor USB OTG controller.
> + */
> +void musb_platform_deinit(void)
> +{
> + /* MUSB soft-reset */
> + writel(2, &regs->sysconfig);
> +}
> +
> diff -uprN omap3-dev/drivers/usb/omap3530_usb.h omap3-dev-usb/
> drivers/usb/omap3530_usb.h
> --- omap3-dev/drivers/usb/omap3530_usb.h 1970-01-01
> 01:00:00.000000000 +0100
> +++ omap3-dev-usb/drivers/usb/omap3530_usb.h 2009-02-01
> 19:17:43.000000000 +0100
> @@ -0,0 +1,49 @@
> +/*
> + * TI's OMAP3530 platform specific USB functions.
> + *
> + * Copyright (c) 2008 Texas Instruments
> + *
> + * 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
> + *
> + * Author: Thomas Abraham t-ab...@ti.com, Texas Instruments
> + */
> +
> +#ifndef __OMAP3530_MUSB_H__
> +#define __OMAP3530_MUSB_H__
> +
> +#include "musb_core.h"
> +
> +/* Base address of OMAP3530 usb0 wrapper */
> +#define OMAP3530_USB0_BASE 0x480AB400
> +/* Base address of OMAP3530 musb core */
> +#define MENTOR_USB0_BASE 0x480AB000
> +/* Timeout for OMAP3530 USB module */
> +#define OMAP3530_USB_TIMEOUT 0x3FFFFFF
> +
> +/*
> + * OMAP3530 platform USB register overlay.
> + */
> +struct omap3530_usb_regs {
> + u32 revision;
> + u32 sysconfig;
> + u32 sysstatus;
> + u32 interfsel;
> + u32 simenable;
> + u32 forcestdby;
> +};
> +
> +#endif /* __OMAP3530_MUSB_H__ */
> +
> diff -uprN omap3-dev/drivers/usb/twl4030-usb.c omap3-dev-usb/drivers/
> usb/twl4030-usb.c
> --- omap3-dev/drivers/usb/twl4030-usb.c 1970-01-01
> 01:00:00.000000000 +0100
> +++ omap3-dev-usb/drivers/usb/twl4030-usb.c 2009-02-01
> 19:17:43.000000000 +0100
> @@ -0,0 +1,169 @@
> +/*
> + * twl4030-usb - TWL4030 USB transceiver, talking to OMAP OTG
> controller
> + *
> + * (C) Copyright 2008 Atin Malaviya (atin.m...@gmail.com)
> + *
> + * Based on: twl4030-usb.c in linux 2.6 (drivers/i2c/chips/twl4030-
> usb.c)
> + * Copyright (C) 2004-2007 Texas Instruments
> + * Copyright (C) 2008 Nokia Corporation
> + * Contact: Felipe Balbi <felipe...@nokia.com>
> + *
> + * Author: Atin Malaviya (atin.m...@gmail.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
> + *
> + */
> +
> +#include <common.h>
> +#include <i2c.h>
> +
> +#define FUNC_CTRL (0x04)
> +# define OPMODE_MASK (3 << 3) /* bits 3 and 4 */
> +# define XCVRSELECT_MASK (3 << 0) /* bits 0 and 1 */
> +#define IFC_CTRL (0x07)
> +# define CARKITMODE (1 << 2)
> +#define POWER_CTRL (0xAC)
> +# define OTG_ENAB (1 << 5)
> +#define PHY_PWR_CTRL (0xFD)
> +# define PHYPWD (1 << 0)
> +#define PHY_CLK_CTRL (0xFE)
> +# define CLOCKGATING_EN (1 << 2)
> +# define CLK32K_EN (1 << 1)
> +# define REQ_PHY_DPLL_CLK (1 << 0)
> +#define PHY_CLK_CTRL_STS (0xFF)
> +# define PHY_DPLL_CLK (1 << 0)
> +
> +static int twl4030_i2c_write(u8 group, u8 reg, u8 data)
> +{
> + int ret = 0;
> + ret = i2c_write(group, reg, 1, &data, 1);
> + if (ret != 0) {
> + serial_printf("TWL4030:I2C:Write[0x%x, 0x%x] Error %d\n", group,
> reg, ret);
> + }
> + return ret;
> +}
> +
> +static int twl4030_i2c_read(u8 group, u8 reg, u8 *data)
> +{
> + int ret = 0;
> + ret = i2c_read(group, reg, 1, data, 1);
> + if (ret != 0) {
> + serial_printf("TWL4030:I2C:Read[0x%x, 0x%x] Error %d\n", group,
> reg, ret);
> + }
> + return ret;
> +}
> +
> +static int twl4030_usb_write(u8 address, u8 data)
> +{
> + int ret = 0;
> + ret = twl4030_i2c_write(PWRMGT_ADDR_ID1, address, data);
> + if (ret != 0) {
> + serial_printf("TWL4030:USB:Write[0x%x] Error %d\n", address, ret);
> + }
> + return ret;
> +}
> +
> +static int twl4030_usb_read(u8 address)
> +{
> + u8 data;
> + int ret = 0;
> + ret = twl4030_i2c_read(PWRMGT_ADDR_ID1, address, &data);
> + if (ret == 0) {
> + ret = data;
> + } else {
> + serial_printf("TWL4030:USB:Read[0x%x] Error %d\n", address, ret);
> + }
> + return ret;
> +}
> +
> +static int twl4030_usb_set_bits(u8 reg, u8 bits)
> +{
> + return twl4030_usb_write(reg + 1, bits);
> +}
> +
> +static int twl4030_usb_clear_bits(u8 reg, u8 bits)
> +{
> + return twl4030_usb_write(reg + 2, bits);
> +}
> +
> +static void twl4030_usb_ldo_init(void)
> +{
> + /* Enable writing to power configuration registers */
> + twl4030_i2c_write(PWRMGT_ADDR_ID4, PROTECT_KEY, 0xC0);
> + twl4030_i2c_write(PWRMGT_ADDR_ID4, PROTECT_KEY, 0x0C);
> +
> + /* put VUSB3V1 LDO in active state */
> + twl4030_i2c_write(PWRMGT_ADDR_ID4, VUSB_DEDICATED2, 0);
> +
> + /* input to VUSB3V1 LDO is from VBAT, not VBUS */
> + twl4030_i2c_write(PWRMGT_ADDR_ID4, VUSB_DEDICATED1, 0x14);
> +
> + /* turn on 3.1V regulator */
> + twl4030_i2c_write(PWRMGT_ADDR_ID4, VUSB3V1_DEV_GRP, 0x20);
> + twl4030_i2c_write(PWRMGT_ADDR_ID4, VUSB3V1_TYPE, 0);
> +
> + /* turn on 1.5V regulator */
> + twl4030_i2c_write(PWRMGT_ADDR_ID4, VUSB1V5_DEV_GRP, 0x20);
> + twl4030_i2c_write(PWRMGT_ADDR_ID4, VUSB1V5_TYPE, 0);
> +
> + /* turn on 1.8V regulator */
> + twl4030_i2c_write(PWRMGT_ADDR_ID4, VUSB1V8_DEV_GRP, 0x20);
> + twl4030_i2c_write(PWRMGT_ADDR_ID4, VUSB1V8_TYPE, 0);
> +
> + /* disable access to power configuration registers */
> + twl4030_i2c_write(PWRMGT_ADDR_ID4, PROTECT_KEY, 0);
> +}
> +
> +static void twl4030_phy_power(void)
> +{
> + u8 pwr;
> +
> + pwr = twl4030_usb_read(PHY_PWR_CTRL);
> + pwr &= ~PHYPWD;
> + twl4030_usb_write(PHY_PWR_CTRL, pwr);
> + twl4030_usb_write(PHY_CLK_CTRL,
> + twl4030_usb_read(PHY_CLK_CTRL) |
> + (CLOCKGATING_EN | CLK32K_EN));
> +}
> +
> +int udc_musb_platform_init(void)
> +{
> + unsigned long timeout;
> +
> + /* twl4030 ldo init */
> + twl4030_usb_ldo_init();
> +
> + /* Enable the twl4030 phy */
> + twl4030_phy_power();
> +
> + /* enable DPLL to access PHY registers over I2C */
> + twl4030_usb_write(PHY_CLK_CTRL,twl4030_usb_read(PHY_CLK_CTRL) |
> REQ_PHY_DPLL_CLK);
> + timeout = get_timer(0) + CONFIG_SYS_HZ;
> + while (!(twl4030_usb_read(PHY_CLK_CTRL_STS) & PHY_DPLL_CLK) &&
> get_timer(0) < timeout) {
> + udelay(10);
> + }
> + if (!(twl4030_usb_read(PHY_CLK_CTRL_STS) & PHY_DPLL_CLK)) {
> + serial_printf("Timeout setting T2 HSUSB PHY DPLL clock\n");
> + return -1;
> + }
> +
> + /* Enable ULPI mode */
> + twl4030_usb_clear_bits(IFC_CTRL, CARKITMODE);
> + twl4030_usb_set_bits(POWER_CTRL, OTG_ENAB);
> + twl4030_usb_clear_bits(FUNC_CTRL,XCVRSELECT_MASK | OPMODE_MASK);
> + /* let ULPI control the DPLL clock */
> + twl4030_usb_write(PHY_CLK_CTRL,twl4030_usb_read(PHY_CLK_CTRL) &
> ~REQ_PHY_DPLL_CLK);
> + return 0;
> +}
> diff -uprN omap3-dev/drivers/usb/usbdcore_musb.c omap3-dev-usb/
> drivers/usb/usbdcore_musb.c
> --- omap3-dev/drivers/usb/usbdcore_musb.c 1970-01-01
> 01:00:00.000000000 +0100
> +++ omap3-dev-usb/drivers/usb/usbdcore_musb.c 2009-02-01
> 19:17:43.000000000 +0100
> @@ -0,0 +1,732 @@
> +/*
> + * (C) Copyright 2008 Texas Instruments Incorporated.
> + *
> + * Based on
> + * u-boot OMAP1510 USB drivers (drivers/usbdcore_omap1510.c)
> + * twl4030 init based on linux (drivers/i2c/chips/twl4030-usb.c)
> + *
> + * Author: Diego Dompe (diego...@ridgerun.com)
> + * Atin Malaviya (atin.m...@gmail.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
> + *
> + */
> +
> +#include <common.h>
> +
> +#include <asm/io.h>
> +#include <asm/arch/clocks.h>
> +#include <asm/arch/clocks_omap3.h>
> +#include <asm/arch/sys_proto.h>
> +#include "usbdcore.h"
> +#include "usbdcore_musb.h"
> +#include "usbdcore_ep0.h"
> +
> +/* Private definitions */
> +enum ep0_status { IDLE, DATA_STAGE, DATA_COMPLETE };
> +
> +/* Private variables */
> +static struct usb_device_instance *udc_device;
> +static enum ep0_status ep0status = IDLE;
> +static unsigned char do_set_address = 0;
> +static struct urb *ep0_urb = NULL;
> +
> +/* Helper functions */
> +/** TODO: Should these go in include/usbdcore.h?? */
> +static void insl(u32 reg, u32 * data, u32 size)
> +{
> + u32 t;
> +
> + for (t = 0; t < size; t++, data++){
> + *data = inl(reg);
> + }
> +}
> +
> +static void outsl(u32 reg, u32 * data, u32 size)
> +{
> + u32 t;
> +
> + for (t = 0; t < size; t++, data++)
> + outl(*data, reg);
> +}
> +
> +static void outsb(u32 reg, u8 * data, u32 size)
> +{
> + u32 t;
> +
> + for (t = 0; t < size; t++, data++)
> + outb(*data, reg);
> +}
> +
> +static void musb_fifo_read(int epnumber, u8 * data, u32 size)
> +{
> + if ((u32)data & 0x3) { /* Not aligned data */
> + insb((UDC_FIFO0 + (epnumber << 2)), data, size);
> + } else { /* 32 bits aligned data */
> + int i;
> +
> + insl(UDC_FIFO0 + (epnumber << 2),(u32 *)data,size>>2);
> + data += size & ~0x3;
> + i = size & 0x3;
> + while (i--) {
> + *data = inb(UDC_FIFO0 + (epnumber << 2));
> + data++;
> + }
> + }
> +}
> +
> +static void musb_fifo_write(int epnumber, u8 * data, u32 size)
> +{
> + if ((u32)data & 0x3) { /* Not aligned data */
> + outsb(UDC_FIFO0 + (epnumber << 2), data, size);
> + } else { /* 32 bits aligned data */
> + int i;
> +
> + outsl(UDC_FIFO0 + (epnumber << 2), (u32 *)data, size>>2);
> + data += size & ~0x3;
> + i = size & 0x3;
> + while (i--) {
> + outb(*data, UDC_FIFO0 + (epnumber << 2));
> + data++;
> + }
> + }
> +}
> +
> +static void musb_fifos_configure(struct usb_device_instance *device)
> +{
> + int ep;
> + struct usb_bus_instance *bus;
> + struct usb_endpoint_instance *endpoint;
> + unsigned short ep_ptr, ep_size, ep_doublebuffer;
> + int ep_addr, packet_size, buffer_size, attributes;
> +
> + bus = device->bus;
> +
> + ep_ptr = 0;
> +
> + for (ep = 0; ep < bus->max_endpoints; ep++) {
> + endpoint = bus->endpoint_array + ep;
> + ep_addr = endpoint->endpoint_address;
> + if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
> + /* IN endpoint */
> + packet_size = endpoint->tx_packetSize;
> + attributes = endpoint->tx_attributes;
> + } else {
> + /* OUT endpoint */
> + packet_size = endpoint->rcv_packetSize;
> + attributes = endpoint->rcv_attributes;
> + }
> +
> + switch (packet_size) {
> + case 0:
> + ep_size = 0;
> + break;
> + case 8:
> + ep_size = 0;
> + break;
> + case 16:
> + ep_size = 1;
> + break;
> + case 32:
> + ep_size = 2;
> + break;
> + case 64:
> + ep_size = 3;
> + break;
> + case 128:
> + ep_size = 4;
> + break;
> + case 256:
> + ep_size = 5;
> + break;
> + case 512:
> + ep_size = 6;
> + break;
> + default:
> + serial_printf("ep 0x%02x has bad packet size %d",
> + ep_addr, packet_size);
> + packet_size = 0;
> + ep_size = 0;
> + break;
> + }
> +
> + switch (attributes & USB_ENDPOINT_XFERTYPE_MASK) {
> + case USB_ENDPOINT_XFER_CONTROL:
> + case USB_ENDPOINT_XFER_BULK:
> + case USB_ENDPOINT_XFER_INT:
> + default:
> + /* A non-isochronous endpoint may optionally be
> + * double-buffered. For now we disable
> + * double-buffering.
> + */
> + ep_doublebuffer = 0;
> + if (packet_size > 64)
> + packet_size = 0;
> + if (!ep || !ep_doublebuffer)
> + buffer_size = packet_size;
> + else
> + buffer_size = packet_size * 2;
> + break;
> + case USB_ENDPOINT_XFER_ISOC:
> + /* Isochronous endpoints are always double-
> + * buffered
> + */
> + ep_doublebuffer = 1;
> + buffer_size = packet_size * 2;
> + break;
> + }
> +
> + /* check to see if our packet buffer RAM is exhausted */
> + if ((ep_ptr + buffer_size) > UDC_MAX_FIFO_SIZE) {
> + serial_printf("out of packet RAM for ep 0x%02x buf size %d",
> + ep_addr, buffer_size);
> + buffer_size = packet_size = 0;
> + }
> +
> + /* force a default configuration for endpoint 0 since it is
> + * always enabled
> + */
> + if (!ep && ((packet_size < 8) || (packet_size > 64))) {
> + buffer_size = packet_size = 64;
> + ep_size = 3;
> + }
> +
> + outb(ep & 0xF, UDC_INDEX);
> + if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
> + /* IN endpoint */
> + outb((ep_doublebuffer << 4) | (ep_size & 0xf), UDC_TXFIFOSZ);
> + outw(ep_ptr >> 3, UDC_TXFIFOADDR);
> + if (!ep) { /* This only apply for ep != 0 */
> + outw(packet_size & 0x3FF, UDC_TXMAXP);
> + }
> + } else {
> + /* OUT endpoint */
> + outb((ep_doublebuffer << 4) | (ep_size & 0xf), UDC_RXFIFOSZ);
> + outw(ep_ptr >> 3, UDC_RXFIFOADDR);
> + if (!ep) { /* This only apply for ep != 0 */
> + outw(packet_size & 0x3FF, UDC_RXMAXP);
> + }
> + }
> + ep_ptr += buffer_size;
> + }
> +}
> +
> +static void musb_ep0_tx(struct usb_endpoint_instance *endpoint)
> +{
> + unsigned int size = 0;
> + struct urb *urb = endpoint->tx_urb;
> +
> + outb(0, UDC_INDEX);
> +
> + if (urb) {
> +
> + if ((size =
> + MIN(urb->actual_length - endpoint->sent,
> + endpoint->tx_packetSize))) {
> +
> + musb_fifo_write(0,urb->buffer + endpoint->sent,size);
> + }
> + endpoint->last = size;
> +
> + if (((endpoint->sent + size) == ep0_urb->device_request.wLength)
> + || (size != endpoint->tx_packetSize)) {
> + ep0status = DATA_COMPLETE;
> + outw(0xA, UDC_CSR0); /* Transmit packet and set dataend */
> + } else {
> + outw(0x2, UDC_CSR0); /* Transmit packet */
> + }
> + }
> +}
> +
> +static void musb_ep0_handler(struct usb_endpoint_instance *endpoint)
> +{
> + u16 csr0;
> +
> + outb(0, UDC_INDEX);
> +
> + /* Check errors */
> + csr0 = inw(UDC_CSR0);
> +
> + if (csr0 & 0x4) { /* SENTSTALL */
> + outw(csr0 & ~0x4, UDC_CSR0); // Clear stall
> + serial_printf("%s: stall received on EP0!\n", __FUNCTION__);
> + }
> +
> + if (csr0 & 0x10) { /* SETUPEND */
> + outw(0x80, UDC_CSR0); /* Clear setupend */
> + serial_printf("%s: setup END early happened! status is %d\n",
> + __FUNCTION__, ep0status);
> + ep0status = IDLE;
> + return;
> + }
> +
> + switch (ep0status) {
> + case DATA_COMPLETE:
> + if (do_set_address) {
> + /* We need to set the address only after
> + the status stage is complete */
> + outb(udc_device->address, UDC_FADDR);
> + do_set_address = 0;
> + }
> + ep0status = IDLE;
> + /* Fallthrough */
> + case IDLE: /* Receiving a setup packet */
> + if (csr0 & 0x1) {
> + insl(UDC_FIFO0, (unsigned int *) &ep0_urb->device_request,
> + 2);
> +
> + /* If we have data, then don't go to IDLE state */
> + if (ep0_urb->device_request.wLength) {
> + ep0status = DATA_STAGE;
> +
> + outw(0x40, UDC_CSR0); // Clear RXPKTRDY
> + if ((ep0_urb->device_request.
> + bmRequestType & USB_REQ_DIRECTION_MASK)
> + == USB_REQ_DEVICE2HOST) {
> +
> + /* Try to process setup packet */
> + if (ep0_recv_setup(ep0_urb)) {
> + /* Not a setup packet, stall next EP0 transaction */
> + outw(0x20, UDC_CSR0);
> + ep0status = IDLE;
> + return;
> + }
> + /* If we are sending data, do it now, as
> + ep0_recv_setup should have prepare them
> + */
> + endpoint->tx_urb = ep0_urb;
> + endpoint->sent = 0;
> +
> + musb_ep0_tx(endpoint);
> + } else {
> + endpoint->rcv_urb = ep0_urb;
> + ep0_urb->actual_length = 0;
> + }
> + } else { /* Processing zero-length packet */
> + /*
> + * The www.linux-usb.org/usbtest 'test 14' fails with error for
> zero
> + * length request. If the SETUP packet requests ZERO length
> data from
> + * device-to-host, the TXPKTRDY bit needs to be set in TXCSR
> otherwise
> + * the STATUS stage of control transfer will never complete.
> + *
> + */
> + if ((ep0_urb->device_request.
> + bmRequestType & USB_REQ_DIRECTION_MASK)
> + == USB_REQ_DEVICE2HOST) {
> + outw(0x4A, UDC_CSR0); // Clear RXPKTRDY and DATAEND and TXPKTRDY
> + } else {
> + outw(0x48, UDC_CSR0); // Clear RXPKTRDY and DATAEND
> + }
> +
> + /* Try to process setup packet */
> + if (ep0_recv_setup(ep0_urb)) {
> + /* Not a setup packet, stall next EP0 transaction */
> + outw(0x20, UDC_CSR0);
> + ep0status = IDLE;
> + return;
> + }
> +
> + switch (ep0_urb->device_request.bRequest) {
> + case USB_REQ_SET_ADDRESS:
> + usbd_device_event_irq(udc_device,
> + DEVICE_ADDRESS_ASSIGNED,
> + 0);
> + do_set_address = 1;
> + break;
> + case USB_REQ_SET_CONFIGURATION:
> + usbd_device_event_irq(udc_device,
> + DEVICE_CONFIGURED, 0);
> + break;
> + }
> +
> + ep0status = DATA_COMPLETE;
> + }
> + }
> + break;
> + case DATA_STAGE:
> + if ((ep0_urb->device_request.
> + bmRequestType & USB_REQ_DIRECTION_MASK)
> + == USB_REQ_DEVICE2HOST) {
> + if (!(csr0 & 0x2)) { // There packet was send?
> + endpoint->sent += endpoint->last;
> +
> + /* If we finished sending data we would not be on the
> DATA_STAGE */
> + musb_ep0_tx(endpoint);
> + }
> + } else {
> + /* Receiving data */
> + u16 length = inw(UDC_COUNT0);
> +
> + if (length) {
> + if (ep0_urb->actual_length + length >
> + ep0_urb->device_request.wLength)
> + length =
> + ep0_urb->device_request.wLength -
> + ep0_urb->actual_length;
> +
> + endpoint->last = length;
> +
> + musb_fifo_read(0,&ep0_urb->buffer[ep0_urb-
> >actual_length],length);
> + ep0_urb->actual_length += length;
> + }
> +
> + /* We finish if we received the amount of data expected, or less
> + of the packet size
> + */
> + if ((ep0_urb->actual_length == ep0_urb->device_request.wLength) ||
> + (endpoint->last != endpoint->tx_packetSize)) {
> + ep0status = DATA_COMPLETE;
> + outw(0x48, UDC_CSR0); // Clear RXPKTRDY and DATAEND
> + /* This will process the incoming data */
> + if (ep0_recv_setup(ep0_urb)) {
> + /* Not a setup packet, stall next EP0 transaction */
> + outw(0x20, UDC_CSR0);
> + return;
> + }
> + } else
> + outw(0x40, UDC_CSR0); // Clear RXPKTRDY
> + }
> + break;
> + }
> +}
> +
> +static void musb_ep_tx(struct usb_endpoint_instance *endpoint)
> +{
> + unsigned int size = 0, epnumber =
> + endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK;
> + struct urb *urb = endpoint->tx_urb;
> +
> + outb(epnumber, UDC_INDEX);
> + if (urb) {
> + if ((size =
> + MIN(urb->actual_length - endpoint->sent,
> + endpoint->tx_packetSize))) {
> + musb_fifo_write(epnumber,urb->buffer + endpoint->sent,size);
> + }
> + endpoint->last = size;
> + endpoint->state = 1; /* Transmit hardware is busy */
> +
> + outw(inw(UDC_TXCSR) | 0x1, UDC_TXCSR); // Transmit packet
> + }
> +}
> +
> +
> +static void musb_tx_handler(struct usb_endpoint_instance *endpoint)
> +{
> + unsigned int epnumber =
> + endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK;
> + u16 txcsr;
> +
> + outb(epnumber, UDC_INDEX);
> +
> + /* Check errors */
> + txcsr = inw(UDC_TXCSR);
> +
> + if (txcsr & 0x4) { /* Clear underrun */
> + txcsr &= ~0x4;
> + }
> + if (txcsr & 0x20) { /* SENTSTALL */
> + outw(txcsr & ~0x20, UDC_TXCSR); /* Clear stall */
> + return;
> + }
> +
> + if (endpoint->tx_urb && !(txcsr & 0x1)) { // The packet was send?
> + if ((endpoint->sent+endpoint->last == endpoint->tx_urb-
> >actual_length) /* Send a zero length packet? */
> + && (endpoint->last == endpoint->tx_packetSize)) {
> + /* Prepare to transmit a zero-length packet. */
> + endpoint->sent += endpoint->last;
> + musb_ep_tx(endpoint);
> + } else if (endpoint->tx_urb->actual_length) {
> + /* retire the data that was just sent */
> + usbd_tx_complete (endpoint);
> + endpoint->state = 0; /* Transmit hardware is free */
> +
> + /* Check to see if we have more data ready to transmit
> + * now.
> + */
> + if (endpoint->tx_urb && endpoint->tx_urb->actual_length) {
> + musb_ep_tx(endpoint);
> + }
> + }
> + }
> +}
> +
> +static void musb_rx_handler(struct usb_endpoint_instance *endpoint)
> +{
> + unsigned int epnumber =
> + endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK;
> + u16 rxcsr;
> + u16 length;
> +
> + outb(epnumber, UDC_INDEX);
> +
> + /* Check errors */
> + rxcsr = inw(UDC_RXCSR);
> +
> + if (!(rxcsr & 0x1)) /* There is a package received? */
> + return;
> +
> + if (rxcsr & 0x40) /* SENTSTALL */
> + outw(rxcsr & ~0x40, UDC_RXCSR); /* Clear stall */
> +
> + length = inw(UDC_RXCOUNT);
> +
> + if (endpoint->rcv_urb) {
> + /* Receiving data */
> + if (length) {
> + musb_fifo_read(epnumber,&endpoint->rcv_urb->buffer[endpoint-
> >rcv_urb->actual_length],length);
> +
> + outw(rxcsr & ~0x1, UDC_RXCSR); /* Clear RXPKTRDY */
> + usbd_rcv_complete(endpoint, length, 0);
> + }
> + } else {
> + serial_printf("%s: no receive URB!\n", __FUNCTION__);
> + }
> +}
> +
> +static void musb_reset(void)
> +{
> + usbd_device_event_irq(udc_device, DEVICE_HUB_CONFIGURED, 0);
> + usbd_device_event_irq(udc_device, DEVICE_RESET, 0);
> + ep0status = IDLE;
> + do_set_address = 0;
> +}
> +
> +/* Public functions - called by usbdcore, usbtty, etc. */
> +void udc_irq(void)
> +{
> + unsigned char int_usb = inb(UDC_INTRUSB);
> + unsigned short int_tx = inw(UDC_INTRTX);
> + unsigned short int_rx = inw(UDC_INTRRX);
> + int ep;
> +
> + if (int_usb) {
> + if (int_usb & 0x4) { /* Reset */
> + /* The controller clears FADDR, INDEX, and FIFOs */
> + musb_reset();
> + }
> + if (int_usb & 0x20) { /* Disconnected */
> + usbd_device_event_irq(udc_device, DEVICE_HUB_RESET, 0);
> + }
> + if (int_usb & 0x1)
> + usbd_device_event_irq (udc_device, DEVICE_BUS_INACTIVE, 0);
> + if (int_usb & 0x2)
> + usbd_device_event_irq (udc_device, DEVICE_BUS_ACTIVITY, 0);
> + }
> +
> + /* Note: IRQ values auto clear so read just before processing */
> + if (int_rx) { /* OUT endpoints */
> + ep = 1;
> + int_rx >>= 1;
> + while (int_rx) {
> + if (int_rx & 1) {
> + musb_rx_handler(udc_device->bus->endpoint_array + ep);
> + }
> + int_rx >>= 1;
> + ep++;
> + }
> + }
> + if (int_tx) { /* IN endpoints */
> + if (int_tx & 1)
> + musb_ep0_handler(udc_device->bus->endpoint_array);
> +
> + ep = 1;
> + int_tx >>= 1;
> + while (int_tx) {
> + if (int_tx & 1) {
> + musb_tx_handler(udc_device->bus->endpoint_array + ep);
> + }
> + int_tx >>= 1;
> + ep++;
> + }
> + }
> +}
> +
> +/* Turn on the USB connection */
> +void udc_connect(void)
> +{
> + outb(0x1, UDC_DEVCTL);
> +
> + if (!(inb(UDC_DEVCTL) & 0x80)) {
> + serial_printf("Error, the USB hardware is not on B mode\n");
> + outb(0x0, UDC_DEVCTL);
> + return;
> + }
> +}
> +
> +/* Turn off the USB connection */
> +void udc_disconnect(void)
> +{
> + if (!(inb(UDC_DEVCTL) & 0x80)) {
> + serial_printf("Error, the USB hardware is not on B mode");
> + return;
> + }
> +
> + outb(0x0, UDC_DEVCTL);
> +}
> +
> +int udc_endpoint_write(struct usb_endpoint_instance *endpoint)
> +{
> + /* Transmit only if the hardware is available */
> + if (endpoint->tx_urb && endpoint->state == 0) {
> + musb_ep_tx(endpoint);
> + }
> + return 0;
> +}
> +
> +/*
> + * udc_setup_ep - setup endpoint
> + *
> + * Associate a physical endpoint with endpoint_instance
> + */
> +void udc_setup_ep(struct usb_device_instance *device, unsigned int
> ep,
> + struct usb_endpoint_instance *endpoint)
> +{
> + int ep_addr;
> + int attributes;
> +
> + /* We dont' have a way to identify if the endpoint definitions
> changed,
> + so we have to always reconfigure the FIFOs to avoid problems */
> + musb_fifos_configure(device);
> +
> + ep_addr = endpoint->endpoint_address;
> + if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
> + /* IN endpoint */
> + attributes = endpoint->tx_attributes;
> + } else {
> + /* OUT endpoint */
> + attributes = endpoint->rcv_attributes;
> + }
> +
> + outb(ep & 0xF, UDC_INDEX);
> + if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
> + /* IN endpoint */
> + if (!ep) { /* This only apply for ep != 0 */
> + /* Empty fifo twice on case of previous double buffer */
> + outw(1<<3,UDC_TXCSR);
> + outw(1<<3,UDC_TXCSR);
> +
> + if (attributes & USB_ENDPOINT_XFER_ISOC)
> + outw(inw(UDC_TXCSR) | (1 << 13) | (1 << 14) | 0x4, UDC_TXCSR);
> + else
> + outw((inw(UDC_TXCSR) | (1 << 13) | 0x4) & ~(1 << 14), UDC_TXCSR);
> + }
> + /* Enable interrupt */
> + outw(inw(UDC_INTRTXE) | (1 << ep), UDC_INTRTXE);
> + } else {
> + /* OUT endpoint */
> + if (!ep) { /* This only apply for ep != 0 */
> + if (attributes & USB_ENDPOINT_XFER_ISOC)
> + outw((inw(UDC_RXCSR) | (1 << 14)) & ~(1 << 13), UDC_RXCSR);
> + else
> + outw(inw(UDC_RXCSR) & ~(1 << 14) & ~(1 << 13), UDC_RXCSR);
> + }
> + /* Enable interrupt */
> + outw(inw(UDC_INTRRXE) | (1 << ep), UDC_INTRRXE);
> + }
> +}
> +
> +/*
> + * udc_startup_events - allow udc code to do any additional startup
> + */
> +void udc_startup_events(struct usb_device_instance *device)
> +{
> + /* The DEVICE_INIT event puts the USB device in the state
> STATE_INIT. */
> + usbd_device_event_irq(device, DEVICE_INIT, 0);
> +
> + /* The DEVICE_CREATE event puts the USB device in the state
> + * STATE_ATTACHED.
> + */
> + usbd_device_event_irq(device, DEVICE_CREATE, 0);
> +
> + /* Some USB controller driver implementations signal
> + * 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 MUSB 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.
> + */
> +
> + /* Save the device structure pointer */
> + udc_device = device;
> +
> + /* Setup ep0 urb */
> + if (!ep0_urb) {
> + ep0_urb =
> + usbd_alloc_urb(udc_device, udc_device->bus->endpoint_array);
> + } else {
> + serial_printf("udc_enable: ep0_urb already allocated %p\n",
> + ep0_urb);
> + }
> +
> + /* Enable control interrupts */
> + outb(0xf7, UDC_INTRUSBE);
> +}
> +
> +void udc_set_nak(int epid)
> +{
> +/* On MUSB the NAKing is controlled by the USB controller buffers,
> + so as long as we don't read data from the FIFO, the controller
> will NAK.
> + Nothing to see here, move along...
> +*/
> +}
> +
> +void udc_unset_nak(int epid)
> +{
> +/* On MUSB the NAKing is controlled by the USB controller buffers,
> + so as long as we don't read data from the FIFO, the controller
> will NAK.
> + Nothing to see here, move along...
> +*/
> +}
> +
> +/* Start to initialize h/w stuff */
> +int udc_init(void)
> +{
> + /* Clock is initialized on the board code */
> +
> + /* MUSB soft-reset */
> + outl(2, UDC_SYSCONFIG);
> +
> + if (udc_musb_platform_init()) {
> + serial_printf("udc_init: platform init failed\n");
> + return -1;
> + }
> +
> + outl(inl(UDC_FORCESTDBY) & ~1,UDC_FORCESTDBY); /* disable MSTANDBY
> */
> + outl(inl(UDC_SYSCONFIG) | (2<<12),UDC_SYSCONFIG); /* enable
> SMARTSTDBY */
> + outl(inl(UDC_SYSCONFIG) & ~1,UDC_SYSCONFIG); /* disable AUTOIDLE */
> + outl(inl(UDC_SYSCONFIG) | (2<<3),UDC_SYSCONFIG); /* enable
> SMARTIDLE */
> + outl(inl(UDC_SYSCONFIG) | 1,UDC_SYSCONFIG); /* enable AUTOIDLE */
> +
> + /* Configure the PHY as PHY interface is 12-pin, 8-bit SDR ULPI */
> + sr32((void *)UDC_INTERFSEL, 0, 1, 1);
> +
> + /* Turn off interrupts */
> + outw(0x00, UDC_INTRTXE);
> + outw(0x00, UDC_INTRRXE);
> +
> +#if CONFIG_MUSB_FULL_SPEED
> + /* Use Full speed for debugging proposes, useful so most USB
> + analyzers can catch the transactions
> + */
> + outb(0, UDC_POWER);
> + serial_printf("MUSB: using full speed\n");
> +#else
> + serial_printf("MUSB: using high speed\n");
> +#endif
> +
> + return 0;
> +}
> diff -uprN omap3-dev/include/configs/omap3_beagle.h omap3-dev-usb/
> include/configs/omap3_beagle.h
> --- omap3-dev/include/configs/omap3_beagle.h 2009-02-01
> 19:17:15.000000000 +0100
> +++ omap3-dev-usb/include/configs/omap3_beagle.h 2009-02-01
> 19:17:43.000000000 +0100
> @@ -92,6 +92,26 @@
> #define CONFIG_OMAP3_MMC 1
> #define CONFIG_DOS_PARTITION 1
>
> +/*
> + * I2C configuration
> + */
> +#define CONFIG_HARD_I2C
> +#define CONFIG_SYS_I2C_SPEED 100000
> +#define CONFIG_SYS_I2C_SLAVE 1
> +#define CONFIG_DRIVER_OMAP34XX_I2C 1
> +
> +/*
> + * USB Configuration
> + */
> +#define CONFIG_USB_DEVICE 1
> +#define CONFIG_USB_TTY 1
> +#define CONFIG_MUSB 1 /* Enable USB driver*/
> +#define CONFIG_TWL4030_USB 1 /* Enable TWL4030 USB */
> +
> +/* Allow console in serial and USB at the same time */
> +#define CONFIG_CONSOLE_MUX 1
> +#define CONFIG_SYS_CONSOLE_IS_IN_ENV 1
> +
> /* commands to include */
> #include <config_cmd_default.h>
>
> @@ -178,6 +198,10 @@
> "run nandargs; " \
> "nand read ${loadaddr} 280000 400000; " \
> "bootm ${loadaddr}\0" \
> + "usbtty=cdc_acm\0"\
> + "stdout=serial,usbtty\0" \
> + "stdin=serial,usbtty\0" \
> + "stderr=serial,usbtty\0"
>
> #define CONFIG_BOOTCOMMAND \
> "if mmcinit; then " \
> diff -uprN omap3-dev/include/configs/omap3_evm.h omap3-dev-usb/
> include/configs/omap3_evm.h
> --- omap3-dev/include/configs/omap3_evm.h 2009-02-01
> 19:17:15.000000000 +0100
> +++ omap3-dev-usb/include/configs/omap3_evm.h 2009-02-01
> 19:17:43.000000000 +0100
> @@ -156,6 +156,26 @@
> /* Environment information */
> #define CONFIG_BOOTDELAY 10
>
> +/*
> + * USB MSC and Keyboard support
> + */
> +#define CONFIG_USB_OMAP3530
> +#define CONFIG_MUSB_HCD
> +
> +#ifdef CONFIG_USB_OMAP3530
> +#define CONFIG_CMD_USB
> +#ifdef CONFIG_MUSB_HCD
> +#define CONFIG_USB_STORAGE
> +#define CONGIG_CMD_STORAGE
> +#define CONFIG_CMD_FAT
> +#define CONFIG_USB_KEYBOARD
> +#endif
> +#ifdef CONFIG_USB_KEYBOARD
> +#define CONFIG_SYS_USB_EVENT_POLL
> +#define CONFIG_PREBOOT "usb start"
> +#endif
> +#endif
> +
> #define CONFIG_EXTRA_ENV_SETTINGS \
> "loadaddr=0x82000000\0" \
> "console=ttyS2,115200n8\0" \
> diff -uprN omap3-dev/include/usbdcore_musb.h omap3-dev-usb/include/
> usbdcore_musb.h
> --- omap3-dev/include/usbdcore_musb.h 1970-01-01 01:00:00.000000000
> +0100
> +++ omap3-dev-usb/include/usbdcore_musb.h 2009-02-01
> 19:17:44.000000000 +0100
> @@ -0,0 +1,120 @@
> +/*
> + * (C) Copyright 2009
> + *
> + * Based on
> + * u-boot OMAP1510 USB drivers (include/usbdcore_omap1510.h)
> + *
> + * Author: Diego Dompe (diego...@ridgerun.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 __USBDCORE_MUSB_H__
> +#define __USBDCORE_MUSB_H__
> +
> +/* USB Function Module Registers */
> +
> +/*
> + * UDC_BASE is defined for the specific silicon under soc
> + * specific cpu.h or related header.
> + */
> +
> +#define UDC_OFFSET(offset) (UDC_BASE+(offset))
> +
> +#define UDC_INTSRCR UDC_OFFSET(0x0A) /* USB Interrupt src Reg*/
> +#define UDC_INTCLRR UDC_OFFSET(0x0A) /* USB Interrupt src clr Reg*/
> +
> +#define UDC_FADDR UDC_OFFSET(0x00)
> +#define UDC_POWER UDC_OFFSET(0x01)
> +#define UDC_INTRTX UDC_OFFSET(0x02)
> +#define UDC_INTRRX UDC_OFFSET(0x04)
> +#define UDC_INTRTXE UDC_OFFSET(0x06) /* Enable register for INTRTX*/
> +#define UDC_INTRRXE UDC_OFFSET(0x08) /* Enable Register for INTRRX*/
> +#define UDC_INTRUSB UDC_OFFSET(0x0A)
> +#define UDC_INTRUSBE UDC_OFFSET(0x0B)
> +#define UDC_INDEX UDC_OFFSET(0x0E)
> +#define UDC_TESTMODE UDC_OFFSET(0x0F)
> +#define UDC_TXMAXP UDC_OFFSET(0x10)
> +#define UDC_CSR0 UDC_OFFSET(0x12)
> +#define UDC_TXCSR UDC_OFFSET(0x12)
> +#define UDC_RXMAXP UDC_OFFSET(0x14)
> +#define UDC_RXCSR UDC_OFFSET(0x16)
> +#define UDC_COUNT0 UDC_OFFSET(0x18)
> +#define UDC_RXCOUNT UDC_OFFSET(0x18)
> +#define UDC_FIFO0 UDC_OFFSET(0x20)
> +#define UDC_FIFO1 UDC_OFFSET(0x24)
> +#define UDC_FIFO2 UDC_OFFSET(0x28)
> +#define UDC_FIFO3 UDC_OFFSET(0x2C)
> +#define UDC_FIFO4 UDC_OFFSET(0x30)
> +#define UDC_FIFO5 UDC_OFFSET(0x34)
> +#define UDC_FIFO6 UDC_OFFSET(0x38)
> +#define UDC_FIFO7 UDC_OFFSET(0x3C)
> +#define UDC_FIFO8 UDC_OFFSET(0x40)
> +#define UDC_FIFO9 UDC_OFFSET(0x44)
> +#define UDC_FIFO10 UDC_OFFSET(0x48)
> +#define UDC_FIFO11 UDC_OFFSET(0x4C)
> +#define UDC_FIFO12 UDC_OFFSET(0x50)
> +#define UDC_FIFO13 UDC_OFFSET(0x54)
> +#define UDC_FIFO14 UDC_OFFSET(0x58)
> +#define UDC_FIFO15 UDC_OFFSET(0x5C)
> +#define UDC_DEVCTL UDC_OFFSET(0x60)
> +#define UDC_TXFIFOSZ UDC_OFFSET(0x62)
> +#define UDC_RXFIFOSZ UDC_OFFSET(0x63)
> +#define UDC_TXFIFOADDR UDC_OFFSET(0x64)
> +#define UDC_RXFIFOADDR UDC_OFFSET(0x66)
> +
> +#define UDC_SYSCONFIG UDC_OFFSET(0x404)
> +#define UDC_INTERFSEL UDC_OFFSET(0x40C)
> +#define UDC_FORCESTDBY UDC_OFFSET(0x414)
> +
> +/* MUSB Endpoint parameters */
> +#define EP0_MAX_PACKET_SIZE 64
> +#define UDC_OUT_ENDPOINT 3 /* Device RX endpoint */
> +#define UDC_OUT_PACKET_SIZE 512
> +#define UDC_IN_ENDPOINT 2 /* Device TX endpoint */
> +#define UDC_IN_PACKET_SIZE 512
> +#define UDC_INT_ENDPOINT 1 /* Device Interrupt/Status
> endpoint */
> +#define UDC_INT_PACKET_SIZE 16
> +#define UDC_BULK_PACKET_SIZE 512
> +
> +#define UDC_MAX_FIFO_SIZE 16384
> +
> +#define DEV_CONFIG_VALUE 1 /* Only one i.e. CDC */
> +
> +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);
> +
> +/* platform specific initialization */
> +int udc_musb_platform_init(void);
> +
> +#endif /* __USBDCORE_MUSB_H__ */
> diff -uprN omap3-dev/include/usb.h omap3-dev-usb/include/usb.h
> --- omap3-dev/include/usb.h 2009-02-01 19:17:16.000000000 +0100
> +++ omap3-dev-usb/include/usb.h 2009-02-01 19:17:44.000000000 +0100
> @@ -183,7 +183,8 @@ struct usb_device {
> #if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || \
> defined(CONFIG_USB_EHCI) || defined(CONFIG_USB_OHCI_NEW) || \
> defined(CONFIG_USB_SL811HS) || defined(CONFIG_USB_ISP116X_HCD) || \
> - defined(CONFIG_USB_R8A66597_HCD) || defined(CONFIG_USB_DAVINCI)
> + defined(CONFIG_USB_R8A66597_HCD) || defined(CONFIG_USB_DAVINCI) || \
> + defined(CONFIG_USB_OMAP3530)
>
> int usb_lowlevel_init(void);
> int usb_lowlevel_stop(void);

Jason Kridner

unread,
Feb 1, 2009, 4:26:11 PM2/1/09
to beagl...@googlegroups.com

On Feb 1, 2009, at 12:39 PM, Dirk Behme wrote:
>
> After Steve applied the sync patches and merged omap3-dev into
> omap3-dev-usb (thanks!), in attachment the diff between these two
> branches. Result is a ~37k U-Boot v1 MUSB patch we should clean up
> now.
>
> Please review and comment.
>
> Review comments should go as patches to omap3-dev-usb. With this, we
> will get a clean OMAP3 MUSB patch in omap3-dev-usb we can send to USB
> maintainer, later.
>
> Note: Unfortunately, it doesn't apply to any upstream branch, yet.
> Upstream mainline has recent USB changes, but no OMAP3 (needed for
> config file changes), yet. Upstream u-boot-arm has OMAP3, but not
> recent USB changes.

I was able to apply this by taking u-boot mainline and merging u-boot-
arm. After applying the patch, I needed to also apply [1] before it
could build.

By creating a gserial.inf based on the Linux kernel Documentation/usb/
gadget_serial.txt, I was able to install a driver on Windows. I was
then able to boot the Angstrom 2.6.28-r8 kernel. The USB gadget
driver came up under the kernel as well.

It seems like the fastest possible you can get to the serial prompt in
Windows is about 3 seconds, so bootdelay would need to be a minimum of
10 or so. I was able to easily work with the serial bootdelay set to
only 1. The process for getting to the serial prompt quickly in
Windows is tricky.

[1] http://www.sakoman.net/cgi-bin/gitweb.cgi?p=u-boot-omap3.git;a=commit;h=12536e347e55e4bc9c670dcc1d00e1f5e533f941

Reply all
Reply to author
Forward
0 new messages