/*
 * Part of this code has been derived from linux:
 * Universal Host Controller Interface driver for USB (take II).
 *
 * (c) 1999-2001 Georg Acher, acher@in.tum.de (executive slave) (base guitar)
 *               Deti Fliegl, deti@fliegl.de (executive slave) (lead voice)
 *               Thomas Sailer, sailer@ife.ee.ethz.ch (chief consultant) (cheer leader)
 *               Roman Weissgaerber, weissg@vienna.at (virt root hub) (studio porter)
 * (c) 2000      Yggdrasil Computing, Inc. (port of new PCI interface support
 *               from usb-ohci.c by Adam Richter, adam@yggdrasil.com).
 * (C) 2000      David Brownell, david-b@pacbell.net (usb-ohci.c)
 *
 * HW-initalization based on material of
 *
 * (C) Copyright 1999 Linus Torvalds
 * (C) Copyright 1999 Johannes Erdfelt
 * (C) Copyright 1999 Randy Dunlap
 * (C) Copyright 1999 Gregory P. Smith
 *
 *
 * Adapted for U-Boot:
 * (C) Copyright 2001 Denis Peter, MPL AG Switzerland
 * (C) Copyright 2008, Daniel Hellström, daniel@gaisler.com
 *     Added AMBA Plug&Play detection of GRUSB, modified interrupt handler.
 *     Added cache flushes where needed.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

/**********************************************************************
 * How it works:
 * -------------
 * The framelist / Transfer descriptor / Queue Heads are similar like
 * in the linux usb_uhci.c.
 *
 * During initialization, the following skeleton is allocated in init_skel:
 *
 *         framespecific           |           common chain
 *
 * framelist[]
 * [  0 ]-----> TD ---------\
 * [  1 ]-----> TD ----------> TD ------> QH -------> QH -------> QH ---> NULL
 *   ...        TD ---------/
 * [1023]-----> TD --------/
 *
 *              ^^             ^^         ^^          ^^          ^^
 *              7 TDs for      1 TD for   Start of    Start of    End Chain
 *              INT (2-128ms)  1ms-INT    CTRL Chain  BULK Chain
 *
 *
 * Since this is a bootloader, the isochronous transfer descriptor have been removed.
 *
 * Interrupt Transfers.
 * --------------------
 * For Interrupt transfers USB_MAX_TEMP_INT_TD Transfer descriptor are available. They
 * will be inserted after the appropriate (depending the interval setting) skeleton TD.
 * If an interrupt has been detected the dev->irqhandler is called. The status and number
 * of transfered bytes is stored in dev->irq_status resp. dev->irq_act_len. If the
 * dev->irqhandler returns 0, the interrupt TD is removed and disabled. If an 1 is returned,
 * the interrupt TD will be reactivated.
 *
 * Control Transfers
 * -----------------
 * Control Transfers are issued by filling the tmp_td with the appropriate data and connect
 * them to the qh_cntrl queue header. Before other control/bulk transfers can be issued,
 * the programm has to wait for completion. This does not allows asynchronous data transfer.
 *
 * Bulk Transfers
 * --------------
 * Bulk Transfers are issued by filling the tmp_td with the appropriate data and connect
 * them to the qh_bulk queue header. Before other control/bulk transfers can be issued,
 * the programm has to wait for completion. This does not allows asynchronous data transfer.
 *
 *
 */

#include <common.h>
#include <ambapp.h>
#include <asm/leon.h>
#include <asm/leon3.h>
#include <asm/processor.h>

#ifdef CONFIG_USB_UHCI

#include <usb.h>
#include "usb_uhci.h"

DECLARE_GLOBAL_DATA_PTR;

#define USB_MAX_TEMP_TD      128	/* number of temporary TDs for bulk and control transfers */
#define USB_MAX_TEMP_INT_TD  32	/* number of temporary TDs for Interrupt transfers */

/*
#define out16r(address,data) (*(unsigned short *)(address) = \
 (unsigned short)( \
 (((unsigned short)(data)&0xff)<<8) | \
 (((unsigned short)(data)&0xff00)>>8) \
 ))
 */
#define out16r(address,data) _out16r((unsigned int)(address), (unsigned short)(data))
void _out16r(unsigned int address, unsigned short data)
{
	unsigned short val = (unsigned short)((((unsigned short)(data) & 0xff)
					       << 8) | (((unsigned short)(data)
							 & 0xff00) >> 8));
#ifdef UHCI_DEBUG_REGS
	printf("out16r(0x%lx,0x%04x = 0x%04x)\n", address, val, data);
#endif
	*(unsigned short *)(address) = val;
}

#define out32r(address,data) _out32r((unsigned int)(address), (unsigned int)(data))
void _out32r(unsigned int address, unsigned int data)
{
	unsigned int val = (unsigned int)((((unsigned int)(data) & 0x000000ff)
					   << 24) | (((unsigned int)(data) &
						      0x0000ff00) << 8) |
					  (((unsigned int)(data) & 0x00ff0000)
					   >> 8) | (((unsigned int)(data) &
						     0xff000000) >> 24));
#ifdef UHCI_DEBUG_REGS
	printf("out32r(0x%lx,0x%lx = 0x%lx)\n", address, val, data);
#endif
	*(unsigned int *)address = val;
}

#define in16r(address) _in16r((unsigned int)(address))
unsigned short _in16r(unsigned int address)
{
	unsigned short val = sparc_load_reg_cachemiss_word(address);
	val = ((val << 8) & 0xff00) | ((val >> 8) & 0xff);
#ifdef UHCI_DEBUG_REGS
	printf("in16r(0x%lx): 0x%04x\n", address, val);
#endif
	return val;
}

#define in32r(address) _in32r((unsigned int)(address))
unsigned int _in32r(unsigned int address)
{
	unsigned int val = sparc_load_reg_cachemiss(address);
	val =
	    ((val << 24) & 0xff000000) | ((val << 8) & 0xff0000) | ((val >> 8) &
								    0xff00) |
	    ((val >> 24) & 0xff);
#ifdef UHCI_DEBUG_REGS
	printf("in32r(0x%lx): 0x%08x\n", address, val);
#endif
	return val;
}

#define READ32(address) sparc_load_reg_cachemiss((unsigned int)(address))

/*#define USB_UHCI_DEBUG*/
#undef USB_UHCI_DEBUG

void usb_show_td(int max);
#ifdef	USB_UHCI_DEBUG
void grusb_show_regs(void);
#define	USB_UHCI_PRINTF(fmt,args...)	printf (fmt ,##args)
#else
#define USB_UHCI_PRINTF(fmt,args...)
#endif

static int grusb_irq = -1;	/* irq vector, if -1 uhci is stopped / reseted */
unsigned int usb_base_addr;	/* base address */

static uhci_td_t td_int[8] __attribute__ ((aligned(16)));	/* Interrupt Transfer descriptors */
static uhci_qh_t qh_cntrl __attribute__ ((aligned(16)));	/* control Queue Head */
static uhci_qh_t qh_bulk __attribute__ ((aligned(16)));	/*  bulk Queue Head */
static uhci_qh_t qh_end __attribute__ ((aligned(16)));	/* end Queue Head */
static uhci_td_t td_last __attribute__ ((aligned(16)));	/* last TD (linked with end chain) */

/* temporary tds */
static uhci_td_t tmp_td[USB_MAX_TEMP_TD] __attribute__ ((aligned(16)));	/* temporary bulk/control td's  */
static uhci_td_t tmp_int_td[USB_MAX_TEMP_INT_TD] __attribute__ ((aligned(16)));	/* temporary interrupt td's  */

static unsigned long framelist[1024] __attribute__ ((aligned(0x1000)));	/* frame list */

static struct virt_root_hub rh;	/* struct for root hub */

/**********************************************************************
 * some forward decleration
 */
int uhci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
		       void *buffer, int transfer_len,
		       struct devrequest *setup);

/* fill a td with the approproiate data. Link, status, info and buffer
 * are used by the USB controller itselfes, dev is used to identify the
 * "connected" device
 */
void usb_fill_td(uhci_td_t * td, unsigned long link, unsigned long status,
		 unsigned long info, unsigned long buffer, unsigned long dev)
{
	td->link = swap_32(link);
	td->status = swap_32(status);
	if ((info & UHCI_PID) == 0)
		info |= USB_PID_OUT;
	td->info = swap_32(info);
	td->buffer = swap_32(buffer);
	td->dev_ptr = dev;
}

/* fill a qh with the approproiate data. Head and element are used by the USB controller
 * itselfes. As soon as a valid dev_ptr is filled, a td chain is connected to the qh.
 * Please note, that after completion of the td chain, the entry element is removed /
 * marked invalid by the USB controller.
 */
void usb_fill_qh(uhci_qh_t * qh, unsigned long head, unsigned long element)
{
	qh->head = swap_32(head);
	qh->element = swap_32(element);
	qh->dev_ptr = 0L;
}

/* get the status of a td->status
 */
unsigned long usb_uhci_td_stat(unsigned long status)
{
	unsigned long result = 0;
	result |= (status & TD_CTRL_NAK) ? USB_ST_NAK_REC : 0;
	result |= (status & TD_CTRL_STALLED) ? USB_ST_STALLED : 0;
	result |= (status & TD_CTRL_DBUFERR) ? USB_ST_BUF_ERR : 0;
	result |= (status & TD_CTRL_BABBLE) ? USB_ST_BABBLE_DET : 0;
	result |= (status & TD_CTRL_CRCTIMEO) ? USB_ST_CRC_ERR : 0;
	result |= (status & TD_CTRL_BITSTUFF) ? USB_ST_BIT_ERR : 0;
	result |= (status & TD_CTRL_ACTIVE) ? USB_ST_NOT_PROC : 0;
	return result;
}

/* get the status and the transfered len of a td chain.
 * called from the completion handler
 */
int usb_get_td_status(uhci_td_t * td, struct usb_device *dev)
{
	unsigned long temp, info;
	unsigned long stat;
	uhci_td_t *mytd = td;

	if (dev->devnum == rh.devnum)
		return 0;
	dev->act_len = 0;
	stat = 0;
	do {
		temp = swap_32((unsigned long)READ32(&mytd->status));
		stat = usb_uhci_td_stat(temp);
		info = swap_32((unsigned long)READ32(&mytd->info));
		if (((info & 0xff) != USB_PID_SETUP) && (((info >> 21) & 0x7ff) != 0x7ff) && (temp & 0x7FF) != 0x7ff) {	/* if not setup and not null data pack */
			dev->act_len += (temp & 0x7FF) + 1;	/* the transfered len is act_len + 1 */
		}
		if (stat) {	/* status no ok */
			dev->status = stat;
			return -1;
		}
		temp = swap_32((unsigned long)READ32(&mytd->link));
		mytd = (uhci_td_t *) (temp & 0xfffffff0);
	} while ((temp & 0x1) == 0);	/* process all TDs */
	dev->status = stat;
	return 0;		/* Ok */
}

/*-------------------------------------------------------------------
 *                         LOW LEVEL STUFF
 *          assembles QHs und TDs for control, bulk and iso
 *-------------------------------------------------------------------*/
int dummy(void)
{
	USB_UHCI_PRINTF("DUMMY\n");
	return 0;
}

/* Submits a control message. That is a Setup, Data and Status transfer.
 * Routine does not wait for completion.
 */
