blob: e3fe075be5d654f29d09cb858e1dd26bf202f18d [file] [log] [blame]
Wolfgang Denkad5bb452007-03-06 18:08:43 +01001/*
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
Wolfgang Denkad5bb452007-03-06 18:08:43 +010037#include <post.h>
38
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020039#if CONFIG_POST & CONFIG_SYS_POST_USB
Wolfgang Denkad5bb452007-03-06 18:08:43 +010040
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;
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200108 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
Wolfgang Denkad5bb452007-03-06 18:08:43 +0100109 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
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200265#endif /* CONFIG_POST & CONFIG_SYS_POST_USB */