/*
 * Copyright (C) 2006 by Bryan O'Donoghue, CodeHermit
 * bodonoghue@CodeHermit.ie
 *
 * References
 * DasUBoot/drivers/usbdcore_omap1510.c, for design and implementation ideas.
 *
 * 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.
 *
 */

/*
 * Notes :
 * 1.	#define __SIMULATE_ERROR__ to inject a CRC error into every 2nd TX
 *		packet to force the USB re-transmit protocol.
 *
 * 2.	#define __DEBUG_UDC__ to switch on debug tracing to serial console
 *	be careful that tracing doesn't create Hiesen-bugs with respect to
 *	response timeouts to control requests.
 *
 * 3.	This driver should be able to support any higher level driver that
 *	that wants to do either of the two standard UDC implementations
 *	Control-Bulk-Interrupt or  Bulk-IN/Bulk-Out standards. Hence
 *	gserial and cdc_acm should work with this code.
 *
 * 4.	NAK events never actually get raised at all, the documentation
 *	is just wrong !
 *
 * 5.	For some reason, cbd_datlen is *always* +2 the value it should be.
 *	this means that having an RX cbd of 16 bytes is not possible, since
 *	the same size is reported for 14 bytes received as 16 bytes received
 *	until we can find out why this happens, RX cbds must be limited to 8
 *	bytes. TODO: check errata for this behaviour.
 *
 * 6.	Right now this code doesn't support properly powering up with the USB
 *	cable attached to the USB host my development board the Adder87x doesn't
 *	have a pull-up fitted to allow this, so it is necessary to power the
 *	board and *then* attached the USB cable to the host. However somebody
 *	with a different design in their board may be able to keep the cable
 *	constantly connected and simply enable/disable a pull-up  re
 *	figure 31.1 in MPC885RM.pdf instead of having to power up the board and
 *	then attach the cable !
 *
 */
#include <common.h>
#include <config.h>

#if defined(CONFIG_MPC885_FAMILY) && defined(CONFIG_USB_DEVICE)
#include <commproc.h>
#include "usbdcore.h"
#include "usbdcore_mpc8xx.h"
#include "usbdcore_ep0.h"

DECLARE_GLOBAL_DATA_PTR;

