r667 - trunk/src/target/u-boot/patches

laforge at sita.openmoko.org laforge at sita.openmoko.org
Sun Feb 4 22:23:24 CET 2007


Author: laforge
Date: 2007-02-04 22:23:23 +0100 (Sun, 04 Feb 2007)
New Revision: 667

Added:
   trunk/src/target/u-boot/patches/uboot-s3c2410_udc.patch
Modified:
   trunk/src/target/u-boot/patches/series
Log:
add initial version of s3c2410 udc driver for u-boot.  This just implements the
USB control pipe so far.  It enumerates, etc. - but doesn't give you actual tty access [yet]


Modified: trunk/src/target/u-boot/patches/series
===================================================================
--- trunk/src/target/u-boot/patches/series	2007-02-04 19:25:27 UTC (rev 666)
+++ trunk/src/target/u-boot/patches/series	2007-02-04 21:23:23 UTC (rev 667)
@@ -9,3 +9,7 @@
 nand-read_write_oob.patch
 env_nand_oob.patch
 nand-dynamic_partitions.patch
+uboot-arm920_s3c2410_irq_demux.patch
+uboot-s3c2410-norelocate_irqvec_cpy.patch
+uboot-usbtty-acm.patch
+uboot-s3c2410_udc.patch

Added: trunk/src/target/u-boot/patches/uboot-s3c2410_udc.patch
===================================================================
--- trunk/src/target/u-boot/patches/uboot-s3c2410_udc.patch	2007-02-04 19:25:27 UTC (rev 666)
+++ trunk/src/target/u-boot/patches/uboot-s3c2410_udc.patch	2007-02-04 21:23:23 UTC (rev 667)
@@ -0,0 +1,1239 @@
+USB Device Controller Driver for Samsung S3C2410 SoC
+
+Index: u-boot.git/drivers/Makefile
+===================================================================
+--- u-boot.git.orig/drivers/Makefile	2007-02-04 20:00:53.000000000 +0100
++++ u-boot.git/drivers/Makefile	2007-02-04 20:01:43.000000000 +0100
+@@ -46,7 +46,7 @@
+ 	  sl811_usb.o sm501.o smc91111.o smiLynxEM.o \
+ 	  status_led.o sym53c8xx.o ahci.o \
+ 	  ti_pci1410a.o tigon3.o tsec.o \
+-	  usbdcore.o usbdcore_ep0.o usbdcore_omap1510.o usbtty.o \
++	  usbdcore.o usbdcore_ep0.o usbdcore_omap1510.o usbdcore_s3c2410.o usbtty.o \
+ 	  videomodes.o w83c553f.o \
+ 	  ks8695eth.o \
+ 	  pxa_pcmcia.o mpc8xx_pcmcia.o tqm8xx_pcmcia.o	\
+Index: u-boot.git/drivers/usbdcore_s3c2410.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ u-boot.git/drivers/usbdcore_s3c2410.c	2007-02-04 22:04:04.000000000 +0100
+@@ -0,0 +1,759 @@
++/* S3C2410 USB Device Controller Driver for u-boot
++ *
++ * (C) Copyright 2007 by OpenMoko, Inc.
++ * Author: Harald Welte <laforge at openmoko.org>
++ *
++ * based on u-boot's udc_omap1510.c and linux' s3c2410_udc.c
++ *
++ * 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>
++
++#if defined(CONFIG_S3C2410) && defined(CONFIG_USB_DEVICE)
++
++#include <asm/io.h>
++#include <s3c2410.h>
++
++#include "usbdcore.h"
++#include "usbdcore_s3c2410.h"
++#include "usbdcore_ep0.h"
++
++
++/* Some kind of debugging output... */
++#if 1
++#define UDCDBG(str)
++#define UDCDBGA(fmt,args...)
++#else  /* The bugs still exists... */
++#define UDCDBG(str) serial_printf("[%s] %s:%d: " str "\n", __FILE__,__FUNCTION__,__LINE__)
++#define UDCDBGA(fmt,args...) serial_printf("[%s] %s:%d: " fmt "\n", __FILE__,__FUNCTION__,__LINE__, ##args)
++#endif
++
++enum ep0_state {
++        EP0_IDLE,
++        EP0_IN_DATA_PHASE,
++        EP0_OUT_DATA_PHASE,
++        EP0_END_XFER,
++        EP0_STALL,
++};
++
++static struct urb *ep0_urb = NULL;
++
++static struct usb_device_instance *udc_device;	/* Used in interrupt handler */
++static u16 udc_devstat = 0;	/* UDC status (DEVSTAT) */
++static u32 udc_interrupts = 0;
++
++static void udc_stall_ep (unsigned int ep_addr);
++
++static struct usb_endpoint_instance *s3c2410_find_ep (int ep)
++{
++	int i;
++
++	for (i = 0; i < udc_device->bus->max_endpoints; i++) {
++		if (udc_device->bus->endpoint_array[i].endpoint_address == ep)
++			return &udc_device->bus->endpoint_array[i];
++	}
++	return NULL;
++}
++
++/* ************************************************************************** */
++/* IO
++ */
++
++static inline int fifo_count_out(void)
++{
++	int tmp;
++
++	tmp = inl(S3C2410_UDC_OUT_FIFO_CNT2_REG) << 8;
++	tmp |= inl(S3C2410_UDC_OUT_FIFO_CNT1_REG);
++
++	return tmp & 0xffff;
++}
++
++static const unsigned long ep_fifo_reg[S3C2410_UDC_NUM_ENDPOINTS] = {
++	S3C2410_UDC_EP0_FIFO_REG,
++	S3C2410_UDC_EP1_FIFO_REG,
++	S3C2410_UDC_EP2_FIFO_REG,
++	S3C2410_UDC_EP3_FIFO_REG,
++	S3C2410_UDC_EP4_FIFO_REG,
++};
++
++static int s3c2410_write_noniso_tx_fifo(struct usb_endpoint_instance *endpoint)
++{
++	struct urb *urb = endpoint->tx_urb;
++	unsigned int last, i;
++	unsigned int ep = endpoint->endpoint_address & 0x7f;
++	unsigned long fifo_reg = ep_fifo_reg[ep];
++
++#if 1
++	UDCDBGA("write_noniso_tx_fifo(ep=%d, fifo_reg=0x%x, len=%d, sent=%d, last=%d",
++		ep, fifo_reg, urb->actual_length, endpoint->sent, endpoint->last);
++#endif
++
++	if (!urb || ep >= S3C2410_UDC_NUM_ENDPOINTS) {
++		serial_printf("no urb or wrong endpoint\n");
++		return -1;
++	}
++
++	S3C2410_UDC_SETIX(ep);
++	if ((last = MIN(urb->actual_length - endpoint->sent,
++		        endpoint->tx_packetSize))) {
++		u8 *cp = urb->buffer + endpoint->sent;
++
++		for (i = 0; i < last; i++)
++			outb(*(cp+i), fifo_reg);
++	}
++	endpoint->last = last;
++
++	if (endpoint->sent + last < urb->actual_length) {
++		//serial_putc('I');
++		//UDCDBG("INCOMPLETE");
++		return 0;
++	}
++
++	if (last == endpoint->tx_packetSize) {
++		/* we need to send one more packet (ZLP) */
++		//serial_putc('Z');
++		//UDCDBG("zero-pending");
++		return 0;
++	}
++
++	//serial_putc('C');
++	//UDCDBG("complete");
++	return 1;
++}
++
++
++static void s3c2410_deconfigure_device (void)
++{
++#if 0
++	int epnum;
++
++	UDCDBG ("clear Cfg_Lock");
++	outw (inw (UDC_SYSCON1) & ~UDC_Cfg_Lock, UDC_SYSCON1);
++	UDCREG (UDC_SYSCON1);
++
++	/* deconfigure all endpoints */
++	for (epnum = 1; epnum <= 15; epnum++) {
++		outw (0, UDC_EP_RX (epnum));
++		outw (0, UDC_EP_TX (epnum));
++	}
++#endif
++}
++
++static void s3c2410_configure_device (struct usb_device_instance *device)
++{
++	S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++	S3C24X0_CLOCK_POWER * const cpower = S3C24X0_GetBase_CLOCK_POWER();
++
++	/* disable EP0-4 SUBD interrupts ? */
++	outl(0x00, S3C2410_UDC_USB_INT_EN_REG);
++
++	/* UPLL already configured by board-level init code */
++
++	/* configure USB pads to device mode */
++	gpio->MISCCR &= ~(S3C2410_MISCCR_USBHOST|S3C2410_MISCCR_USBSUSPND1);
++
++	/* don't disable USB clock */
++	cpower->CLKSLOW &= ~S3C2410_CLKSLOW_UCLK_OFF;
++
++	/* clear interrupt registers */
++	inl(S3C2410_UDC_EP_INT_REG);
++	inl(S3C2410_UDC_USB_INT_REG);
++	outl(0xff, S3C2410_UDC_EP_INT_REG);
++	outl(0xff, S3C2410_UDC_USB_INT_REG);
++
++	/* enable USB interrupts for RESET and SUSPEND/RESUME */
++	outl(S3C2410_UDC_USBINT_RESET|S3C2410_UDC_USBINT_SUSPEND,
++	     S3C2410_UDC_USB_INT_EN_REG);
++}
++
++static void udc_set_address(unsigned char address)
++{
++	address |= 0x80; /* ADDR_UPDATE bit */
++	outl(address, S3C2410_UDC_FUNC_ADDR_REG);
++}
++
++extern struct usb_device_descriptor device_descriptor;
++
++static void s3c2410_udc_ep0(void)
++{
++	u_int8_t ep0csr;
++	struct usb_endpoint_instance *ep0 = udc_device->bus->endpoint_array;
++
++	S3C2410_UDC_SETIX(0);
++	ep0csr = inl(S3C2410_UDC_IN_CSR1_REG);
++
++	UDCDBGA("-> Entering EP0 handler, EP0_CSR=0x%x, EP0_state=%u", ep0csr,
++		ep0->state);
++
++	/* clear stall status */
++	if (ep0csr & S3C2410_UDC_EP0_CSR_SENTSTL) {
++	    	UDCDBG("Clearing SENT_STALL");
++		clear_ep0_sst();
++		ep0->state = EP0_IDLE;
++		return;
++	}
++
++	/* clear setup end */
++	if (ep0csr & S3C2410_UDC_EP0_CSR_SE
++	    /* && ep0->state != EP0_IDLE */) {
++	    	UDCDBG("Clearing SETUP_END");
++		clear_ep0_se();
++		ep0->state = EP0_IDLE;
++		return;
++	}
++
++	switch (ep0->state) {
++	case EP0_IDLE:
++		if (ep0csr & S3C2410_UDC_EP0_CSR_OPKRDY) {
++			int fifo_count;
++			unsigned char *datap = (unsigned char *) &ep0_urb->device_request;
++			/* host->device packet has been received */
++
++			/* pull it out of the fifo */
++			fifo_count = fifo_count_out();
++			if (fifo_count != 8) {
++				UDCDBGA("STRANGE FIFO COUNT: %u bytes", fifo_count);
++				set_ep0_ss();
++				return;
++			}
++
++			while (fifo_count--) {
++				*datap = (unsigned char)inl(S3C2410_UDC_EP0_FIFO_REG);
++				datap++;
++			}
++
++			if (ep0_recv_setup(ep0_urb)) {
++				/* Not a setup packet, stall next EP0 transaction */
++				UDCDBG("can't parse setup packet, still waiting for setup");
++				set_ep0_ss();
++				return;
++			}
++
++			/* There are two requests with which we need to deal manually here */
++			switch (ep0_urb->device_request.bRequest) {
++			case USB_REQ_SET_CONFIGURATION:
++				if (!ep0_urb->device_request.wValue)
++					usbd_device_event_irq (udc_device, DEVICE_DE_CONFIGURED, 0);
++				else
++					usbd_device_event_irq (udc_device, DEVICE_CONFIGURED, 0);
++				break;
++			case USB_REQ_SET_ADDRESS:
++				udc_set_address(udc_device->address);
++				break;
++			}
++
++			/* check whether we need to write/read */
++			if ((ep0_urb->device_request.bmRequestType & USB_REQ_DIRECTION_MASK)
++			    == USB_REQ_HOST2DEVICE) {
++				UDCDBG("control write on EP0");
++				/* FIXME: implement this. We now only do setup_out with
++				 * empty data phase */
++				//set_ep0_ss();
++				//ep0->state = EP0_OUT_DATA_PHASE;
++				set_ep0_de_out();
++			} else {
++				/* device -> host */
++				UDCDBG("control read on EP0");
++				clear_ep0_opr();
++
++				ep0->tx_urb = ep0_urb;
++				ep0->sent = ep0->last = 0;
++
++				if (s3c2410_write_noniso_tx_fifo(ep0)) {
++					ep0->state = EP0_IDLE;
++					//if (!inl(S3C2410_UDC_USB_INT_REG) & S3C2410_UDC_USBINT_RESET)
++						set_ep0_de_in();
++				} else {
++					ep0->state = EP0_IN_DATA_PHASE;
++					set_ep0_ipr();
++#if 1
++					do {
++						ep0csr = inl(S3C2410_UDC_IN_CSR1_REG);
++						if ((ep0csr & S3C2410_UDC_EP0_CSR_IPKRDY))
++							continue;
++						//serial_printf("csr0=0x%x\n", ep0csr);
++
++						ep0->sent += ep0->last;
++						if (s3c2410_write_noniso_tx_fifo(ep0)) {
++							ep0->state = EP0_IDLE;
++							set_ep0_de_in();
++							break;
++						} else
++							set_ep0_ipr();
++					} while (1);
++#endif
++				}
++			}
++		}
++		break;
++	case EP0_IN_DATA_PHASE:
++
++		if (!(ep0csr & S3C2410_UDC_EP0_CSR_IPKRDY)) {
++			ep0->sent += ep0->last;
++
++			if (s3c2410_write_noniso_tx_fifo(ep0)) {
++				ep0->state = EP0_IDLE;
++				set_ep0_de_in();
++			} else {
++				ep0->state = EP0_IN_DATA_PHASE;
++				set_ep0_ipr();
++			}
++		}
++		break;
++	case EP0_OUT_DATA_PHASE:
++		/* FIXME: Not supported */
++		break;
++	case EP0_END_XFER:
++		ep0->state = EP0_IDLE;
++		break;
++	case EP0_STALL:
++		//set_ep0_ss;
++		ep0->state = EP0_IDLE;
++		break;
++	}
++}
++
++
++static void s3c2410_udc_epn(int ep)
++{
++	struct usb_endpoint_instance *endpoint;
++	struct urb *urb;
++	u32 ep_csr1;
++
++	/* FIXME: implement data endpoint handling */
++	UDCDBGA("for ep=%u", ep);
++
++	if (ep >= S3C2410_UDC_NUM_ENDPOINTS)
++		return;
++
++	endpoint = &udc_device->bus->endpoint_array[ep];
++
++	S3C2410_UDC_SETIX(ep);
++	ep_csr1 = inl(S3C2410_UDC_IN_CSR1_REG);
++
++	if (endpoint->endpoint_address & USB_DIR_IN) {
++		/* IN transfer (device to host) */
++		urb = endpoint->tx_urb;
++		if (ep_csr1 & S3C2410_UDC_ICSR1_SENTSTL) {
++			/* Stall handshake */
++			outl(0x00, S3C2410_UDC_IN_CSR1_REG);
++			return;
++		}
++		if (!(ep_csr1 & S3C2410_UDC_ICSR1_PKTRDY) && urb) {
++			/* push pending data into FIFO */
++			if ((endpoint->last == endpoint->tx_packetSize) && 
++			    (urb->actual_length - endpoint->sent - endpoint->last == 0)) {
++				endpoint->sent += endpoint->last;
++				/* Write 0 bytes of data (ZLP) */
++				outl(ep_csr1|S3C2410_UDC_ICSR1_PKTRDY, S3C2410_UDC_IN_CSR1_REG);
++			} else {
++				/* write actual data to fifo */
++				s3c2410_write_noniso_tx_fifo(endpoint);
++				outl(ep_csr1|S3C2410_UDC_ICSR1_PKTRDY, S3C2410_UDC_IN_CSR1_REG);
++
++				usbd_tx_complete(endpoint);
++			}
++		}
++	} else {
++		/* OUT transfer (host to device) */
++		urb = endpoint->rcv_urb;
++		if (ep_csr1 & S3C2410_UDC_OCSR1_SENTSTL) {
++			/* Stall handshake */
++			outl(0x00, S3C2410_UDC_IN_CSR1_REG);
++			return;
++		}
++		if ((ep_csr1 & S3C2410_UDC_OCSR1_PKTRDY) && urb) {
++			/* Read pending data from fifo */
++			u32 fifo_count = fifo_count_out();
++			int is_last = 0;
++			u32 i, urb_avail = urb->buffer_length - urb->actual_length;
++			u8 *cp;
++
++			if (fifo_count < endpoint->rcv_packetSize)
++				is_last = 1;
++
++			if (fifo_count < urb_avail)
++				urb_avail = fifo_count;
++
++			for (i = 0; i < urb_avail; i++)
++				*cp++ = inb(ep_fifo_reg[ep]);
++
++			if (is_last) {
++				outl(ep_csr1 & ~S3C2410_UDC_OCSR1_PKTRDY, 
++				     S3C2410_UDC_OUT_CSR1_REG);
++			}
++			usbd_rcv_complete(endpoint, urb_avail, 0);
++		}
++	}
++			
++	urb = endpoint->rcv_urb;
++}
++
++/*
++-------------------------------------------------------------------------------
++*/
++
++/* Handle general USB interrupts and dispatch according to type.
++ * This function implements TRM Figure 14-13.
++ */
++int udc_irq(void)
++{
++	struct usb_endpoint_instance *ep0 = udc_device->bus->endpoint_array;
++	u_int32_t save_idx = inl(S3C2410_UDC_INDEX_REG);
++
++	/* read interrupt sources */
++	u_int32_t usb_status = inl(S3C2410_UDC_USB_INT_REG);
++	u_int32_t usbd_status = inl(S3C2410_UDC_EP_INT_REG);
++
++	UDCDBGA("< IRQ usbs=0x%02x, usbds=0x%02x start >", usb_status,
++		usbd_status);
++
++	/* clear interrupts */
++	outl(usb_status, S3C2410_UDC_USB_INT_REG);
++	//outl(usbd_status, S3C2410_UDC_EP_INT_REG);
++
++	if (usb_status & S3C2410_UDC_USBINT_RESET) {
++		//serial_putc('R');
++		UDCDBGA("RESET pwr=0x%x", inl(S3C2410_UDC_PWR_REG));
++		udc_setup_ep(udc_device, 0, ep0);
++		outl(S3C2410_UDC_EP0_CSR_SSE|S3C2410_UDC_EP0_CSR_SOPKTRDY, S3C2410_UDC_EP0_CSR_REG);
++		ep0->state = EP0_IDLE;
++		usbd_device_event_irq (udc_device, DEVICE_RESET, 0);
++	}
++
++	if (usb_status & S3C2410_UDC_USBINT_RESUME) {
++		UDCDBG("RESUME");
++		usbd_device_event_irq(udc_device, DEVICE_BUS_ACTIVITY, 0);
++	}
++
++	if (usb_status & S3C2410_UDC_USBINT_SUSPEND) {
++		UDCDBG("SUSPEND");
++		usbd_device_event_irq(udc_device, DEVICE_BUS_INACTIVE, 0);
++	}
++
++	/* Endpoint Interrupts */
++	if (usbd_status) {
++		int i;
++
++		if (usbd_status & S3C2410_UDC_INT_EP0) {
++			s3c2410_udc_ep0();
++			outl(S3C2410_UDC_INT_EP0, S3C2410_UDC_EP_INT_REG);
++		}
++
++		for (i = 1; i < 5; i++) {
++			u_int32_t tmp = 1 << i;
++
++			if (usbd_status & tmp) {
++				/* FIXME: Handle EP X */
++				s3c2410_udc_epn(i);
++				outl(tmp, S3C2410_UDC_EP_INT_REG);
++			}
++		}
++	}
++	S3C2410_UDC_SETIX(save_idx);
++	udc_interrupts++;
++
++	return usb_status | usbd_status;
++}
++
++/*
++-------------------------------------------------------------------------------
++*/
++
++
++/*
++ * Start of public functions.
++ */
++
++/* Called to start packet transmission. */
++void udc_endpoint_write (struct usb_endpoint_instance *endpoint)
++{
++	unsigned short epnum =
++		endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK;
++
++	UDCDBGA ("Starting transmit on ep %x", epnum);
++
++	if (endpoint->tx_urb) {
++#if 0
++		/* select the endpoint FIFO */
++		outw (UDC_EP_Sel | UDC_EP_Dir | epnum, UDC_EP_NUM);
++		/* write data to FIFO */
++		omap1510_write_noniso_tx_fifo (endpoint);
++		/* enable tx FIFO to start transmission */
++		outw (UDC_Set_FIFO_En, UDC_CTRL);
++		/* deselect the endpoint FIFO */
++		outw (UDC_EP_Dir | epnum, UDC_EP_NUM);
++#endif
++	}
++}
++
++/* Start to initialize h/w stuff */
++int udc_init (void)
++{
++	S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
++	S3C24X0_INTERRUPT * irq = S3C24X0_GetBase_INTERRUPT();
++
++	udc_device = NULL;
++
++	UDCDBG ("starting");
++
++	/* Set and check clock control.
++	 * We might ought to be using the clock control API to do
++	 * this instead of fiddling with the clock registers directly
++	 * here.
++	 */
++	clk_power->CLKCON |= (1 << 7);
++	irq->INTMSK &= ~BIT_USBD;
++
++	/* Print banner with device revision */
++	printf ("USB:   S3C2410 USB Deviced\n");
++
++	/*
++	 * At this point, device is ready for configuration...
++	 */
++
++	//UDCDBG("disable USB interrupts");
++	UDCDBG("enable USB interrupts");
++	outl(0xff, S3C2410_UDC_EP_INT_EN_REG);
++	outl(0x04, S3C2410_UDC_USB_INT_EN_REG);
++
++	return 0;
++}
++
++/* Stall endpoint */
++static void udc_stall_ep(unsigned int ep_num)
++{
++	UDCDBGA ("stall ep %d", ep_num);
++
++	S3C2410_UDC_SETIX(ep_num);
++
++	switch (ep_num) {
++	case 0:
++		outw(S3C2410_UDC_EP0_CSR_SENDSTL, S3C2410_UDC_EP0_CSR_REG);
++		break;
++		/* FIXME */
++	default:
++#if 0
++	if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
++		outw(ep_num)
++		if (inw (UDC_EP_RX (ep_num)) & UDC_EPn_RX_Valid) {
++			/* we have a valid rx endpoint, so halt it */
++			outw (UDC_EP_Sel | ep_num, UDC_EP_NUM);
++			outw (UDC_Set_Halt, UDC_CTRL);
++			outw (ep_num, UDC_EP_NUM);
++		}
++	} else {
++		if (inw (UDC_EP_TX (ep_num)) & UDC_EPn_TX_Valid) {
++			/* we have a valid tx endpoint, so halt it */
++			outw (UDC_EP_Sel | UDC_EP_Dir | ep_num, UDC_EP_NUM);
++			outw (UDC_Set_Halt, UDC_CTRL);
++			outw (ep_num, UDC_EP_NUM);
++		}
++	}
++#endif
++		break;
++	}
++}
++
++/*
++ * udc_setup_ep - setup endpoint
++ *
++ * Associate a physical endpoint with endpoint_instance
++ */
++int udc_setup_ep (struct usb_device_instance *device,
++		   unsigned int ep, struct usb_endpoint_instance *endpoint)
++{
++	int ep_addr = endpoint->endpoint_address;
++	int packet_size;
++	int attributes;
++
++	u_int32_t maxp;
++
++	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;
++	}
++
++	if (packet_size <= 8)
++		maxp = S3C2410_UDC_MAXP_8;
++	else if (packet_size <= 16)
++		maxp = S3C2410_UDC_MAXP_16;
++	else if (packet_size <= 32)
++		maxp = S3C2410_UDC_MAXP_32;
++	else
++		maxp = S3C2410_UDC_MAXP_64;
++
++	UDCDBGA("setting up endpoint %u addr %x packet_size %u maxp %u", ep,
++		endpoint->endpoint_address, packet_size, maxp);
++
++	/* Set maximum packet size */
++	S3C2410_UDC_SETIX(ep);
++	writel(maxp, S3C2410_UDC_MAXP_REG);
++
++	return 0;
++}
++
++/* ************************************************************************** */
++
++/**
++ * udc_connected - is the USB cable connected
++ *
++ * Return non-zero if cable is connected.
++ */
++#if 0
++int udc_connected (void)
++{
++	return ((inw (UDC_DEVSTAT) & UDC_ATT) == UDC_ATT);
++}
++#endif
++
++/* Turn on the USB connection by enabling the pullup resistor */
++void udc_connect (void)
++{
++	UDCDBG ("connect, enable Pullup");
++#if defined(CONFIG_ARCH_GTA01_v4) || defined(CONFIG_ARCH_GTA01B_v2)
++	S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++
++	// s3c2410_gpio_setpin(GTA01_GPIO_USB_PULLUP, 1);
++	gpio->GPBDAT |= (1 << 9);
++#endif
++}
++
++/* Turn off the USB connection by disabling the pullup resistor */
++void udc_disconnect (void)
++{
++	UDCDBG ("disconnect, disable Pullup");
++#if defined(CONFIG_ARCH_GTA01_v4) || defined(CONFIG_ARCH_GTA01B_v2)
++	S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++
++	//s3c2410_gpio_setpin(GTA01_GPIO_USB_PULLUP, 0);
++	gpio->GPBDAT &= ~(1 << 9);
++#endif
++}
++
++/* Switch on the UDC */
++void udc_enable (struct usb_device_instance *device)
++{
++	UDCDBGA ("enable device %p, status %d", device, device->status);
++
++	/* initialize driver state variables */
++	udc_devstat = 0;
++
++	/* 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);
++	}
++
++#ifdef FIXME
++	/* The VBUS_MODE bit selects whether VBUS detection is done via
++	 * software (1) or hardware (0).  When software detection is
++	 * selected, VBUS_CTRL selects whether USB is not connected (0)
++	 * or connected (1).
++	 */
++	outl (inl (FUNC_MUX_CTRL_0) | UDC_VBUS_CTRL | UDC_VBUS_MODE,
++	      FUNC_MUX_CTRL_0);
++	UDCREGL (FUNC_MUX_CTRL_0);
++#endif
++
++	s3c2410_configure_device(device);
++}
++
++/* Switch off the UDC */
++void udc_disable (void)
++{
++	UDCDBG ("disable UDC");
++
++	s3c2410_deconfigure_device();
++
++#ifdef FIXME
++	/* The VBUS_MODE bit selects whether VBUS detection is done via
++	 * software (1) or hardware (0).  When software detection is
++	 * selected, VBUS_CTRL selects whether USB is not connected (0)
++	 * or connected (1).
++	 */
++	outl (inl (FUNC_MUX_CTRL_0) | UDC_VBUS_MODE, FUNC_MUX_CTRL_0);
++	outl (inl (FUNC_MUX_CTRL_0) & ~UDC_VBUS_CTRL, FUNC_MUX_CTRL_0);
++	UDCREGL (FUNC_MUX_CTRL_0);
++#endif
++
++	/* Free ep0 URB */
++	if (ep0_urb) {
++		/*usbd_dealloc_urb(ep0_urb); */
++		ep0_urb = NULL;
++	}
++
++	/* Reset device pointer.
++	 * We ought to do this here to balance the initialization of udc_device
++	 * in udc_enable, but some of our other exported functions get called
++	 * by the bus interface driver after udc_disable, so we have to hang on
++	 * to the device pointer to avoid a null pointer dereference. */
++	/* udc_device = NULL; */
++}
++
++/**
++ * udc_startup - 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 OMAP USB client controller has the capability to detect when the
++	 * USB cable is connected to a powered USB bus via the ATT bit in the
++	 * DEVSTAT register, so we will defer the DEVICE_HUB_CONFIGURED and
++	 * DEVICE_RESET events until later.
++	 */
++
++	/* The GTA01 can detect usb device attachment, but we just assume being
++	 * attached for now (go to STATE_POWERED) */
++	usbd_device_event_irq (device, DEVICE_HUB_CONFIGURED, 0);
++
++	udc_enable (device);
++}
++
++void udc_set_nak(int epid)
++{
++	
++}
++
++void udc_unset_nak(int epid)
++{
++}
++#endif
+Index: u-boot.git/drivers/usbdcore_s3c2410.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ u-boot.git/drivers/usbdcore_s3c2410.h	2007-02-04 20:01:43.000000000 +0100
+@@ -0,0 +1,273 @@
++/* linux/include/asm/arch-s3c2410/regs-udc.h
++ *
++ * Copyright (C) 2004 Herbert Poetzl <herbert at 13thfloor.at>
++ *
++ * 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.
++ *
++ *  Changelog:
++ *    01-08-2004	Initial creation
++ *    12-09-2004	Cleanup for submission
++ *    24-10-2004	Fixed S3C2410_UDC_MAXP_REG definition
++ *    10-03-2005	Changed S3C2410_VA to S3C24XX_VA
++ *    10-01-2007	Modify for u-boot
++ */
++
++#ifndef __ASM_ARCH_REGS_UDC_H
++#define __ASM_ARCH_REGS_UDC_H
++
++#define S3C2410_UDC_REG_BASE_PHYS	0x52000000
++#define S3C2410_UDC_NUM_ENDPOINTS	5
++
++#define S3C2410_USBDREG(x) (x + S3C2410_UDC_REG_BASE_PHYS)
++
++#define S3C2410_UDC_FUNC_ADDR_REG	S3C2410_USBDREG(0x0140)
++#define S3C2410_UDC_PWR_REG		S3C2410_USBDREG(0x0144)
++#define S3C2410_UDC_EP_INT_REG		S3C2410_USBDREG(0x0148)
++
++#define S3C2410_UDC_USB_INT_REG		S3C2410_USBDREG(0x0158)
++#define S3C2410_UDC_EP_INT_EN_REG	S3C2410_USBDREG(0x015c)
++
++#define S3C2410_UDC_USB_INT_EN_REG	S3C2410_USBDREG(0x016c)
++
++#define S3C2410_UDC_FRAME_NUM1_REG	S3C2410_USBDREG(0x0170)
++#define S3C2410_UDC_FRAME_NUM2_REG	S3C2410_USBDREG(0x0174)
++
++#define S3C2410_UDC_EP0_FIFO_REG	S3C2410_USBDREG(0x01c0)
++#define S3C2410_UDC_EP1_FIFO_REG	S3C2410_USBDREG(0x01c4)
++#define S3C2410_UDC_EP2_FIFO_REG	S3C2410_USBDREG(0x01c8)
++#define S3C2410_UDC_EP3_FIFO_REG	S3C2410_USBDREG(0x01cc)
++#define S3C2410_UDC_EP4_FIFO_REG	S3C2410_USBDREG(0x01d0)
++
++#define S3C2410_UDC_EP1_DMA_CON		S3C2410_USBDREG(0x0200)
++#define S3C2410_UDC_EP1_DMA_UNIT	S3C2410_USBDREG(0x0204)
++#define S3C2410_UDC_EP1_DMA_FIFO	S3C2410_USBDREG(0x0208)
++#define S3C2410_UDC_EP1_DMA_TTC_L	S3C2410_USBDREG(0x020c)
++#define S3C2410_UDC_EP1_DMA_TTC_M	S3C2410_USBDREG(0x0210)
++#define S3C2410_UDC_EP1_DMA_TTC_H	S3C2410_USBDREG(0x0214)
++
++#define S3C2410_UDC_EP2_DMA_CON		S3C2410_USBDREG(0x0218)
++#define S3C2410_UDC_EP2_DMA_UNIT	S3C2410_USBDREG(0x021c)
++#define S3C2410_UDC_EP2_DMA_FIFO	S3C2410_USBDREG(0x0220)
++#define S3C2410_UDC_EP2_DMA_TTC_L	S3C2410_USBDREG(0x0224)
++#define S3C2410_UDC_EP2_DMA_TTC_M	S3C2410_USBDREG(0x0228)
++#define S3C2410_UDC_EP2_DMA_TTC_H	S3C2410_USBDREG(0x022c)
++
++#define S3C2410_UDC_EP3_DMA_CON		S3C2410_USBDREG(0x0240)
++#define S3C2410_UDC_EP3_DMA_UNIT	S3C2410_USBDREG(0x0244)
++#define S3C2410_UDC_EP3_DMA_FIFO	S3C2410_USBDREG(0x0248)
++#define S3C2410_UDC_EP3_DMA_TTC_L	S3C2410_USBDREG(0x024c)
++#define S3C2410_UDC_EP3_DMA_TTC_M	S3C2410_USBDREG(0x0250)
++#define S3C2410_UDC_EP3_DMA_TTC_H	S3C2410_USBDREG(0x0254)
++
++#define S3C2410_UDC_EP4_DMA_CON		S3C2410_USBDREG(0x0258)
++#define S3C2410_UDC_EP4_DMA_UNIT	S3C2410_USBDREG(0x025c)
++#define S3C2410_UDC_EP4_DMA_FIFO	S3C2410_USBDREG(0x0260)
++#define S3C2410_UDC_EP4_DMA_TTC_L	S3C2410_USBDREG(0x0264)
++#define S3C2410_UDC_EP4_DMA_TTC_M	S3C2410_USBDREG(0x0268)
++#define S3C2410_UDC_EP4_DMA_TTC_H	S3C2410_USBDREG(0x026c)
++
++#define S3C2410_UDC_INDEX_REG		S3C2410_USBDREG(0x0178)
++
++/* indexed registers */
++
++#define S3C2410_UDC_MAXP_REG		S3C2410_USBDREG(0x0180)
++
++#define S3C2410_UDC_EP0_CSR_REG		S3C2410_USBDREG(0x0184)
++
++#define S3C2410_UDC_IN_CSR1_REG		S3C2410_USBDREG(0x0184)
++#define S3C2410_UDC_IN_CSR2_REG		S3C2410_USBDREG(0x0188)
++
++#define S3C2410_UDC_OUT_CSR1_REG	S3C2410_USBDREG(0x0190)
++#define S3C2410_UDC_OUT_CSR2_REG	S3C2410_USBDREG(0x0194)
++#define S3C2410_UDC_OUT_FIFO_CNT1_REG	S3C2410_USBDREG(0x0198)
++#define S3C2410_UDC_OUT_FIFO_CNT2_REG	S3C2410_USBDREG(0x019c)
++
++
++
++#define S3C2410_UDC_PWR_ISOUP		(1<<7) // R/W
++#define S3C2410_UDC_PWR_RESET		(1<<3) // R
++#define S3C2410_UDC_PWR_RESUME		(1<<2) // R/W
++#define S3C2410_UDC_PWR_SUSPEND		(1<<1) // R
++#define S3C2410_UDC_PWR_ENSUSPEND	(1<<0) // R/W
++
++#define S3C2410_UDC_PWR_DEFAULT		0x00
++
++#define S3C2410_UDC_INT_EP4		(1<<4) // R/W (clear only)
++#define S3C2410_UDC_INT_EP3		(1<<3) // R/W (clear only)
++#define S3C2410_UDC_INT_EP2		(1<<2) // R/W (clear only)
++#define S3C2410_UDC_INT_EP1		(1<<1) // R/W (clear only)
++#define S3C2410_UDC_INT_EP0		(1<<0) // R/W (clear only)
++
++#define S3C2410_UDC_USBINT_RESET	(1<<2) // R/W (clear only)
++#define S3C2410_UDC_USBINT_RESUME	(1<<1) // R/W (clear only)
++#define S3C2410_UDC_USBINT_SUSPEND	(1<<0) // R/W (clear only)
++
++#define S3C2410_UDC_INTE_EP4		(1<<4) // R/W
++#define S3C2410_UDC_INTE_EP3		(1<<3) // R/W
++#define S3C2410_UDC_INTE_EP2		(1<<2) // R/W
++#define S3C2410_UDC_INTE_EP1		(1<<1) // R/W
++#define S3C2410_UDC_INTE_EP0		(1<<0) // R/W
++
++#define S3C2410_UDC_USBINTE_RESET	(1<<2) // R/W
++#define S3C2410_UDC_USBINTE_SUSPEND	(1<<0) // R/W
++
++
++#define S3C2410_UDC_INDEX_EP0		(0x00)
++#define S3C2410_UDC_INDEX_EP1		(0x01) // ??
++#define S3C2410_UDC_INDEX_EP2		(0x02) // ??
++#define S3C2410_UDC_INDEX_EP3		(0x03) // ??
++#define S3C2410_UDC_INDEX_EP4		(0x04) // ??
++
++#define S3C2410_UDC_ICSR1_CLRDT		(1<<6) // R/W
++#define S3C2410_UDC_ICSR1_SENTSTL	(1<<5) // R/W (clear only)
++#define S3C2410_UDC_ICSR1_SENDSTL	(1<<4) // R/W
++#define S3C2410_UDC_ICSR1_FFLUSH	(1<<3) // W   (set only)
++#define S3C2410_UDC_ICSR1_UNDRUN	(1<<2) // R/W (clear only)
++#define S3C2410_UDC_ICSR1_PKTRDY	(1<<0) // R/W (set only)
++
++#define S3C2410_UDC_ICSR2_AUTOSET	(1<<7) // R/W
++#define S3C2410_UDC_ICSR2_ISO		(1<<6) // R/W
++#define S3C2410_UDC_ICSR2_MODEIN	(1<<5) // R/W
++#define S3C2410_UDC_ICSR2_DMAIEN	(1<<4) // R/W
++
++#define S3C2410_UDC_OCSR1_CLRDT		(1<<7) // R/W
++#define S3C2410_UDC_OCSR1_SENTSTL	(1<<6) // R/W (clear only)
++#define S3C2410_UDC_OCSR1_SENDSTL	(1<<5) // R/W
++#define S3C2410_UDC_OCSR1_FFLUSH	(1<<4) // R/W
++#define S3C2410_UDC_OCSR1_DERROR	(1<<3) // R
++#define S3C2410_UDC_OCSR1_OVRRUN	(1<<2) // R/W (clear only)
++#define S3C2410_UDC_OCSR1_PKTRDY	(1<<0) // R/W (clear only)
++
++#define S3C2410_UDC_OCSR2_AUTOCLR	(1<<7) // R/W
++#define S3C2410_UDC_OCSR2_ISO		(1<<6) // R/W
++#define S3C2410_UDC_OCSR2_DMAIEN	(1<<5) // R/W
++
++#define S3C2410_UDC_SETIX(X)	writel(X, S3C2410_UDC_INDEX_REG)
++
++#define S3C2410_UDC_EP0_CSR_OPKRDY	(1<<0)
++#define S3C2410_UDC_EP0_CSR_IPKRDY	(1<<1)
++#define S3C2410_UDC_EP0_CSR_SENTSTL	(1<<2)
++#define S3C2410_UDC_EP0_CSR_DE		(1<<3)
++#define S3C2410_UDC_EP0_CSR_SE		(1<<4)
++#define S3C2410_UDC_EP0_CSR_SENDSTL	(1<<5)
++#define S3C2410_UDC_EP0_CSR_SOPKTRDY	(1<<6)
++#define S3C2410_UDC_EP0_CSR_SSE	(1<<7)
++
++#define S3C2410_UDC_MAXP_8		(1<<0)
++#define S3C2410_UDC_MAXP_16		(1<<1)
++#define S3C2410_UDC_MAXP_32		(1<<2)
++#define S3C2410_UDC_MAXP_64		(1<<3)
++
++/****************** MACROS ******************/
++#define BIT_MASK	0xFF
++
++#if 1
++#define maskl(v,m,a)      \
++		writel((readl(a) & ~(m))|((v)&(m)), (a))
++#else
++#define maskl(v,m,a)	do {					\
++	unsigned long foo = readl(a);				\
++	unsigned long bar = (foo & ~(m)) | ((v)&(m));		\
++	serial_printf("0x%08x:0x%x->0x%x\n", (a), foo, bar);	\
++	writel(bar, (a));					\
++} while(0)
++#endif
++
++#define clear_ep0_sst() do {			\
++	S3C2410_UDC_SETIX(0); 			\
++	writel(0x00, S3C2410_UDC_EP0_CSR_REG); 	\
++} while(0)
++
++#define clear_ep0_se() do {				\
++	S3C2410_UDC_SETIX(0); 				\
++	maskl(S3C2410_UDC_EP0_CSR_SSE,			\
++		BIT_MASK, S3C2410_UDC_EP0_CSR_REG); 	\
++} while(0)
++
++#define clear_ep0_opr() do {				\
++	S3C2410_UDC_SETIX(0);				\
++	maskl(S3C2410_UDC_EP0_CSR_SOPKTRDY,		\
++		BIT_MASK, S3C2410_UDC_EP0_CSR_REG); 	\
++} while(0)
++
++#define set_ep0_ipr() do {				\
++	S3C2410_UDC_SETIX(0);				\
++	maskl(S3C2410_UDC_EP0_CSR_IPKRDY,		\
++		BIT_MASK, S3C2410_UDC_EP0_CSR_REG); 	\
++} while(0)
++
++#define set_ep0_de() do {				\
++	S3C2410_UDC_SETIX(0);				\
++	maskl(S3C2410_UDC_EP0_CSR_DE,			\
++		BIT_MASK, S3C2410_UDC_EP0_CSR_REG);	\
++} while(0)
++
++#define set_ep0_ss() do {				\
++	S3C2410_UDC_SETIX(0);				\
++	maskl(S3C2410_UDC_EP0_CSR_SENDSTL,		\
++		BIT_MASK, S3C2410_UDC_EP0_CSR_REG);	\
++} while(0)
++
++#define set_ep0_de_out() do {				\
++	S3C2410_UDC_SETIX(0);				\
++	maskl((S3C2410_UDC_EP0_CSR_SOPKTRDY	 	\
++		| S3C2410_UDC_EP0_CSR_DE),		\
++		BIT_MASK, S3C2410_UDC_EP0_CSR_REG);	\
++} while(0)
++
++#define set_ep0_sse_out() do {				\
++	S3C2410_UDC_SETIX(0);				\
++	maskl((S3C2410_UDC_EP0_CSR_SOPKTRDY 		\
++		| S3C2410_UDC_EP0_CSR_SSE),		\
++		BIT_MASK, S3C2410_UDC_EP0_CSR_REG);	\
++} while(0)
++
++#define set_ep0_de_in() do {				\
++	S3C2410_UDC_SETIX(0);				\
++	maskl((S3C2410_UDC_EP0_CSR_IPKRDY		\
++		| S3C2410_UDC_EP0_CSR_DE),		\
++		BIT_MASK, S3C2410_UDC_EP0_CSR_REG);	\
++} while(0)
++
++
++#if 0
++
++#define clear_stall_ep1_out(base) do {			\
++	S3C2410_UDC_SETIX(base,EP1);			\
++	orl(0,base+S3C2410_UDC_OUT_CSR1_REG);		\
++} while(0)
++
++
++#define clear_stall_ep2_out(base) do {			\
++	S3C2410_UDC_SETIX(base,EP2);			\
++	orl(0, base+S3C2410_UDC_OUT_CSR1_REG);		\
++} while(0)
++
++
++#define clear_stall_ep3_out(base) do {			\
++	S3C2410_UDC_SETIX(base,EP3);			\
++	orl(0,base+S3C2410_UDC_OUT_CSR1_REG);		\
++} while(0)
++
++
++#define clear_stall_ep4_out(base) do {			\
++	S3C2410_UDC_SETIX(base,EP4);			\
++	orl(0, base+S3C2410_UDC_OUT_CSR1_REG);		\
++} while(0)
++
++#endif
++
++/* S3C2410 Endpoint parameters */
++#define EP0_MAX_PACKET_SIZE	8
++#define UDC_OUT_ENDPOINT 	2
++#define UDC_OUT_PACKET_SIZE	64
++#define UDC_IN_ENDPOINT		1
++#define UDC_IN_PACKET_SIZE 	64
++#define UDC_INT_ENDPOINT	5
++#define UDC_INT_PACKET_SIZE	16
++#define UDC_BULK_PACKET_SIZE	16
++
++#endif
+Index: u-boot.git/include/s3c2410.h
+===================================================================
+--- u-boot.git.orig/include/s3c2410.h	2007-02-04 20:00:53.000000000 +0100
++++ u-boot.git/include/s3c2410.h	2007-02-04 20:01:43.000000000 +0100
+@@ -233,4 +233,40 @@
+ 		 rINTPND;\
+ 		 }
+ /* Wait until rINTPND is changed for the case that the ISR is very short. */
++
++#define S3C2410_MISCCR_USBDEV	    (0<<3)
++#define S3C2410_MISCCR_USBHOST	    (1<<3)
++
++#define S3C2410_MISCCR_CLK0_MPLL    (0<<4)
++#define S3C2410_MISCCR_CLK0_UPLL    (1<<4)
++#define S3C2410_MISCCR_CLK0_FCLK    (2<<4)
++#define S3C2410_MISCCR_CLK0_HCLK    (3<<4)
++#define S3C2410_MISCCR_CLK0_PCLK    (4<<4)
++#define S3C2410_MISCCR_CLK0_DCLK0   (5<<4)
++#define S3C2410_MISCCR_CLK0_MASK    (7<<4)
++
++#define S3C2410_MISCCR_CLK1_MPLL    (0<<8)
++#define S3C2410_MISCCR_CLK1_UPLL    (1<<8)
++#define S3C2410_MISCCR_CLK1_FCLK    (2<<8)
++#define S3C2410_MISCCR_CLK1_HCLK    (3<<8)
++#define S3C2410_MISCCR_CLK1_PCLK    (4<<8)
++#define S3C2410_MISCCR_CLK1_DCLK1   (5<<8)
++#define S3C2410_MISCCR_CLK1_MASK    (7<<8)
++
++#define S3C2410_MISCCR_USBSUSPND0   (1<<12)
++#define S3C2410_MISCCR_USBSUSPND1   (1<<13)
++
++#define S3C2410_MISCCR_nRSTCON	    (1<<16)
++
++#define S3C2410_MISCCR_nEN_SCLK0    (1<<17)
++#define S3C2410_MISCCR_nEN_SCLK1    (1<<18)
++#define S3C2410_MISCCR_nEN_SCLKE    (1<<19)
++#define S3C2410_MISCCR_SDSLEEP	    (7<<17)
++
++#define S3C2410_CLKSLOW_UCLK_OFF	(1<<7)
++#define S3C2410_CLKSLOW_MPLL_OFF	(1<<5)
++#define S3C2410_CLKSLOW_SLOW		(1<<4)
++#define S3C2410_CLKSLOW_SLOWVAL(x)	(x)
++#define S3C2410_CLKSLOW_GET_SLOWVAL(x)	((x) & 7)
++
+ #endif /*__S3C2410_H__*/
+Index: u-boot.git/drivers/usbdcore_ep0.c
+===================================================================
+--- u-boot.git.orig/drivers/usbdcore_ep0.c	2007-02-04 20:01:39.000000000 +0100
++++ u-boot.git/drivers/usbdcore_ep0.c	2007-02-04 20:41:17.000000000 +0100
+@@ -43,10 +43,10 @@
+ 
+ #include <common.h>
+ 
+-#if defined(CONFIG_OMAP1510) && defined(CONFIG_USB_DEVICE)
++#if defined(CONFIG_USB_DEVICE)
+ #include "usbdcore.h"
+ 
+-#if 0
++#if 1
+ #define dbg_ep0(lvl,fmt,args...) serial_printf("[%s] %s:%d: "fmt"\n",__FILE__,__FUNCTION__,__LINE__,##args)
+ #else
+ #define dbg_ep0(lvl,fmt,args...)
+@@ -190,6 +190,9 @@
+ 		return -1L;
+ 	}
+ 
++	/* re-initialize the ep0 buffer pointer */
++	urb->buffer = (u8 *) urb->buffer_data;
++
+ 	/* setup tx urb */
+ 	urb->actual_length = 0;
+ 	cp = urb->buffer;
+@@ -206,6 +209,9 @@
+ 			     usbd_device_device_descriptor (device, port))) {
+ 				return -1;
+ 			}
++			urb->buffer = device_descriptor;
++			urb->actual_length = MIN(sizeof(*device_descriptor), max);
++#if 0
+ 			/* copy descriptor for this device */
+ 			copy_config (urb, device_descriptor,
+ 				     sizeof (struct usb_device_descriptor),
+@@ -217,6 +223,7 @@
+ 			device_descriptor->bMaxPacketSize0 =
+ 				urb->device->bus->maxpacketsize;
+ 
++#endif
+ 		}
+ 		/*dbg_ep0(3, "copied device configuration, actual_length: %x", urb->actual_length); */
+ 		break;
+@@ -250,9 +257,14 @@
+ 					 index);
+ 				return -1;
+ 			}
++			urb->buffer = configuration_descriptor;
++			urb->actual_length = 
++				MIN(le16_to_cpu(configuration_descriptor->wTotalLength), max);
++#if 0
+ 			copy_config (urb, configuration_descriptor,
+ 				     le16_to_cpu(configuration_descriptor->wTotalLength),
+ 				     max);
++#endif
+ 		}
+ 		break;
+ 
+@@ -543,7 +555,8 @@
+ 			/*dbg_ep0(2, "address: %d %d %d", */
+ 			/*        request->wValue, le16_to_cpu(request->wValue), device->address); */
+ 
+-			serial_printf ("DEVICE_ADDRESS_ASSIGNED.. event?\n");
++			//serial_printf ("DEVICE_ADDRESS_ASSIGNED.. event?\n");
++			//udc_set_address(device->address);
+ 			return 0;
+ 
+ 		case USB_REQ_SET_DESCRIPTOR:	/* XXX should we support this? */
+Index: u-boot.git/include/configs/gta01.h
+===================================================================
+--- u-boot.git.orig/include/configs/gta01.h	2007-02-04 20:00:53.000000000 +0100
++++ u-boot.git/include/configs/gta01.h	2007-02-04 20:01:43.000000000 +0100
+@@ -173,6 +173,16 @@
+ #define CONFIG_USB_OHCI		1
+ #endif
+ 
++#define CONFIG_USB_DEVICE     1
++#define CONFIG_USB_TTY                1
++#if 0
++#define CONFIG_USBD_MANUFACTURER      "OpenMoko, Inc."
++#define CONFIG_USBD_PRODUCT_NAME        "Neo1973 Bootloader"
++#define CONFIG_USBD_VENDORID    0x2342
++#define CONFIG_USBD_PRODUCTID   0x0815
++#endif
++
++
+ /*-----------------------------------------------------------------------
+  * Physical Memory Map
+  */
+Index: u-boot.git/common/main.c
+===================================================================
+--- u-boot.git.orig/common/main.c	2007-02-04 20:00:53.000000000 +0100
++++ u-boot.git/common/main.c	2007-02-04 20:01:43.000000000 +0100
+@@ -962,6 +962,10 @@
+ 			show_activity(0);
+ 		}
+ #endif
++#ifdef CONFIG_USB_DEVICE__
++		while (udc_irq_poll())
++			;
++#endif
+ 		c = getc();
+ 
+ 		/*
+Index: u-boot.git/cpu/arm920t/s3c24x0/interrupts.c
+===================================================================
+--- u-boot.git.orig/cpu/arm920t/s3c24x0/interrupts.c	2007-02-04 20:00:53.000000000 +0100
++++ u-boot.git/cpu/arm920t/s3c24x0/interrupts.c	2007-02-04 20:01:43.000000000 +0100
+@@ -222,6 +222,13 @@
+ 	S3C24X0_INTERRUPT * irq = S3C24X0_GetBase_INTERRUPT();
+ 	u_int32_t intpnd = irq->INTPND;
+ 
++#ifdef CONFIG_USB_DEVICE
++	if (intpnd & BIT_USBD) {
++		udc_irq();
++		irq->SRCPND = BIT_USBD;
++		irq->INTPND = BIT_USBD;
++	}
++#endif /* USB_DEVICE */
+ }
+ #endif /* USE_IRQ */
+ 
+Index: u-boot.git/drivers/usbtty.h
+===================================================================
+--- u-boot.git.orig/drivers/usbtty.h	2007-02-04 20:00:53.000000000 +0100
++++ u-boot.git/drivers/usbtty.h	2007-02-04 20:01:43.000000000 +0100
+@@ -29,6 +29,8 @@
+ #include "usbdcore_mpc8xx.h"
+ #elif defined(CONFIG_OMAP1510)
+ #include "usbdcore_omap1510.h"
++#elif defined(CONFIG_S3C2410)
++#include "usbdcore_s3c2410.h"
+ #endif
+ 
+ #include <config.h>





More information about the commitlog mailing list