Commit f298e4b6 authored by Tom Rix's avatar Tom Rix Committed by Remy Bohmer

OMAP3 Add usb device support

This change adds the usb device support for musb.

Omap3 platform support added at the same level as davinci.

The interface for usbtty to use the musb device support was added.

Verified on omap3 beagle, zoom1 and zoom2.
Signed-off-by: default avatarTom Rix <Tom.Rix@windriver.com>
parent bffbb2a8
......@@ -29,6 +29,8 @@
#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_PXA27X)
#include <usb/pxa27x_udc.h>
#endif
......
......@@ -26,7 +26,9 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libusb_musb.a
COBJS-$(CONFIG_MUSB_HCD) += musb_hcd.o musb_core.o
COBJS-$(CONFIG_MUSB_UDC) += musb_udc.o musb_core.o
COBJS-$(CONFIG_USB_DAVINCI) += davinci.o
COBJS-$(CONFIG_USB_OMAP3) += omap3.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
......
......@@ -32,7 +32,9 @@ struct musb_regs *musbr;
*/
void musb_start(void)
{
#if defined(CONFIG_MUSB_HCD)
u8 devctl;
#endif
/* disable all interrupts */
writew(0, &musbr->intrtxe);
......@@ -74,9 +76,10 @@ void musb_configure_ep(struct musb_epinfo *epinfo, u8 cnt)
/* Configure fifo size and fifo base address */
writeb(idx, &musbr->txfifosz);
writew(fifoaddr >> 3, &musbr->txfifoadd);
csr = readw(&musbr->txcsr);
#if defined(CONFIG_MUSB_HCD)
/* clear the data toggle bit */
csr = readw(&musbr->txcsr);
writew(csr | MUSB_TXCSR_CLRDATATOG, &musbr->txcsr);
#endif
/* Flush fifo if required */
......@@ -87,9 +90,10 @@ void musb_configure_ep(struct musb_epinfo *epinfo, u8 cnt)
/* Configure fifo size and fifo base address */
writeb(idx, &musbr->rxfifosz);
writew(fifoaddr >> 3, &musbr->rxfifoadd);
csr = readw(&musbr->rxcsr);
#if defined(CONFIG_MUSB_HCD)
/* clear the data toggle bit */
csr = readw(&musbr->rxcsr);
writew(csr | MUSB_RXCSR_CLRDATATOG, &musbr->rxcsr);
#endif
/* Flush fifo if required */
......
......@@ -40,6 +40,36 @@
#define MUSB_EP0_FIFOSIZE 64 /* This is non-configurable */
/* EP0 */
struct musb_ep0_regs {
u16 reserved4;
u16 csr0;
u16 reserved5;
u16 reserved6;
u16 count0;
u8 host_type0;
u8 host_naklimit0;
u8 reserved7;
u8 reserved8;
u8 reserved9;
u8 configdata;
};
/* EP 1-15 */
struct musb_epN_regs {
u16 txmaxp;
u16 txcsr;
u16 rxmaxp;
u16 rxcsr;
u16 rxcount;
u8 txtype;
u8 txinterval;
u8 rxtype;
u8 rxinterval;
u8 reserved0;
u8 fifosize;
};
/* Mentor USB core register overlay structure */
struct musb_regs {
/* common registers */
......@@ -97,6 +127,16 @@ struct musb_regs {
u8 rxhubaddr;
u8 rxhubport;
} tar[16];
/*
* end point registers
* ep0 elements are valid when array index is 0
* otherwise epN is valid
*/
union musb_ep_regs {
struct musb_ep0_regs ep0;
struct musb_epN_regs epN;
} ep[16];
} __attribute__((aligned(32)));
/*
......
/*
* 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
*/
/* Define MUSB_DEBUG before including this file to get debug macros */
#ifdef MUSB_DEBUG
#define MUSB_FLAGS_PRINT(v, x, y) \
if (((v) & MUSB_##x##_##y)) \
serial_printf("\t\t"#y"\n")
static inline void musb_print_pwr(u8 b)
{
serial_printf("\tpower 0x%2.2x\n", b);
MUSB_FLAGS_PRINT(b, POWER, ISOUPDATE);
MUSB_FLAGS_PRINT(b, POWER, SOFTCONN);
MUSB_FLAGS_PRINT(b, POWER, HSENAB);
MUSB_FLAGS_PRINT(b, POWER, HSMODE);
MUSB_FLAGS_PRINT(b, POWER, RESET);
MUSB_FLAGS_PRINT(b, POWER, RESUME);
MUSB_FLAGS_PRINT(b, POWER, SUSPENDM);
MUSB_FLAGS_PRINT(b, POWER, ENSUSPEND);
}
static inline void musb_print_csr0(u16 w)
{
serial_printf("\tcsr0 0x%4.4x\n", w);
MUSB_FLAGS_PRINT(w, CSR0, FLUSHFIFO);
MUSB_FLAGS_PRINT(w, CSR0_P, SVDSETUPEND);
MUSB_FLAGS_PRINT(w, CSR0_P, SVDRXPKTRDY);
MUSB_FLAGS_PRINT(w, CSR0_P, SENDSTALL);
MUSB_FLAGS_PRINT(w, CSR0_P, SETUPEND);
MUSB_FLAGS_PRINT(w, CSR0_P, DATAEND);
MUSB_FLAGS_PRINT(w, CSR0_P, SENTSTALL);
MUSB_FLAGS_PRINT(w, CSR0, TXPKTRDY);
MUSB_FLAGS_PRINT(w, CSR0, RXPKTRDY);
}
static inline void musb_print_intrusb(u8 b)
{
serial_printf("\tintrusb 0x%2.2x\n", b);
MUSB_FLAGS_PRINT(b, INTR, VBUSERROR);
MUSB_FLAGS_PRINT(b, INTR, SESSREQ);
MUSB_FLAGS_PRINT(b, INTR, DISCONNECT);
MUSB_FLAGS_PRINT(b, INTR, CONNECT);
MUSB_FLAGS_PRINT(b, INTR, SOF);
MUSB_FLAGS_PRINT(b, INTR, RESUME);
MUSB_FLAGS_PRINT(b, INTR, SUSPEND);
if (b & MUSB_INTR_BABBLE)
serial_printf("\t\tMUSB_INTR_RESET or MUSB_INTR_BABBLE\n");
}
static inline void musb_print_intrtx(u16 w)
{
serial_printf("\tintrtx 0x%4.4x\n", w);
}
static inline void musb_print_intrrx(u16 w)
{
serial_printf("\tintrx 0x%4.4x\n", w);
}
static inline void musb_print_devctl(u8 b)
{
serial_printf("\tdevctl 0x%2.2x\n", b);
if (b & MUSB_DEVCTL_BDEVICE)
serial_printf("\t\tB device\n");
else
serial_printf("\t\tA device\n");
if (b & MUSB_DEVCTL_FSDEV)
serial_printf("\t\tFast Device -(host mode)\n");
if (b & MUSB_DEVCTL_LSDEV)
serial_printf("\t\tSlow Device -(host mode)\n");
if (b & MUSB_DEVCTL_HM)
serial_printf("\t\tHost mode\n");
else
serial_printf("\t\tPeripherial mode\n");
if (b & MUSB_DEVCTL_HR)
serial_printf("\t\tHost request started(B device)\n");
else
serial_printf("\t\tHost request finished(B device)\n");
if (b & MUSB_DEVCTL_BDEVICE) {
if (b & MUSB_DEVCTL_SESSION)
serial_printf("\t\tStart of session(B device)\n");
else
serial_printf("\t\tEnd of session(B device)\n");
} else {
if (b & MUSB_DEVCTL_SESSION)
serial_printf("\t\tStart of session(A device)\n");
else
serial_printf("\t\tEnd of session(A device)\n");
}
}
static inline void musb_print_config(u8 b)
{
serial_printf("\tconfig 0x%2.2x\n", b);
if (b & MUSB_CONFIGDATA_MPRXE)
serial_printf("\t\tAuto combine rx bulk packets\n");
if (b & MUSB_CONFIGDATA_MPTXE)
serial_printf("\t\tAuto split tx bulk packets\n");
if (b & MUSB_CONFIGDATA_BIGENDIAN)
serial_printf("\t\tBig Endian ordering\n");
else
serial_printf("\t\tLittle Endian ordering\n");
if (b & MUSB_CONFIGDATA_HBRXE)
serial_printf("\t\tHigh speed rx iso endpoint\n");
if (b & MUSB_CONFIGDATA_HBTXE)
serial_printf("\t\tHigh speed tx iso endpoint\n");
if (b & MUSB_CONFIGDATA_DYNFIFO)
serial_printf("\t\tDynamic fifo sizing\n");
if (b & MUSB_CONFIGDATA_SOFTCONE)
serial_printf("\t\tSoft Connect\n");
if (b & MUSB_CONFIGDATA_UTMIDW)
serial_printf("\t\t16 bit data width\n");
else
serial_printf("\t\t8 bit data width\n");
}
static inline void musb_print_rxmaxp(u16 w)
{
serial_printf("\trxmaxp 0x%4.4x\n", w);
}
static inline void musb_print_rxcsr(u16 w)
{
serial_printf("\trxcsr 0x%4.4x\n", w);
MUSB_FLAGS_PRINT(w, RXCSR, AUTOCLEAR);
MUSB_FLAGS_PRINT(w, RXCSR, DMAENAB);
MUSB_FLAGS_PRINT(w, RXCSR, DISNYET);
MUSB_FLAGS_PRINT(w, RXCSR, PID_ERR);
MUSB_FLAGS_PRINT(w, RXCSR, DMAMODE);
MUSB_FLAGS_PRINT(w, RXCSR, CLRDATATOG);
MUSB_FLAGS_PRINT(w, RXCSR, FLUSHFIFO);
MUSB_FLAGS_PRINT(w, RXCSR, DATAERROR);
MUSB_FLAGS_PRINT(w, RXCSR, FIFOFULL);
MUSB_FLAGS_PRINT(w, RXCSR, RXPKTRDY);
MUSB_FLAGS_PRINT(w, RXCSR_P, SENTSTALL);
MUSB_FLAGS_PRINT(w, RXCSR_P, SENDSTALL);
MUSB_FLAGS_PRINT(w, RXCSR_P, OVERRUN);
if (w & MUSB_RXCSR_P_ISO)
serial_printf("\t\tiso mode\n");
else
serial_printf("\t\tbulk mode\n");
}
static inline void musb_print_txmaxp(u16 w)
{
serial_printf("\ttxmaxp 0x%4.4x\n", w);
}
static inline void musb_print_txcsr(u16 w)
{
serial_printf("\ttxcsr 0x%4.4x\n", w);
MUSB_FLAGS_PRINT(w, TXCSR, TXPKTRDY);
MUSB_FLAGS_PRINT(w, TXCSR, FIFONOTEMPTY);
MUSB_FLAGS_PRINT(w, TXCSR, FLUSHFIFO);
MUSB_FLAGS_PRINT(w, TXCSR, CLRDATATOG);
MUSB_FLAGS_PRINT(w, TXCSR_P, UNDERRUN);
MUSB_FLAGS_PRINT(w, TXCSR_P, SENTSTALL);
MUSB_FLAGS_PRINT(w, TXCSR_P, SENDSTALL);
if (w & MUSB_TXCSR_MODE)
serial_printf("\t\tTX mode\n");
else
serial_printf("\t\tRX mode\n");
}
#else
/* stubs */
#define musb_print_pwr(b)
#define musb_print_csr0(w)
#define musb_print_intrusb(b)
#define musb_print_intrtx(w)
#define musb_print_intrrx(w)
#define musb_print_devctl(b)
#define musb_print_config(b)
#define musb_print_rxmaxp(w)
#define musb_print_rxcsr(w)
#define musb_print_txmaxp(w)
#define musb_print_txcsr(w)
#endif /* MUSB_DEBUG */
This diff is collapsed.
/*
* Copyright (c) 2009 Wind River Systems, Inc.
* Tom Rix <Tom.Rix@windriver.com>
*
* This is file is based on
* repository git.gitorious.org/u-boot-omap3/mainline.git,
* branch omap3-dev-usb, file drivers/usb/host/omap3530_usb.c
*
* This is the unique part of its copyright :
*
* ------------------------------------------------------------------------
*
* Copyright (c) 2009 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
*/
#include <twl4030.h>
#include "omap3.h"
static int platform_needs_initialization = 1;
struct musb_config musb_cfg = {
(struct musb_regs *)MENTOR_USB0_BASE,
OMAP3_USB_TIMEOUT,
0
};
/*
* OMAP3 USB OTG registers.
*/
struct omap3_otg_regs {
u32 revision;
u32 sysconfig;
u32 sysstatus;
u32 interfsel;
u32 simenable;
u32 forcestdby;
};
static struct omap3_otg_regs *otg;
#define OMAP3_OTG_SYSCONFIG_SMART_STANDBY_MODE 0x2000
#define OMAP3_OTG_SYSCONFIG_NO_STANDBY_MODE 0x1000
#define OMAP3_OTG_SYSCONFIG_SMART_IDLE_MODE 0x0010
#define OMAP3_OTG_SYSCONFIG_NO_IDLE_MODE 0x0008
#define OMAP3_OTG_SYSCONFIG_ENABLEWAKEUP 0x0004
#define OMAP3_OTG_SYSCONFIG_SOFTRESET 0x0002
#define OMAP3_OTG_SYSCONFIG_AUTOIDLE 0x0001
#define OMAP3_OTG_SYSSTATUS_RESETDONE 0x0001
#define OMAP3_OTG_INTERFSEL_OMAP 0x0001
#define OMAP3_OTG_FORCESTDBY_STANDBY 0x0001
#ifdef DEBUG_MUSB_OMAP3
static void musb_db_otg_regs(void)
{
u32 l;
l = readl(&otg->revision);
serial_printf("OTG_REVISION 0x%x\n", l);
l = readl(&otg->sysconfig);
serial_printf("OTG_SYSCONFIG 0x%x\n", l);
l = readl(&otg->sysstatus);
serial_printf("OTG_SYSSTATUS 0x%x\n", l);
l = readl(&otg->interfsel);
serial_printf("OTG_INTERFSEL 0x%x\n", l);
l = readl(&otg->forcestdby);
serial_printf("OTG_FORCESTDBY 0x%x\n", l);
}
#endif
int musb_platform_init(void)
{
int ret = -1;
if (platform_needs_initialization) {
u32 stdby;
if (twl4030_usb_ulpi_init()) {
serial_printf("ERROR: %s Could not initialize PHY\n",
__PRETTY_FUNCTION__);
goto end;
}
otg = (struct omap3_otg_regs *)OMAP3_OTG_BASE;
/* Set OTG to always be on */
writel(OMAP3_OTG_SYSCONFIG_NO_STANDBY_MODE |
OMAP3_OTG_SYSCONFIG_NO_IDLE_MODE, &otg->sysconfig);
/* Set the interface */
writel(OMAP3_OTG_INTERFSEL_OMAP, &otg->interfsel);
/* Clear force standby */
stdby = readl(&otg->forcestdby);
stdby &= ~OMAP3_OTG_FORCESTDBY_STANDBY;
writel(stdby, &otg->forcestdby);
platform_needs_initialization = 0;
}
ret = platform_needs_initialization;
end:
return ret;
}
void musb_platform_deinit(void)
{
/* noop */
}
/*
* Copyright (c) 2009 Wind River Systems, Inc.
* Tom Rix <Tom.Rix@windriver.com>
*
* This file is based on the file drivers/usb/musb/davinci.h
*
* This is the unique part of its copyright:
*
* --------------------------------------------------------------------
*
* Copyright (c) 2008 Texas Instruments
* Author: Thomas Abraham t-abraham@ti.com, 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
*/
#ifndef _MUSB_OMAP3_H_
#define _MUSB_OMAP3_H_
#include "musb_core.h"
/* Base address of MUSB registers */
#define MENTOR_USB0_BASE (OMAP34XX_CORE_L4_IO_BASE + 0xAB000)
/* Base address of OTG registers */
#define OMAP3_OTG_BASE (MENTOR_USB0_BASE + 0x400)
/* Timeout for USB module */
#define OMAP3_USB_TIMEOUT 0x3FFFFFF
int musb_platform_init(void);
#endif /* _MUSB_OMAP3_H */
......@@ -131,7 +131,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_OMAP3)
int usb_lowlevel_init(void);
int usb_lowlevel_stop(void);
......
/*
* 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__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment