/*
 * (C) Copyright 2002
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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>

/*
 * USB test
 *
 * The USB controller is tested in the local loopback mode.
 * It is configured so that endpoint 0 operates as host and endpoint 1
 * operates as function endpoint. After that an IN token transaction
 * is performed.
 * Refer to MPC850 User Manual, Section 32.11.1 USB Host Controller
 * Initialization Example.
 */

#include <post.h>

#if CONFIG_POST & CFG_POST_USB

#include <commproc.h>
#include <command.h>

#define TOUT_LOOP 100

#define	PROFF_USB		((uint)0x0000)

#define CPM_USB_EP0_BASE	0x0a00
#define CPM_USB_EP1_BASE	0x0a20

#define CPM_USB_DT0_BASE	0x0a80
#define CPM_USB_DT1_BASE	0x0a90
#define CPM_USB_DR0_BASE	0x0aa0
#define CPM_USB_DR1_BASE	0x0ab0

#define CPM_USB_RX0_BASE	0x0b00
#define CPM_USB_RX1_BASE	0x0b08
#define CPM_USB_TX0_BASE	0x0b20
#define CPM_USB_TX1_BASE	0x0b28

#define USB_EXPECT(x)		if (!(x)) goto Done;

typedef struct usb_param {
	ushort ep0ptr;
	ushort ep1ptr;
	ushort ep2ptr;
	ushort ep3ptr;
	uint rstate;
	uint rptr;
	ushort frame_n;
	ushort rbcnt;
	ushort rtemp;
} usb_param_t;

typedef struct usb_param_block {
	ushort rbase;
	ushort tbase;
	uchar rfcr;
	uchar tfcr;
	ushort mrblr;
	ushort rbptr;
	ushort tbptr;
	uint tstate;
	uint tptr;
	ushort tcrc;
	ushort tbcnt;
	uint res[2];
} usb_param_block_t;

typedef struct usb {
	uchar usmod;
	uchar usadr;
	uchar uscom;
	uchar res1;
	ushort usep[4];
	uchar res2[4];
	ushort usber;
	uchar res3[2];
	ushort usbmr;
	uchar res4;
	uchar usbs;
	uchar res5[8];
} usb_t;