int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
		       int transfer_len, struct devrequest *setup)
{
	unsigned long destination, status;
	int maxsze = usb_maxpacket(dev, pipe);
	unsigned long dataptr;
	int len;
	int pktsze;
	int i = 0;

	if (!maxsze) {
		USB_UHCI_PRINTF
		    ("uhci_submit_control_urb: pipesize for pipe %lx is zero\n",
		     pipe);
		return -1;
	}
	if (((pipe >> 8) & 0x7f) == rh.devnum) {
		/* this is the root hub -> redirect it */
		return uhci_submit_rh_msg(dev, pipe, buffer, transfer_len,
					  setup);
	}
	USB_UHCI_PRINTF("uhci_submit_control start len %x, maxsize %x\n",
			transfer_len, maxsze);
	/* The "pipe" thing contains the destination in bits 8--18 */
	destination = (pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP;	/* Setup stage */
	/* 3 errors */
	status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | (3 << 27);
	/* (urb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD); */
	/*  Build the TD for the control request, try forever, 8 bytes of data */
	usb_fill_td(&tmp_td[i], UHCI_PTR_TERM, status, destination | (7 << 21),
		    (unsigned long)setup, (unsigned long)dev);
#ifdef DEBUG_EXTRA
	{
		char *sp = (char *)setup;
		printf("SETUP to pipe %lx: %x %x %x %x %x %x %x %x\n", pipe,
		       sp[0], sp[1], sp[2], sp[3], sp[4], sp[5], sp[6], sp[7]);
	}
#endif
	dataptr = (unsigned long)buffer;
	len = transfer_len;

	/* If direction is "send", change the frame from SETUP (0x2D)
	   to OUT (0xE1). Else change it from SETUP to IN (0x69). */
	destination =
	    (pipe & PIPE_DEVEP_MASK) | ((pipe & USB_DIR_IN) ==
					0 ? USB_PID_OUT : USB_PID_IN);
	while (len > 0) {
		/* data stage */
		pktsze = len;
		i++;
		if (pktsze > maxsze)
			pktsze = maxsze;
		destination ^= 1 << TD_TOKEN_TOGGLE;	/* toggle DATA0/1 */
		usb_fill_td(&tmp_td[i], UHCI_PTR_TERM, status, destination | ((pktsze - 1) << 21), dataptr, (unsigned long)dev);	/* Status, pktsze bytes of data */
		tmp_td[i - 1].link = swap_32((unsigned long)&tmp_td[i]);

		dataptr += pktsze;
		len -= pktsze;
	}

	/*  Build the final TD for control status */
	/* It's only IN if the pipe is out AND we aren't expecting data */

	destination &= ~UHCI_PID;
	if (((pipe & USB_DIR_IN) == 0) || (transfer_len == 0))
		destination |= USB_PID_IN;
	else
		destination |= USB_PID_OUT;
	destination |= 1 << TD_TOKEN_TOGGLE;	/* End in Data1 */
	i++;
	status &= ~TD_CTRL_SPD;
	/* no limit on errors on final packet , 0 bytes of data */
	usb_fill_td(&tmp_td[i], UHCI_PTR_TERM, status | TD_CTRL_IOC,
		    destination | (UHCI_NULL_DATA_SIZE << 21), 0,
		    (unsigned long)dev);
	tmp_td[i - 1].link = swap_32((unsigned long)&tmp_td[i]);	/* queue status td */
	/* usb_show_td(i+1); */
	USB_UHCI_PRINTF("uhci_submit_control end (%d tmp_tds used)\n", i);
	/* first mark the control QH element terminated */
	qh_cntrl.element = 0xffffffffL;
	/* set qh active */
	qh_cntrl.dev_ptr = (unsigned long)dev;
	/* fill in tmp_td_chain */
	dummy();
	qh_cntrl.element = swap_32((unsigned long)&tmp_td[0]);
	return 0;
}

/*-------------------------------------------------------------------
 * Prepare TDs for bulk transfers.
 */
int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
		    int transfer_len)
{
	unsigned long destination, status, info;
	unsigned long dataptr;
	int maxsze = usb_maxpacket(dev, pipe);
	int len;
	int i = 0;

	if (transfer_len < 0) {
		printf("Negative transfer length in submit_bulk\n");
		return -1;
	}
	if (!maxsze)
		return -1;
	/* The "pipe" thing contains the destination in bits 8--18. */
	destination = (pipe & PIPE_DEVEP_MASK) | usb_packetid(pipe);
	/* 3 errors */
	status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | (3 << 27);
	/*      ((urb->transfer_flags & USB_DISABLE_SPD) ? 0 : TD_CTRL_SPD) | (3 << 27); */
	/* Build the TDs for the bulk request */
	len = transfer_len;
	dataptr = (unsigned long)buffer;
	do {
		int pktsze = len;
		if (pktsze > maxsze)
			pktsze = maxsze;
		/* pktsze bytes of data  */
		info =
		    destination | (((pktsze - 1) & UHCI_NULL_DATA_SIZE) << 21) |
		    (usb_gettoggle
		     (dev, usb_pipeendpoint(pipe),
		      usb_pipeout(pipe)) << TD_TOKEN_TOGGLE);

		if ((len - pktsze) == 0)
			status |= TD_CTRL_IOC;	/* last one generates INT */

		usb_fill_td(&tmp_td[i], UHCI_PTR_TERM, status, info, dataptr, (unsigned long)dev);	/* Status, pktsze bytes of data */
		if (i > 0)
			tmp_td[i - 1].link = swap_32((unsigned long)&tmp_td[i]);
		i++;
		dataptr += pktsze;
		len -= pktsze;
		usb_dotoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
	} while (len > 0);
	/* first mark the bulk QH element terminated */
	qh_bulk.element = 0xffffffffL;
	/* set qh active */
	qh_bulk.dev_ptr = (unsigned long)dev;
	/* fill in tmp_td_chain */
	qh_bulk.element = swap_32((unsigned long)&tmp_td[0]);
	return 0;
}

