6334088ea4bb8443b028c127c46ec481312d8404
[oweals/u-boot.git] / post / cpu / mpc8xx / usb.c
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
47 typedef 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
59 typedef 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
74 typedef 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
89 int 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 */