xref: /openbmc/u-boot/drivers/usb/gadget/aspeed_udc.c (revision 93265845)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) ASPEED Technology Inc.
4  *
5  */
6 
7 #include <asm/io.h>
8 #include <asm/byteorder.h>
9 #include <common.h>
10 #include <config.h>
11 #include <dm.h>
12 #include <fdtdec.h>
13 #include <reset.h>
14 #include <usbdevice.h>
15 
16 #include "ep0.h"
17 
18 #define MIN(_x, _y)		\
19 	typeof(_x) (x) = (_x);	\
20 	typeof(_y) (y) = (_y);	\
21 	((x) < (y) ? (x) : (y))
22 
23 /* number of endpoints on this UDC */
24 #define UDC_MAX_ENDPOINTS	21
25 
26 static struct urb *ep0_urb;
27 static struct usb_device_instance *udc_device;
28 
29 struct aspeed_udc_priv {
30 	u32 udc_base;
31 	int init;
32 };
33 
34 struct aspeed_udc_priv *aspeed_udc;
35 
36 /*************************************************************************************/
37 #define AST_VHUB_CTRL				0x00
38 #define AST_VHUB_CONF				0x04
39 #define AST_VHUB_IER				0x08
40 #define AST_VHUB_ISR				0x0C
41 #define AST_VHUB_EP_ACK_IER			0x10
42 #define AST_VHUB_EP_NAK_IER			0x14
43 #define AST_VHUB_EP_ACK_ISR			0x18
44 #define AST_VHUB_EP_NAK_ISR			0x1C
45 #define AST_VHUB_DEV_RESET			0x20
46 #define AST_VHUB_USB_STS			0x24
47 #define AST_VHUB_EP_DATA			0x28
48 #define AST_VHUB_ISO_TX_FAIL			0x2C
49 #define AST_VHUB_EP0_CTRL			0x30
50 #define AST_VHUB_EP0_DATA_BUFF			0x34
51 #define AST_VHUB_EP1_CTRL			0x38
52 #define AST_VHUB_EP1_STS_CHG			0x3C
53 
54 #define AST_VHUB_SETUP_DATA0			0x80
55 #define AST_VHUB_SETUP_DATA1			0x84
56 
57 /*  ************************************************************************************/
58 /* AST_VHUB_CTRL				0x00 */
59 #define ROOT_PHY_CLK_EN				BIT(31)
60 #define ROOT_PHY_RESET_DIS			BIT(11)
61 #define ROOT_UPSTREAM_EN			BIT(0)
62 
63 /* AST_VHUB_ISR					0x0C */
64 #define ISR_EP_NAK				BIT(17)
65 #define ISR_EP_ACK_STALL			BIT(16)
66 #define ISR_DEVICE7				BIT(15)
67 #define ISR_DEVICE6				BIT(14)
68 #define ISR_DEVICE5				BIT(13)
69 #define ISR_DEVICE4				BIT(12)
70 #define ISR_DEVICE3				BIT(11)
71 #define ISR_DEVICE2				BIT(10)
72 #define ISR_DEVICE1				BIT(9)
73 #define ISR_SUSPEND_RESUME			BIT(8)
74 #define ISR_BUS_SUSPEND				BIT(7)
75 #define ISR_BUS_RESET				BIT(6)
76 #define ISR_HUB_EP1_IN_DATA_ACK			BIT(5)
77 #define ISR_HUB_EP0_IN_DATA_NAK			BIT(4)
78 #define ISR_HUB_EP0_IN_ACK_STALL		BIT(3)
79 #define ISR_HUB_EP0_OUT_NAK			BIT(2)
80 #define ISR_HUB_EP0_OUT_ACK_STALL		BIT(1)
81 #define ISR_HUB_EP0_SETUP			BIT(0)
82 
83 /* AST_VHUB_USB_STS				0x24 */
84 #define USB_BUS_HIGH_SPEED			BIT(27)
85 
86 /* AST_VHUB_EP0_CTRL				0x30 */
87 #define EP0_GET_RX_LEN(x)			(((x) >> 16) & 0x7f)
88 #define EP0_TX_LEN(x)				(((x) & 0x7f) << 8)
89 #define EP0_RX_BUFF_RDY				BIT(2)
90 #define EP0_TX_BUFF_RDY				BIT(1)
91 #define EP0_STALL				BIT(0)
92 
93 #define AST_UDC_DEV_CTRL			0x00
94 #define AST_UDC_DEV_ISR				0x04
95 #define AST_UDC_DEV_EP0_CTRL			0x08
96 #define AST_UDC_DEV_EP0_DATA_BUFF		0x0C
97 
98 /*************************************************************************************/
99 #define AST_EP_BASE				0x200
100 #define AST_EP_OFFSET				0x10
101 #define AST_EP_CONFIG				0x00
102 #define AST_EP_DMA_CTRL				0x04
103 #define AST_EP_DMA_BUFF				0x08
104 #define AST_EP_DMA_STS				0x0C
105 
106 /*************************************************************************************/
107 /* AST_EP_CONFIG				0x00 */
108 #define EP_SET_MAX_PKT(x)			(((x) & 0x3ff) << 16)
109 #define EP_SET_EP_STALL				BIT(12)
110 #define EP_SET_EP_NUM(x)			(((x) & 0xf) << 8)
111 #define EP_TYPE_BULK_IN				(0x2 << 4)
112 #define EP_TYPE_BULK_OUT			(0x3 << 4)
113 #define EP_TYPE_INT_IN				(0x4 << 4)
114 #define EP_TYPE_INT_OUT				(0x5 << 4)
115 #define EP_TYPE_ISO_IN				(0x6 << 4)
116 #define EP_TYPE_ISO_OUT				(0x7 << 4)
117 #define EP_ENABLE				BIT(0)
118 
119 /* AST_EP_DMA_CTRL				0x04 */
120 #define EP_SINGLE_DESC_MODE			BIT(1)
121 
122 /* AST_EP_DMA_STS				0x0C */
123 #define AST_EP_TX_DATA_BYTE(x)			(((x) & 0x3ff) << 16)
124 #define AST_EP_START_TRANS			BIT(0)
125 
126 /*-------------------------------------------------------------------------*/
127 #define ast_udc_read(offset) \
128 	__raw_readl(aspeed_udc->udc_base + (offset))
129 #define ast_udc_write(val, offset) \
130 	__raw_writel((u32)val, aspeed_udc->udc_base + (offset))
131 
132 #define ast_ep_read(ep_reg, reg) \
133 	__raw_readl((ep_reg) + (reg))
134 #define ast_ep_write(ep_reg, val, reg) \
135 	__raw_writel((u32)val, (ep_reg) + (reg))
136 /*-------------------------------------------------------------------------*/
137 
138 int is_usbd_high_speed(void)
139 {
140 	if (ast_udc_read(AST_VHUB_USB_STS) & USB_BUS_HIGH_SPEED)
141 		return 1;
142 
143 	return 0;
144 }
145 
146 static void udc_stall_ep(u32 ep_num)
147 {
148 	u32 ep_reg;
149 
150 	usbdbg("stall ep: %d", ep_num);
151 
152 	if (ep_num) {
153 		ep_reg = aspeed_udc->udc_base + AST_EP_BASE +
154 			 (AST_EP_OFFSET * (ep_num - 1));
155 		ast_ep_write(ep_reg, ast_ep_read(ep_reg, AST_EP_CONFIG) |
156 			     EP_SET_EP_STALL,
157 			     AST_EP_CONFIG);
158 
159 	} else {
160 		ast_udc_write(ast_udc_read(AST_VHUB_EP0_CTRL) | EP0_STALL,
161 			      AST_VHUB_EP0_CTRL);
162 	}
163 }
164 
165 int udc_endpoint_write(struct usb_endpoint_instance *endpoint)
166 {
167 	struct urb *urb = endpoint->tx_urb;
168 	u32 remaining_packet;
169 	u32 ep_reg, length;
170 	int timeout = 2000; // 2ms
171 	int ep_num;
172 	u8 *data;
173 
174 	if (!endpoint) {
175 		usberr("Error input: endpoint\n");
176 		return -1;
177 	}
178 
179 	ep_num = endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK;
180 	ep_reg = aspeed_udc->udc_base + AST_EP_BASE + (AST_EP_OFFSET * (ep_num - 1));
181 	remaining_packet = urb->actual_length - endpoint->sent;
182 
183 	if (endpoint->tx_packetSize < remaining_packet)
184 		length = endpoint->tx_packetSize;
185 	else
186 		length = remaining_packet;
187 
188 //	usbdbg("ep: %d, trans len: %d, ep sent: %d, urb actual len: %d\n",
189 //		ep_num, length, endpoint->sent, urb->actual_length);
190 
191 	data = (u8 *)urb->buffer;
192 	data += endpoint->sent;
193 
194 	// tx trigger
195 	ast_ep_write(ep_reg, data, AST_EP_DMA_BUFF);
196 	ast_ep_write(ep_reg, AST_EP_TX_DATA_BYTE(length), AST_EP_DMA_STS);
197 	ast_ep_write(ep_reg, AST_EP_TX_DATA_BYTE(length) | AST_EP_START_TRANS,
198 		     AST_EP_DMA_STS);
199 
200 	endpoint->last = length;
201 
202 	// wait for tx complete
203 	while (ast_ep_read(ep_reg, AST_EP_DMA_STS) & 0x1) {
204 		if (timeout-- == 0)
205 			return -1;
206 
207 		udelay(1);
208 	}
209 
210 	return 0;
211 }
212 
213 static void ast_udc_ep_handle(struct usb_endpoint_instance *endpoint)
214 {
215 	int ep_isout, ep_num;
216 	int nbytes;
217 	u32 ep_reg;
218 
219 	ep_isout = (endpoint->endpoint_address & USB_ENDPOINT_DIR_MASK) ==
220 		   USB_DIR_OUT;
221 	ep_num = endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK;
222 
223 	ep_reg = aspeed_udc->udc_base + AST_EP_BASE + (AST_EP_OFFSET * (ep_num - 1));
224 
225 	if (ep_isout) {
226 		nbytes = (ast_ep_read(ep_reg, AST_EP_DMA_STS) >> 16) & 0x7ff;
227 		usbd_rcv_complete(endpoint, nbytes, 0);
228 
229 		//trigger next
230 		ast_ep_write(ep_reg, AST_EP_START_TRANS, AST_EP_DMA_STS);
231 
232 	} else {
233 		usbd_tx_complete(endpoint);
234 	}
235 }
236 
237 static void ast_udc_ep0_rx(struct usb_endpoint_instance *endpoint)
238 {
239 	struct urb *urb;
240 	u8 *buff;
241 
242 	if (!endpoint) {
243 		usberr("Error input: endpoint\n");
244 		return;
245 	}
246 
247 	urb = endpoint->rcv_urb;
248 	if (!urb) {
249 		usberr("Error: rcv_urb is empty\n");
250 		return;
251 	}
252 
253 	buff = urb->buffer;
254 	ast_udc_write(buff, AST_VHUB_EP0_DATA_BUFF);
255 
256 	// trigger rx
257 	ast_udc_write(EP0_RX_BUFF_RDY, AST_VHUB_EP0_CTRL);
258 }
259 
260 static void ast_udc_ep0_out(struct usb_endpoint_instance *endpoint)
261 {
262 	u16 rx_len = EP0_GET_RX_LEN(ast_udc_read(AST_VHUB_EP0_CTRL));
263 
264 	/* Check direction */
265 	if ((ep0_urb->device_request.bmRequestType & USB_REQ_DIRECTION_MASK) ==
266 		USB_REQ_DEVICE2HOST) {
267 		if (rx_len != 0)
268 			usberr("Unexpected USB REQ direction: D2H\n");
269 
270 	} else {
271 		usbdbg("EP0 OUT packet ACK, sent zero-length packet");
272 		ast_udc_write(EP0_TX_BUFF_RDY, AST_VHUB_EP0_CTRL);
273 	}
274 }
275 
276 static void ast_udc_ep0_tx(struct usb_endpoint_instance *endpoint)
277 {
278 	struct urb *urb;
279 	u32 last;
280 
281 	if (!endpoint) {
282 		usberr("Error input: endpoint\n");
283 		return;
284 	}
285 
286 	urb = endpoint->tx_urb;
287 	if (!urb) {
288 		usberr("Error: tx_urb is empty\n");
289 		return;
290 	}
291 
292 	usbdbg("urb->buffer: %p, buffer_length: %d, actual_length: %d, sent:%d",
293 	       urb->buffer, urb->buffer_length,
294 	       urb->actual_length, endpoint->sent);
295 
296 	last = MIN(urb->actual_length - endpoint->sent,
297 		   endpoint->tx_packetSize);
298 
299 	if (last) {
300 		u8 *cp = urb->buffer + endpoint->sent;
301 
302 		usbdbg("send address %x", (u32)cp);
303 
304 		/*
305 		 * This ensures that USBD packet fifo is accessed
306 		 * - through word aligned pointer or
307 		 * - through non word aligned pointer but only
308 		 *   with a max length to make the next packet
309 		 *   word aligned
310 		 */
311 
312 		usbdbg("ep sent: %d, tx_packetSize: %d, last: %d",
313 		       endpoint->sent, endpoint->tx_packetSize, last);
314 
315 		ast_udc_write(cp, AST_VHUB_EP0_DATA_BUFF);
316 
317 		// trigger tx
318 		ast_udc_write(EP0_TX_LEN(last), AST_VHUB_EP0_CTRL);
319 		ast_udc_write(EP0_TX_LEN(last) | EP0_TX_BUFF_RDY, AST_VHUB_EP0_CTRL);
320 	}
321 
322 	endpoint->last = last;
323 }
324 
325 void ast_udc_ep0_in(struct usb_endpoint_instance *endpoint)
326 {
327 	struct usb_device_request *request = &ep0_urb->device_request;
328 
329 	usbdbg("ast_udc_ep0_in");
330 
331 	/* Check direction */
332 	if ((request->bmRequestType & USB_REQ_DIRECTION_MASK) ==
333 	    USB_REQ_HOST2DEVICE) {
334 		/*
335 		 * This tx interrupt must be for a control write status
336 		 * stage packet.
337 		 */
338 		usbdbg("ACK on EP0 control write status stage packet");
339 	} else {
340 		/*
341 		 * This tx interrupt must be for a control read data
342 		 * stage packet.
343 		 */
344 		int wLength = le16_to_cpu(request->wLength);
345 
346 		/*
347 		 * Update our count of bytes sent so far in this
348 		 * transfer.
349 		 */
350 		endpoint->sent += endpoint->last;
351 
352 		/*
353 		 * We are finished with this transfer if we have sent
354 		 * all of the bytes in our tx urb (urb->actual_length)
355 		 * unless we need a zero-length terminating packet.  We
356 		 * need a zero-length terminating packet if we returned
357 		 * fewer bytes than were requested (wLength) by the host,
358 		 * and the number of bytes we returned is an exact
359 		 * multiple of the packet size endpoint->tx_packetSize.
360 		 */
361 		if (endpoint->sent == ep0_urb->actual_length &&
362 		    (ep0_urb->actual_length == wLength ||
363 		     endpoint->last != endpoint->tx_packetSize)) {
364 			/* Done with control read data stage. */
365 			usbdbg("control read data stage complete");
366 			//trigger for rx
367 			endpoint->rcv_urb = ep0_urb;
368 			endpoint->sent = 0;
369 			ast_udc_ep0_rx(endpoint);
370 
371 		} else {
372 			/*
373 			 * We still have another packet of data to send
374 			 * in this control read data stage or else we
375 			 * need a zero-length terminating packet.
376 			 */
377 			usbdbg("ACK control read data stage packet");
378 
379 			ast_udc_ep0_tx(endpoint);
380 		}
381 	}
382 }
383 
384 static void ast_udc_setup_handle(struct usb_endpoint_instance *endpoint)
385 {
386 	u32 *setup = (u32 *)(aspeed_udc->udc_base + AST_VHUB_SETUP_DATA0);
387 	u8 *datap = (u8 *)&ep0_urb->device_request;
388 
389 	usbdbg("-> Entering device setup");
390 
391 	/* 8 bytes setup packet */
392 	memcpy(datap, setup, sizeof(setup) * 2);
393 
394 	/* Try to process setup packet */
395 	if (ep0_recv_setup(ep0_urb)) {
396 		/* Not a setup packet, stall next EP0 transaction */
397 		udc_stall_ep(0);
398 		usbinfo("Cannot parse setup packet, wait another setup...\n");
399 		return;
400 	}
401 
402 	/* Check direction */
403 	if ((ep0_urb->device_request.bmRequestType & USB_REQ_DIRECTION_MASK) ==
404 	    USB_REQ_HOST2DEVICE) {
405 		switch (ep0_urb->device_request.bRequest) {
406 		case USB_REQ_SET_ADDRESS:
407 			usbdbg("set addr: %x", ep0_urb->device_request.wValue);
408 			ast_udc_write(ep0_urb->device_request.wValue,
409 				      AST_VHUB_CONF);
410 			ast_udc_write(EP0_TX_BUFF_RDY, AST_VHUB_EP0_CTRL);
411 			usbd_device_event_irq(udc_device,
412 					      DEVICE_ADDRESS_ASSIGNED, 0);
413 			break;
414 
415 		case USB_REQ_SET_CONFIGURATION:
416 			usbdbg("set configuration");
417 			ast_udc_write(EP0_TX_BUFF_RDY, AST_VHUB_EP0_CTRL);
418 			usbd_device_event_irq(udc_device,
419 					      DEVICE_CONFIGURED, 0);
420 			break;
421 
422 		default:
423 			if (ep0_urb->device_request.wLength) {
424 				endpoint->rcv_urb = ep0_urb;
425 				endpoint->sent = 0;
426 				ast_udc_ep0_rx(endpoint);
427 
428 			} else {
429 				// send zero-length IN packet
430 				ast_udc_write(EP0_TX_BUFF_RDY,
431 					      AST_VHUB_EP0_CTRL);
432 			}
433 			break;
434 		}
435 
436 	} else {
437 		usbdbg("control read on EP0");
438 		/*
439 		 * The ep0_recv_setup function has already placed our response
440 		 * packet data in ep0_urb->buffer and the packet length in
441 		 * ep0_urb->actual_length.
442 		 */
443 		endpoint->tx_urb = ep0_urb;
444 		endpoint->sent = 0;
445 		ast_udc_ep0_tx(endpoint);
446 	}
447 
448 	usbdbg("<- Leaving device setup");
449 }
450 
451 void udc_irq(void)
452 {
453 	u32 isr = ast_udc_read(AST_VHUB_ISR);
454 	u32 ep_isr;
455 	int i;
456 
457 	if (!isr)
458 		return;
459 
460 	if (isr & ISR_BUS_RESET) {
461 		usbdbg("ISR_BUS_RESET");
462 		ast_udc_write(ISR_BUS_RESET, AST_VHUB_ISR);
463 		usbd_device_event_irq(udc_device, DEVICE_RESET, 0);
464 	}
465 
466 	if (isr & ISR_BUS_SUSPEND) {
467 		usbdbg("ISR_BUS_SUSPEND");
468 		ast_udc_write(ISR_BUS_SUSPEND, AST_VHUB_ISR);
469 		usbd_device_event_irq(udc_device, DEVICE_BUS_INACTIVE, 0);
470 	}
471 
472 	if (isr & ISR_SUSPEND_RESUME) {
473 		usbdbg("ISR_SUSPEND_RESUME");
474 		ast_udc_write(ISR_SUSPEND_RESUME, AST_VHUB_ISR);
475 		usbd_device_event_irq(udc_device, DEVICE_BUS_ACTIVITY, 0);
476 	}
477 
478 	if (isr & ISR_HUB_EP0_IN_ACK_STALL) {
479 //		usbdbg("ISR_HUB_EP0_IN_ACK_STALL");
480 		ast_udc_write(ISR_HUB_EP0_IN_ACK_STALL, AST_VHUB_ISR);
481 		ast_udc_ep0_in(udc_device->bus->endpoint_array);
482 	}
483 
484 	if (isr & ISR_HUB_EP0_OUT_ACK_STALL) {
485 //		usbdbg("ISR_HUB_EP0_OUT_ACK_STALL");
486 		ast_udc_write(ISR_HUB_EP0_OUT_ACK_STALL, AST_VHUB_ISR);
487 		ast_udc_ep0_out(udc_device->bus->endpoint_array);
488 	}
489 
490 	if (isr & ISR_HUB_EP0_OUT_NAK) {
491 //		usbdbg("ISR_HUB_EP0_OUT_NAK");
492 		ast_udc_write(ISR_HUB_EP0_OUT_NAK, AST_VHUB_ISR);
493 	}
494 
495 	if (isr & ISR_HUB_EP0_IN_DATA_NAK) {
496 //		usbdbg("ISR_HUB_EP0_IN_DATA_ACK");
497 		ast_udc_write(ISR_HUB_EP0_IN_DATA_NAK, AST_VHUB_ISR);
498 	}
499 
500 	if (isr & ISR_HUB_EP0_SETUP) {
501 		usbdbg("SETUP");
502 		ast_udc_write(ISR_HUB_EP0_SETUP, AST_VHUB_ISR);
503 		ast_udc_setup_handle(udc_device->bus->endpoint_array);
504 	}
505 
506 	if (isr & ISR_HUB_EP1_IN_DATA_ACK) {
507 		// HUB Bitmap control
508 		usberr("Error: EP1 IN ACK");
509 		ast_udc_write(ISR_HUB_EP1_IN_DATA_ACK, AST_VHUB_ISR);
510 		ast_udc_write(0x00, AST_VHUB_EP1_STS_CHG);
511 	}
512 
513 	if (isr & ISR_DEVICE1)
514 		usberr("ISR_DEVICE1");
515 
516 	if (isr & ISR_DEVICE2)
517 		usberr("ISR_DEVICE2");
518 
519 	if (isr & ISR_DEVICE3)
520 		usberr("ISR_DEVICE3");
521 
522 	if (isr & ISR_DEVICE4)
523 		usberr("ISR_DEVICE4");
524 
525 	if (isr & ISR_DEVICE5)
526 		usberr("ISR_DEVICE5");
527 
528 	if (isr & ISR_DEVICE6)
529 		usberr("ISR_DEVICE6");
530 
531 	if (isr & ISR_DEVICE7)
532 		usberr("ISR_DEVICE7");
533 
534 	if (isr & ISR_EP_ACK_STALL) {
535 //		usbdbg("ISR_EP_ACK_STALL");
536 		ep_isr = ast_udc_read(AST_VHUB_EP_ACK_ISR);
537 		for (i = 0; i < UDC_MAX_ENDPOINTS; i++) {
538 			if (ep_isr & (0x1 << i)) {
539 				ast_udc_write(BIT(i), AST_VHUB_EP_ACK_ISR);
540 				ast_udc_ep_handle(udc_device->bus->endpoint_array + i + 1);
541 			}
542 		}
543 	}
544 
545 	if (isr & ISR_EP_NAK) {
546 		usbdbg("ISR_EP_NAK");
547 		ast_udc_write(ISR_EP_NAK, AST_VHUB_ISR);
548 	}
549 }
550 
551 /*
552  * udc_unset_nak
553  *
554  * Suspend sending of NAK tokens for DATA OUT tokens on a given endpoint.
555  * Switch off NAKing on this endpoint to accept more data output from host.
556  */
557 void udc_unset_nak(int ep_num)
558 {
559 /* Do nothing */
560 }
561 
562 /*
563  * udc_set_nak
564  *
565  * Allow upper layers to signal lower layers should not accept more RX data
566  */
567 void udc_set_nak(int ep_num)
568 {
569 /* Do nothing */
570 }
571 
572 /* Associate a physical endpoint with endpoint instance */
573 void udc_setup_ep(struct usb_device_instance *device, unsigned int id,
574 		  struct usb_endpoint_instance *endpoint)
575 {
576 	int ep_num, ep_addr, ep_isout, ep_type, ep_size;
577 	u32 ep_conf;
578 	u32 ep_reg;
579 
580 	usbdbg("setting up endpoint id: %d", id);
581 
582 	if (!endpoint) {
583 		usberr("Error: invalid endpoint");
584 		return;
585 	}
586 
587 	ep_num = endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK;
588 	if (ep_num >= UDC_MAX_ENDPOINTS) {
589 		usberr("Error: ep num is out-of-range %d", ep_num);
590 		return;
591 	}
592 
593 	if (ep_num == 0) {
594 		/* Done for ep0 */
595 		return;
596 	}
597 
598 	ep_addr = endpoint->endpoint_address;
599 	ep_isout = (ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT;
600 	ep_type = ep_isout ? endpoint->rcv_attributes : endpoint->tx_attributes;
601 	ep_size = ep_isout ? endpoint->rcv_packetSize : endpoint->tx_packetSize;
602 
603 	usbdbg("addr %x, num %d, dir %s, type %s, packet size %d",
604 	       ep_addr, ep_num,
605 	       ep_isout ? "out" : "in",
606 	       ep_type == USB_ENDPOINT_XFER_ISOC ? "isoc" :
607 	       ep_type == USB_ENDPOINT_XFER_BULK ? "bulk" :
608 	       ep_type == USB_ENDPOINT_XFER_INT ? "int" : "???",
609 	       ep_size);
610 
611 	/* Configure EP */
612 	if (ep_size == 1024)
613 		ep_conf = 0;
614 	else
615 		ep_conf = EP_SET_MAX_PKT(ep_size);
616 
617 	ep_conf |= EP_SET_EP_NUM(ep_num);
618 
619 	switch (ep_type) {
620 	case USB_ENDPOINT_XFER_ISOC:
621 		if (ep_isout)
622 			ep_conf |= EP_TYPE_ISO_OUT;
623 		else
624 			ep_conf |= EP_TYPE_ISO_IN;
625 		break;
626 	case USB_ENDPOINT_XFER_BULK:
627 		if (ep_isout)
628 			ep_conf |= EP_TYPE_BULK_OUT;
629 		else
630 			ep_conf |= EP_TYPE_BULK_IN;
631 		break;
632 	case USB_ENDPOINT_XFER_INT:
633 		if (ep_isout)
634 			ep_conf |= EP_TYPE_INT_OUT;
635 		else
636 			ep_conf |= EP_TYPE_INT_IN;
637 		break;
638 	}
639 
640 	ep_reg = aspeed_udc->udc_base + AST_EP_BASE + (AST_EP_OFFSET * (ep_num - 1));
641 
642 	ast_ep_write(ep_reg, EP_SINGLE_DESC_MODE, AST_EP_DMA_CTRL);
643 	ast_ep_write(ep_reg, 0, AST_EP_DMA_STS);
644 	ast_ep_write(ep_reg, ep_conf | EP_ENABLE, AST_EP_CONFIG);
645 
646 	//also setup dma
647 	if (ep_isout) {
648 		ast_ep_write(ep_reg, endpoint->rcv_urb->buffer, AST_EP_DMA_BUFF);
649 		ast_ep_write(ep_reg, AST_EP_START_TRANS, AST_EP_DMA_STS);
650 
651 	} else {
652 		ast_ep_write(ep_reg, endpoint->tx_urb->buffer, AST_EP_DMA_BUFF);
653 	}
654 }
655 
656 /* Connect the USB device to the bus */
657 void udc_connect(void)
658 {
659 	usbdbg("UDC connect");
660 	ast_udc_write(ast_udc_read(AST_VHUB_CTRL) | ROOT_UPSTREAM_EN,
661 		      AST_VHUB_CTRL);
662 }
663 
664 /* Disconnect the USB device to the bus */
665 void udc_disconnect(void)
666 {
667 	usbdbg("UDC disconnect");
668 	ast_udc_write(ast_udc_read(AST_VHUB_CTRL) & ~ROOT_UPSTREAM_EN,
669 		      AST_VHUB_CTRL);
670 }
671 
672 void udc_enable(struct usb_device_instance *device)
673 {
674 	usbdbg("enable UDC");
675 
676 	udc_device = device;
677 	if (!ep0_urb)
678 		ep0_urb = usbd_alloc_urb(udc_device,
679 					 udc_device->bus->endpoint_array);
680 	else
681 		usbinfo("ep0_urb %p already allocated", ep0_urb);
682 }
683 
684 void udc_disable(void)
685 {
686 	usbdbg("disable UDC");
687 
688 	/* Free ep0 URB */
689 	if (ep0_urb) {
690 		usbd_dealloc_urb(ep0_urb);
691 		ep0_urb = NULL;
692 	}
693 
694 	/* Reset device pointer */
695 	udc_device = NULL;
696 }
697 
698 /* Allow udc code to do any additional startup */
699 void udc_startup_events(struct usb_device_instance *device)
700 {
701 	usbdbg("udc_startup_events");
702 
703 	/* The DEVICE_INIT event puts the USB device in the state STATE_INIT */
704 	usbd_device_event_irq(device, DEVICE_INIT, 0);
705 
706 	/* The DEVICE_CREATE event puts the USB device in the state
707 	 * STATE_ATTACHED
708 	 */
709 	usbd_device_event_irq(device, DEVICE_CREATE, 0);
710 
711 	udc_enable(device);
712 }
713 
714 int udc_init(void)
715 {
716 	usbdbg("udc_init");
717 
718 	if (!aspeed_udc) {
719 		usberr("Error: udc driver is not init yet");
720 		return -1;
721 	}
722 
723 	// Disable PHY reset
724 	ast_udc_write(ROOT_PHY_CLK_EN | ROOT_PHY_RESET_DIS, AST_VHUB_CTRL);
725 
726 	ast_udc_write(0, AST_VHUB_DEV_RESET);
727 
728 	ast_udc_write(~BIT(18), AST_VHUB_ISR);
729 	ast_udc_write(~BIT(18), AST_VHUB_IER);
730 
731 	ast_udc_write(~BIT(UDC_MAX_ENDPOINTS), AST_VHUB_EP_ACK_ISR);
732 	ast_udc_write(~BIT(UDC_MAX_ENDPOINTS), AST_VHUB_EP_ACK_IER);
733 
734 	ast_udc_write(0, AST_VHUB_EP0_CTRL);
735 	ast_udc_write(0, AST_VHUB_EP1_CTRL);
736 
737 	return 0;
738 }
739 
740 static int aspeed_udc_probe(struct udevice *dev)
741 {
742 	struct aspeed_udc_priv *udc = dev_get_priv(dev);
743 	struct reset_ctl udc_reset_ctl;
744 	int ret;
745 
746 	ret = reset_get_by_index(dev, 0, &udc_reset_ctl);
747 	if (ret) {
748 		printf("%s: Failed to get udc reset signal\n", __func__);
749 		return ret;
750 	}
751 
752 	reset_assert(&udc_reset_ctl);
753 
754 	// Wait 10ms for PLL locking
755 	mdelay(10);
756 	reset_deassert(&udc_reset_ctl);
757 
758 	udc->init = 1;
759 
760 	return 0;
761 }
762 
763 static int aspeed_udc_ofdata_to_platdata(struct udevice *dev)
764 {
765 	aspeed_udc = dev_get_priv(dev);
766 
767 	/* Get the controller base address */
768 	aspeed_udc->udc_base = (u32)devfdt_get_addr_index(dev, 0);
769 
770 	return 0;
771 }
772 
773 static const struct udevice_id aspeed_udc_ids[] = {
774 	{ .compatible = "aspeed,ast2600-usb-vhub" },
775 	{ }
776 };
777 
778 U_BOOT_DRIVER(aspeed_udc) = {
779 	.name			= "aspeed_udc",
780 	.id			= UCLASS_MISC,
781 	.of_match		= aspeed_udc_ids,
782 	.probe			= aspeed_udc_probe,
783 	.ofdata_to_platdata	= aspeed_udc_ofdata_to_platdata,
784 	.priv_auto_alloc_size	= sizeof(struct aspeed_udc_priv),
785 };
786