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