1/* 2 * (C) Copyright 2002 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * See file CREDITS for list of people who contributed to this 6 * project. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 * MA 02111-1307 USA 22 */ 23 24#include <common.h> 25 26/* 27 * USB test 28 * 29 * The USB controller is tested in the local loopback mode. 30 * It is configured so that endpoint 0 operates as host and endpoint 1 31 * operates as function endpoint. After that an IN token transaction 32 * is performed. 33 * Refer to MPC850 User Manual, Section 32.11.1 USB Host Controller 34 * Initialization Example. 35 */ 36 37#include <post.h> 38 39#if CONFIG_POST & CONFIG_SYS_POST_USB 40 41#include <commproc.h> 42#include <command.h> 43 44#define TOUT_LOOP 100 45 46#define PROFF_USB ((uint)0x0000) 47 48#define CPM_USB_EP0_BASE 0x0a00 49#define CPM_USB_EP1_BASE 0x0a20 50 51#define CPM_USB_DT0_BASE 0x0a80 52#define CPM_USB_DT1_BASE 0x0a90 53#define CPM_USB_DR0_BASE 0x0aa0 54#define CPM_USB_DR1_BASE 0x0ab0 55 56#define CPM_USB_RX0_BASE 0x0b00 57#define CPM_USB_RX1_BASE 0x0b08 58#define CPM_USB_TX0_BASE 0x0b20 59#define CPM_USB_TX1_BASE 0x0b28 60 61#define USB_EXPECT(x) if (!(x)) goto Done; 62 63typedef struct usb_param { 64 ushort ep0ptr; 65 ushort ep1ptr; 66 ushort ep2ptr; 67 ushort ep3ptr; 68 uint rstate; 69 uint rptr; 70 ushort frame_n; 71 ushort rbcnt; 72 ushort rtemp; 73} usb_param_t; 74 75typedef struct usb_param_block { 76 ushort rbase; 77 ushort tbase; 78 uchar rfcr; 79 uchar tfcr; 80 ushort mrblr; 81 ushort rbptr; 82 ushort tbptr; 83 uint tstate; 84 uint tptr; 85 ushort tcrc; 86 ushort tbcnt; 87 uint res[2]; 88} usb_param_block_t; 89 90typedef struct usb { 91 uchar usmod; 92 uchar usadr; 93 uchar uscom; 94 uchar res1; 95 ushort usep[4]; 96 uchar res2[4]; 97 ushort usber; 98 uchar res3[2]; 99 ushort usbmr; 100 uchar res4; 101 uchar usbs; 102 uchar res5[8]; 103} usb_t; 104 105int usb_post_test (int flags) 106{ 107 int res = -1; 108 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR; 109 volatile cpm8xx_t *cp = &(im->im_cpm); 110 volatile usb_param_t *pram_ptr; 111 uint dpram; 112 ushort DPRAM; 113 volatile cbd_t *tx; 114 volatile cbd_t *rx; 115 volatile usb_t *usbr; 116 volatile usb_param_block_t *ep0; 117 volatile usb_param_block_t *ep1; 118 int j; 119 120 pram_ptr = (usb_param_t *) & (im->im_cpm.cp_dparam[PROFF_USB]); 121 dpram = (uint) im->im_cpm.cp_dpmem; 122 DPRAM = dpram; 123 tx = (cbd_t *) (dpram + CPM_USB_TX0_BASE); 124 rx = (cbd_t *) (dpram + CPM_USB_RX0_BASE); 125 ep0 = (usb_param_block_t *) (dpram + CPM_USB_EP0_BASE); 126 ep1 = (usb_param_block_t *) (dpram + CPM_USB_EP1_BASE); 127 usbr = (usb_t *) & (im->im_cpm.cp_scc[0]); 128 129 /* 01 */ 130 im->im_ioport.iop_padir &= ~(ushort) 0x0200; 131 im->im_ioport.iop_papar |= (ushort) 0x0200; 132 133 cp->cp_sicr &= ~0x000000FF; 134 cp->cp_sicr |= 0x00000018; 135 136 cp->cp_brgc4 = 0x00010001; 137 138 /* 02 */ 139 im->im_ioport.iop_padir &= ~(ushort) 0x0002; 140 im->im_ioport.iop_padir &= ~(ushort) 0x0001; 141 142 im->im_ioport.iop_papar |= (ushort) 0x0002; 143 im->im_ioport.iop_papar |= (ushort) 0x0001; 144 145 /* 03 */ 146 im->im_ioport.iop_pcdir &= ~(ushort) 0x0020; 147 im->im_ioport.iop_pcdir &= ~(ushort) 0x0010; 148 149 im->im_ioport.iop_pcpar &= ~(ushort) 0x0020; 150 im->im_ioport.iop_pcpar &= ~(ushort) 0x0010; 151 152 im->im_ioport.iop_pcso |= (ushort) 0x0020; 153 im->im_ioport.iop_pcso |= (ushort) 0x0010; 154 155 /* 04 */ 156 im->im_ioport.iop_pcdir |= (ushort) 0x0200; 157 im->im_ioport.iop_pcdir |= (ushort) 0x0100; 158 159 im->im_ioport.iop_pcpar |= (ushort) 0x0200; 160 im->im_ioport.iop_pcpar |= (ushort) 0x0100; 161 162 /* 05 */ 163 pram_ptr->frame_n = 0; 164 165 /* 06 */ 166 pram_ptr->ep0ptr = DPRAM + CPM_USB_EP0_BASE; 167 pram_ptr->ep1ptr = DPRAM + CPM_USB_EP1_BASE; 168 169 /* 07-10 */ 170 tx[0].cbd_sc = 0xB800; 171 tx[0].cbd_datlen = 3; 172 tx[0].cbd_bufaddr = dpram + CPM_USB_DT0_BASE; 173 174 tx[1].cbd_sc = 0xBC80; 175 tx[1].cbd_datlen = 3; 176 tx[1].cbd_bufaddr = dpram + CPM_USB_DT1_BASE; 177 178 rx[0].cbd_sc = 0xA000; 179 rx[0].cbd_datlen = 0; 180 rx[0].cbd_bufaddr = dpram + CPM_USB_DR0_BASE; 181 182 rx[1].cbd_sc = 0xA000; 183 rx[1].cbd_datlen = 0; 184 rx[1].cbd_bufaddr = dpram + CPM_USB_DR1_BASE; 185 186 /* 11-12 */ 187 *(volatile int *) (dpram + CPM_USB_DT0_BASE) = 0x69856000; 188 *(volatile int *) (dpram + CPM_USB_DT1_BASE) = 0xABCD1234; 189 190 *(volatile int *) (dpram + CPM_USB_DR0_BASE) = 0; 191 *(volatile int *) (dpram + CPM_USB_DR1_BASE) = 0; 192 193 /* 13-16 */ 194 ep0->rbase = DPRAM + CPM_USB_RX0_BASE; 195 ep0->tbase = DPRAM + CPM_USB_TX0_BASE; 196 ep0->rfcr = 0x18; 197 ep0->tfcr = 0x18; 198 ep0->mrblr = 0x100; 199 ep0->rbptr = DPRAM + CPM_USB_RX0_BASE; 200 ep0->tbptr = DPRAM + CPM_USB_TX0_BASE; 201 ep0->tstate = 0; 202 203 /* 17-20 */ 204 ep1->rbase = DPRAM + CPM_USB_RX1_BASE; 205 ep1->tbase = DPRAM + CPM_USB_TX1_BASE; 206 ep1->rfcr = 0x18; 207 ep1->tfcr = 0x18; 208 ep1->mrblr = 0x100; 209 ep1->rbptr = DPRAM + CPM_USB_RX1_BASE; 210 ep1->tbptr = DPRAM + CPM_USB_TX1_BASE; 211 ep1->tstate = 0; 212 213 /* 21-24 */ 214 usbr->usep[0] = 0x0000; 215 usbr->usep[1] = 0x1100; 216 usbr->usep[2] = 0x2200; 217 usbr->usep[3] = 0x3300; 218 219 /* 25 */ 220 usbr->usmod = 0x06; 221 222 /* 26 */ 223 usbr->usadr = 0x05; 224 225 /* 27 */ 226 usbr->uscom = 0; 227 228 /* 28 */ 229 usbr->usmod |= 0x01; 230 udelay (1); 231 232 /* 29-30 */ 233 usbr->uscom = 0x80; 234 usbr->uscom = 0x81; 235 236 /* Wait for the data packet to be transmitted */ 237 for (j = 0; j < TOUT_LOOP; j++) { 238 if (tx[1].cbd_sc & (ushort) 0x8000) 239 udelay (1); 240 else 241 break; 242 } 243 244 USB_EXPECT (j < TOUT_LOOP); 245 246 USB_EXPECT (tx[0].cbd_sc == 0x3800); 247 USB_EXPECT (tx[0].cbd_datlen == 3); 248 249 USB_EXPECT (tx[1].cbd_sc == 0x3C80); 250 USB_EXPECT (tx[1].cbd_datlen == 3); 251 252 USB_EXPECT (rx[0].cbd_sc == 0x2C00); 253 USB_EXPECT (rx[0].cbd_datlen == 5); 254 255 USB_EXPECT (*(volatile int *) (dpram + CPM_USB_DR0_BASE) == 256 0xABCD122B); 257 USB_EXPECT (*(volatile char *) (dpram + CPM_USB_DR0_BASE + 4) == 0x42); 258 259 res = 0; 260 Done: 261 262 return res; 263} 264 265#endif /* CONFIG_POST & CONFIG_SYS_POST_USB */ 266