libpayload: Fix OHCI some more
[coreboot.git] / payloads / libpayload / drivers / usb / ohci.c
1 /*
2  * This file is part of the libpayload project.
3  *
4  * Copyright (C) 2010 Patrick Georgi
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 //#define USB_DEBUG
31
32 #include <arch/virtual.h>
33 #include <usb/usb.h>
34 #include "ohci_private.h"
35 #include "ohci.h"
36
37 static void ohci_start (hci_t *controller);
38 static void ohci_stop (hci_t *controller);
39 static void ohci_reset (hci_t *controller);
40 static void ohci_shutdown (hci_t *controller);
41 static int ohci_bulk (endpoint_t *ep, int size, u8 *data, int finalize);
42 static int ohci_control (usbdev_t *dev, direction_t dir, int drlen, void *devreq,
43                          int dalen, u8 *data);
44 static void* ohci_create_intr_queue (endpoint_t *ep, int reqsize, int reqcount, int reqtiming);
45 static void ohci_destroy_intr_queue (endpoint_t *ep, void *queue);
46 static u8* ohci_poll_intr_queue (void *queue);
47
48 static void
49 ohci_reset (hci_t *controller)
50 {
51 }
52
53 #ifdef USB_DEBUG
54 /* Section 4.3.3 */
55 static const char *completion_codes[] = {
56         "No error",
57         "CRC",
58         "Bit stuffing",
59         "Data toggle mismatch",
60         "Stall",
61         "Device not responding",
62         "PID check failure",
63         "Unexpected PID",
64         "Data overrun",
65         "Data underrun",
66         "--- (10)",
67         "--- (11)",
68         "Buffer overrun",
69         "Buffer underrun",
70         "Not accessed (14)",
71         "Not accessed (15)"
72 };
73
74 /* Section 4.3.1.2 */
75 static const char *direction[] = {
76         "SETUP",
77         "OUT",
78         "IN",
79         "reserved / from TD"
80 };
81 #endif
82
83 hci_t *
84 ohci_init (pcidev_t addr)
85 {
86         int i;
87
88         hci_t *controller = new_controller ();
89
90         if (!controller)
91                 usb_fatal("Could not create USB controller instance.\n");
92
93         controller->instance = malloc (sizeof (ohci_t));
94         if(!controller->instance)
95                 usb_fatal("Not enough memory creating USB controller instance.\n");
96
97         controller->start = ohci_start;
98         controller->stop = ohci_stop;
99         controller->reset = ohci_reset;
100         controller->shutdown = ohci_shutdown;
101         controller->bulk = ohci_bulk;
102         controller->control = ohci_control;
103         controller->create_intr_queue = ohci_create_intr_queue;
104         controller->destroy_intr_queue = ohci_destroy_intr_queue;
105         controller->poll_intr_queue = ohci_poll_intr_queue;
106         for (i = 0; i < 128; i++) {
107                 controller->devices[i] = 0;
108         }
109         init_device_entry (controller, 0);
110         OHCI_INST (controller)->roothub = controller->devices[0];
111
112         controller->bus_address = addr;
113         controller->reg_base = pci_read_config32 (controller->bus_address, 0x10); // OHCI mandates MMIO, so bit 0 is clear
114         OHCI_INST (controller)->opreg = (opreg_t*)phys_to_virt(controller->reg_base);
115         printf("OHCI Version %x.%x\n", (OHCI_INST (controller)->opreg->HcRevision >> 4) & 0xf, OHCI_INST (controller)->opreg->HcRevision & 0xf);
116
117         if ((OHCI_INST (controller)->opreg->HcControl & HostControllerFunctionalStateMask) == USBReset) {
118                 /* cold boot */
119                 OHCI_INST (controller)->opreg->HcControl &= ~RemoteWakeupConnected;
120                 OHCI_INST (controller)->opreg->HcFmInterval = (11999 * FrameInterval) | ((((11999 - 210)*6)/7) * FSLargestDataPacket);
121                 /* TODO: right value for PowerOnToPowerGoodTime ? */
122                 OHCI_INST (controller)->opreg->HcRhDescriptorA = NoPowerSwitching | NoOverCurrentProtection | (10 * PowerOnToPowerGoodTime);
123                 OHCI_INST (controller)->opreg->HcRhDescriptorB = (0 * DeviceRemovable);
124                 udelay(100); /* TODO: reset asserting according to USB spec */
125         } else if ((OHCI_INST (controller)->opreg->HcControl & HostControllerFunctionalStateMask) != USBOperational) {
126                 OHCI_INST (controller)->opreg->HcControl = (OHCI_INST (controller)->opreg->HcControl & ~HostControllerFunctionalStateMask) | USBResume;
127                 udelay(100); /* TODO: resume time according to USB spec */
128         }
129         int interval = OHCI_INST (controller)->opreg->HcFmInterval;
130
131         td_t *periodic_td = memalign(sizeof(*periodic_td), sizeof(*periodic_td));
132         memset((void*)periodic_td, 0, sizeof(*periodic_td));
133         for (i=0; i<32; i++) OHCI_INST (controller)->hcca->HccaInterruptTable[i] = virt_to_phys(periodic_td);
134         /* TODO: build HCCA data structures */
135
136         OHCI_INST (controller)->opreg->HcCommandStatus = HostControllerReset;
137         udelay (10); /* at most 10us for reset to complete. State must be set to Operational within 2ms (5.1.1.4) */
138         OHCI_INST (controller)->opreg->HcFmInterval = interval;
139         OHCI_INST (controller)->hcca = memalign(256, 256);
140         memset((void*)OHCI_INST (controller)->hcca, 0, 256);
141
142         OHCI_INST (controller)->opreg->HcHCCA = virt_to_phys(OHCI_INST (controller)->hcca);
143         OHCI_INST (controller)->opreg->HcControl &= ~IsochronousEnable; // unused by this driver
144         // disable everything, contrary to what OHCI spec says in 5.1.1.4, as we don't need IRQs
145         OHCI_INST (controller)->opreg->HcInterruptEnable = 1<<31;
146         OHCI_INST (controller)->opreg->HcInterruptDisable = ~(1<<31);
147         OHCI_INST (controller)->opreg->HcInterruptStatus = ~0;
148         OHCI_INST (controller)->opreg->HcPeriodicStart = (((OHCI_INST (controller)->opreg->HcFmInterval & FrameIntervalMask) / 10) * 9);
149         OHCI_INST (controller)->opreg->HcControl = (OHCI_INST (controller)->opreg->HcControl & ~HostControllerFunctionalStateMask) | USBOperational;
150
151         mdelay(100);
152
153         controller->devices[0]->controller = controller;
154         controller->devices[0]->init = ohci_rh_init;
155         controller->devices[0]->init (controller->devices[0]);
156         ohci_reset (controller);
157         return controller;
158 }
159
160 static void
161 ohci_shutdown (hci_t *controller)
162 {
163         if (controller == 0)
164                 return;
165         detach_controller (controller);
166         ohci_stop(controller);
167         OHCI_INST (controller)->roothub->destroy (OHCI_INST (controller)->
168                                                   roothub);
169         free (OHCI_INST (controller));
170         free (controller);
171 }
172
173 static void
174 ohci_start (hci_t *controller)
175 {
176 // TODO: turn on all operation of OHCI, but assume that it's initialized.
177 }
178
179 static void
180 ohci_stop (hci_t *controller)
181 {
182 // TODO: turn off all operation of OHCI
183 }
184
185 static void
186 dump_td(td_t *cur, int level)
187 {
188 #ifdef USB_DEBUG
189         static const char *spaces="          ";
190         const char *spc=spaces+(10-level);
191         debug("%std at %x (%s), condition code: %s\n", spc, cur, direction[cur->direction], completion_codes[cur->condition_code & 0xf]);
192         debug("%s toggle: %x\n", spc, cur->toggle);
193 #endif
194 }
195
196 static int
197 wait_for_ed(usbdev_t *dev, ed_t *head)
198 {
199         td_t *cur;
200
201         /* wait for results */
202         while (((head->head_pointer & ~3) != head->tail_pointer) &&
203                 !(head->head_pointer & 1) &&
204                 ((((td_t*)phys_to_virt(head->head_pointer & ~3))->condition_code & 0xf)>=0xe)) {
205                 debug("intst: %x; ctrl: %x; cmdst: %x; head: %x -> %x, tail: %x, condition: %x\n",
206                         OHCI_INST(dev->controller)->opreg->HcInterruptStatus,
207                         OHCI_INST(dev->controller)->opreg->HcControl,
208                         OHCI_INST(dev->controller)->opreg->HcCommandStatus,
209                         head->head_pointer,
210                         ((td_t*)phys_to_virt(head->head_pointer & ~3))->next_td,
211                         head->tail_pointer,
212                         ((td_t*)phys_to_virt(head->head_pointer & ~3))->condition_code);
213                 mdelay(1);
214         }
215         mdelay(5);
216         if (OHCI_INST(dev->controller)->opreg->HcInterruptStatus & WritebackDoneHead) {
217                 debug("done queue:\n");
218                 debug("%x, %x\n", OHCI_INST(dev->controller)->hcca->HccaDoneHead, phys_to_virt(OHCI_INST(dev->controller)->hcca->HccaDoneHead));
219                 if ((OHCI_INST(dev->controller)->hcca->HccaDoneHead & ~1) == 0) {
220                         debug("HcInterruptStatus %x\n", OHCI_INST(dev->controller)->opreg->HcInterruptStatus);
221                 }
222                 td_t *done_queue = NULL;
223                 td_t *done_head = (td_t*)phys_to_virt(OHCI_INST(dev->controller)->hcca->HccaDoneHead);
224                 while (1) {
225                         td_t *oldnext = (td_t*)phys_to_virt(done_head->next_td);
226                         if (oldnext == done_queue) break; /* last element refers to second to last, ie. endless loop */
227                         if (oldnext == phys_to_virt(0)) break; /* last element of done list == first element of real list */
228                         debug("head is %x, pointing to %x. requeueing to %x\n", done_head, oldnext, done_queue);
229                         done_head->next_td = (u32)done_queue;
230                         done_queue = done_head;
231                         done_head = oldnext;
232                 }
233                 for (cur = done_queue; cur != 0; cur = (td_t*)cur->next_td) {
234                         dump_td(cur, 1);
235                 }
236                 OHCI_INST(dev->controller)->opreg->HcInterruptStatus &= ~WritebackDoneHead;
237         }
238
239         if (head->head_pointer & 1) {
240                 debug("HALTED!\n");
241                 return 1;
242         }
243         return 0;
244 }
245
246 static int
247 ohci_control (usbdev_t *dev, direction_t dir, int drlen, void *devreq, int dalen,
248               unsigned char *data)
249 {
250         int i;
251
252         td_t *cur;
253
254         // pages are specified as 4K in OHCI, so don't use getpagesize()
255         int first_page = (unsigned long)data / 4096;
256         int last_page = (unsigned long)(data+dalen-1)/4096;
257         if (last_page < first_page) last_page = first_page;
258         int pages = (dalen==0)?0:(last_page - first_page + 1);
259         int td_count = (pages+1)/2;
260
261         td_t *tds = memalign(sizeof(td_t), (td_count+3)*sizeof(td_t));
262         memset((void*)tds, 0, (td_count+3)*sizeof(td_t));
263
264         for (i=0; i < td_count + 3; i++) {
265                 tds[i].next_td = virt_to_phys(&tds[i+1]);
266         }
267         tds[td_count + 3].next_td = 0;
268
269         tds[0].direction = OHCI_SETUP;
270         tds[0].toggle_from_td = 1;
271         tds[0].toggle = 0;
272         tds[0].error_count = 0;
273         tds[0].delay_interrupt = 7;
274         tds[0].condition_code = 0xf;
275         tds[0].current_buffer_pointer = virt_to_phys(devreq);
276         tds[0].buffer_end = virt_to_phys(devreq + drlen - 1);
277
278         cur = &tds[0];
279
280         while (pages > 0) {
281                 cur++;
282                 cur->direction = (dir==IN)?OHCI_IN:OHCI_OUT;
283                 cur->toggle_from_td = 0;
284                 cur->toggle = 1;
285                 cur->error_count = 0;
286                 cur->delay_interrupt = 7;
287                 cur->condition_code = 0xf;
288                 cur->current_buffer_pointer = virt_to_phys(data);
289                 pages--;
290                 int consumed = (4096 - ((unsigned long)data % 4096));
291                 if (consumed >= dalen) {
292                         // end of data is within same page
293                         cur->buffer_end = virt_to_phys(data + dalen - 1);
294                         dalen = 0;
295                         /* assert(pages == 0); */
296                 } else {
297                         dalen -= consumed;
298                         data += consumed;
299                         pages--;
300                         int second_page_size = dalen;
301                         if (dalen > 4096) {
302                                 second_page_size = 4096;
303                         }
304                         cur->buffer_end = virt_to_phys(data + second_page_size - 1);
305                         dalen -= second_page_size;
306                         data += second_page_size;
307                 }
308         }
309
310         cur++;
311         cur->direction = (dir==IN)?OHCI_OUT:OHCI_IN;
312         cur->toggle_from_td = 1;
313         cur->toggle = 1;
314         cur->error_count = 0;
315         cur->delay_interrupt = 7;
316         cur->condition_code = 0xf;
317         cur->current_buffer_pointer = 0;
318         cur->buffer_end = 0;
319
320         /* final dummy TD */
321         cur++;
322
323         /* Data structures */
324         ed_t *head = memalign(sizeof(ed_t), sizeof(ed_t));
325         memset((void*)head, 0, sizeof(*head));
326         head->function_address = dev->address;
327         head->endpoint_number = 0;
328         head->direction = OHCI_FROM_TD;
329         head->lowspeed = dev->speed;
330         head->format = 0;
331         head->maximum_packet_size = dev->endpoints[0].maxpacketsize;
332         head->tail_pointer = virt_to_phys(cur);
333         head->head_pointer = virt_to_phys(tds);
334         head->halted = 0;
335         head->toggle = 0;
336
337         debug("doing control transfer with %x. first_td at %x\n", head->function_address, virt_to_phys(tds));
338
339         /* activate schedule */
340         OHCI_INST(dev->controller)->opreg->HcControlHeadED = virt_to_phys(head);
341         OHCI_INST(dev->controller)->opreg->HcControl |= ControlListEnable;
342         OHCI_INST(dev->controller)->opreg->HcCommandStatus = ControlListFilled;
343
344         int failure = wait_for_ed(dev, head);
345         OHCI_INST(dev->controller)->opreg->HcControl &= ~ControlListEnable;
346
347         /* free memory */
348         free((void*)tds);
349         free((void*)head);
350
351         return failure;
352 }
353
354 /* finalize == 1: if data is of packet aligned size, add a zero length packet */
355 static int
356 ohci_bulk (endpoint_t *ep, int dalen, u8 *data, int finalize)
357 {
358         int i;
359         debug("bulk: %x bytes from %x, finalize: %x, maxpacketsize: %x\n", dalen, data, finalize, ep->maxpacketsize);
360
361         td_t *cur;
362
363         // pages are specified as 4K in OHCI, so don't use getpagesize()
364         int first_page = (unsigned long)data / 4096;
365         int last_page = (unsigned long)(data+dalen-1)/4096;
366         if (last_page < first_page) last_page = first_page;
367         int pages = (dalen==0)?0:(last_page - first_page + 1);
368         int td_count = (pages+1)/2;
369
370         if (finalize && ((dalen % ep->maxpacketsize) == 0)) {
371                 td_count++;
372         }
373
374         td_t *tds = memalign(sizeof(td_t), (td_count+1)*sizeof(td_t));
375         memset((void*)tds, 0, (td_count+1)*sizeof(td_t));
376
377         for (i=0; i < td_count; i++) {
378                 tds[i].next_td = virt_to_phys(&tds[i+1]);
379         }
380
381         for (cur = tds; cur->next_td != 0; cur++) {
382                 cur->toggle_from_td = 0;
383                 cur->error_count = 0;
384                 cur->delay_interrupt = 7;
385                 cur->condition_code = 0xf;
386                 cur->direction = (ep->direction==IN)?OHCI_IN:OHCI_OUT;
387                 cur->current_buffer_pointer = virt_to_phys(data);
388                 pages--;
389                 if (dalen == 0) {
390                         /* magic TD for empty packet transfer */
391                         cur->current_buffer_pointer = 0;
392                         cur->buffer_end = 0;
393                         /* assert((pages == 0) && finalize); */
394                 }
395                 int consumed = (4096 - ((unsigned long)data % 4096));
396                 if (consumed >= dalen) {
397                         // end of data is within same page
398                         cur->buffer_end = virt_to_phys(data + dalen - 1);
399                         dalen = 0;
400                         /* assert(pages == finalize); */
401                 } else {
402                         dalen -= consumed;
403                         data += consumed;
404                         pages--;
405                         int second_page_size = dalen;
406                         if (dalen > 4096) {
407                                 second_page_size = 4096;
408                         }
409                         cur->buffer_end = virt_to_phys(data + second_page_size - 1);
410                         dalen -= second_page_size;
411                         data += second_page_size;
412                 }
413         }
414
415         /* Data structures */
416         ed_t *head = memalign(sizeof(ed_t), sizeof(ed_t));
417         memset((void*)head, 0, sizeof(*head));
418         head->function_address = ep->dev->address;
419         head->endpoint_number = ep->endpoint & 0xf;
420         head->direction = (ep->direction==IN)?OHCI_IN:OHCI_OUT;
421         head->lowspeed = ep->dev->speed;
422         head->format = 0;
423         head->maximum_packet_size = ep->maxpacketsize;
424         head->tail_pointer = virt_to_phys(cur);
425         head->head_pointer = virt_to_phys(tds);
426         head->halted = 0;
427         head->toggle = ep->toggle;
428
429         debug("doing bulk transfer with %x(%x). first_td at %x, last %x\n", head->function_address, head->endpoint_number, virt_to_phys(tds), virt_to_phys(cur));
430
431         /* activate schedule */
432         OHCI_INST(ep->dev->controller)->opreg->HcBulkHeadED = virt_to_phys(head);
433         OHCI_INST(ep->dev->controller)->opreg->HcControl |= BulkListEnable;
434         OHCI_INST(ep->dev->controller)->opreg->HcCommandStatus = BulkListFilled;
435
436         int failure = wait_for_ed(ep->dev, head);
437         OHCI_INST(ep->dev->controller)->opreg->HcControl &= ~BulkListEnable;
438
439         ep->toggle = head->toggle;
440
441         /* free memory */
442         free((void*)tds);
443         free((void*)head);
444
445         if (failure) {
446                 /* try cleanup */
447                 clear_stall(ep);
448         }
449
450         return failure;
451 }
452
453 /* create and hook-up an intr queue into device schedule */
454 static void*
455 ohci_create_intr_queue (endpoint_t *ep, int reqsize, int reqcount, int reqtiming)
456 {
457         return NULL;
458 }
459
460 /* remove queue from device schedule, dropping all data that came in */
461 static void
462 ohci_destroy_intr_queue (endpoint_t *ep, void *q_)
463 {
464 }
465
466 /* read one intr-packet from queue, if available. extend the queue for new input.
467    return NULL if nothing new available.
468    Recommended use: while (data=poll_intr_queue(q)) process(data);
469  */
470 static u8*
471 ohci_poll_intr_queue (void *q_)
472 {
473         return NULL;
474 }
475