/* search a free interrupt td
 */
uhci_td_t *uhci_alloc_int_td(void)
{
	int i;
	for (i = 0; i < USB_MAX_TEMP_INT_TD; i++) {
		if (tmp_int_td[i].dev_ptr == 0)	/* no device assigned -> free TD */
			return &tmp_int_td[i];
	}
	return NULL;
}

/*-------------------------------------------------------------------
 * submits USB interrupt (ie. polling ;-)
 */
int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
		   int transfer_len, int interval)
{
	int nint, n;
	unsigned long status, destination;
	unsigned long info, tmp;
	uhci_td_t *mytd;
	if (interval < 0 || interval >= 256)
		return -1;

	if (interval == 0)
		nint = 0;
	else {
		for (nint = 0, n = 1; nint <= 8; nint++, n += n) {	/* round interval down to 2^n */
			if (interval < n) {
				interval = n / 2;
				break;
			}
		}
		nint--;
	}

	USB_UHCI_PRINTF("Rounded interval to %i, chain  %i\n", interval, nint);
	mytd = uhci_alloc_int_td();
	if (mytd == NULL) {
		printf("No free INT TDs found\n");
		return -1;
	}
	status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | TD_CTRL_IOC | (3 << 27);
/*		(urb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD) | (3 << 27);
*/

	destination =
	    (pipe & PIPE_DEVEP_MASK) | usb_packetid(pipe) |
	    (((transfer_len - 1) & 0x7ff) << 21);

	info =
	    destination |
	    (usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) <<
	     TD_TOKEN_TOGGLE);
	tmp = swap_32(td_int[nint].link);
	usb_fill_td(mytd, tmp, status, info, (unsigned long)buffer,
		    (unsigned long)dev);
	/* Link it */
	tmp = swap_32((unsigned long)mytd);
	td_int[nint].link = tmp;

	usb_dotoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));

	return 0;
}

/**********************************************************************
 * Low Level functions
 */

void reset_hc(void)
{

	/* Global reset for 100ms */
	out16r(usb_base_addr + USBPORTSC1, 0x0204);
	out16r(usb_base_addr + USBPORTSC2, 0x0204);
	out16r(usb_base_addr + USBCMD, USBCMD_GRESET | USBCMD_RS);
	/* Turn off all interrupts */
	out16r(usb_base_addr + USBINTR, 0);
	mdelay(50);
	out16r(usb_base_addr + USBCMD, 0);
	mdelay(10);
}

void start_hc(void)
{
	int timeout = 1000;

	while (in16r(usb_base_addr + USBCMD) & USBCMD_HCRESET) {
		if (!--timeout) {
			printf("USBCMD_HCRESET timed out!\n");
			break;
		}
	}
	/* Turn on all interrupts */
	out16r(usb_base_addr + USBINTR,
	       USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP);
	/* Start at frame 0 */
	out16r(usb_base_addr + USBFRNUM, 0);
	/* set Framebuffer base address */
	out32r(usb_base_addr + USBFLBASEADD, (unsigned long)&framelist);
	/* Run and mark it configured with a 64-byte max packet */
	out16r(usb_base_addr + USBCMD, USBCMD_RS | USBCMD_CF | USBCMD_MAXP);
}

/* Initialize the skeleton
 */
void usb_init_skel(void)
{
	unsigned long temp;
	int n;

	for (n = 0; n < USB_MAX_TEMP_INT_TD; n++)
		tmp_int_td[n].dev_ptr = 0L;	/* no devices connected */
	/* last td */
	usb_fill_td(&td_last, UHCI_PTR_TERM, TD_CTRL_IOC, USB_PID_OUT, 0, 0L);
	/* usb_fill_td(&td_last,UHCI_PTR_TERM,0,0,0); */
	/* End Queue Header */
	usb_fill_qh(&qh_end, UHCI_PTR_TERM, (unsigned long)&td_last);
	/* Bulk Queue Header */
	temp = (unsigned long)&qh_end;
	usb_fill_qh(&qh_bulk, temp | UHCI_PTR_QH, UHCI_PTR_TERM);
	/* Control Queue Header */
	temp = (unsigned long)&qh_bulk;
	usb_fill_qh(&qh_cntrl, temp | UHCI_PTR_QH, UHCI_PTR_TERM);
	/* 1ms Interrupt td */
	temp = (unsigned long)&qh_cntrl;
	usb_fill_td(&td_int[0], temp | UHCI_PTR_QH, 0, USB_PID_OUT, 0, 0L);
	temp = (unsigned long)&td_int[0];
	for (n = 1; n < 8; n++)
		usb_fill_td(&td_int[n], temp, 0, USB_PID_OUT, 0, 0L);
	for (n = 0; n < 1024; n++) {
		/* link all framelist pointers to one of the interrupts */
		int m, o;
		if ((n & 127) == 127)
			framelist[n] = swap_32((unsigned long)&td_int[0]);
		else
			for (o = 1, m = 2; m <= 128; o++, m += m)
				if ((n & (m - 1)) == ((m - 1) / 2))
					framelist[n] =
					    swap_32((unsigned long)&td_int[o]);

	}
}

/* check the common skeleton for completed transfers, and update the status
 * of the "connected" device. Called from the IRQ routine.
 */
