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