#define ERR(fmt, args...)\
	serial_printf("ERROR : [%s] %s:%d: "fmt,\
				__FILE__,__FUNCTION__,__LINE__, ##args)
#ifdef __DEBUG_UDC__
#define DBG(fmt,args...)\
		serial_printf("[%s] %s:%d: "fmt,\
				__FILE__,__FUNCTION__,__LINE__, ##args)
#else
#define DBG(fmt,args...)
#endif

/* Static Data */
#ifdef __SIMULATE_ERROR__
static char err_poison_test = 0;
#endif
static struct mpc8xx_ep ep_ref[MAX_ENDPOINTS];
static u32 address_base = STATE_NOT_READY;
static mpc8xx_udc_state_t udc_state = 0;
static struct usb_device_instance *udc_device = 0;
static volatile usb_epb_t *endpoints[MAX_ENDPOINTS];
static volatile cbd_t *tx_cbd[TX_RING_SIZE];
static volatile cbd_t *rx_cbd[RX_RING_SIZE];
static volatile immap_t *immr = 0;
static volatile cpm8xx_t *cp = 0;
static volatile usb_pram_t *usb_paramp = 0;
static volatile usb_t *usbp = 0;
static int rx_ct = 0;
static int tx_ct = 0;

/* Static Function Declarations */
static void mpc8xx_udc_state_transition_up (usb_device_state_t initial,
					    usb_device_state_t final);
static void mpc8xx_udc_state_transition_down (usb_device_state_t initial,
					      usb_device_state_t final);
static void mpc8xx_udc_stall (unsigned int ep);
static void mpc8xx_udc_flush_tx_fifo (int epid);
static void mpc8xx_udc_flush_rx_fifo (void);
static void mpc8xx_udc_clear_rxbd (volatile cbd_t * rx_cbdp);
static void mpc8xx_udc_init_tx (struct usb_endpoint_instance *epi,
				struct urb *tx_urb);
static void mpc8xx_udc_dump_request (struct usb_device_request *request);
static void mpc8xx_udc_clock_init (volatile immap_t * immr,
				   volatile cpm8xx_t * cp);
static int mpc8xx_udc_ep_tx (struct usb_endpoint_instance *epi);
static int mpc8xx_udc_epn_rx (unsigned int epid, volatile cbd_t * rx_cbdp);
static void mpc8xx_udc_ep0_rx (volatile cbd_t * rx_cbdp);
static void mpc8xx_udc_cbd_init (void);
static void mpc8xx_udc_endpoint_init (void);
static void mpc8xx_udc_cbd_attach (int ep, uchar tx_size, uchar rx_size);
static u32 mpc8xx_udc_alloc (u32 data_size, u32 alignment);
static int mpc8xx_udc_ep0_rx_setup (volatile cbd_t * rx_cbdp);
static void mpc8xx_udc_set_nak (unsigned int ep);
static short mpc8xx_udc_handle_txerr (void);
static void mpc8xx_udc_advance_rx (volatile cbd_t ** rx_cbdp, int epid);

/******************************************************************************
			       Global Linkage
 *****************************************************************************/

/* udc_init
 *
 * Do initial bus gluing
 */
int udc_init (void)
{
	/* Init various pointers */
	immr = (immap_t *) CFG_IMMR;
	cp = (cpm8xx_t *) & (immr->im_cpm);
	usb_paramp = (usb_pram_t *) & (cp->cp_dparam[PROFF_USB]);
	usbp = (usb_t *) & (cp->cp_scc[0]);

	memset (ep_ref, 0x00, (sizeof (struct mpc8xx_ep) * MAX_ENDPOINTS));

	udc_device = 0;
	udc_state = STATE_NOT_READY;

	usbp->usmod = 0x00;
	usbp->uscom = 0;

	/* Set USB Frame #0, Respond at Address & Get a clock source  */
	usbp->usaddr = 0x00;
	mpc8xx_udc_clock_init (immr, cp);

	/* PA15, PA14 as perhiperal USBRXD and USBOE */
	immr->im_ioport.iop_padir &= ~0x0003;
	immr->im_ioport.iop_papar |= 0x0003;

	/* PC11/PC10 as peripheral USBRXP USBRXN */
	immr->im_ioport.iop_pcso |= 0x0030;

	/* PC7/PC6 as perhiperal USBTXP and USBTXN */
	immr->im_ioport.iop_pcdir |= 0x0300;
	immr->im_ioport.iop_pcpar |= 0x0300;

	/* Set the base address */
	address_base = (u32) (cp->cp_dpmem + CPM_USB_BASE);

	/* Initialise endpoints and circular buffers */
	mpc8xx_udc_endpoint_init ();
	mpc8xx_udc_cbd_init ();

	/* Assign allocated Dual Port Endpoint descriptors */
	usb_paramp->ep0ptr = (u32) endpoints[0];
	usb_paramp->ep1ptr = (u32) endpoints[1];
	usb_paramp->ep2ptr = (u32) endpoints[2];
	usb_paramp->ep3ptr = (u32) endpoints[3];
	usb_paramp->frame_n = 0;

	DBG ("ep0ptr=0x%08x ep1ptr=0x%08x ep2ptr=0x%08x ep3ptr=0x%08x\n",
	     usb_paramp->ep0ptr, usb_paramp->ep1ptr, usb_paramp->ep2ptr,
	     usb_paramp->ep3ptr);

	return 0;
}

/* udc_irq
 *
 * Poll for whatever events may have occured
 */
void udc_irq (void)
{
	int epid = 0;
	volatile cbd_t *rx_cbdp = 0;
	volatile cbd_t *rx_cbdp_base = 0;

	if (udc_state != STATE_READY) {
		return;
	}

	if (usbp->usber & USB_E_BSY) {
		/* This shouldn't happen. If it does then it's a bug ! */
		usbp->usber |= USB_E_BSY;
		mpc8xx_udc_flush_rx_fifo ();
	}

	/* Scan all RX/Bidirectional Endpoints for RX data. */
	for (epid = 0; epid < MAX_ENDPOINTS; epid++) {
		if (!ep_ref[epid].prx) {
			continue;
		}
		rx_cbdp = rx_cbdp_base = ep_ref[epid].prx;

		do {
			if (!(rx_cbdp->cbd_sc & RX_BD_E)) {

				if (rx_cbdp->cbd_sc & 0x1F) {
					/* Corrupt data discard it.
					 * Controller has NAK'd this packet.
					 */
					mpc8xx_udc_clear_rxbd (rx_cbdp);

				} else {
					if (!epid) {
						mpc8xx_udc_ep0_rx (rx_cbdp);

					} else {
						/* Process data */
						mpc8xx_udc_set_nak (epid);
						mpc8xx_udc_epn_rx (epid, rx_cbdp);
						mpc8xx_udc_clear_rxbd (rx_cbdp);
					}
				}

				/* Advance RX CBD pointer */
				mpc8xx_udc_advance_rx (&rx_cbdp, epid);
				ep_ref[epid].prx = rx_cbdp;
			} else {
				/* Advance RX CBD pointer */
				mpc8xx_udc_advance_rx (&rx_cbdp, epid);
			}

		} while (rx_cbdp != rx_cbdp_base);
	}

	/* Handle TX events as appropiate, the correct place to do this is
	 * in a tx routine. Perhaps TX on epn was pre-empted by ep0
	 */

	if (usbp->usber & USB_E_TXB) {
		usbp->usber |= USB_E_TXB;
	}

	if (usbp->usber & (USB_TX_ERRMASK)) {
		mpc8xx_udc_handle_txerr ();
	}

	/* Switch to the default state, respond at the default address */
	if (usbp->usber & USB_E_RESET) {
		usbp->usber |= USB_E_RESET;
		usbp->usaddr = 0x00;
		udc_device->device_state = STATE_DEFAULT;
	}

	/* if(usbp->usber&USB_E_IDLE){
	   We could suspend here !
	   usbp->usber|=USB_E_IDLE;
	   DBG("idle state change\n");
	   }
	   if(usbp->usbs){
	   We could resume here when IDLE is deasserted !
	   Not worth doing, so long as we are self powered though.
	   }
	*/

	return;
}

/* udc_endpoint_write
 *
 * Write some data to an endpoint
 */
int udc_endpoint_write (struct usb_endpoint_instance *epi)
{
	int ep = 0;
	short epid = 1, unnak = 0, ret = 0;

	if (udc_state != STATE_READY) {
		ERR ("invalid udc_state != STATE_READY!\n");
		return -1;
	}

	if (!udc_device || !epi) {
		return -1;
	}

	if (udc_device->device_state != STATE_CONFIGURED) {
		return -1;
	}

	ep = epi->endpoint_address & 0x03;
	if (ep >= MAX_ENDPOINTS) {
		return -1;
	}

	/* Set NAK for all RX endpoints during TX */
	for (epid = 1; epid < MAX_ENDPOINTS; epid++) {

		/* Don't set NAK on DATA IN/CONTROL endpoints */
		if (ep_ref[epid].sc & USB_DIR_IN) {
			continue;
		}

		if (!(usbp->usep[epid] & (USEP_THS_NAK | USEP_RHS_NAK))) {
			unnak |= 1 << epid;
		}

		mpc8xx_udc_set_nak (epid);
	}

	mpc8xx_udc_init_tx (&udc_device->bus->endpoint_array[ep],
			    epi->tx_urb);
	ret = mpc8xx_udc_ep_tx (&udc_device->bus->endpoint_array[ep]);

	/* Remove temporary NAK */
	for (epid = 1; epid < MAX_ENDPOINTS; epid++) {
		if (unnak & (1 << epid)) {
			udc_unset_nak (epid);
		}
	}

	return ret;
}

/* mpc8xx_udc_assign_urb
 *
 * Associate a given urb to an endpoint TX or RX transmit/receive buffers
 */
static int mpc8xx_udc_assign_urb (int ep, char direction)
{
	struct usb_endpoint_instance *epi = 0;

	if (ep >= MAX_ENDPOINTS) {
		goto err;
	}
	epi = &udc_device->bus->endpoint_array[ep];
	if (!epi) {
		goto err;
	}

	if (!ep_ref[ep].urb) {
		ep_ref[ep].urb = usbd_alloc_urb (udc_device, udc_device->bus->endpoint_array);
		if (!ep_ref[ep].urb) {
			goto err;
		}
	} else {
		ep_ref[ep].urb->actual_length = 0;
	}

	switch (direction) {
	case USB_DIR_IN:
		epi->tx_urb = ep_ref[ep].urb;
		break;
	case USB_DIR_OUT:
		epi->rcv_urb = ep_ref[ep].urb;
		break;
	default:
		goto err;
	}
	return 0;

      err:
	udc_state = STATE_ERROR;
	return -1;
}

/* udc_setup_ep
 *
 * Associate U-Boot software endpoints to mpc8xx endpoint parameter ram
 * Isochronous endpoints aren't yet supported!
 */
void udc_setup_ep (struct usb_device_instance *device, unsigned int ep,
		   struct usb_endpoint_instance *epi)
{
	uchar direction = 0;
	int ep_attrib = 0;

	if (epi && (ep < MAX_ENDPOINTS)) {

		if (ep == 0) {
			if (epi->rcv_attributes != USB_ENDPOINT_XFER_CONTROL
			    || epi->tx_attributes !=
			    USB_ENDPOINT_XFER_CONTROL) {

				/* ep0 must be a control endpoint */
				udc_state = STATE_ERROR;
				return;

			}
			if (!(ep_ref[ep].sc & EP_ATTACHED)) {
				mpc8xx_udc_cbd_attach (ep, epi->tx_packetSize,
						       epi->rcv_packetSize);
			}
			usbp->usep[ep] = 0x0000;
			return;
		}

		if ((epi->endpoint_address & USB_ENDPOINT_DIR_MASK)
		    == USB_DIR_IN) {

			direction = 1;
			ep_attrib = epi->tx_attributes;
			epi->rcv_packetSize = 0;
			ep_ref[ep].sc |= USB_DIR_IN;
		} else {

			direction = 0;
			ep_attrib = epi->rcv_attributes;
			epi->tx_packetSize = 0;
			ep_ref[ep].sc &= ~USB_DIR_IN;
		}

		if (mpc8xx_udc_assign_urb (ep, epi->endpoint_address
					   & USB_ENDPOINT_DIR_MASK)) {
			return;
		}

		switch (ep_attrib) {
		case USB_ENDPOINT_XFER_CONTROL:
			if (!(ep_ref[ep].sc & EP_ATTACHED)) {
				mpc8xx_udc_cbd_attach (ep,
						       epi->tx_packetSize,
						       epi->rcv_packetSize);
			}
			usbp->usep[ep] = ep << 12;
			epi->rcv_urb = epi->tx_urb = ep_ref[ep].urb;

			break;
		case USB_ENDPOINT_XFER_BULK:
		case USB_ENDPOINT_XFER_INT:
			if (!(ep_ref[ep].sc & EP_ATTACHED)) {
				if (direction) {
					mpc8xx_udc_cbd_attach (ep,
							       epi->tx_packetSize,
							       0);
				} else {
					mpc8xx_udc_cbd_attach (ep,
							       0,
							       epi->rcv_packetSize);
				}
			}
			usbp->usep[ep] = (ep << 12) | ((ep_attrib) << 8);

			break;
		case USB_ENDPOINT_XFER_ISOC:
		default:
			serial_printf ("Error endpoint attrib %d>3\n", ep_attrib);
			udc_state = STATE_ERROR;
			break;
		}
	}

}

/* udc_connect
 *
 * Move state, switch on the USB
 */
void udc_connect (void)
{
	/* Enable pull-up resistor on D+
	 * TODO: fit a pull-up resistor to drive SE0 for > 2.5us
	 */

	if (udc_state != STATE_ERROR) {
		udc_state = STATE_READY;
		usbp->usmod |= USMOD_EN;
	}
}

/* udc_disconnect
 *
 * Disconnect is not used but, is included for completeness
 */
void udc_disconnect (void)
{
	/* Disable pull-up resistor on D-
	 * TODO: fix a pullup resistor to control this
	 */

	if (udc_state != STATE_ERROR) {
		udc_state = STATE_NOT_READY;
	}
	usbp->usmod &= ~USMOD_EN;
}

/* udc_enable
 *
 * Grab an EP0 URB, register interest in a subset of USB events
 */
void udc_enable (struct usb_device_instance *device)
{
	if (udc_state == STATE_ERROR) {
		return;
	}

	udc_device = device;

	if (!ep_ref[0].urb) {
		ep_ref[0].urb = usbd_alloc_urb (device, device->bus->endpoint_array);
	}

	/* Register interest in all events except SOF, enable transceiver */
	usbp->usber = 0x03FF;
	usbp->usbmr = 0x02F7;

	return;
}

/* udc_disable
 *
 * disable the currently hooked device
 */
void udc_disable (void)
{
	int i = 0;

	if (udc_state == STATE_ERROR) {
		DBG ("Won't disable UDC. udc_state==STATE_ERROR !\n");
		return;
	}

	udc_device = 0;

	for (; i < MAX_ENDPOINTS; i++) {
		if (ep_ref[i].urb) {
			usbd_dealloc_urb (ep_ref[i].urb);
			ep_ref[i].urb = 0;
		}
	}

	usbp->usbmr = 0x00;
	usbp->usmod = ~USMOD_EN;
	udc_state = STATE_NOT_READY;
}

/* udc_startup_events
 *
 * Enable the specified device
 */
void udc_startup_events (struct usb_device_instance *device)
{
	udc_enable (device);
	if (udc_state == STATE_READY) {
		usbd_device_event_irq (device, DEVICE_CREATE, 0);
	}
}

/* udc_set_nak
 *
 * Allow upper layers to signal lower layers should not accept more RX data
 *
 */
void udc_set_nak (int epid)
{
	if (epid) {
		mpc8xx_udc_set_nak (epid);
	}
}

/* udc_unset_nak
 *
 * Suspend sending of NAK tokens for DATA OUT tokens on a given endpoint.
 * Switch off NAKing on this endpoint to accept more data output from host.
 *
 */
void udc_unset_nak (int epid)
{
	if (epid > MAX_ENDPOINTS) {
		return;
	}

	if (usbp->usep[epid] & (USEP_THS_NAK | USEP_RHS_NAK)) {
		usbp->usep[epid] &= ~(USEP_THS_NAK | USEP_RHS_NAK);
		__asm__ ("eieio");
	}
}

/******************************************************************************
			      Static Linkage
******************************************************************************/

/* udc_state_transition_up
 * udc_state_transition_down
 *
 * Helper functions to implement device state changes.	The device states and
 * the events that transition between them are:
 *
 *				STATE_ATTACHED
 *				||	/\
 *				\/	||
 *	DEVICE_HUB_CONFIGURED			DEVICE_HUB_RESET
 *				||	/\
 *				\/	||
 *				STATE_POWERED
 *				||	/\
 *				\/	||
 *	DEVICE_RESET				DEVICE_POWER_INTERRUPTION
 *				||	/\
 *				\/	||
 *				STATE_DEFAULT
 *				||	/\
 *				\/	||
 *	DEVICE_ADDRESS_ASSIGNED			DEVICE_RESET
 *				||	/\
 *				\/	||
 *				STATE_ADDRESSED
 *				||	/\
 *				\/	||
 *	DEVICE_CONFIGURED			DEVICE_DE_CONFIGURED
 *				||	/\
 *				\/	||
 *				STATE_CONFIGURED
 *
 * udc_state_transition_up transitions up (in the direction from STATE_ATTACHED
 * to STATE_CONFIGURED) from the specified initial state to the specified final
 * state, passing through each intermediate state on the way.  If the initial
 * state is at or above (i.e. nearer to STATE_CONFIGURED) the final state, then
 * no state transitions will take place.
 *
 * udc_state_transition_down transitions down (in the direction from
 * STATE_CONFIGURED to STATE_ATTACHED) from the specified initial state to the
 * specified final state, passing through each intermediate state on the way.
 * If the initial state is at or below (i.e. nearer to STATE_ATTACHED) the final
 * state, then no state transitions will take place.
 *
 */

static void mpc8xx_udc_state_transition_up (usb_device_state_t initial,
					    usb_device_state_t final)
{
	if (initial < final) {
		switch (initial) {
		case STATE_ATTACHED:
			usbd_device_event_irq (udc_device,
					       DEVICE_HUB_CONFIGURED, 0);
			if (final == STATE_POWERED)
				break;
		case STATE_POWERED:
			usbd_device_event_irq (udc_device, DEVICE_RESET, 0);
			if (final == STATE_DEFAULT)
				break;
		case STATE_DEFAULT:
			usbd_device_event_irq (udc_device,
					       DEVICE_ADDRESS_ASSIGNED, 0);
			if (final == STATE_ADDRESSED)
				break;
		case STATE_ADDRESSED:
			usbd_device_event_irq (udc_device, DEVICE_CONFIGURED,
					       0);
		case STATE_CONFIGURED:
			break;
		default:
			break;
		}
	}
}

static void mpc8xx_udc_state_transition_down (usb_device_state_t initial,
					      usb_device_state_t final)
{
	if (initial > final) {
		switch (initial) {
		case STATE_CONFIGURED:
			usbd_device_event_irq (udc_device,
					       DEVICE_DE_CONFIGURED, 0);
			if (final == STATE_ADDRESSED)
				break;
		case STATE_ADDRESSED:
			usbd_device_event_irq (udc_device, DEVICE_RESET, 0);
			if (final == STATE_DEFAULT)
				break;
		case STATE_DEFAULT:
			usbd_device_event_irq (udc_device,
					       DEVICE_POWER_INTERRUPTION, 0);
			if (final == STATE_POWERED)
				break;
		case STATE_POWERED:
			usbd_device_event_irq (udc_device, DEVICE_HUB_RESET,
					       0);
		case STATE_ATTACHED:
			break;
		default:
			break;
		}
	}
}

/* mpc8xx_udc_stall
 *
 * Force returning of STALL tokens on the given endpoint. Protocol or function
 * STALL conditions are permissable here
 */
static void mpc8xx_udc_stall (unsigned int ep)
{
	usbp->usep[ep] |= STALL_BITMASK;
}

/* mpc8xx_udc_set_nak
 *
 * Force returning of NAK responses for the given endpoint as a kind of very
 * simple flow control
 */
static void mpc8xx_udc_set_nak (unsigned int ep)
{
	usbp->usep[ep] |= NAK_BITMASK;
	__asm__ ("eieio");
}

/* mpc8xx_udc_handle_txerr
 *
 * Handle errors relevant to TX. Return a status code to allow calling
 * indicative of what if anything happened
 */
static short mpc8xx_udc_handle_txerr ()
{
	short ep = 0, ret = 0;

	for (; ep < TX_RING_SIZE; ep++) {
		if (usbp->usber & (0x10 << ep)) {

			/* Timeout or underrun */
			if (tx_cbd[ep]->cbd_sc & 0x06) {
				ret = 1;
				mpc8xx_udc_flush_tx_fifo (ep);

			} else {
				if (usbp->usep[ep] & STALL_BITMASK) {
					if (!ep) {
						usbp->usep[ep] &= ~STALL_BITMASK;
					}
				}	/* else NAK */
			}
			usbp->usber |= (0x10 << ep);
		}
	}
	return ret;
}

/* mpc8xx_udc_advance_rx
 *
 * Advance cbd rx
 */
static void mpc8xx_udc_advance_rx (volatile cbd_t ** rx_cbdp, int epid)
{
	if ((*rx_cbdp)->cbd_sc & RX_BD_W) {
		*rx_cbdp = (volatile cbd_t *) (endpoints[epid]->rbase + CFG_IMMR);

	} else {
		(*rx_cbdp)++;
	}
}


/* mpc8xx_udc_flush_tx_fifo
 *
 * Flush a given TX fifo. Assumes one tx cbd per endpoint
 */
static void mpc8xx_udc_flush_tx_fifo (int epid)
{
	volatile cbd_t *tx_cbdp = 0;

	if (epid > MAX_ENDPOINTS) {
		return;
	}

	/* TX stop */
	immr->im_cpm.cp_cpcr = ((epid << 2) | 0x1D01);
	__asm__ ("eieio");
	while (immr->im_cpm.cp_cpcr & 0x01);

	usbp->uscom = 0x40 | 0;

	/* reset ring */
	tx_cbdp = (cbd_t *) (endpoints[epid]->tbptr + CFG_IMMR);
	tx_cbdp->cbd_sc = (TX_BD_I | TX_BD_W);


	endpoints[epid]->tptr = endpoints[epid]->tbase;
	endpoints[epid]->tstate = 0x00;
	endpoints[epid]->tbcnt = 0x00;

	/* TX start */
	immr->im_cpm.cp_cpcr = ((epid << 2) | 0x2D01);
	__asm__ ("eieio");
	while (immr->im_cpm.cp_cpcr & 0x01);

	return;
}

/* mpc8xx_udc_flush_rx_fifo
 *
 * For the sake of completeness of the namespace, it seems like
 * a good-design-decision (tm) to include mpc8xx_udc_flush_rx_fifo();
 * If RX_BD_E is true => a driver bug either here or in an upper layer
 * not polling frequently enough. If RX_BD_E is true we have told the host
 * we have accepted data but, the CPM found it had no-where to put that data
 * which needless to say would be a bad thing.
 */
static void mpc8xx_udc_flush_rx_fifo ()
{
	int i = 0;

	for (i = 0; i < RX_RING_SIZE; i++) {
		if (!(rx_cbd[i]->cbd_sc & RX_BD_E)) {
			ERR ("buf %p used rx data len = 0x%x sc=0x%x!\n",
			     rx_cbd[i], rx_cbd[i]->cbd_datlen,
			     rx_cbd[i]->cbd_sc);

		}
	}
	ERR ("BUG : Input over-run\n");
}

/* mpc8xx_udc_clear_rxbd
 *
 * Release control of RX CBD to CP.
 */
static void mpc8xx_udc_clear_rxbd (volatile cbd_t * rx_cbdp)
{
	rx_cbdp->cbd_datlen = 0x0000;
	rx_cbdp->cbd_sc = ((rx_cbdp->cbd_sc & RX_BD_W) | (RX_BD_E | RX_BD_I));
	__asm__ ("eieio");
}

/* mpc8xx_udc_tx_irq
 *
 * Parse for tx timeout, control RX or USB reset/busy conditions
 * Return -1 on timeout, -2 on fatal error, else return zero
 */
static int mpc8xx_udc_tx_irq (int ep)
{
	int i = 0;

	if (usbp->usber & (USB_TX_ERRMASK)) {
		if (mpc8xx_udc_handle_txerr ()) {
			/* Timeout, controlling function must retry send */
			return -1;
		}
	}

	if (usbp->usber & (USB_E_RESET | USB_E_BSY)) {
		/* Fatal, abandon TX transaction */
		return -2;
	}

	if (usbp->usber & USB_E_RXB) {
		for (i = 0; i < RX_RING_SIZE; i++) {
			if (!(rx_cbd[i]->cbd_sc & RX_BD_E)) {
				if ((rx_cbd[i] == ep_ref[0].prx) || ep) {
					return -2;
				}
			}
		}
	}

	return 0;
}

/* mpc8xx_udc_ep_tx
 *
 * Transmit in a re-entrant fashion outbound USB packets.
 * Implement retry/timeout mechanism described in USB specification
 * Toggle DATA0/DATA1 pids as necessary
 * Introduces non-standard tx_retry. The USB standard has no scope for slave
 * devices to give up TX, however tx_retry stops us getting stuck in an endless
 * TX loop.
 */
static int mpc8xx_udc_ep_tx (struct usb_endpoint_instance *epi)
{
	struct urb *urb = epi->tx_urb;
	volatile cbd_t *tx_cbdp = 0;
	unsigned int ep = 0, pkt_len = 0, x = 0, tx_retry = 0;
	int ret = 0;

	if (!epi || (epi->endpoint_address & 0x03) >= MAX_ENDPOINTS || !urb) {
		return -1;
	}

	ep = epi->endpoint_address & 0x03;
	tx_cbdp = (cbd_t *) (endpoints[ep]->tbptr + CFG_IMMR);

	if (tx_cbdp->cbd_sc & TX_BD_R || usbp->usber & USB_E_TXB) {
		mpc8xx_udc_flush_tx_fifo (ep);
		usbp->usber |= USB_E_TXB;
	};

	while (tx_retry++ < 100) {
		ret = mpc8xx_udc_tx_irq (ep);
		if (ret == -1) {
			/* ignore timeout here */
		} else if (ret == -2) {
			/* Abandon TX */
			mpc8xx_udc_flush_tx_fifo (ep);
			return -1;
		}

		tx_cbdp = (cbd_t *) (endpoints[ep]->tbptr + CFG_IMMR);
		while (tx_cbdp->cbd_sc & TX_BD_R) {
		};
		tx_cbdp->cbd_sc = (tx_cbdp->cbd_sc & TX_BD_W);

		pkt_len = urb->actual_length - epi->sent;

		if (pkt_len > epi->tx_packetSize || pkt_len > EP_MAX_PKT) {
			pkt_len = MIN (epi->tx_packetSize, EP_MAX_PKT);
		}

		for (x = 0; x < pkt_len; x++) {
			*((unsigned char *) (tx_cbdp->cbd_bufaddr + x)) =
				urb->buffer[epi->sent + x];
		}
		tx_cbdp->cbd_datlen = pkt_len;
		tx_cbdp->cbd_sc |= (CBD_TX_BITMASK | ep_ref[ep].pid);
		__asm__ ("eieio");

#ifdef __SIMULATE_ERROR__
		if (++err_poison_test == 2) {
			err_poison_test = 0;
			tx_cbdp->cbd_sc &= ~TX_BD_TC;
		}
#endif

		usbp->uscom = (USCOM_STR | ep);

		while (!(usbp->usber & USB_E_TXB)) {
			ret = mpc8xx_udc_tx_irq (ep);
			if (ret == -1) {
				/* TX timeout */
				break;
			} else if (ret == -2) {
				if (usbp->usber & USB_E_TXB) {
					usbp->usber |= USB_E_TXB;
				}
				mpc8xx_udc_flush_tx_fifo (ep);
				return -1;
			}
		};

		if (usbp->usber & USB_E_TXB) {
			usbp->usber |= USB_E_TXB;
		}

		/* ACK must be present <= 18bit times from TX */
		if (ret == -1) {
			continue;
		}

		/* TX ACK : USB 2.0 8.7.2, Toggle PID, Advance TX */
		epi->sent += pkt_len;
		epi->last = MIN (urb->actual_length - epi->sent, epi->tx_packetSize);
		TOGGLE_TX_PID (ep_ref[ep].pid);

		if (epi->sent >= epi->tx_urb->actual_length) {

			epi->tx_urb->actual_length = 0;
			epi->sent = 0;

			if (ep_ref[ep].sc & EP_SEND_ZLP) {
				ep_ref[ep].sc &= ~EP_SEND_ZLP;
			} else {
				return 0;
			}
		}
	}

	ERR ("TX fail, endpoint 0x%x tx bytes 0x%x/0x%x\n", ep, epi->sent,
	     epi->tx_urb->actual_length);

	return -1;
}

/* mpc8xx_udc_dump_request
 *
 * Dump a control request to console
 */
static void mpc8xx_udc_dump_request (struct usb_device_request *request)
{
	DBG ("bmRequestType:%02x bRequest:%02x wValue:%04x "
	     "wIndex:%04x wLength:%04x ?\n",
	     request->bmRequestType,
	     request->bRequest,
	     request->wValue, request->wIndex, request->wLength);

	return;
}

/* mpc8xx_udc_ep0_rx_setup
 *
 * Decode received ep0 SETUP packet. return non-zero on error
 */
static int mpc8xx_udc_ep0_rx_setup (volatile cbd_t * rx_cbdp)
{
	unsigned int x = 0;
	struct urb *purb = ep_ref[0].urb;
	struct usb_endpoint_instance *epi =
		&udc_device->bus->endpoint_array[0];

	for (; x < rx_cbdp->cbd_datlen; x++) {
		*(((unsigned char *) &ep_ref[0].urb->device_request) + x) =
			*((unsigned char *) (rx_cbdp->cbd_bufaddr + x));
	}

	mpc8xx_udc_clear_rxbd (rx_cbdp);

	if (ep0_recv_setup (purb)) {
		mpc8xx_udc_dump_request (&purb->device_request);
		return -1;
	}

	if ((purb->device_request.bmRequestType & USB_REQ_DIRECTION_MASK)
	    == USB_REQ_HOST2DEVICE) {

		switch (purb->device_request.bRequest) {
		case USB_REQ_SET_ADDRESS:
			/* Send the Status OUT ZLP */
			ep_ref[0].pid = TX_BD_PID_DATA1;
			purb->actual_length = 0;
			mpc8xx_udc_init_tx (epi, purb);
			mpc8xx_udc_ep_tx (epi);

			/* Move to the addressed state */
			usbp->usaddr = udc_device->address;
			mpc8xx_udc_state_transition_up (udc_device->device_state,
							STATE_ADDRESSED);
			return 0;

		case USB_REQ_SET_CONFIGURATION:
			if (!purb->device_request.wValue) {
				/* Respond at default address */
				usbp->usaddr = 0x00;
				mpc8xx_udc_state_transition_down (udc_device->device_state,
								  STATE_ADDRESSED);
			} else {
				/* TODO: Support multiple configurations */
				mpc8xx_udc_state_transition_up (udc_device->device_state,
								STATE_CONFIGURED);
				for (x = 1; x < MAX_ENDPOINTS; x++) {
					if ((udc_device->bus->endpoint_array[x].endpoint_address & USB_ENDPOINT_DIR_MASK)
					    == USB_DIR_IN) {
						ep_ref[x].pid = TX_BD_PID_DATA0;
					} else {
						ep_ref[x].pid = RX_BD_PID_DATA0;
					}
					/* Set configuration must unstall endpoints */
					usbp->usep[x] &= ~STALL_BITMASK;
				}
			}
			break;
		default:
			/* CDC/Vendor specific */
			break;
		}

		/* Send ZLP as ACK in Status OUT phase */
		ep_ref[0].pid = TX_BD_PID_DATA1;
		purb->actual_length = 0;
		mpc8xx_udc_init_tx (epi, purb);
		mpc8xx_udc_ep_tx (epi);

	} else {

		if (purb->actual_length) {
			ep_ref[0].pid = TX_BD_PID_DATA1;
			mpc8xx_udc_init_tx (epi, purb);

			if (!(purb->actual_length % EP0_MAX_PACKET_SIZE)) {
				ep_ref[0].sc |= EP_SEND_ZLP;
			}

			if (purb->device_request.wValue ==
			    USB_DESCRIPTOR_TYPE_DEVICE) {
				if (le16_to_cpu (purb->device_request.wLength)
				    > purb->actual_length) {
					/* Send EP0_MAX_PACKET_SIZE bytes
					 * unless correct size requested.
					 */
					if (purb->actual_length > epi->tx_packetSize) {
						purb->actual_length = epi->tx_packetSize;
					}
				}
			}
			mpc8xx_udc_ep_tx (epi);

		} else {
			/* Corrupt SETUP packet? */
			ERR ("Zero length data or SETUP with DATA-IN phase ?\n");
			return 1;
		}
	}
	return 0;
}

/* mpc8xx_udc_init_tx
 *
 * Setup some basic parameters for a TX transaction
 */
static void mpc8xx_udc_init_tx (struct usb_endpoint_instance *epi,
				struct urb *tx_urb)
{
	epi->sent = 0;
	epi->last = 0;
	epi->tx_urb = tx_urb;
}

/* mpc8xx_udc_ep0_rx
 *
 * Receive ep0/control USB data. Parse and possibly send a response.
 */
static void mpc8xx_udc_ep0_rx (volatile cbd_t * rx_cbdp)
{
	if (rx_cbdp->cbd_sc & RX_BD_PID_SETUP) {

		/* Unconditionally accept SETUP packets */
		if (mpc8xx_udc_ep0_rx_setup (rx_cbdp)) {
			mpc8xx_udc_stall (0);
		}

	} else {

		mpc8xx_udc_clear_rxbd (rx_cbdp);

		if ((rx_cbdp->cbd_datlen - 2)) {
			/* SETUP with a DATA phase
			 * outside of SETUP packet.
			 * Reply with STALL.
			 */
			mpc8xx_udc_stall (0);
		}
	}
}

/* mpc8xx_udc_epn_rx
 *
 * Receive some data from cbd into USB system urb data abstraction
 * Upper layers should NAK if there is insufficient RX data space
 */
static int mpc8xx_udc_epn_rx (unsigned int epid, volatile cbd_t * rx_cbdp)
{
	struct usb_endpoint_instance *epi = 0;
	struct urb *urb = 0;
	unsigned int x = 0;

	if (epid >= MAX_ENDPOINTS || !rx_cbdp->cbd_datlen) {
		return 0;
	}

	/* USB 2.0 PDF section 8.6.4
	 * Discard data with invalid PID it is a resend.
	 */
	if (ep_ref[epid].pid != (rx_cbdp->cbd_sc & 0xC0)) {
		return 1;
	}
	TOGGLE_RX_PID (ep_ref[epid].pid);

	epi = &udc_device->bus->endpoint_array[epid];
	urb = epi->rcv_urb;

	for (; x < (rx_cbdp->cbd_datlen - 2); x++) {
		*((unsigned char *) (urb->buffer + urb->actual_length + x)) =
			*((unsigned char *) (rx_cbdp->cbd_bufaddr + x));
	}

	if (x) {
		usbd_rcv_complete (epi, x, 0);
		if (ep_ref[epid].urb->status == RECV_ERROR) {
			DBG ("RX error unset NAK\n");
			udc_unset_nak (epid);
		}
	}
	return x;
}

/* mpc8xx_udc_clock_init
 *
 * Obtain a clock reference for Full Speed Signaling
 */
static void mpc8xx_udc_clock_init (volatile immap_t * immr,
				   volatile cpm8xx_t * cp)
{

#if defined(CFG_USB_EXTC_CLK)

	/* This has been tested with a 48MHz crystal on CLK6 */
	switch (CFG_USB_EXTC_CLK) {
	case 1:
		immr->im_ioport.iop_papar |= 0x0100;
		immr->im_ioport.iop_padir &= ~0x0100;
		cp->cp_sicr |= 0x24;
		break;
	case 2:
		immr->im_ioport.iop_papar |= 0x0200;
		immr->im_ioport.iop_padir &= ~0x0200;
		cp->cp_sicr |= 0x2D;
		break;
	case 3:
		immr->im_ioport.iop_papar |= 0x0400;
		immr->im_ioport.iop_padir &= ~0x0400;
		cp->cp_sicr |= 0x36;
		break;
	case 4:
		immr->im_ioport.iop_papar |= 0x0800;
		immr->im_ioport.iop_padir &= ~0x0800;
		cp->cp_sicr |= 0x3F;
		break;
	default:
		udc_state = STATE_ERROR;
		break;
	}

#elif defined(CFG_USB_BRGCLK)

	/* This has been tested with brgclk == 50MHz */
	int divisor = 0;

	if (gd->cpu_clk < 48000000L) {
		ERR ("brgclk is too slow for full-speed USB!\n");
		udc_state = STATE_ERROR;
		return;
	}

	/* Assume the brgclk is 'good enough', we want !(gd->cpu_clk%48Mhz)
	 * but, can /probably/ live with close-ish alternative rates.
	 */
	divisor = (gd->cpu_clk / 48000000L) - 1;
	cp->cp_sicr &= ~0x0000003F;

	switch (CFG_USB_BRGCLK) {
	case 1:
		cp->cp_brgc1 |= (divisor | CPM_BRG_EN);
		cp->cp_sicr &= ~0x2F;
		break;
	case 2:
		cp->cp_brgc2 |= (divisor | CPM_BRG_EN);
		cp->cp_sicr |= 0x00000009;
		break;
	case 3:
		cp->cp_brgc3 |= (divisor | CPM_BRG_EN);
		cp->cp_sicr |= 0x00000012;
		break;
	case 4:
		cp->cp_brgc4 = (divisor | CPM_BRG_EN);
		cp->cp_sicr |= 0x0000001B;
		break;
	default:
		udc_state = STATE_ERROR;
		break;
	}

#else
#error "CFG_USB_EXTC_CLK or CFG_USB_BRGCLK must be defined"
#endif

}

/* mpc8xx_udc_cbd_attach
 *
 * attach a cbd to and endpoint
 */
static void mpc8xx_udc_cbd_attach (int ep, uchar tx_size, uchar rx_size)
{

	if (!tx_cbd[ep] || !rx_cbd[ep] || ep >= MAX_ENDPOINTS) {
		udc_state = STATE_ERROR;
		return;
	}

	if (tx_size > USB_MAX_PKT || rx_size > USB_MAX_PKT ||
	    (!tx_size && !rx_size)) {
		udc_state = STATE_ERROR;
		return;
	}

	/* Attach CBD to appropiate Parameter RAM Endpoint data structure */
	if (rx_size) {
		endpoints[ep]->rbase = (u32) rx_cbd[rx_ct];
		endpoints[ep]->rbptr = (u32) rx_cbd[rx_ct];
		rx_ct++;

		if (!ep) {

			endpoints[ep]->rbptr = (u32) rx_cbd[rx_ct];
			rx_cbd[rx_ct]->cbd_sc |= RX_BD_W;
			rx_ct++;

		} else {
			rx_ct += 2;
			endpoints[ep]->rbptr = (u32) rx_cbd[rx_ct];
			rx_cbd[rx_ct]->cbd_sc |= RX_BD_W;
			rx_ct++;
		}

		/* Where we expect to RX data on this endpoint */
		ep_ref[ep].prx = rx_cbd[rx_ct - 1];
	} else {

		ep_ref[ep].prx = 0;
		endpoints[ep]->rbase = 0;
		endpoints[ep]->rbptr = 0;
	}

	if (tx_size) {
		endpoints[ep]->tbase = (u32) tx_cbd[tx_ct];
		endpoints[ep]->tbptr = (u32) tx_cbd[tx_ct];
		tx_ct++;
	} else {
		endpoints[ep]->tbase = 0;
		endpoints[ep]->tbptr = 0;
	}

	endpoints[ep]->tstate = 0;
	endpoints[ep]->tbcnt = 0;
	endpoints[ep]->mrblr = EP_MAX_PKT;
	endpoints[ep]->rfcr = 0x18;
	endpoints[ep]->tfcr = 0x18;
	ep_ref[ep].sc |= EP_ATTACHED;

	DBG ("ep %d rbase 0x%08x rbptr 0x%08x tbase 0x%08x tbptr 0x%08x prx = %p\n",
		ep, endpoints[ep]->rbase, endpoints[ep]->rbptr,
		endpoints[ep]->tbase, endpoints[ep]->tbptr,
		ep_ref[ep].prx);

	return;
}

/* mpc8xx_udc_cbd_init
 *
 * Allocate space for a cbd and allocate TX/RX data space
 */
static void mpc8xx_udc_cbd_init (void)
{
	int i = 0;

	for (; i < TX_RING_SIZE; i++) {
		tx_cbd[i] = (cbd_t *)
			mpc8xx_udc_alloc (sizeof (cbd_t), sizeof (int));
	}

	for (i = 0; i < RX_RING_SIZE; i++) {
		rx_cbd[i] = (cbd_t *)
			mpc8xx_udc_alloc (sizeof (cbd_t), sizeof (int));
	}

	for (i = 0; i < TX_RING_SIZE; i++) {
		tx_cbd[i]->cbd_bufaddr =
			mpc8xx_udc_alloc (EP_MAX_PKT, sizeof (int));

		tx_cbd[i]->cbd_sc = (TX_BD_I | TX_BD_W);
		tx_cbd[i]->cbd_datlen = 0x0000;
	}


	for (i = 0; i < RX_RING_SIZE; i++) {
		rx_cbd[i]->cbd_bufaddr =
			mpc8xx_udc_alloc (EP_MAX_PKT, sizeof (int));
		rx_cbd[i]->cbd_sc = (RX_BD_I | RX_BD_E);
		rx_cbd[i]->cbd_datlen = 0x0000;

	}

	return;
}

/* mpc8xx_udc_endpoint_init
 *
 * Attach an endpoint to some dpram
 */
static void mpc8xx_udc_endpoint_init (void)
{
	int i = 0;

	for (; i < MAX_ENDPOINTS; i++) {
		endpoints[i] = (usb_epb_t *)
			mpc8xx_udc_alloc (sizeof (usb_epb_t), 32);
	}
}

/* mpc8xx_udc_alloc
 *
 * Grab the address of some dpram
 */
static u32 mpc8xx_udc_alloc (u32 data_size, u32 alignment)
{
	u32 retaddr = address_base;

	while (retaddr % alignment) {
		retaddr++;
	}
	address_base += data_size;

	return retaddr;
}

#endif /* CONFIG_MPC885_FAMILY && CONFIG_USB_DEVICE) */