void usb_check_skel(void)
{
	struct usb_device *dev;
	/* start with the control qh */
	if (qh_cntrl.dev_ptr != 0) {	/* it's a device assigned check if this caused IRQ */
		dev = (struct usb_device *)qh_cntrl.dev_ptr;
		/* Flush cache now that hardware updated DATA and TDs/QHs */
		if (!gd->arch.snooping_avail)
			sparc_dcache_flush_all();
		usb_get_td_status(&tmp_td[0], dev);	/* update status */
		if (!(dev->status & USB_ST_NOT_PROC)) {	/* is not active anymore, disconnect devices */
			qh_cntrl.dev_ptr = 0;
		}
	}
	/* now process the bulk */
	if (qh_bulk.dev_ptr != 0) {	/* it's a device assigned check if this caused IRQ */
		dev = (struct usb_device *)qh_bulk.dev_ptr;
		/* Flush cache now that hardware updated DATA and TDs/QHs */
		if (!gd->arch.snooping_avail)
			sparc_dcache_flush_all();
		usb_get_td_status(&tmp_td[0], dev);	/* update status */
		if (!(dev->status & USB_ST_NOT_PROC)) {	/* is not active anymore, disconnect devices */
			qh_bulk.dev_ptr = 0;
		}
	}
}

/* check the interrupt chain, ubdate the status of the appropriate device,
 * call the appropriate irqhandler and reactivate the TD if the irqhandler
 * returns with 1
 */
void usb_check_int_chain(void)
{
	int i, res;
	unsigned long link, status;
	struct usb_device *dev;
	uhci_td_t *td, *prevtd;

	for (i = 0; i < 8; i++) {
		prevtd = &td_int[i];	/* the first previous td is the skeleton td */
		link = swap_32(READ32(&td_int[i].link)) & 0xfffffff0;	/* next in chain */
		td = (uhci_td_t *) link;	/* assign it */
		/* all interrupt TDs are finally linked to the td_int[0].
		 * so we process all until we find the td_int[0].
		 * if int0 chain points to a QH, we're also done
		 */
		while (((i > 0) && (link != (unsigned long)&td_int[0])) ||
		       ((i == 0)
			&& !(swap_32(READ32(&td->link)) & UHCI_PTR_QH))) {
			/* check if a device is assigned with this td */
			status = swap_32(READ32(&td->status));
			if ((td->dev_ptr != 0L) && !(status & TD_CTRL_ACTIVE)) {
				/* td is not active and a device is assigned -> call irqhandler */
				dev = (struct usb_device *)td->dev_ptr;
				dev->irq_act_len = ((status & 0x7FF) == 0x7FF) ? 0 : (status & 0x7FF) + 1;	/* transfered length */
				dev->irq_status = usb_uhci_td_stat(status);	/* get status */
				res = dev->irq_handle(dev);	/* call irqhandler */
				if (res == 1) {
					/* reactivate */
					status |= TD_CTRL_ACTIVE;
					td->status = swap_32(status);
					prevtd = td;	/* previous td = this td */
				} else {
					prevtd->link = READ32(&td->link);	/* link previous td directly to the nex td -> unlinked */
					/* remove device pointer */
					td->dev_ptr = 0L;
				}
			}	/* if we call the irq handler */
			link = swap_32(READ32(&td->link)) & 0xfffffff0;	/* next in chain */
			td = (uhci_td_t *) link;	/* assign it */
		}		/* process all td in this int chain */
	}			/* next interrupt chain */
}

/* usb interrupt service routine.
 */
void handle_usb_interrupt(void)
{
	unsigned short status;
	static int error = 0;

	/*
	 * Read the interrupt status, and write it back to clear the
	 * interrupt cause
	 */

	status = in16r(usb_base_addr + USBSTS);

	if (!status)		/* shared interrupt, not mine */
		return;
	if (status != 1) {
		/* remove host controller halted state */
		if ((status & (USBSTS_HCPE | USBSTS_HCH)) ==
		    (USBSTS_HCPE | USBSTS_HCH)) {
			/* Stop due to bug in driver, or hardware */
			out16r(usb_base_addr + USBSTS, status);
			out16r(usb_base_addr + USBCMD,
			       USBCMD_HCRESET | USBCMD_GRESET);
			printf
			    ("GRUSB: HW detected error(s) in USB Descriptors (STS: 0x%x)\n",
			     status);
			usb_show_td(8);
			return;
		} else if ((status & 0x20)
			   && ((in16r(usb_base_addr + USBCMD) & USBCMD_RS) ==
			       0)) {
			if (error < 10) {
				out16r(usb_base_addr + USBCMD,
				       USBCMD_RS | in16r(usb_base_addr +
							 USBCMD));
				error++;
			}
		} else
			error = 0;
	}
	usb_check_int_chain();	/* call interrupt handlers for int tds */
	usb_check_skel();	/* call completion handler for common transfer routines */
	out16r(usb_base_addr + USBSTS, status);
}

/* init uhci
 */
int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
{
	ambapp_ahbdev ahbdev;

	/* Find GRUSB core using AMBA Plug&Play information */
	if (ambapp_ahbslv_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_UHCI,
		CONFIG_SYS_GRLIB_GRUSB_INDEX, &ahbdev) != 1) {
		printf("USB UHCI: Failed to find GRUSB controller\n");
		return -1;
	}
	usb_base_addr = ahbdev.address[0];
	grusb_irq = ahbdev.irq;
	/*
	   usb_base_addr = 0xfffa0000;
	   grusb_irq = 10;
	 */
#ifdef USB_UHCI_DEBUG
	grusb_show_regs();
