/*
 * (C) Copyright 2002
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#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 & CONFIG_SYS_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 *) CONFIG_SYS_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 & CONFIG_SYS_POST_USB */
