From 90cabc5422ab6a7e2c839025bcead88a3ca4519d Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Thu, 18 Feb 2010 16:59:35 +0900 Subject: [PATCH] s5pc110: Add S5PC110 S3C UDC OTG driver and enable CDC Ethernet networking (tftp) Signed-off-by: Kyungmin Park --- board/samsung/universal/universal.c | 59 ++++ common/cmd_misc.c | 4 +- cpu/arm_cortexa8/cpu.c | 4 +- cpu/arm_cortexa8/s5pc1xx/timer.c | 2 +- drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/ether.c | 73 +++-- drivers/usb/gadget/gadget_chips.h | 7 + drivers/usb/gadget/s3c_udc.h | 72 +++-- drivers/usb/gadget/s3c_udc_otg.c | 485 +++++++++--------------------- drivers/usb/gadget/s3c_udc_otg_xfer_dma.c | 27 +- include/asm-arm/arch-s5pc1xx/hs_otg.h | 32 ++ include/asm-arm/arch-s5pc1xx/regs-otg.h | 264 ++++++++++++++++ include/configs/s5pc1xx_universal.h | 28 +- 13 files changed, 663 insertions(+), 395 deletions(-) create mode 100644 include/asm-arm/arch-s5pc1xx/hs_otg.h create mode 100644 include/asm-arm/arch-s5pc1xx/regs-otg.h diff --git a/board/samsung/universal/universal.c b/board/samsung/universal/universal.c index 4e79660..d9795d1 100644 --- a/board/samsung/universal/universal.c +++ b/board/samsung/universal/universal.c @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include #include #include @@ -2043,6 +2045,63 @@ void board_sleep_resume(void) check_micro_usb(1); } +#if defined(CONFIG_USB_GADGET_S3C_UDC_OTG) + +static int s5pc1xx_phy_control(int on) +{ + static int status; + + if (on && !status) { +// printf("turning USB power on\n"); +#ifdef CONFIG_CMD_PMIC + run_command("pmic ldo 3 on", 0); +#endif + /* S5PC110 */ + if (board_is_limo_universal() || + board_is_limo_real() || + board_is_media()) { + /* check usb path */ + if (board_is_limo_real() && !hwrevision(6)) + check_mhl(); + } + + if (machine_is_tickertape()) + /* USB_SEL: XM0ADDR_0: MP04[0] output mode */ + gpio_direction_output(&s5pc110_gpio->gpio_mp0_4, 0, 0); + + /* USB Path to AP */ + micro_usb_switch(0); + status = 1; + } else if (!on && status) { +// printf("turning USB power off\n"); +#ifdef CONFIG_CMD_PMIC + run_command("pmic ldo 3 off", 0); +#endif + status = 0; + } + udelay(10000); +} + +struct s3c_plat_otg_data s5pc110_otg_data = { + .phy_control = s5pc1xx_phy_control, + .regs_phy = S5PC110_PHY_BASE, + .regs_otg = S5PC110_OTG_BASE, +}; + +int board_eth_init(bd_t *bis) +{ + int res = -1; + + if (cpu_is_s5pc100()) + return -1; + + s3c_udc_probe(&s5pc110_otg_data); + if (usb_eth_initialize(bis) >= 0) + res = 0; + return res; +} +#endif + #ifdef CONFIG_CMD_USBDOWN int usb_board_init(void) { diff --git a/common/cmd_misc.c b/common/cmd_misc.c index b0ced2f..d5b759d 100644 --- a/common/cmd_misc.c +++ b/common/cmd_misc.c @@ -27,7 +27,7 @@ #include #include -int do_sleep (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_sleep1 (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong start = get_timer(0); ulong delay; @@ -50,7 +50,7 @@ int do_sleep (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } U_BOOT_CMD( - sleep , 2, 1, do_sleep, + wait , 2, 1, do_sleep1, "delay execution for some time", "N\n" " - delay execution for N seconds (N is _decimal_ !!!)" diff --git a/cpu/arm_cortexa8/cpu.c b/cpu/arm_cortexa8/cpu.c index a01e0d6..3b6f86b 100644 --- a/cpu/arm_cortexa8/cpu.c +++ b/cpu/arm_cortexa8/cpu.c @@ -39,7 +39,7 @@ #include #endif -static void cache_flush(void); +void cache_flush(void); int cleanup_before_linux(void) { @@ -77,7 +77,7 @@ int cleanup_before_linux(void) return 0; } -static void cache_flush(void) +void cache_flush(void) { asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0)); } diff --git a/cpu/arm_cortexa8/s5pc1xx/timer.c b/cpu/arm_cortexa8/s5pc1xx/timer.c index 297e69a..d9ca7c1 100644 --- a/cpu/arm_cortexa8/s5pc1xx/timer.c +++ b/cpu/arm_cortexa8/s5pc1xx/timer.c @@ -112,7 +112,7 @@ void reset_timer(void) unsigned long get_timer(unsigned long base) { - return get_timer_masked() - base; + return (get_timer_masked()/2000 - base); } void set_timer(unsigned long t) diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 27e7f40..ebfdd07 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -38,6 +38,7 @@ endif # new USB gadget layer dependencies COBJS-$(CONFIG_USB_ETHER) += ether.o epautoconf.o config.o usbstring.o COBJS-$(CONFIG_USB_GADGET_AT91) += at91_udc.o +COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index f290883..3793e1d 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -30,7 +30,7 @@ #include "gadget_chips.h" -#define USB_NET_NAME "usb0" +#define USB_NET_NAME "CDC Ethernet" #define dprintf(x, ...) #undef INFO #define INFO(x, s...) printf(s) @@ -108,7 +108,7 @@ static const char driver_desc [] = DRIVER_DESC; |USB_CDC_PACKET_TYPE_PROMISCUOUS \ |USB_CDC_PACKET_TYPE_DIRECTED) -#define USB_CONNECT_TIMEOUT (3 * CONFIG_SYS_HZ) +#define USB_CONNECT_TIMEOUT (10 * CONFIG_SYS_HZ) /*-------------------------------------------------------------------------*/ static struct eth_dev l_ethdev; @@ -134,6 +134,14 @@ static inline int is_cdc(struct eth_dev *dev) #define DEFAULT_QLEN 2 /* double buffering by default */ +#ifdef CONFIG_USB_GADGET_DUALSPEED + +static unsigned qmult = 5; + +#else /* full speed (low speed doesn't do bulk) */ +#define qmult 1 +#endif + /* peak bulk transfer bits-per-second */ #define HS_BPS (13 * 512 * 8 * 1000 * 8) #define FS_BPS (19 * 64 * 1 * 1000 * 8) @@ -920,10 +928,14 @@ static void eth_status_complete (struct usb_ep *ep, struct usb_request *req) int value = req->status; struct eth_dev *dev = ep->driver_data; + dprintf("eth_status_complete\n"); + /* issue the second notification if host reads the first */ if (event->bNotificationType == USB_CDC_NOTIFY_NETWORK_CONNECTION && value == 0) { - __le32 *data = req->buf + sizeof *event; + char *src, *dst = req->buf + sizeof *event; + __le32 data; + int i; event->bmRequestType = 0xA1; event->bNotificationType = USB_CDC_NOTIFY_SPEED_CHANGE; @@ -932,8 +944,16 @@ static void eth_status_complete (struct usb_ep *ep, struct usb_request *req) event->wLength = __constant_cpu_to_le16 (8); /* SPEED_CHANGE data is up/down speeds in bits/sec */ - data [0] = data [1] = cpu_to_le32 (BITRATE (dev->gadget)); + data = cpu_to_le32 (BITRATE (dev->gadget)); + + src = &data; + for (i=0; i<4; i++) + *dst++ = *src++; + src = &data; + for (i=0; i<4; i++) + *dst++ = *src++; + req->length = STATUS_BYTECOUNT; value = usb_ep_queue (ep, req, GFP_ATOMIC); dprintf ("send SPEED_CHANGE --> %d\n", value); @@ -950,6 +970,7 @@ static void eth_status_complete (struct usb_ep *ep, struct usb_request *req) } } req->context = NULL; + dprintf("done\n"); } static void issue_start_status (struct eth_dev *dev) @@ -1422,7 +1443,7 @@ static void eth_unbind (struct usb_gadget *gadget) { struct eth_dev *dev = get_gadget_data (gadget); - printf("eth_unbind:...\n"); + dprintf("eth_unbind:...\n"); if (dev->stat_req) { usb_ep_free_request (dev->status_ep, dev->stat_req); @@ -1759,6 +1780,7 @@ static int usb_eth_init(struct eth_device* netdev, bd_t* bd) { struct eth_dev *dev=&l_ethdev; struct usb_gadget *gadget; + int status = 0; unsigned long ts; unsigned long timeout = USB_CONNECT_TIMEOUT; @@ -1767,12 +1789,18 @@ static int usb_eth_init(struct eth_device* netdev, bd_t* bd) goto fail; } + status = usb_gadget_register_driver(ð_driver); + if (status < 0) + goto fail; + + usb_gadget_handle_interrupts(); + dev->network_started = 0; dev->tx_req = NULL; dev->rx_req = NULL; packet_received = 0; - packet_sent = 0; + packet_sent = 1; gadget = dev->gadget; usb_gadget_connect(gadget); @@ -1783,12 +1811,17 @@ static int usb_eth_init(struct eth_device* netdev, bd_t* bd) ts = get_timer(0); while (!l_ethdev.network_started) { + int irq_res; /* Handle control-c and timeouts */ if (ctrlc() || (get_timer(ts) > timeout)) { printf("The remote end did not respond in time.\n"); goto fail; } - usb_gadget_handle_interrupts(); + irq_res = usb_gadget_handle_interrupts(); + + /* hack nice progress display */ + if (irq_res && !l_ethdev.network_started) + printf("."); } rx_submit (dev, dev->rx_req, 0); @@ -1805,6 +1838,13 @@ static int usb_eth_send(struct eth_device* netdev, volatile void* packet, int le struct eth_dev *dev = &l_ethdev; dprintf("%s:...\n",__func__); + while(!packet_sent) + { + packet_sent=0; + usb_gadget_handle_interrupts(); + dprintf("^"); + } + req = dev->tx_req; req->buf = (void *)packet; @@ -1820,7 +1860,7 @@ static int usb_eth_send(struct eth_device* netdev, volatile void* packet, int le length++; req->length = length; -#if 0 +#if 1 /* throttle highspeed IRQ rate back slightly */ if (gadget_is_dualspeed(dev->gadget)) req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH) @@ -1832,10 +1872,6 @@ static int usb_eth_send(struct eth_device* netdev, volatile void* packet, int le if (!retval) dprintf("%s: packet queued\n",__func__); - while(!packet_sent) - { - packet_sent=0; - } return 0; } @@ -1844,6 +1880,8 @@ static int usb_eth_recv(struct eth_device* netdev) { struct eth_dev *dev = &l_ethdev; + dprintf("%s:...\n",__func__); + usb_gadget_handle_interrupts(); if (packet_received) @@ -1856,9 +1894,11 @@ static int usb_eth_recv(struct eth_device* netdev) if (dev->rx_req) rx_submit (dev, dev->rx_req, 0); + dprintf("-"); } else printf("dev->rx_req invalid\n"); } + dprintf("done\n"); return 0; } @@ -1872,7 +1912,8 @@ void usb_eth_halt(struct eth_device* netdev) return; } - usb_gadget_disconnect(dev->gadget); + usb_gadget_unregister_driver(ð_driver); + usb_gadget_handle_interrupts(); } static struct usb_gadget_driver eth_driver = { @@ -1893,7 +1934,7 @@ int usb_eth_initialize(bd_t *bi) int status = 0; struct eth_device *netdev=&l_netdev; - sprintf(netdev->name,"usb_ether"); + sprintf(netdev->name, "USB CDC Ethernet"); netdev->init = usb_eth_init; netdev->send = usb_eth_send; @@ -1934,10 +1975,6 @@ int usb_eth_initialize(bd_t *bi) if (status) goto fail; - status = usb_gadget_register_driver(ð_driver); - if (status < 0) - goto fail; - eth_register(netdev); return 0; diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index 480bc87..e66c8fb 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h @@ -150,6 +150,11 @@ #define gadget_is_m66592(g) 0 #endif +#ifdef CONFIG_USB_GADGET_S3C_UDC_OTG +#define gadget_is_s3c_udc_otg(g) !strcmp("s3c-udc", (g)->name) +#else +#define gadget_is_s3c_udc_otg(g) 0 +#endif // CONFIG_USB_GADGET_SX2 // CONFIG_USB_GADGET_AU1X00 @@ -215,5 +220,7 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) return 0x20; else if (gadget_is_m66592(gadget)) return 0x21; + else if (gadget_is_s3c_udc_otg(gadget)) + return 0x22; return -ENOENT; } diff --git a/drivers/usb/gadget/s3c_udc.h b/drivers/usb/gadget/s3c_udc.h index 40cc18a..b2ac008 100644 --- a/drivers/usb/gadget/s3c_udc.h +++ b/drivers/usb/gadget/s3c_udc.h @@ -22,56 +22,39 @@ #ifndef __S3C_USB_GADGET #define __S3C_USB_GADGET -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -//#include #include #include +#include + + +#define __iomem + +/*-------------------------------------------------------------------------*/ #define DMA_BUFFER_SIZE (4096*4) /* DMA bounce buffer size, 16K is enough even for mass storage */ // Max packet size +/* #if defined(CONFIG_USB_GADGET_S3C_FS) #define EP0_FIFO_SIZE 8 #define EP_FIFO_SIZE 64 #define S3C_MAX_ENDPOINTS 5 #elif defined(CONFIG_USB_GADGET_S3C_HS) || defined(CONFIG_PLAT_S5P64XX) || defined(CONFIG_PLAT_S5PC1XX) \ || defined(CONFIG_CPU_S5P6442) +*/ #define EP0_FIFO_SIZE 64 #define EP_FIFO_SIZE 512 #define EP_FIFO_SIZE2 1024 #define S3C_MAX_ENDPOINTS 16 +/* #else #define EP0_FIFO_SIZE 64 #define EP_FIFO_SIZE 512 #define EP_FIFO_SIZE2 1024 #define S3C_MAX_ENDPOINTS 16 #endif - +*/ #define WAIT_FOR_SETUP 0 #define DATA_STATE_XMIT 1 #define DATA_STATE_NEED_ZLP 2 @@ -126,7 +109,8 @@ struct s3c_udc { struct usb_gadget gadget; struct usb_gadget_driver *driver; //struct device *dev; - struct platform_device *dev; +// struct platform_device *dev; + struct s3c_plat_otg_data *pdata; spinlock_t lock; void *dma_buf[S3C_MAX_ENDPOINTS+1]; @@ -135,8 +119,8 @@ struct s3c_udc { unsigned char usb_address; - struct regulator *regulator_a; - struct regulator *regulator_d; +// struct regulator *regulator_a; +// struct regulator *regulator_d; unsigned req_pending:1, req_std:1, req_config:1; }; @@ -147,4 +131,32 @@ extern struct s3c_udc *the_controller; #define ep_index(EP) ((EP)->bEndpointAddress&0xF) #define ep_maxpacket(EP) ((EP)->ep.maxpacket) + + +/*-------------------------------------------------------------------------*/ + +#ifdef DEBUG +#define DBG(stuff...) printf("udc: " stuff) +#else +#define DBG(stuff...) do{}while(0) +#endif + +#ifdef VERBOSE +#define VDBG(x...) printf(x) +//VDBG(x...) printf(__FUNCTION__ , x) +#else +#define VDBG(stuff...) do{}while(0) +#endif + +#ifdef PACKET_TRACE +# define PACKET VDBG +#else +# define PACKET(stuff...) do{}while(0) +#endif + +#define ERR(stuff...) printf("ERR udc: " stuff) +#define WARN(stuff...) printf("WARNING udc: " stuff) +#define INFO(stuff...) printf("INFO udc: " stuff) + + #endif diff --git a/drivers/usb/gadget/s3c_udc_otg.c b/drivers/usb/gadget/s3c_udc_otg.c index 0353027..f728fa7 100644 --- a/drivers/usb/gadget/s3c_udc_otg.c +++ b/drivers/usb/gadget/s3c_udc_otg.c @@ -21,64 +21,73 @@ * */ -#include "s3c_udc.h" -#include -#include -#include -#include "s3c_udc-regs-otg.h" -#include -#include +#include +#include +#include +#include -void __iomem *regs_otg; -void __iomem *regs_phy; -struct resource *res_otg; -struct resource *res_phy; +#include +#include -/* Initializes OTG Phy. */ -void otg_phy_init(void) -{ - printk("otg phy init: regs %08x, phy %08x\n", (u32)regs_otg, (u32)regs_phy); - /*USB PHY0 Enable */ -// writel(readl(S5P_USB_PHY_CONTROL)|(0x1<<0), S5P_USB_PHY_CONTROL); - writel(readl(S5PC110_USB_PHY_CON)|(0x1<<0), S5PC110_USB_PHY_CON); - writel((readl(S3C_USBOTG_PHYPWR)&~(0x3<<3)&~(0x1<<0))|(0x1<<5), - S3C_USBOTG_PHYPWR); - writel((readl(S3C_USBOTG_PHYCLK)&~(0x5<<2))|(0x3<<0), - S3C_USBOTG_PHYCLK); - writel((readl(S3C_USBOTG_RSTCON)&~(0x3<<1))|(0x1<<0), - S3C_USBOTG_RSTCON); - udelay(10); - writel(readl(S3C_USBOTG_RSTCON)&~(0x7<<0), S3C_USBOTG_RSTCON); - udelay(10); +/* common */ +typedef int spinlock_t; +typedef int wait_queue_head_t; +typedef int irqreturn_t; +#define spin_lock_init(...) +#define spin_lock(...) +#define spin_lock_irqsave(lock, flags) flags=1 +#define spin_unlock(...) +#define spin_unlock_irqrestore(lock, flags) flags=0 +#define disable_irq(...) +#define enable_irq(...) - printk("otg phy init done\n"); +#define mutex_init(...) +#define mutex_lock(...) +#define mutex_unlock(...) -} -EXPORT_SYMBOL(otg_phy_init); +#define WARN_ON(x) if (x) { printf("WARNING in %s line %d\n", __FILE__, __LINE__); } -/* OTG PHY Power Off */ -void otg_phy_off(void) -{ - printk("otg phy off\n"); - writel(readl(S3C_USBOTG_PHYPWR)|(0x3<<3), S3C_USBOTG_PHYPWR); - writel(readl(S5PC110_USB_PHY_CON)&~(1<<0), S5PC110_USB_PHY_CON); -// writel(readl(S5P_USB_PHY_CONTROL)&~(1<<0), S5P_USB_PHY_CONTROL); - printk("otg phy off done\n"); -} -EXPORT_SYMBOL(otg_phy_off); +#define printk printf +#define KERN_WARNING +#define KERN_ERR +#define KERN_NOTICE +#define KERN_DEBUG -#if defined(CONFIG_USB_GADGET_S3C_OTGD_DMA_MODE) /* DMA mode */ -#define OTG_DMA_MODE 1 +#define GFP_KERNEL 0 -#elif defined(CONFIG_USB_GADGET_S3C_OTGD_SLAVE_MODE) /* Slave mode */ -#define OTG_DMA_MODE 0 -#error " Slave Mode is not implemented to do later" -#else -#error " Unknown S3C OTG operation mode, Select a correct operation mode" -#endif +#define IRQ_HANDLED 1 + +#define ENOTSUPP 524 /* Operation is not supported */ + +#define EXPORT_SYMBOL(x) + +#define dma_cache_maint(addr, size, mode) cache_flush() + +#define kmalloc(size, type) malloc(size) +#define kfree(addr) free(addr) +#define mdelay(n) ({unsigned long msec = (n); while (msec--) udelay(1000); }) + +#include +#include +#include +#include + +#include + +#define __iomem + +#include "s3c_udc.h" +#include +#include +#include + + +/***********************************************************/ + +#define OTG_DMA_MODE 1 #undef DEBUG_S3C_UDC_SETUP #undef DEBUG_S3C_UDC_EP0 @@ -87,12 +96,12 @@ EXPORT_SYMBOL(otg_phy_off); #undef DEBUG_S3C_UDC_IN_EP #undef DEBUG_S3C_UDC -#define DEBUG_S3C_UDC_SETUP -#define DEBUG_S3C_UDC_EP0 +//#define DEBUG_S3C_UDC_SETUP +//#define DEBUG_S3C_UDC_EP0 * //#define DEBUG_S3C_UDC_ISR //#define DEBUG_S3C_UDC_OUT_EP //#define DEBUG_S3C_UDC_IN_EP -#define DEBUG_S3C_UDC +//#define DEBUG_S3C_UDC #define EP0_CON 0 #define EP_MASK 0xF @@ -146,7 +155,6 @@ static char *state_names[] = { #define DEBUG_IN_EP(fmt,args...) do {} while(0) #endif - #define DRIVER_DESC "S3C HS USB OTG Device Driver, (c) 2008-2009 Samsung Electronics" #define DRIVER_VERSION "15 March 2009" @@ -207,61 +215,55 @@ static struct usb_ep_ops s3c_ep_ops = { .fifo_flush = s3c_fifo_flush, }; -#ifdef CONFIG_USB_GADGET_DEBUG_FILES +#define create_proc_files() do {} while (0) +#define remove_proc_files() do {} while (0) -static const char proc_node_name[] = "driver/udc"; +/***********************************************************/ -static int -udc_proc_read(char *page, char **start, off_t off, int count, - int *eof, void *_dev) +void __iomem *regs_otg; +void __iomem *regs_phy; + + +void otg_phy_init(void) { - char *buf = page; - struct s3c_udc *dev = _dev; - char *next = buf; - unsigned size = count; - unsigned long flags; - int t; + the_controller->pdata->phy_control(1); - if (off != 0) - return 0; + /*USB PHY0 Enable */ +// printf("USB PHY0 Enable\n"); +// writel(readl(S5P_USB_PHY_CONTROL)|(0x1<<0), S5P_USB_PHY_CONTROL); + writel(readl(S5PC110_USB_PHY_CON)|(0x1<<0), S5PC110_USB_PHY_CON); + + writel((readl(S3C_USBOTG_PHYPWR)&~(0x3<<3)&~(0x1<<0))|(0x1<<5), + S3C_USBOTG_PHYPWR); + writel((readl(S3C_USBOTG_PHYCLK)&~(0x5<<2))|(0x3<<0), + S3C_USBOTG_PHYCLK); + writel((readl(S3C_USBOTG_RSTCON)&~(0x3<<1))|(0x1<<0), + S3C_USBOTG_RSTCON); - local_irq_save(flags); - - /* basic device status */ - t = scnprintf(next, size, - DRIVER_DESC "\n" - "%s version: %s\n" - "Gadget driver: %s\n" - "\n", - driver_name, DRIVER_VERSION, - dev->driver ? dev->driver->driver.name : "(none)"); - size -= t; - next += t; - - local_irq_restore(flags); - *eof = 1; - return count - size; + writel(0x1, S3C_USBOTG_RSTCON); + udelay(20); + writel(0x0, S3C_USBOTG_RSTCON); + udelay(20); } -#define create_proc_files() \ - create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev) -#define remove_proc_files() \ - remove_proc_entry(proc_node_name, NULL) +void otg_phy_off(void) +{ + writel(readl(S3C_USBOTG_PHYPWR)|(0x3<<3), S3C_USBOTG_PHYPWR); + writel(readl(S5PC110_USB_PHY_CON)&~(1<<0), S5PC110_USB_PHY_CON); +// writel(readl(S5P_USB_PHY_CONTROL)&~(1<<0), S5P_USB_PHY_CONTROL); + + writel((readl(S3C_USBOTG_PHYPWR)&~(0x3<<3)&~(0x1<<0)),S3C_USBOTG_PHYPWR); + writel((readl(S3C_USBOTG_PHYCLK)&~(0x5<<2)),S3C_USBOTG_PHYCLK); -#else /* !CONFIG_USB_GADGET_DEBUG_FILES */ + udelay(10000); -#define create_proc_files() do {} while (0) -#define remove_proc_files() do {} while (0) + the_controller->pdata->phy_control(0); +} -#endif /* CONFIG_USB_GADGET_DEBUG_FILES */ +/***********************************************************/ -#if OTG_DMA_MODE /* DMA Mode */ #include "s3c_udc_otg_xfer_dma.c" -#else /* Slave Mode */ -#include "s3c_udc_otg_xfer_slave.c" -#endif - /* * udc_disable - disable USB device controller */ @@ -335,10 +337,10 @@ static int udc_enable(struct s3c_udc *dev) int usb_gadget_register_driver(struct usb_gadget_driver *driver) { struct s3c_udc *dev = the_controller; - int retval; + int retval = 0; unsigned long flags; - DEBUG_SETUP("%s: %s\n", __FUNCTION__, driver->driver.name); + DEBUG_SETUP("%s: %s\n", __FUNCTION__, "no name"); if (!driver || (driver->speed != USB_SPEED_FULL && driver->speed != USB_SPEED_HIGH) @@ -370,9 +372,9 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) */ /* first hook up the driver ... */ dev->driver = driver; - dev->gadget.dev.driver = &driver->driver; +// dev->gadget.dev.driver = &driver->driver; spin_unlock_irqrestore(&dev->lock, flags); - retval = device_add(&dev->gadget.dev); +// retval = device_add(&dev->gadget.dev); if(retval) { /* TODO */ printk("target device_add failed, error %d\n", retval); @@ -381,18 +383,18 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) retval = driver->bind(&dev->gadget); if (retval) { - printk("%s: bind to driver %s --> error %d\n", dev->gadget.name, - driver->driver.name, retval); - device_del(&dev->gadget.dev); +// printk("%s: bind to driver %s --> error %d\n", dev->gadget.name, +// driver->driver.name, retval); +// device_del(&dev->gadget.dev); dev->driver = 0; - dev->gadget.dev.driver = 0; +// dev->gadget.dev.driver = 0; return retval; } enable_irq(IRQ_OTG); - printk("Registered gadget driver '%s'\n", driver->driver.name); +// printk("Registered gadget driver %s\n", dev->gadget.name); udc_enable(dev); return 0; @@ -419,14 +421,14 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) spin_unlock_irqrestore(&dev->lock, flags); driver->unbind(&dev->gadget); - device_del(&dev->gadget.dev); +// device_del(&dev->gadget.dev); disable_irq(IRQ_OTG); - printk("Unregistered gadget driver '%s'\n", driver->driver.name); +// printk("Unregistered gadget driver '%s'\n", driver->driver.name); udc_disable(dev); - +/* if (!IS_ERR(dev->regulator_a)) { regulator_disable(dev->regulator_a); regulator_put(dev->regulator_a); @@ -437,7 +439,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) regulator_put(dev->regulator_d); dev->regulator_d = NULL; } - +*/ return 0; } @@ -470,10 +472,28 @@ static void done(struct s3c_ep *ep, struct s3c_request *req, int status) /* don't modify queue heads during completion callback */ ep->stopped = 1; +#ifdef DEBUG_S3C_UDC + printf("calling complete callback\n"); + { + int i, len = req->req.length; + + printf("pkt[%d] = ", req->req.length); + if (len > 64) + len = 64; + for (i=0; ireq.buf)[i]); + if ((i & 7) == 7) + printf(" "); + } + printf("\n"); + } +#endif spin_unlock(&ep->dev->lock); req->req.complete(&ep->ep, &req->req); spin_lock(&ep->dev->lock); + DEBUG("callback completed\n"); + ep->stopped = stopped; } @@ -527,6 +547,8 @@ static void reconfig_usbd(void) int i; unsigned int uTemp = writel(CORE_SOFT_RESET, S3C_UDC_OTG_GRSTCTL); + DEBUG(2, "Reseting OTG controller\n"); + writel( 0<<15 /* PHY Low Power Clock sel*/ |1<<14 /* Non-Periodic TxFIFO Rewind Enable*/ |0x5<<10 /* Turnaround time*/ @@ -590,12 +612,14 @@ static void reconfig_usbd(void) /* Flush the RX FIFO */ writel(0x10, S3C_UDC_OTG_GRSTCTL); - while(readl(S3C_UDC_OTG_GRSTCTL) & 0x10); + while(readl(S3C_UDC_OTG_GRSTCTL) & 0x10) + DEBUG("%s: waiting for S3C_UDC_OTG_GRSTCTL\n", __FUNCTION__); /* Flush all the Tx FIFO's */ writel(0x10<<6, S3C_UDC_OTG_GRSTCTL); writel((0x10<<6)|0x20, S3C_UDC_OTG_GRSTCTL); - while(readl(S3C_UDC_OTG_GRSTCTL) & 0x20); + while(readl(S3C_UDC_OTG_GRSTCTL) & 0x20) + DEBUG("%s: waiting for S3C_UDC_OTG_GRSTCTL\n", __FUNCTION__); /* 13. Clear NAK bit of EP0, EP1, EP2*/ /* For Slave mode*/ @@ -860,10 +884,11 @@ static struct s3c_udc memory = { .ops = &s3c_udc_ops, .ep0 = &memory.ep[0].ep, .name = driver_name, - .dev = { +/* .dev = { .init_name = "gadget", .release = nop_release, }, +*/ }, /* control endpoint */ @@ -1099,21 +1124,18 @@ static struct s3c_udc memory = { /* * probe - binds to the platform device */ -static struct clk *otg_clock = NULL; -static int s3c_udc_probe(struct platform_device *pdev) +int s3c_udc_probe(struct s3c_plat_otg_data *pdata) { - struct resource *res; struct s3c_udc *dev = &memory; - int retval, i; + int retval=0, i; - DEBUG("%s: %p\n", __FUNCTION__, pdev); + DEBUG("%s: %p\n", __FUNCTION__, pdata); - spin_lock_init(&dev->lock); - dev->dev = pdev; + dev->pdata = pdata; - device_initialize(&dev->gadget.dev); - dev->gadget.dev.parent = &pdev->dev; + regs_phy = (void *)pdata->regs_phy; + regs_otg = (void*)pdata->regs_otg; dev->gadget.is_dualspeed = 1; /* Hack only*/ dev->gadget.is_otg = 0; @@ -1123,241 +1145,28 @@ static int s3c_udc_probe(struct platform_device *pdev) dev->gadget.a_alt_hnp_support = 0; the_controller = dev; - platform_set_drvdata(pdev, dev); - - otg_clock = clk_get(&pdev->dev, "otg"); - if (otg_clock == NULL) { - printk(KERN_INFO "failed to find otg clock source\n"); - return -ENOENT; - } - clk_enable(otg_clock); - /* basic endpoint records init */ for (i = 0; i < S3C_MAX_ENDPOINTS+1; i++) dev->dma_buf[i] = kmalloc(DMA_BUFFER_SIZE, GFP_KERNEL); usb_ctrl = dev->dma_buf[0]; - - printk(KERN_INFO "allocating resources\n"); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - printk(KERN_INFO "cannot find register resource 0\n"); - return -EINVAL; - } - - res_otg = request_mem_region(res->start, resource_size(res), - dev_name(&pdev->dev)); - if (!res_otg) { - printk(KERN_INFO "cannot reserve registers\n"); - return -ENOENT; - } - - regs_otg = ioremap(res->start, resource_size(res)); - if (!regs_otg) { - printk(KERN_INFO "cannot map registers\n"); - retval = -ENXIO; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (!res) { - printk(KERN_INFO "cannot find register resource 1\n"); - return -EINVAL; - } - - res_phy = request_mem_region(res->start, resource_size(res), - dev_name(&pdev->dev)); - if (!res_phy) { - printk(KERN_INFO "cannot reserve registers\n"); - return -ENOENT; - } - - regs_phy = ioremap(res->start, resource_size(res)); - if (!regs_phy) { - printk(KERN_INFO "cannot map registers\n"); - retval = -ENXIO; - } udc_reinit(dev); - local_irq_disable(); - - /* irq setup after old hardware state is cleaned up */ - retval = - request_irq(IRQ_OTG, s3c_udc_irq, 0, driver_name, dev); - - if (retval != 0) { - DEBUG(KERN_ERR "%s: can't get irq %i, err %d\n", driver_name, - IRQ_OTG, retval); - return -EBUSY; - } - - disable_irq(IRQ_OTG); - local_irq_enable(); - create_proc_files(); - return retval; } static int s3c_udc_remove(struct platform_device *pdev) { - struct s3c_udc *dev = platform_get_drvdata(pdev); - - DEBUG("%s: %p\n", __FUNCTION__, pdev); - - regulator_disable(dev->regulator_a); - regulator_disable(dev->regulator_d); - regulator_put(dev->regulator_a); - regulator_put(dev->regulator_d); - - if (otg_clock != NULL) { - clk_disable(otg_clock); - clk_put(otg_clock); - otg_clock = NULL; - } - - remove_proc_files(); - usb_gadget_unregister_driver(dev->driver); - - free_irq(IRQ_OTG, dev); - - platform_set_drvdata(pdev, 0); - - iounmap(regs_otg); - iounmap(regs_phy); - - release_mem_region(res_phy->start, resource_size(res_phy)); - release_mem_region(res_otg->start, resource_size(res_otg)); - the_controller = 0; - return 0; } -#ifdef CONFIG_PM -static int s3c_udc_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct s3c_udc *dev = platform_get_drvdata(pdev); - int i; - - if (dev->driver) { - if (dev->driver->suspend) - dev->driver->suspend(&dev->gadget); - - /* Terminate any outstanding requests */ - for (i = 0; i < S3C_MAX_ENDPOINTS; i++) { - struct s3c_ep *ep = &dev->ep[i]; - if ( ep->dev != NULL ) - spin_lock(&ep->dev->lock); - ep->stopped = 1; - nuke(ep, -ESHUTDOWN); - if ( ep->dev != NULL ) - spin_unlock(&ep->dev->lock); - } - - disable_irq(IRQ_OTG); - udc_disable(dev); - clk_disable(otg_clock); - - /* Workaround: can't find a regulator at probe time */ - if (!dev->regulator_a) { - dev->regulator_a = regulator_get(&pdev->dev, "vusb_a"); - if (IS_ERR(dev->regulator_a)) - dev->regulator_a = NULL; - else - regulator_enable(dev->regulator_a); - } - - if (!dev->regulator_d) { - dev->regulator_d = regulator_get(&pdev->dev, "vusb_d"); - if (IS_ERR(dev->regulator_d)) - dev->regulator_d = NULL; - else - regulator_enable(dev->regulator_d); - } - - if (dev->regulator_a && regulator_is_enabled(dev->regulator_a)) { - int ret = regulator_disable(dev->regulator_a); - if (ret) - return ret; - } - - if (dev->regulator_d && regulator_is_enabled(dev->regulator_d)) { - int ret = regulator_disable(dev->regulator_d); - if (ret) - return ret; - } - } - - return 0; -} - -static int s3c_udc_resume(struct platform_device *pdev) -{ - struct s3c_udc *dev = platform_get_drvdata(pdev); - - if (dev->driver) { - if (dev->regulator_d) { - int ret = regulator_enable(dev->regulator_d); - if (ret) - return ret; - } - - if (dev->regulator_a) { - int ret = regulator_enable(dev->regulator_a); - if (ret) - return ret; - } - - clk_enable(otg_clock); - udc_reinit(dev); - enable_irq(IRQ_OTG); - udc_enable(dev); - - if (dev->driver->resume) - dev->driver->resume(&dev->gadget); - } - - return 0; -} -#else -#define s3c_udc_suspend NULL -#define s3c_udc_resume NULL -#endif /* CONFIG_PM */ - -/*-------------------------------------------------------------------------*/ -static struct platform_driver s3c_udc_driver = { - .probe = s3c_udc_probe, - .remove = s3c_udc_remove, - .suspend = s3c_udc_suspend, - .resume = s3c_udc_resume, - .driver = { - .owner = THIS_MODULE, - .name = "s3c-otg", - }, -}; - -static int __init udc_init(void) +int usb_gadget_handle_interrupts() { - int ret; - - ret = platform_driver_register(&s3c_udc_driver); - if(!ret) - printk("%s : %s\n" - "%s : version %s %s \n", - driver_name, DRIVER_DESC, - driver_name, DRIVER_VERSION, OTG_DMA_MODE? "(DMA Mode)" : "(Slave Mode)"); - - return ret; -} + u32 intr_status = readl(S3C_UDC_OTG_GINTSTS); + u32 gintmsk = readl(S3C_UDC_OTG_GINTMSK); -static void __exit udc_exit(void) -{ - platform_driver_unregister(&s3c_udc_driver); - printk("Unloaded %s version %s\n", driver_name, DRIVER_VERSION); + if (intr_status & gintmsk) + return s3c_udc_irq(1, (void*)the_controller); + return 0; } - -module_init(udc_init); -module_exit(udc_exit); - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_AUTHOR("Samsung"); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/gadget/s3c_udc_otg_xfer_dma.c b/drivers/usb/gadget/s3c_udc_otg_xfer_dma.c index eaca2bd..95c6015 100644 --- a/drivers/usb/gadget/s3c_udc_otg_xfer_dma.c +++ b/drivers/usb/gadget/s3c_udc_otg_xfer_dma.c @@ -77,6 +77,15 @@ static inline void s3c_udc_pre_setup(void) ep_ctrl = readl(S3C_UDC_OTG_DOEPCTL(EP0_CON)); writel(ep_ctrl|DEPCTL_EPENA|DEPCTL_CNAK, S3C_UDC_OTG_DOEPCTL(EP0_CON)); + + DEBUG_OUT_EP("%s: EP%d RX DMA start : DOEPDMA = 0x%x, DOEPTSIZ = 0x%x, DOEPCTL = 0x%x\n" + "\tbuf = 0x%p, pktcnt = %d, xfersize = %d\n", + __func__, 0, + readl(S3C_UDC_OTG_DOEPDMA(0)), + readl(S3C_UDC_OTG_DOEPTSIZ(0)), + readl(S3C_UDC_OTG_DOEPCTL(0)), + usb_ctrl, 1, sizeof(*usb_ctrl)); + } static int setdma_rx(struct s3c_ep *ep, struct s3c_request *req) @@ -511,7 +520,7 @@ static int s3c_queue(struct usb_ep *_ep, struct usb_request *_req, if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) { - DEBUG("%s: bad ep\n", __func__); + DEBUG("%s: bad ep: %s, %d, %x\n", __func__, ep->ep.name, !ep->desc, _ep); return -EINVAL; } @@ -535,6 +544,22 @@ static int s3c_queue(struct usb_ep *_ep, struct usb_request *_req, _req, _req->length,_req->buf, list_empty(&ep->queue), ep->stopped); +#ifdef DEBUG_S3C_UDC + { + int i, len = _req->length; + + printf("pkt = "); + if (len > 64) + len = 64; + for (i=0; ibuf)[i]); + if ((i & 7) == 7) + printf(" "); + } + printf("\n"); + } +#endif + if (list_empty(&ep->queue) && !ep->stopped) { if (ep_num == 0) { diff --git a/include/asm-arm/arch-s5pc1xx/hs_otg.h b/include/asm-arm/arch-s5pc1xx/hs_otg.h new file mode 100644 index 0000000..d68db04 --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/hs_otg.h @@ -0,0 +1,32 @@ +/* + * (C) Copyright 2009 SAMSUNG Electronics + * Minkyu Kang + * + * 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 __ASM_ARCH_HSOTG_H_ +#define __ASM_ARCH_HSOTG_H_ + +#ifndef __ASSEMBLY__ +struct s3c_plat_otg_data { + int (*phy_control)(int on); + unsigned int regs_phy; + unsigned int regs_otg; +}; + +#endif /* __ASSEMBLY__ */ +#endif diff --git a/include/asm-arm/arch-s5pc1xx/regs-otg.h b/include/asm-arm/arch-s5pc1xx/regs-otg.h new file mode 100644 index 0000000..72769c4 --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/regs-otg.h @@ -0,0 +1,264 @@ +/* linux/arch/arm/plat-s3c/include/plat/regs-otg.h + * + * Copyright (C) 2004 Herbert Poetzl + * + * This include file 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. +*/ + +#ifndef __ASM_ARCH_REGS_USB_OTG_HS_H +#define __ASM_ARCH_REGS_USB_OTG_HS_H + +/* + * USB2.0 HS OTG + */ +#define S5PC100_OTG_BASE 0xED200000 +#define S5PC100_PHY_BASE 0xED300000 + +#define S5PC110_OTG_BASE 0xEC000000 +#define S5PC110_PHY_BASE 0xEC100000 + +/* USB2.0 OTG Controller register */ +#define S3C_USBOTG_PHYREG(x) (((u32)regs_phy) + (x)) +#define S3C_USBOTG_PHYPWR S3C_USBOTG_PHYREG(0x0) +#define S3C_USBOTG_PHYCLK S3C_USBOTG_PHYREG(0x4) +#define S3C_USBOTG_RSTCON S3C_USBOTG_PHYREG(0x8) + + +/* USB2.0 OTG Controller register */ +#define S3C_USBOTGREG(x) (((u32)regs_otg) + (x)) +/*============================================================================================== */ + /* Core Global Registers */ +#define S3C_UDC_OTG_GOTGCTL S3C_USBOTGREG(0x000) /* OTG Control & Status */ +#define S3C_UDC_OTG_GOTGINT S3C_USBOTGREG(0x004) /* OTG Interrupt */ +#define S3C_UDC_OTG_GAHBCFG S3C_USBOTGREG(0x008) /* Core AHB Configuration */ +#define S3C_UDC_OTG_GUSBCFG S3C_USBOTGREG(0x00C) /* Core USB Configuration */ +#define S3C_UDC_OTG_GRSTCTL S3C_USBOTGREG(0x010) /* Core Reset */ +#define S3C_UDC_OTG_GINTSTS S3C_USBOTGREG(0x014) /* Core Interrupt */ +#define S3C_UDC_OTG_GINTMSK S3C_USBOTGREG(0x018) /* Core Interrupt Mask */ +#define S3C_UDC_OTG_GRXSTSR S3C_USBOTGREG(0x01C) /* Receive Status Debug Read/Status Read */ +#define S3C_UDC_OTG_GRXSTSP S3C_USBOTGREG(0x020) /* Receive Status Debug Pop/Status Pop */ +#define S3C_UDC_OTG_GRXFSIZ S3C_USBOTGREG(0x024) /* Receive FIFO Size */ +#define S3C_UDC_OTG_GNPTXFSIZ S3C_USBOTGREG(0x028) /* Non-Periodic Transmit FIFO Size */ +#define S3C_UDC_OTG_GNPTXSTS S3C_USBOTGREG(0x02C) /* Non-Periodic Transmit FIFO/Queue Status */ + +#define S3C_UDC_OTG_HPTXFSIZ S3C_USBOTGREG(0x100) /* Host Periodic Transmit FIFO Size */ +#define S3C_UDC_OTG_DIEPTXF(n) S3C_USBOTGREG(0x104 + ((n)-1)*0x4)/* Device IN EP Transmit FIFO Size Register */ + +/*============================================================================================== */ +/* Host Mode Registers */ +/*------------------------------------------------ */ +/* Host Global Registers */ +#define S3C_UDC_OTG_HCFG S3C_USBOTGREG(0x400) /* Host Configuration */ +#define S3C_UDC_OTG_HFIR S3C_USBOTGREG(0x404) /* Host Frame Interval */ +#define S3C_UDC_OTG_HFNUM S3C_USBOTGREG(0x408) /* Host Frame Number/Frame Time Remaining */ +#define S3C_UDC_OTG_HPTXSTS S3C_USBOTGREG(0x410) /* Host Periodic Transmit FIFO/Queue Status */ +#define S3C_UDC_OTG_HAINT S3C_USBOTGREG(0x414) /* Host All Channels Interrupt */ +#define S3C_UDC_OTG_HAINTMSK S3C_USBOTGREG(0x418) /* Host All Channels Interrupt Mask */ + +/*------------------------------------------------ */ +/* Host Port Control & Status Registers */ +#define S3C_UDC_OTG_HPRT S3C_USBOTGREG(0x440) /* Host Port Control & Status */ + +/*------------------------------------------------ */ +/* Host Channel-Specific Registers */ +#define S3C_UDC_OTG_HCCHAR0 S3C_USBOTGREG(0x500) /* Host Channel-0 Characteristics */ +#define S3C_UDC_OTG_HCSPLT0 S3C_USBOTGREG(0x504) /* Host Channel-0 Split Control */ +#define S3C_UDC_OTG_HCINT0 S3C_USBOTGREG(0x508) /* Host Channel-0 Interrupt */ +#define S3C_UDC_OTG_HCINTMSK0 S3C_USBOTGREG(0x50C) /* Host Channel-0 Interrupt Mask */ +#define S3C_UDC_OTG_HCTSIZ0 S3C_USBOTGREG(0x510) /* Host Channel-0 Transfer Size */ +#define S3C_UDC_OTG_HCDMA0 S3C_USBOTGREG(0x514) /* Host Channel-0 DMA Address */ + + +/*============================================================================================== */ +/* Device Mode Registers */ +/*------------------------------------------------ */ +/* Device Global Registers */ +#define S3C_UDC_OTG_DCFG S3C_USBOTGREG(0x800) /* Device Configuration */ +#define S3C_UDC_OTG_DCTL S3C_USBOTGREG(0x804) /* Device Control */ +#define S3C_UDC_OTG_DSTS S3C_USBOTGREG(0x808) /* Device Status */ +#define S3C_UDC_OTG_DIEPMSK S3C_USBOTGREG(0x810) /* Device IN Endpoint Common Interrupt Mask */ +#define S3C_UDC_OTG_DOEPMSK S3C_USBOTGREG(0x814) /* Device OUT Endpoint Common Interrupt Mask */ +#define S3C_UDC_OTG_DAINT S3C_USBOTGREG(0x818) /* Device All Endpoints Interrupt */ +#define S3C_UDC_OTG_DAINTMSK S3C_USBOTGREG(0x81C) /* Device All Endpoints Interrupt Mask */ +#define S3C_UDC_OTG_DTKNQR1 S3C_USBOTGREG(0x820) /* Device IN Token Sequence Learning Queue Read 1 */ +#define S3C_UDC_OTG_DTKNQR2 S3C_USBOTGREG(0x824) /* Device IN Token Sequence Learning Queue Read 2 */ +#define S3C_UDC_OTG_DVBUSDIS S3C_USBOTGREG(0x828) /* Device VBUS Discharge Time */ +#define S3C_UDC_OTG_DVBUSPULSE S3C_USBOTGREG(0x82C) /* Device VBUS Pulsing Time */ +#define S3C_UDC_OTG_DTKNQR3 S3C_USBOTGREG(0x830) /* Device IN Token Sequence Learning Queue Read 3 */ +#define S3C_UDC_OTG_DTKNQR4 S3C_USBOTGREG(0x834) /* Device IN Token Sequence Learning Queue Read 4 */ + +/*------------------------------------------------ */ +/* Device Logical IN Endpoint-Specific Registers */ +#define S3C_UDC_OTG_DIEPCTL(n) S3C_USBOTGREG(0x900 + n*0x20) /* Device IN Endpoint n Control */ +#define S3C_UDC_OTG_DIEPINT(n) S3C_USBOTGREG(0x908 + n*0x20) /* Device IN Endpoint n Interrupt */ +#define S3C_UDC_OTG_DIEPTSIZ(n) S3C_USBOTGREG(0x910 + n*0x20) /* Device IN Endpoint n Transfer Size */ +#define S3C_UDC_OTG_DIEPDMA(n) S3C_USBOTGREG(0x914 + n*0x20) /* Device IN Endpoint n DMA Address */ + +/*------------------------------------------------ */ +/* Device Logical OUT Endpoint-Specific Registers */ +#define S3C_UDC_OTG_DOEPCTL(n) S3C_USBOTGREG(0xB00 + n*0x20) /* Device OUT Endpoint n Control */ +#define S3C_UDC_OTG_DOEPINT(n) S3C_USBOTGREG(0xB08 + n*0x20) /* Device OUT Endpoint n Interrupt */ +#define S3C_UDC_OTG_DOEPTSIZ(n) S3C_USBOTGREG(0xB10 + n*0x20) /* Device OUT Endpoint n Transfer Size */ +#define S3C_UDC_OTG_DOEPDMA(n) S3C_USBOTGREG(0xB14 + n*0x20) /* Device OUT Endpoint n DMA Address */ + +/*------------------------------------------------ */ +/* Endpoint FIFO address */ +#define S3C_UDC_OTG_EP0_FIFO S3C_USBOTGREG(0x1000) +#define S3C_UDC_OTG_EP1_FIFO S3C_USBOTGREG(0x2000) +#define S3C_UDC_OTG_EP2_FIFO S3C_USBOTGREG(0x3000) +#define S3C_UDC_OTG_EP3_FIFO S3C_USBOTGREG(0x4000) +#define S3C_UDC_OTG_EP4_FIFO S3C_USBOTGREG(0x5000) +#define S3C_UDC_OTG_EP5_FIFO S3C_USBOTGREG(0x6000) +#define S3C_UDC_OTG_EP6_FIFO S3C_USBOTGREG(0x7000) +#define S3C_UDC_OTG_EP7_FIFO S3C_USBOTGREG(0x8000) +#define S3C_UDC_OTG_EP8_FIFO S3C_USBOTGREG(0x9000) +#define S3C_UDC_OTG_EP9_FIFO S3C_USBOTGREG(0xA000) +#define S3C_UDC_OTG_EP10_FIFO S3C_USBOTGREG(0xB000) +#define S3C_UDC_OTG_EP11_FIFO S3C_USBOTGREG(0xC000) +#define S3C_UDC_OTG_EP12_FIFO S3C_USBOTGREG(0xD000) +#define S3C_UDC_OTG_EP13_FIFO S3C_USBOTGREG(0xE000) +#define S3C_UDC_OTG_EP14_FIFO S3C_USBOTGREG(0xF000) +#define S3C_UDC_OTG_EP15_FIFO S3C_USBOTGREG(0x10000) + +/*===================================================================== */ +/*definitions related to CSR setting */ + +/* S3C_UDC_OTG_GOTGCTL */ +#define B_SESSION_VALID (0x1<<19) +#define A_SESSION_VALID (0x1<<18) + +/* S3C_UDC_OTG_GAHBCFG */ +#define PTXFE_HALF (0<<8) +#define PTXFE_ZERO (1<<8) +#define NPTXFE_HALF (0<<7) +#define NPTXFE_ZERO (1<<7) +#define MODE_SLAVE (0<<5) +#define MODE_DMA (1<<5) +#define BURST_SINGLE (0<<1) +#define BURST_INCR (1<<1) +#define BURST_INCR4 (3<<1) +#define BURST_INCR8 (5<<1) +#define BURST_INCR16 (7<<1) +#define GBL_INT_UNMASK (1<<0) +#define GBL_INT_MASK (0<<0) + +/* S3C_UDC_OTG_GRSTCTL */ +#define AHB_MASTER_IDLE (1u<<31) +#define CORE_SOFT_RESET (0x1<<0) + +/* S3C_UDC_OTG_GINTSTS/S3C_UDC_OTG_GINTMSK core interrupt register */ +#define INT_RESUME (1u<<31) +#define INT_DISCONN (0x1<<29) +#define INT_CONN_ID_STS_CNG (0x1<<28) +#define INT_OUT_EP (0x1<<19) +#define INT_IN_EP (0x1<<18) +#define INT_ENUMDONE (0x1<<13) +#define INT_RESET (0x1<<12) +#define INT_SUSPEND (0x1<<11) +#define INT_EARLY_SUSPEND (0x1<<10) +#define INT_NP_TX_FIFO_EMPTY (0x1<<5) +#define INT_RX_FIFO_NOT_EMPTY (0x1<<4) +#define INT_SOF (0x1<<3) +#define INT_DEV_MODE (0x0<<0) +#define INT_HOST_MODE (0x1<<1) +#define INT_GOUTNakEff (0x01<<7) +#define INT_GINNakEff (0x01<<6) + +#define FULL_SPEED_CONTROL_PKT_SIZE 8 +#define FULL_SPEED_BULK_PKT_SIZE 64 + +#define HIGH_SPEED_CONTROL_PKT_SIZE 64 +#define HIGH_SPEED_BULK_PKT_SIZE 512 + +#define RX_FIFO_SIZE (1024*4) +#define NPTX_FIFO_SIZE (1024*4) +#define PTX_FIFO_SIZE (1536*1) + +#define DEPCTL_TXFNUM_0 (0x0<<22) +#define DEPCTL_TXFNUM_1 (0x1<<22) +#define DEPCTL_TXFNUM_2 (0x2<<22) +#define DEPCTL_TXFNUM_3 (0x3<<22) +#define DEPCTL_TXFNUM_4 (0x4<<22) + +/* Enumeration speed */ +#define USB_HIGH_30_60MHZ (0x0<<1) +#define USB_FULL_30_60MHZ (0x1<<1) +#define USB_LOW_6MHZ (0x2<<1) +#define USB_FULL_48MHZ (0x3<<1) + +/* S3C_UDC_OTG_GRXSTSP STATUS */ +#define OUT_PKT_RECEIVED (0x2<<17) +#define OUT_TRANSFER_COMPLELTED (0x3<<17) +#define SETUP_TRANSACTION_COMPLETED (0x4<<17) +#define SETUP_PKT_RECEIVED (0x6<<17) +#define GLOBAL_OUT_NAK (0x1<<17) + +/* S3C_UDC_OTG_DCTL device control register */ +#define NORMAL_OPERATION (0x1<<0) +#define SOFT_DISCONNECT (0x1<<1) +#define TEST_CONTROL_MASK (0x7<<4) +#define TEST_J_MODE (0x1<<4) +#define TEST_K_MODE (0x2<<4) +#define TEST_SE0_NAK_MODE (0x3<<4) +#define TEST_PACKET_MODE (0x4<<4) +#define TEST_FORCE_ENABLE_MODE (0x5<<4) + +/* S3C_UDC_OTG_DAINT device all endpoint interrupt register */ +#define DAINT_OUT_BIT (16) +#define DAINT_MASK (0xFFFF) + +/* S3C_UDC_OTG_DIEPCTL0/DOEPCTL0 device control IN/OUT endpoint 0 control register */ +#define DEPCTL_EPENA (0x1<<31) +#define DEPCTL_EPDIS (0x1<<30) +#define DEPCTL_SETD1PID (0x1<<29) +#define DEPCTL_SETD0PID (0x1<<28) +#define DEPCTL_SNAK (0x1<<27) +#define DEPCTL_CNAK (0x1<<26) +#define DEPCTL_STALL (0x1<<21) +#define DEPCTL_TYPE_BIT (18) +#define DEPCTL_TYPE_MASK (0x3<<18) +#define DEPCTL_CTRL_TYPE (0x0<<18) +#define DEPCTL_ISO_TYPE (0x1<<18) +#define DEPCTL_BULK_TYPE (0x2<<18) +#define DEPCTL_INTR_TYPE (0x3<<18) +#define DEPCTL_USBACTEP (0x1<<15) +#define DEPCTL_NEXT_EP_BIT (11) +#define DEPCTL_MPS_BIT (0) +#define DEPCTL_MPS_MASK (0x7FF) + +#define DEPCTL0_MPS_64 (0x0<<0) +#define DEPCTL0_MPS_32 (0x1<<0) +#define DEPCTL0_MPS_16 (0x2<<0) +#define DEPCTL0_MPS_8 (0x3<<0) +#define DEPCTL_MPS_BULK_512 (512<<0) +#define DEPCTL_MPS_INT_MPS_16 (16<<0) + +#define DIEPCTL0_NEXT_EP_BIT (11) + +/* S3C_UDC_OTG_DIEPCTLn/DOEPCTLn device control IN/OUT endpoint n control register */ + +/* S3C_UDC_OTG_DIEPMSK/DOEPMSK device IN/OUT endpoint common interrupt mask register */ +/* S3C_UDC_OTG_DIEPINTn/DOEPINTn device IN/OUT endpoint interrupt register */ +#define BACK2BACK_SETUP_RECEIVED (0x1<<6) +#define INTKNEPMIS (0x1<<5) +#define INTKN_TXFEMP (0x1<<4) +#define NON_ISO_IN_EP_TIMEOUT (0x1<<3) +#define CTRL_OUT_EP_SETUP_PHASE_DONE (0x1<<3) +#define AHB_ERROR (0x1<<2) +#define EPDISBLD (0x1<<1) +#define TRANSFER_DONE (0x1<<0) + +/*DIEPTSIZ0 / DOEPTSIZ0 */ + +/* DEPTSIZ common bit */ +#define DEPTSIZ_PKT_CNT_BIT (19) +#define DEPTSIZ_XFER_SIZE_BIT (0) + +#define DEPTSIZ_SETUP_PKCNT_1 (1<<29) +#define DEPTSIZ_SETUP_PKCNT_2 (2<<29) +#define DEPTSIZ_SETUP_PKCNT_3 (3<<29) + +#endif diff --git a/include/configs/s5pc1xx_universal.h b/include/configs/s5pc1xx_universal.h index 0c693a1..453d7da 100644 --- a/include/configs/s5pc1xx_universal.h +++ b/include/configs/s5pc1xx_universal.h @@ -110,7 +110,6 @@ #undef CONFIG_CMD_IMLS #undef CONFIG_CMD_FLASH #undef CONFIG_CMD_IMLS -#undef CONFIG_CMD_NET #define CONFIG_CMD_CACHE #define CONFIG_CMD_REGINFO #define CONFIG_CMD_ONENAND @@ -124,15 +123,35 @@ #define CONFIG_SYS_64BIT_VSPRINTF 1 -#define CONFIG_BOOTDELAY 1 +#define CONFIG_BOOTDELAY 10 #define CONFIG_ZERO_BOOTDELAY_CHECK +/* Ethernet */ +#define CONFIG_NET_MULTI 1 +#define CONFIG_NET_RETRY_COUNT 2 +#define CONFIG_NET_DO_NOT_TRY_ANOTHER 1 + +/* Configure Ethernet over USB */ +/*#define CONFIG_USB_ETH_RNDIS 1*/ +#define CONFIG_USB_GADGET 1 +#define CONFIG_USB_GADGET_S3C_UDC_OTG 1 +#define CONFIG_USB_GADGET_DUALSPEED 1 +#define CONFIG_USB_ETHER 1 +#define CONFIG_USBNET_MANUFACTURER "S5PC1xx U-Boot" +/* ethaddr settings can be overruled via environment settings */ +#define CONFIG_USBNET_DEV_ADDR "8e:28:0f:fa:3c:39" +#define CONFIG_USBNET_HOST_ADDR "0a:fa:63:8b:e8:0a" +#define CONFIG_USB_CDC_VENDOR_ID 0x0525 +#define CONFIG_USB_CDC_PRODUCT_ID 0xa4a1 +#define CONFIG_USB_RNDIS_VENDOR_ID 0x0525 +#define CONFIG_USB_RNDIS_PRODUCT_ID 0xa4a2 + #define CONFIG_NETMASK 255.255.255.0 #define CONFIG_IPADDR 192.168.129.3 #define CONFIG_SERVERIP 192.168.129.1 #define CONFIG_GATEWAYIP 192.168.129.1 -#define CONFIG_ETHADDR 00:0E:99:34:10:00 +#define CONFIG_ETHADDR 8e:28:0f:fa:3c:39 #define CONFIG_MTD_DEVICE #define CONFIG_MTD_PARTITIONS @@ -196,6 +215,9 @@ "ubifsboot=set bootargs root=ubi0!rootfs rootfstype=ubifs " \ CONFIG_UBIFS_OPTION CONFIG_UBI_MTD " ${opts} ${lcdinfo} " \ CONFIG_COMMON_BOOT "; run bootk\0" \ + "tftpboot=set bootargs root=ubi0!rootfs rootfstype=ubifs " \ + CONFIG_UBIFS_OPTION CONFIG_UBI_MTD " ${opts} ${lcdinfo} " \ + CONFIG_COMMON_BOOT "; tftp 0x30007FC0 uImage; bootm 0x30007FC0\0" \ "boottrace=setenv opts initcall_debug; run bootcmd\0" \ "android=set bootargs root=ubi0!ramdisk " CONFIG_UBI_MTD \ " rootfstype=ubifs init=/init.sh " CONFIG_COMMON_BOOT "; run bootk\0" \ -- 2.7.4