#endif
	memset(td_int, 0, sizeof(td_int));
	memset(tmp_td, 0, sizeof(tmp_td));
	memset(tmp_int_td, 0, sizeof(tmp_int_td));
	memset(&qh_cntrl, 0, sizeof(qh_cntrl));
	memset(&qh_end, 0, sizeof(qh_end));
	memset(&td_last, 0, sizeof(td_last));

	irq_free_handler(grusb_irq);
	USB_UHCI_PRINTF("GRUSB: at 0x%lx irq %d\n", usb_base_addr, grusb_irq);
	rh.devnum = 0;
	usb_init_skel();
	reset_hc();
	start_hc();
	irq_install_handler(grusb_irq,
			    (interrupt_handler_t *) handle_usb_interrupt, NULL);
	return 0;
}

/* stop uhci
 */
int usb_lowlevel_stop(int index)
{
	if (grusb_irq == -1)
		return 1;
	irq_free_handler(grusb_irq);
	reset_hc();
	grusb_irq = -1;
	return 0;
}

/*******************************************************************************************
 * Virtual Root Hub
 * Since the uhci does not have a real HUB, we simulate one ;-)
 */
#undef	USB_RH_DEBUG

#ifdef	USB_RH_DEBUG
#define	USB_RH_PRINTF(fmt,args...)	printf (fmt ,##args)
static void usb_display_wValue(unsigned short wValue, unsigned short wIndex);
static void usb_display_Req(unsigned short req);
#else
#define USB_RH_PRINTF(fmt,args...)
static void usb_display_wValue(unsigned short wValue, unsigned short wIndex)
{
}
static void usb_display_Req(unsigned short req)
{
}
#endif

#define WANT_USB_ROOT_HUB_HUB_DES
#include <usbroothubdes.h>
#undef WANT_USB_ROOT_HUB_HUB_DES

/*
 * Root Hub Control Pipe (interrupt Pipes are not supported)
 */

int uhci_submit_rh_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
		       int transfer_len, struct devrequest *cmd)
{
	void *data = buffer;
	int leni = transfer_len;
	int len = 0;
	int status = 0;
	int stat = 0;
	int i;

	unsigned short cstatus;

	unsigned short bmRType_bReq;
	unsigned short wValue;
	unsigned short wIndex;
	unsigned short wLength;

	if (usb_pipeint(pipe)) {
		printf("Root-Hub submit IRQ: NOT implemented\n");
		return 0;
	}
	bmRType_bReq = cmd->requesttype | cmd->request << 8;
	wValue = swap_16(cmd->value);
	wIndex = swap_16(cmd->index);
	wLength = swap_16(cmd->length);
	usb_display_Req(bmRType_bReq);
	for (i = 0; i < 8; i++)
		rh.c_p_r[i] = 0;
	USB_RH_PRINTF("Root-Hub: adr: %2x cmd(%1x): %02x%02x %04x %04x %04x\n",
		      dev->devnum, 8, cmd->requesttype, cmd->request, wValue,
		      wIndex, wLength);

	switch (bmRType_bReq) {
		/* Request Destination:
		   without flags: Device,
		   RH_INTERFACE: interface,
		   RH_ENDPOINT: endpoint,
		   RH_CLASS means HUB here,
		   RH_OTHER | RH_CLASS  almost ever means HUB_PORT here
		 */

	case RH_GET_STATUS:
		*(unsigned short *)data = swap_16(1);
		len = 2;
		break;
	case RH_GET_STATUS | RH_INTERFACE:
		*(unsigned short *)data = swap_16(0);
		len = 2;
		break;
	case RH_GET_STATUS | RH_ENDPOINT:
		*(unsigned short *)data = swap_16(0);
		len = 2;
		break;
	case RH_GET_STATUS | RH_CLASS:
		*(unsigned long *)data = swap_32(0);
		len = 4;
		break;		/* hub power ** */
	case RH_GET_STATUS | RH_OTHER | RH_CLASS:

		status = in16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1));
		cstatus = ((status & USBPORTSC_CSC) >> (1 - 0)) |
		    ((status & USBPORTSC_PEC) >> (3 - 1)) |
		    (rh.c_p_r[wIndex - 1] << (0 + 4));
		status = (status & USBPORTSC_CCS) | ((status & USBPORTSC_PE) >> (2 - 1)) | ((status & USBPORTSC_SUSP) >> (12 - 2)) | ((status & USBPORTSC_PR) >> (9 - 4)) | (1 << 8) |	/* power on ** */
		    ((status & USBPORTSC_LSDA) << (-8 + 9));

		*(unsigned short *)data = swap_16(status);
		*(unsigned short *)(data + 2) = swap_16(cstatus);
		len = 4;
		break;
	case RH_CLEAR_FEATURE | RH_ENDPOINT:
		switch (wValue) {
		case (RH_ENDPOINT_STALL):
			len = 0;
			break;
		}
		break;

	case RH_CLEAR_FEATURE | RH_CLASS:
		switch (wValue) {
		case (RH_C_HUB_OVER_CURRENT):
			len = 0;	/* hub power over current ** */
			break;
		}
		break;

	case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
		usb_display_wValue(wValue, wIndex);
		switch (wValue) {
		case (RH_PORT_ENABLE):
			status =
			    in16r(usb_base_addr + USBPORTSC1 +
				  2 * (wIndex - 1));
			status = (status & 0xfff5) & ~USBPORTSC_PE;
			out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
			       status);
			len = 0;
			break;
		case (RH_PORT_SUSPEND):
			status =
			    in16r(usb_base_addr + USBPORTSC1 +
				  2 * (wIndex - 1));
			status = (status & 0xfff5) & ~USBPORTSC_SUSP;
			out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
			       status);
			len = 0;
			break;
		case (RH_PORT_POWER):
			len = 0;	/* port power ** */
			break;
		case (RH_C_PORT_CONNECTION):
			status =
			    in16r(usb_base_addr + USBPORTSC1 +
				  2 * (wIndex - 1));
			status = (status & 0xfff5) | USBPORTSC_CSC;
			out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
			       status);
			len = 0;
			break;
		case (RH_C_PORT_ENABLE):
			status =
			    in16r(usb_base_addr + USBPORTSC1 +
				  2 * (wIndex - 1));
			status = (status & 0xfff5) | USBPORTSC_PEC;
			out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
			       status);
			len = 0;
			break;
		case (RH_C_PORT_SUSPEND):
