blob: 7fa5288803809653a12fb5308edafaf15b0405e4 [file] [log] [blame]
Lei Wen26cc5122011-10-05 08:11:40 -07001/*
2 * Copyright 2011, Marvell Semiconductor Inc.
3 * Lei Wen <leiwen@marvell.com>
4 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
Lei Wen26cc5122011-10-05 08:11:40 -07006 *
7 * Back ported to the 8xx platform (from the 8260 platform) by
8 * Murray.Jensen@cmst.csiro.au, 27-Jan-01.
9 */
10
11#include <common.h>
12#include <command.h>
13#include <config.h>
14#include <net.h>
15#include <malloc.h>
16#include <asm/io.h>
17#include <linux/types.h>
18#include <usb/mv_udc.h>
19
20#ifndef DEBUG
21#define DBG(x...) do {} while (0)
22#else
23#define DBG(x...) printf(x)
24static const char *reqname(unsigned r)
25{
26 switch (r) {
27 case USB_REQ_GET_STATUS: return "GET_STATUS";
28 case USB_REQ_CLEAR_FEATURE: return "CLEAR_FEATURE";
29 case USB_REQ_SET_FEATURE: return "SET_FEATURE";
30 case USB_REQ_SET_ADDRESS: return "SET_ADDRESS";
31 case USB_REQ_GET_DESCRIPTOR: return "GET_DESCRIPTOR";
32 case USB_REQ_SET_DESCRIPTOR: return "SET_DESCRIPTOR";
33 case USB_REQ_GET_CONFIGURATION: return "GET_CONFIGURATION";
34 case USB_REQ_SET_CONFIGURATION: return "SET_CONFIGURATION";
35 case USB_REQ_GET_INTERFACE: return "GET_INTERFACE";
36 case USB_REQ_SET_INTERFACE: return "SET_INTERFACE";
37 default: return "*UNKNOWN*";
38 }
39}
40#endif
41
42#define PAGE_SIZE 4096
43#define QH_MAXNUM 32
44static struct usb_endpoint_descriptor ep0_out_desc = {
45 .bLength = sizeof(struct usb_endpoint_descriptor),
46 .bDescriptorType = USB_DT_ENDPOINT,
47 .bEndpointAddress = 0,
48 .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
49};
50
51static struct usb_endpoint_descriptor ep0_in_desc = {
52 .bLength = sizeof(struct usb_endpoint_descriptor),
53 .bDescriptorType = USB_DT_ENDPOINT,
54 .bEndpointAddress = USB_DIR_IN,
55 .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
56};
57
58struct ept_queue_head *epts;
59struct ept_queue_item *items[2 * NUM_ENDPOINTS];
60static int mv_pullup(struct usb_gadget *gadget, int is_on);
61static int mv_ep_enable(struct usb_ep *ep,
62 const struct usb_endpoint_descriptor *desc);
63static int mv_ep_disable(struct usb_ep *ep);
64static int mv_ep_queue(struct usb_ep *ep,
65 struct usb_request *req, gfp_t gfp_flags);
66static struct usb_request *
67mv_ep_alloc_request(struct usb_ep *ep, unsigned int gfp_flags);
68static void mv_ep_free_request(struct usb_ep *ep, struct usb_request *_req);
69
70static struct usb_gadget_ops mv_udc_ops = {
71 .pullup = mv_pullup,
72};
73
74static struct usb_ep_ops mv_ep_ops = {
75 .enable = mv_ep_enable,
76 .disable = mv_ep_disable,
77 .queue = mv_ep_queue,
78 .alloc_request = mv_ep_alloc_request,
79 .free_request = mv_ep_free_request,
80};
81
82static struct mv_ep ep[2 * NUM_ENDPOINTS];
83static struct mv_drv controller = {
84 .gadget = {
85 .ep0 = &ep[0].ep,
86 .name = "mv_udc",
87 },
88};
89
90static struct usb_request *
91mv_ep_alloc_request(struct usb_ep *ep, unsigned int gfp_flags)
92{
93 struct mv_ep *mv_ep = container_of(ep, struct mv_ep, ep);
94 return &mv_ep->req;
95}
96
97static void mv_ep_free_request(struct usb_ep *ep, struct usb_request *_req)
98{
99 return;
100}
101
102static void ep_enable(int num, int in)
103{
104 struct ept_queue_head *head;
105 struct mv_udc *udc = controller.udc;
106 unsigned n;
107 head = epts + 2*num + in;
108
109 n = readl(&udc->epctrl[num]);
110 if (in)
111 n |= (CTRL_TXE | CTRL_TXR | CTRL_TXT_BULK);
112 else
113 n |= (CTRL_RXE | CTRL_RXR | CTRL_RXT_BULK);
114
115 if (num != 0)
116 head->config = CONFIG_MAX_PKT(EP_MAX_PACKET_SIZE) | CONFIG_ZLT;
117 writel(n, &udc->epctrl[num]);
118}
119
120static int mv_ep_enable(struct usb_ep *ep,
121 const struct usb_endpoint_descriptor *desc)
122{
123 struct mv_ep *mv_ep = container_of(ep, struct mv_ep, ep);
124 int num, in;
125 num = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
126 in = (desc->bEndpointAddress & USB_DIR_IN) != 0;
127 ep_enable(num, in);
128 mv_ep->desc = desc;
129 return 0;
130}
131
132static int mv_ep_disable(struct usb_ep *ep)
133{
134 return 0;
135}
136
137static int mv_ep_queue(struct usb_ep *ep,
138 struct usb_request *req, gfp_t gfp_flags)
139{
140 struct mv_ep *mv_ep = container_of(ep, struct mv_ep, ep);
141 struct mv_udc *udc = controller.udc;
142 struct ept_queue_item *item;
143 struct ept_queue_head *head;
144 unsigned phys;
145 int bit, num, len, in;
146 num = mv_ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
147 in = (mv_ep->desc->bEndpointAddress & USB_DIR_IN) != 0;
148 item = items[2 * num + in];
149 head = epts + 2 * num + in;
150 phys = (unsigned)req->buf;
151 len = req->length;
152
153 item->next = TERMINATE;
154 item->info = INFO_BYTES(len) | INFO_IOC | INFO_ACTIVE;
155 item->page0 = phys;
156 item->page1 = (phys & 0xfffff000) + 0x1000;
157
158 head->next = (unsigned) item;
159 head->info = 0;
160
161 DBG("ept%d %s queue len %x, buffer %x\n",
162 num, in ? "in" : "out", len, phys);
163
164 if (in)
165 bit = EPT_TX(num);
166 else
167 bit = EPT_RX(num);
168
169 flush_cache(phys, len);
170 flush_cache((unsigned long)item, sizeof(struct ept_queue_item));
171 writel(bit, &udc->epprime);
172
173 return 0;
174}
175
176static void handle_ep_complete(struct mv_ep *ep)
177{
178 struct ept_queue_item *item;
179 int num, in, len;
180 num = ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
181 in = (ep->desc->bEndpointAddress & USB_DIR_IN) != 0;
182 if (num == 0)
183 ep->desc = &ep0_out_desc;
184 item = items[2 * num + in];
185
186 if (item->info & 0xff)
187 printf("EP%d/%s FAIL nfo=%x pg0=%x\n",
188 num, in ? "in" : "out", item->info, item->page0);
189
190 len = (item->info >> 16) & 0x7fff;
191 ep->req.length -= len;
192 DBG("ept%d %s complete %x\n",
193 num, in ? "in" : "out", len);
194 ep->req.complete(&ep->ep, &ep->req);
195 if (num == 0) {
196 ep->req.length = 0;
197 usb_ep_queue(&ep->ep, &ep->req, 0);
198 ep->desc = &ep0_in_desc;
199 }
200}
201
202#define SETUP(type, request) (((type) << 8) | (request))
203
204static void handle_setup(void)
205{
206 struct usb_request *req = &ep[0].req;
207 struct mv_udc *udc = controller.udc;
208 struct ept_queue_head *head;
209 struct usb_ctrlrequest r;
210 int status = 0;
211 int num, in, _num, _in, i;
212 char *buf;
213 head = epts;
214
215 flush_cache((unsigned long)head, sizeof(struct ept_queue_head));
216 memcpy(&r, head->setup_data, sizeof(struct usb_ctrlrequest));
217 writel(EPT_RX(0), &udc->epstat);
218 DBG("handle setup %s, %x, %x index %x value %x\n", reqname(r.bRequest),
219 r.bRequestType, r.bRequest, r.wIndex, r.wValue);
220
221 switch (SETUP(r.bRequestType, r.bRequest)) {
222 case SETUP(USB_RECIP_ENDPOINT, USB_REQ_CLEAR_FEATURE):
223 _num = r.wIndex & 15;
224 _in = !!(r.wIndex & 0x80);
225
226 if ((r.wValue == 0) && (r.wLength == 0)) {
227 req->length = 0;
228 for (i = 0; i < NUM_ENDPOINTS; i++) {
229 if (!ep[i].desc)
230 continue;
231 num = ep[i].desc->bEndpointAddress
232 & USB_ENDPOINT_NUMBER_MASK;
233 in = (ep[i].desc->bEndpointAddress
234 & USB_DIR_IN) != 0;
235 if ((num == _num) && (in == _in)) {
236 ep_enable(num, in);
237 usb_ep_queue(controller.gadget.ep0,
238 req, 0);
239 break;
240 }
241 }
242 }
243 return;
244
245 case SETUP(USB_RECIP_DEVICE, USB_REQ_SET_ADDRESS):
246 /*
247 * write address delayed (will take effect
248 * after the next IN txn)
249 */
250 writel((r.wValue << 25) | (1 << 24), &udc->devaddr);
251 req->length = 0;
252 usb_ep_queue(controller.gadget.ep0, req, 0);
253 return;
254
255 case SETUP(USB_DIR_IN | USB_RECIP_DEVICE, USB_REQ_GET_STATUS):
256 req->length = 2;
257 buf = (char *)req->buf;
258 buf[0] = 1 << USB_DEVICE_SELF_POWERED;
259 buf[1] = 0;
260 usb_ep_queue(controller.gadget.ep0, req, 0);
261 return;
262 }
263 /* pass request up to the gadget driver */
264 if (controller.driver)
265 status = controller.driver->setup(&controller.gadget, &r);
266 else
267 status = -ENODEV;
268
269 if (!status)
270 return;
271 DBG("STALL reqname %s type %x value %x, index %x\n",
272 reqname(r.bRequest), r.bRequestType, r.wValue, r.wIndex);
273 writel((1<<16) | (1 << 0), &udc->epctrl[0]);
274}
275
276static void stop_activity(void)
277{
278 int i, num, in;
279 struct ept_queue_head *head;
280 struct mv_udc *udc = controller.udc;
281 writel(readl(&udc->epcomp), &udc->epcomp);
282 writel(readl(&udc->epstat), &udc->epstat);
283 writel(0xffffffff, &udc->epflush);
284
285 /* error out any pending reqs */
286 for (i = 0; i < NUM_ENDPOINTS; i++) {
287 if (i != 0)
288 writel(0, &udc->epctrl[i]);
289 if (ep[i].desc) {
290 num = ep[i].desc->bEndpointAddress
291 & USB_ENDPOINT_NUMBER_MASK;
292 in = (ep[i].desc->bEndpointAddress & USB_DIR_IN) != 0;
293 head = epts + (num * 2) + (in);
294 head->info = INFO_ACTIVE;
295 }
296 }
297}
298
299void udc_irq(void)
300{
301 struct mv_udc *udc = controller.udc;
302 unsigned n = readl(&udc->usbsts);
303 writel(n, &udc->usbsts);
304 int bit, i, num, in;
305
306 n &= (STS_SLI | STS_URI | STS_PCI | STS_UI | STS_UEI);
307 if (n == 0)
308 return;
309
310 if (n & STS_URI) {
311 DBG("-- reset --\n");
312 stop_activity();
313 }
314 if (n & STS_SLI)
315 DBG("-- suspend --\n");
316
317 if (n & STS_PCI) {
318 DBG("-- portchange --\n");
319 bit = (readl(&udc->portsc) >> 26) & 3;
320 if (bit == 2) {
321 controller.gadget.speed = USB_SPEED_HIGH;
322 for (i = 1; i < NUM_ENDPOINTS && n; i++)
323 if (ep[i].desc)
324 ep[i].ep.maxpacket = 512;
325 } else {
326 controller.gadget.speed = USB_SPEED_FULL;
327 }
328 }
329
330 if (n & STS_UEI)
331 printf("<UEI %x>\n", readl(&udc->epcomp));
332
333 if ((n & STS_UI) || (n & STS_UEI)) {
334 n = readl(&udc->epstat);
335 if (n & EPT_RX(0))
336 handle_setup();
337
338 n = readl(&udc->epcomp);
339 if (n != 0)
340 writel(n, &udc->epcomp);
341
342 for (i = 0; i < NUM_ENDPOINTS && n; i++) {
343 if (ep[i].desc) {
344 num = ep[i].desc->bEndpointAddress
345 & USB_ENDPOINT_NUMBER_MASK;
346 in = (ep[i].desc->bEndpointAddress
347 & USB_DIR_IN) != 0;
348 bit = (in) ? EPT_TX(num) : EPT_RX(num);
349 if (n & bit)
350 handle_ep_complete(&ep[i]);
351 }
352 }
353 }
354}
355
356int usb_gadget_handle_interrupts(void)
357{
358 u32 value;
359 struct mv_udc *udc = controller.udc;
360
361 value = readl(&udc->usbsts);
362 if (value)
363 udc_irq();
364
365 return value;
366}
367
368static int mv_pullup(struct usb_gadget *gadget, int is_on)
369{
370 struct mv_udc *udc = controller.udc;
371 if (is_on) {
372 /* RESET */
373 writel(USBCMD_ITC(MICRO_8FRAME) | USBCMD_RST, &udc->usbcmd);
374 udelay(200);
375
376 writel((unsigned) epts, &udc->epinitaddr);
377
378 /* select DEVICE mode */
379 writel(USBMODE_DEVICE, &udc->usbmode);
380
381 writel(0xffffffff, &udc->epflush);
382
383 /* Turn on the USB connection by enabling the pullup resistor */
384 writel(USBCMD_ITC(MICRO_8FRAME) | USBCMD_RUN, &udc->usbcmd);
385 } else {
386 stop_activity();
387 writel(USBCMD_FS2, &udc->usbcmd);
388 udelay(800);
389 if (controller.driver)
390 controller.driver->disconnect(gadget);
391 }
392
393 return 0;
394}
395
396void udc_disconnect(void)
397{
398 struct mv_udc *udc = controller.udc;
399 /* disable pullup */
400 stop_activity();
401 writel(USBCMD_FS2, &udc->usbcmd);
402 udelay(800);
403 if (controller.driver)
404 controller.driver->disconnect(&controller.gadget);
405}
406
407static int mvudc_probe(void)
408{
409 struct ept_queue_head *head;
410 int i;
411
412 controller.gadget.ops = &mv_udc_ops;
413 controller.udc = (struct mv_udc *)CONFIG_USB_REG_BASE;
414 epts = memalign(PAGE_SIZE, QH_MAXNUM * sizeof(struct ept_queue_head));
415 memset(epts, 0, QH_MAXNUM * sizeof(struct ept_queue_head));
416 for (i = 0; i < 2 * NUM_ENDPOINTS; i++) {
417 /*
418 * For item0 and item1, they are served as ep0
419 * out&in seperately
420 */
421 head = epts + i;
422 if (i < 2)
423 head->config = CONFIG_MAX_PKT(EP0_MAX_PACKET_SIZE)
424 | CONFIG_ZLT | CONFIG_IOS;
425 else
426 head->config = CONFIG_MAX_PKT(EP_MAX_PACKET_SIZE)
427 | CONFIG_ZLT;
428 head->next = TERMINATE;
429 head->info = 0;
430
431 items[i] = memalign(PAGE_SIZE, sizeof(struct ept_queue_item));
432 }
433
434 INIT_LIST_HEAD(&controller.gadget.ep_list);
435 ep[0].ep.maxpacket = 64;
436 ep[0].ep.name = "ep0";
437 ep[0].desc = &ep0_in_desc;
438 INIT_LIST_HEAD(&controller.gadget.ep0->ep_list);
439 for (i = 0; i < 2 * NUM_ENDPOINTS; i++) {
440 if (i != 0) {
441 ep[i].ep.maxpacket = 512;
442 ep[i].ep.name = "ep-";
443 list_add_tail(&ep[i].ep.ep_list,
444 &controller.gadget.ep_list);
445 ep[i].desc = NULL;
446 }
447 ep[i].ep.ops = &mv_ep_ops;
448 }
449 return 0;
450}
451
452int usb_gadget_register_driver(struct usb_gadget_driver *driver)
453{
454 struct mv_udc *udc = controller.udc;
455 int retval;
456
457 if (!driver
458 || driver->speed < USB_SPEED_FULL
459 || !driver->bind
460 || !driver->setup) {
461 DBG("bad parameter.\n");
462 return -EINVAL;
463 }
464
465 if (!mvudc_probe()) {
466 usb_lowlevel_init();
467 /* select ULPI phy */
468 writel(PTS(PTS_ENABLE) | PFSC, &udc->portsc);
469 }
470 retval = driver->bind(&controller.gadget);
471 if (retval) {
472 DBG("driver->bind() returned %d\n", retval);
473 return retval;
474 }
475 controller.driver = driver;
476
477 return 0;
478}
479
480int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
481{
482 return 0;
483}