diff options
Diffstat (limited to 'post/usb.c')
| -rw-r--r-- | post/usb.c | 269 | 
1 files changed, 269 insertions, 0 deletions
| diff --git a/post/usb.c b/post/usb.c new file mode 100644 index 000000000..0c74cfa5d --- /dev/null +++ b/post/usb.c @@ -0,0 +1,269 @@ +/* + * (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. + */ + +#ifdef CONFIG_POST + +#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 */ + +#endif /* CONFIG_POST */ |