/*** WR_RH_PORTSTAT(RH_PS_PSSC); */
			len = 0;
			break;
		case (RH_C_PORT_OVER_CURRENT):
			len = 0;
			break;
		case (RH_C_PORT_RESET):
			rh.c_p_r[wIndex - 1] = 0;
			len = 0;
			break;
		}
		break;
	case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
		usb_display_wValue(wValue, wIndex);
		switch (wValue) {
		case (RH_PORT_SUSPEND):
			status =
			    in16r(usb_base_addr + USBPORTSC1 +
				  2 * (wIndex - 1));
			status = (status & 0xfff5) | USBPORTSC_SUSP;
			out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
			       status);
			len = 0;
			break;
		case (RH_PORT_RESET):
			status =
			    in16r(usb_base_addr + USBPORTSC1 +
				  2 * (wIndex - 1));
			status = (status & 0xfff5) | USBPORTSC_PR;
			out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
			       status);
			mdelay(10);
			status = (status & 0xfff5) & ~USBPORTSC_PR;
			out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
			       status);
			udelay(10);
			status = (status & 0xfff5) | USBPORTSC_PE;
			out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
			       status);
			mdelay(10);
			status = (status & 0xfff5) | 0xa;
			out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
			       status);
			len = 0;
			break;
		case (RH_PORT_POWER):
			len = 0;	/* port power ** */
			break;
		case (RH_PORT_ENABLE):
			status =
			    in16r(usb_base_addr + USBPORTSC1 +
				  2 * (wIndex - 1));
			status = (status & 0xfff5) | USBPORTSC_PE;
			out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
			       status);
			len = 0;
			break;
		}
		break;

	case RH_SET_ADDRESS:
		rh.devnum = wValue;
		len = 0;
		break;
	case RH_GET_DESCRIPTOR:
		switch ((wValue & 0xff00) >> 8) {
		case (0x01):	/* device descriptor */
			i = sizeof(root_hub_config_des);
			status = i > wLength ? wLength : i;
			len = leni > status ? status : leni;
			memcpy(data, root_hub_dev_des, len);
			break;
		case (0x02):	/* configuration descriptor */
			i = sizeof(root_hub_config_des);
			status = i > wLength ? wLength : i;
			len = leni > status ? status : leni;
			memcpy(data, root_hub_config_des, len);
			break;
		case (0x03):	/*string descriptors */
			if (wValue == 0x0300) {
				i = sizeof(root_hub_str_index0);
				status = i > wLength ? wLength : i;
				len = leni > status ? status : leni;
				memcpy(data, root_hub_str_index0, len);
				break;
			}
			if (wValue == 0x0301) {
				i = sizeof(root_hub_str_index1);
				status = i > wLength ? wLength : i;
				len = leni > status ? status : leni;
				memcpy(data, root_hub_str_index1, len);
				break;
			}
			stat = USB_ST_STALLED;
		}
		break;

	case RH_GET_DESCRIPTOR | RH_CLASS:
		root_hub_hub_des[2] = 2;
		i = sizeof(root_hub_hub_des);
		status = i > wLength ? wLength : i;
		len = leni > status ? status : leni;
		memcpy(data, root_hub_hub_des, len);
		break;
	case RH_GET_CONFIGURATION:
		*(unsigned char *)data = 0x01;
		len = 1;
		break;
	case RH_SET_CONFIGURATION:
		len = 0;
		break;
	default:
		stat = USB_ST_STALLED;
	}
	USB_RH_PRINTF("Root-Hub stat %lx port1: %x port2: %x\n\n", stat,
		      in16r(usb_base_addr + USBPORTSC1),
		      in16r(usb_base_addr + USBPORTSC2));
	dev->act_len = len;
	dev->status = stat;
	return stat;

}

/********************************************************************************
 * Some Debug Routines
 */

#ifdef	USB_RH_DEBUG

static void usb_display_Req(unsigned short req)
{
	USB_RH_PRINTF("- Root-Hub Request: ");
	switch (req) {
	case RH_GET_STATUS:
		USB_RH_PRINTF("Get Status ");
		break;
	case RH_GET_STATUS | RH_INTERFACE:
		USB_RH_PRINTF("Get Status Interface ");
		break;
	case RH_GET_STATUS | RH_ENDPOINT:
		USB_RH_PRINTF("Get Status Endpoint ");
		break;
	case RH_GET_STATUS | RH_CLASS:
		USB_RH_PRINTF("Get Status Class");
		break;		/* hub power ** */
	case RH_GET_STATUS | RH_OTHER | RH_CLASS:
		USB_RH_PRINTF("Get Status Class Others");
		break;
	case RH_CLEAR_FEATURE | RH_ENDPOINT:
		USB_RH_PRINTF("Clear Feature Endpoint ");
		break;
	case RH_CLEAR_FEATURE | RH_CLASS:
		USB_RH_PRINTF("Clear Feature Class ");
		break;
	case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
		USB_RH_PRINTF("Clear Feature Other Class ");
		break;
	case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
		USB_RH_PRINTF("Set Feature Other Class ");
		break;
	case RH_SET_ADDRESS:
		USB_RH_PRINTF("Set Address ");
		break;
	case RH_GET_DESCRIPTOR:
		USB_RH_PRINTF("Get Descriptor ");
		break;
	case RH_GET_DESCRIPTOR | RH_CLASS:
		USB_RH_PRINTF("Get Descriptor Class ");
		break;
	case RH_GET_CONFIGURATION:
		USB_RH_PRINTF("Get Configuration ");
		break;
	case RH_SET_CONFIGURATION:
		USB_RH_PRINTF("Get Configuration ");
		break;
	default:
		USB_RH_PRINTF("****UNKNOWN**** 0x%04X ", req);
	}
	USB_RH_PRINTF("\n");

}