int usb_post_test (int flags)
{
	int res = -1;
	volatile immap_t *im = (immap_t *) CFG_IMMR;
	volatile cpm8xx_t *cp = &(im->im_cpm);
	volatile usb_param_t *pram_ptr;
	uint dpram;
	ushort DPRAM;
	volatile cbd_t *tx;
	volatile cbd_t *rx;
	volatile usb_t *usbr;
	volatile usb_param_block_t *ep0;
	volatile usb_param_block_t *ep1;
	int j;

	pram_ptr = (usb_param_t *) & (im->im_cpm.cp_dparam[PROFF_USB]);
	dpram = (uint) im->im_cpm.cp_dpmem;
	DPRAM = dpram;
	tx = (cbd_t *) (dpram + CPM_USB_TX0_BASE);
	rx = (cbd_t *) (dpram + CPM_USB_RX0_BASE);
	ep0 = (usb_param_block_t *) (dpram + CPM_USB_EP0_BASE);
	ep1 = (usb_param_block_t *) (dpram + CPM_USB_EP1_BASE);
	usbr = (usb_t *) & (im->im_cpm.cp_scc[0]);

	/* 01 */
	im->im_ioport.iop_padir &= ~(ushort) 0x0200;
	im->im_ioport.iop_papar |= (ushort) 0x0200;

	cp->cp_sicr &= ~0x000000FF;
	cp->cp_sicr |= 0x00000018;

	cp->cp_brgc4 = 0x00010001;

	/* 02 */
	im->im_ioport.iop_padir &= ~(ushort) 0x0002;
	im->im_ioport.iop_padir &= ~(ushort) 0x0001;

	im->im_ioport.iop_papar |= (ushort) 0x0002;
	im->im_ioport.iop_papar |= (ushort) 0x0001;

	/* 03 */
	im->im_ioport.iop_pcdir &= ~(ushort) 0x0020;
	im->im_ioport.iop_pcdir &= ~(ushort) 0x0010;

	im->im_ioport.iop_pcpar &= ~(ushort) 0x0020;
	im->im_ioport.iop_pcpar &= ~(ushort) 0x0010;

	im->im_ioport.iop_pcso |= (ushort) 0x0020;
	im->im_ioport.iop_pcso |= (ushort) 0x0010;

	/* 04 */
	im->im_ioport.iop_pcdir |= (ushort) 0x0200;
	im->im_ioport.iop_pcdir |= (ushort) 0x0100;

	im->im_ioport.iop_pcpar |= (ushort) 0x0200;
	im->im_ioport.iop_pcpar |= (ushort) 0x0100;

	/* 05 */
	pram_ptr->frame_n = 0;

	/* 06 */
	pram_ptr->ep0ptr = DPRAM + CPM_USB_EP0_BASE;
	pram_ptr->ep1ptr = DPRAM + CPM_USB_EP1_BASE;

	/* 07-10 */
	tx[0].cbd_sc = 0xB800;
	tx[0].cbd_datlen = 3;
	tx[0].cbd_bufaddr = dpram + CPM_USB_DT0_BASE;

	tx[1].cbd_sc = 0xBC80;
	tx[1].cbd_datlen = 3;
	tx[1].cbd_bufaddr = dpram + CPM_USB_DT1_BASE;

	rx[0].cbd_sc = 0xA000;
	rx[0].cbd_datlen = 0;
	rx[0].cbd_bufaddr = dpram + CPM_USB_DR0_BASE;

	rx[1].cbd_sc = 0xA000;
	rx[1].cbd_datlen = 0;
	rx[1].cbd_bufaddr = dpram + CPM_USB_DR1_BASE;

	/* 11-12 */
	*(volatile int *) (dpram + CPM_USB_DT0_BASE) = 0x69856000;
	*(volatile int *) (dpram + CPM_USB_DT1_BASE) = 0xABCD1234;

	*(volatile int *) (dpram + CPM_USB_DR0_BASE) = 0;
	*(volatile int *) (dpram + CPM_USB_DR1_BASE) = 0;

	/* 13-16 */
	ep0->rbase = DPRAM + CPM_USB_RX0_BASE;
	ep0->tbase = DPRAM + CPM_USB_TX0_BASE;
	ep0->rfcr = 0x18;
	ep0->tfcr = 0x18;
	ep0->mrblr = 0x100;
	ep0->rbptr = DPRAM + CPM_USB_RX0_BASE;
	ep0->tbptr = DPRAM + CPM_USB_TX0_BASE;
	ep0->tstate = 0;

	/* 17-20 */
	ep1->rbase = DPRAM + CPM_USB_RX1_BASE;
	ep1->tbase = DPRAM + CPM_USB_TX1_BASE;
	ep1->rfcr = 0x18;
	ep1->tfcr = 0x18;
	ep1->mrblr = 0x100;
	ep1->rbptr = DPRAM + CPM_USB_RX1_BASE;
	ep1->tbptr = DPRAM + CPM_USB_TX1_BASE;
	ep1->tstate = 0;

	/* 21-24 */
	usbr->usep[0] = 0x0000;
	usbr->usep[1] = 0x1100;
	usbr->usep[2] = 0x2200;
	usbr->usep[3] = 0x3300;

	/* 25 */
	usbr->usmod = 0x06;

	/* 26 */
	usbr->usadr = 0x05;

	/* 27 */
	usbr->uscom = 0;

	/* 28 */
	usbr->usmod |= 0x01;
	udelay (1);

	/* 29-30 */
	usbr->uscom = 0x80;
	usbr->uscom = 0x81;

	/* Wait for the data packet to be transmitted */
	for (j = 0; j < TOUT_LOOP; j++) {
		if (tx[1].cbd_sc & (ushort) 0x8000)
			udelay (1);
		else
			break;
	}

	USB_EXPECT (j < TOUT_LOOP);

	USB_EXPECT (tx[0].cbd_sc == 0x3800);
	USB_EXPECT (tx[0].cbd_datlen == 3);

	USB_EXPECT (tx[1].cbd_sc == 0x3C80);
	USB_EXPECT (tx[1].cbd_datlen == 3);

	USB_EXPECT (rx[0].cbd_sc == 0x2C00);
	USB_EXPECT (rx[0].cbd_datlen == 5);

	USB_EXPECT (*(volatile int *) (dpram + CPM_USB_DR0_BASE) ==
				0xABCD122B);
	USB_EXPECT (*(volatile char *) (dpram + CPM_USB_DR0_BASE + 4) == 0x42);

	res = 0;
  Done:

	return res;
}

#endif /* CONFIG_POST & CFG_POST_USB */