static void usb_display_wValue(unsigned short wValue, unsigned short wIndex)
{
	switch (wValue) {
	case (RH_PORT_ENABLE):
		USB_RH_PRINTF("Root-Hub: Enable Port %d\n", wIndex);
		break;
	case (RH_PORT_SUSPEND):
		USB_RH_PRINTF("Root-Hub: Suspend Port %d\n", wIndex);
		break;
	case (RH_PORT_POWER):
		USB_RH_PRINTF("Root-Hub: Port Power %d\n", wIndex);
		break;
	case (RH_C_PORT_CONNECTION):
		USB_RH_PRINTF("Root-Hub: C Port Connection Port %d\n", wIndex);
		break;
	case (RH_C_PORT_ENABLE):
		USB_RH_PRINTF("Root-Hub: C Port Enable Port %d\n", wIndex);
		break;
	case (RH_C_PORT_SUSPEND):
		USB_RH_PRINTF("Root-Hub: C Port Suspend Port %d\n", wIndex);
		break;
	case (RH_C_PORT_OVER_CURRENT):
		USB_RH_PRINTF("Root-Hub: C Port Over Current Port %d\n",
			      wIndex);
		break;
	case (RH_C_PORT_RESET):
		USB_RH_PRINTF("Root-Hub: C Port reset Port %d\n", wIndex);
		break;
	default:
		USB_RH_PRINTF("Root-Hub: unknown %x %x\n", wValue, wIndex);
		break;
	}
}

#endif

/*#ifdef	USB_UHCI_DEBUG*/

static int usb_display_td(uhci_td_t * td)
{
	unsigned long tmp;
	int valid;

	printf("TD at %p:\n", td);

	tmp = swap_32(READ32(&td->link));
	printf("Link points to 0x%08lX, %s first, %s, %s\n", tmp & 0xfffffff0,
	       ((tmp & 0x4) == 0x4) ? "Depth" : "Breath",
	       ((tmp & 0x2) == 0x2) ? "QH" : "TD",
	       ((tmp & 0x1) == 0x1) ? "invalid" : "valid");
	valid = ((tmp & 0x1) == 0x0);
	tmp = swap_32(READ32(&td->status));
	printf
	    ("     %s %ld Errors %s %s %s \n     %s %s %s %s %s %s\n     Len 0x%lX\n",
	     (((tmp >> 29) & 0x1) == 0x1) ? "SPD Enable" : "SPD Disable",
	     ((tmp >> 28) & 0x3),
	     (((tmp >> 26) & 0x1) == 0x1) ? "Low Speed" : "Full Speed",
	     (((tmp >> 25) & 0x1) == 0x1) ? "ISO " : "",
	     (((tmp >> 24) & 0x1) == 0x1) ? "IOC " : "",
	     (((tmp >> 23) & 0x1) == 0x1) ? "Active " : "Inactive ",
	     (((tmp >> 22) & 0x1) == 0x1) ? "Stalled" : "",
	     (((tmp >> 21) & 0x1) == 0x1) ? "Data Buffer Error" : "",
	     (((tmp >> 20) & 0x1) == 0x1) ? "Babble" : "",
	     (((tmp >> 19) & 0x1) == 0x1) ? "NAK" : "",
	     (((tmp >> 18) & 0x1) == 0x1) ? "Bitstuff Error" : "",
	     (tmp & 0x7ff));
	tmp = swap_32(READ32(&td->info));
	printf("     MaxLen 0x%lX\n", ((tmp >> 21) & 0x7FF));
	printf("     %sEndpoint 0x%lX Dev Addr 0x%lX PID 0x%lX\n",
	       ((tmp >> 19) & 0x1) == 0x1 ? "TOGGLE " : "", ((tmp >> 15) & 0xF),
	       ((tmp >> 8) & 0x7F), tmp & 0xFF);
	tmp = swap_32(READ32(&td->buffer));
	printf("     Buffer 0x%08lX\n", tmp);
	printf("     DEV %08lX\n", td->dev_ptr);
	return valid;
}

void usb_show_td(int max)
{
	int i;
	if (max > 0) {
		for (i = 0; i < max; i++) {
			usb_display_td(&tmp_td[i]);
		}
	} else {
		i = 0;
		do {
			printf("tmp_td[%d]\n", i);
		} while (usb_display_td(&tmp_td[i++]));
	}
}

void grusb_show_regs(void)
{
	unsigned int tmp;

	tmp = in16r(usb_base_addr + USBCMD);
	printf(" USBCMD:   0x%04x\n", tmp);
	tmp = in16r(usb_base_addr + USBSTS);
	printf(" USBSTS:   0x%04x\n", tmp);
	tmp = in16r(usb_base_addr + USBINTR);
	printf(" USBINTR:   0x%04x\n", tmp);
	tmp = in16r(usb_base_addr + USBFRNUM);
	printf(" FRNUM:   0x%04x\n", tmp);
	tmp = in32r(usb_base_addr + USBFLBASEADD);
	printf(" FLBASEADD:   0x%08x\n", tmp);
	tmp = in16r(usb_base_addr + USBSOF);
	printf(" SOFMOD:   0x%04x\n", tmp);
	tmp = in16r(usb_base_addr + USBPORTSC1);
	printf(" PORTSC1:   0x%04x\n", tmp);
}

/*#endif*/
#endif				/* CONFIG_USB_UHCI */

/* EOF */
