Lines Matching +full:ddr +full:- +full:sel

1 // SPDX-License-Identifier: GPL-2.0+
4 * Designware DWC2 on-chip full/high speed USB OTG 2.0 device controllers
10 * git://git.kernel.org/pub/scm/linux/kernel/git/kki_ap/linux-2.6-samsung.git
15 * Ported to u-boot:
32 #include <asm/mach-types.h>
68 static const char driver_name[] = "dwc2-udc";
69 static const char ep0name[] = "ep0-control";
115 the_controller->gadget.dev.device_data = p; in set_udc_gadget_private_data()
120 return gadget->dev.device_data; in get_udc_gadget_private_data()
148 return !!(readl(&reg->gintsts) & INT_RESET); in dfu_usb_get_reset()
159 * udc_disable - disable USB device controller
167 dev->ep0state = WAIT_FOR_SETUP; in udc_disable()
168 dev->gadget.speed = USB_SPEED_UNKNOWN; in udc_disable()
169 dev->usb_address = 0; in udc_disable()
175 * udc_reinit - initialize software state
184 INIT_LIST_HEAD(&dev->gadget.ep_list); in udc_reinit()
185 INIT_LIST_HEAD(&dev->gadget.ep0->ep_list); in udc_reinit()
186 dev->ep0state = WAIT_FOR_SETUP; in udc_reinit()
190 struct dwc2_ep *ep = &dev->ep[i]; in udc_reinit()
193 list_add_tail(&ep->ep.ep_list, &dev->gadget.ep_list); in udc_reinit()
195 ep->desc = 0; in udc_reinit()
196 ep->stopped = 0; in udc_reinit()
197 INIT_LIST_HEAD(&ep->queue); in udc_reinit()
198 ep->pio_irqs = 0; in udc_reinit()
201 /* the rest was statically initialized, and is read-only */ in udc_reinit()
219 readl(&reg->gintmsk)); in udc_enable()
221 dev->gadget.speed = USB_SPEED_UNKNOWN; in udc_enable()
238 || (driver->speed != USB_SPEED_FULL in usb_gadget_register_driver()
239 && driver->speed != USB_SPEED_HIGH) in usb_gadget_register_driver()
240 || !driver->bind || !driver->disconnect || !driver->setup) in usb_gadget_register_driver()
241 return -EINVAL; in usb_gadget_register_driver()
243 return -ENODEV; in usb_gadget_register_driver()
244 if (dev->driver) in usb_gadget_register_driver()
245 return -EBUSY; in usb_gadget_register_driver()
247 spin_lock_irqsave(&dev->lock, flags); in usb_gadget_register_driver()
249 dev->driver = driver; in usb_gadget_register_driver()
250 spin_unlock_irqrestore(&dev->lock, flags); in usb_gadget_register_driver()
257 retval = driver->bind(&dev->gadget); in usb_gadget_register_driver()
260 "%s: bind to driver --> error %d\n", in usb_gadget_register_driver()
261 dev->gadget.name, retval); in usb_gadget_register_driver()
262 dev->driver = 0; in usb_gadget_register_driver()
269 "Registered gadget driver %s\n", dev->gadget.name); in usb_gadget_register_driver()
284 return -ENODEV; in usb_gadget_unregister_driver()
285 if (!driver || driver != dev->driver) in usb_gadget_unregister_driver()
286 return -EINVAL; in usb_gadget_unregister_driver()
288 spin_lock_irqsave(&dev->lock, flags); in usb_gadget_unregister_driver()
289 dev->driver = 0; in usb_gadget_unregister_driver()
291 spin_unlock_irqrestore(&dev->lock, flags); in usb_gadget_unregister_driver()
293 driver->unbind(&dev->gadget); in usb_gadget_unregister_driver()
302 * done - retire a request; caller blocked irqs
306 unsigned int stopped = ep->stopped; in done()
309 __func__, ep->ep.name, ep, &req->req, stopped); in done()
311 list_del_init(&req->queue); in done()
313 if (likely(req->req.status == -EINPROGRESS)) in done()
314 req->req.status = status; in done()
316 status = req->req.status; in done()
318 if (status && status != -ESHUTDOWN) { in done()
320 ep->ep.name, &req->req, status, in done()
321 req->req.actual, req->req.length); in done()
325 ep->stopped = 1; in done()
330 int i, len = req->req.length; in done()
332 printf("pkt[%d] = ", req->req.length); in done()
336 printf("%02x", ((u8 *)req->req.buf)[i]); in done()
343 spin_unlock(&ep->dev->lock); in done()
344 req->req.complete(&ep->ep, &req->req); in done()
345 spin_lock(&ep->dev->lock); in done()
349 ep->stopped = stopped; in done()
353 * nuke - dequeue ALL requests
359 debug("%s: %s %p\n", __func__, ep->ep.name, ep); in nuke()
362 while (!list_empty(&ep->queue)) { in nuke()
363 req = list_entry(ep->queue.next, struct dwc2_request, queue); in nuke()
374 if (dev->gadget.speed == USB_SPEED_UNKNOWN) in stop_activity()
376 dev->gadget.speed = USB_SPEED_UNKNOWN; in stop_activity()
380 struct dwc2_ep *ep = &dev->ep[i]; in stop_activity()
381 ep->stopped = 1; in stop_activity()
382 nuke(ep, -ESHUTDOWN); in stop_activity()
387 spin_unlock(&dev->lock); in stop_activity()
388 driver->disconnect(&dev->gadget); in stop_activity()
389 spin_lock(&dev->lock); in stop_activity()
392 /* re-init driver-visible data structures */ in stop_activity()
398 /* 2. Soft-reset OTG Core and then unreset again. */ in reconfig_usbd()
400 unsigned int uTemp = writel(CORE_SOFT_RESET, &reg->grstctl); in reconfig_usbd()
407 0<<15 /* PHY Low Power Clock sel*/ in reconfig_usbd()
408 |1<<14 /* Non-Periodic TxFIFO Rewind Enable*/ in reconfig_usbd()
412 |0<<7 /* Ulpi DDR sel*/ in reconfig_usbd()
422 if (dev->pdata->usb_gusbcfg) in reconfig_usbd()
423 dflt_gusbcfg = dev->pdata->usb_gusbcfg; in reconfig_usbd()
425 writel(dflt_gusbcfg, &reg->gusbcfg); in reconfig_usbd()
428 uTemp = readl(&reg->dctl); in reconfig_usbd()
430 writel(uTemp, &reg->dctl); in reconfig_usbd()
435 uTemp = readl(&reg->dctl); in reconfig_usbd()
437 writel(uTemp, &reg->dctl); in reconfig_usbd()
441 writel(EP_MISS_CNT(1) | DEV_SPEED_HIGH_SPEED_20, &reg->dcfg); in reconfig_usbd()
446 writel(GINTMSK_INIT, &reg->gintmsk); in reconfig_usbd()
449 writel(DEPCTL_EPDIS|DEPCTL_SNAK, &reg->out_endp[EP0_CON].doepctl); in reconfig_usbd()
450 writel(DEPCTL_EPDIS|DEPCTL_SNAK, &reg->in_endp[EP0_CON].diepctl); in reconfig_usbd()
453 writel(DEPCTL_EPDIS|DEPCTL_SNAK, &reg->out_endp[i].doepctl); in reconfig_usbd()
454 writel(DEPCTL_EPDIS|DEPCTL_SNAK, &reg->in_endp[i].diepctl); in reconfig_usbd()
459 | (1 << EP0_CON), &reg->daintmsk); in reconfig_usbd()
462 writel(DOEPMSK_INIT, &reg->doepmsk); in reconfig_usbd()
465 writel(DIEPMSK_INIT, &reg->diepmsk); in reconfig_usbd()
471 if (dev->pdata->rx_fifo_sz) in reconfig_usbd()
472 rx_fifo_sz = dev->pdata->rx_fifo_sz; in reconfig_usbd()
473 if (dev->pdata->np_tx_fifo_sz) in reconfig_usbd()
474 np_tx_fifo_sz = dev->pdata->np_tx_fifo_sz; in reconfig_usbd()
475 if (dev->pdata->tx_fifo_sz) in reconfig_usbd()
476 tx_fifo_sz = dev->pdata->tx_fifo_sz; in reconfig_usbd()
478 /* 11. Set Rx FIFO Size (in 32-bit words) */ in reconfig_usbd()
479 writel(rx_fifo_sz, &reg->grxfsiz); in reconfig_usbd()
483 &reg->gnptxfsiz); in reconfig_usbd()
486 writel((rx_fifo_sz + np_tx_fifo_sz + tx_fifo_sz*(i-1)) | in reconfig_usbd()
487 tx_fifo_sz << 16, &reg->dieptxf[i-1]); in reconfig_usbd()
490 writel(RX_FIFO_FLUSH, &reg->grstctl); in reconfig_usbd()
491 while (readl(&reg->grstctl) & RX_FIFO_FLUSH) in reconfig_usbd()
495 writel(TX_FIFO_FLUSH_ALL, &reg->grstctl); in reconfig_usbd()
496 writel(TX_FIFO_FLUSH_ALL | TX_FIFO_FLUSH, &reg->grstctl); in reconfig_usbd()
497 while (readl(&reg->grstctl) & TX_FIFO_FLUSH) in reconfig_usbd()
504 &reg->out_endp[EP0_CON].doepctl); in reconfig_usbd()
507 writel(GAHBCFG_INIT, &reg->gahbcfg); in reconfig_usbd()
519 dev->gadget.speed = USB_SPEED_HIGH; in set_max_pktsize()
524 dev->gadget.speed = USB_SPEED_FULL; in set_max_pktsize()
527 dev->ep[0].ep.maxpacket = ep0_fifo_size; in set_max_pktsize()
529 dev->ep[i].ep.maxpacket = ep_fifo_size; in set_max_pktsize()
531 /* EP0 - Control IN (64 bytes)*/ in set_max_pktsize()
532 ep_ctrl = readl(&reg->in_endp[EP0_CON].diepctl); in set_max_pktsize()
533 writel(ep_ctrl|(0<<0), &reg->in_endp[EP0_CON].diepctl); in set_max_pktsize()
535 /* EP0 - Control OUT (64 bytes)*/ in set_max_pktsize()
536 ep_ctrl = readl(&reg->out_endp[EP0_CON].doepctl); in set_max_pktsize()
537 writel(ep_ctrl|(0<<0), &reg->out_endp[EP0_CON].doepctl); in set_max_pktsize()
550 if (!_ep || !desc || ep->desc || _ep->name == ep0name in dwc2_ep_enable()
551 || desc->bDescriptorType != USB_DT_ENDPOINT in dwc2_ep_enable()
552 || ep->bEndpointAddress != desc->bEndpointAddress in dwc2_ep_enable()
554 le16_to_cpu(get_unaligned(&desc->wMaxPacketSize))) { in dwc2_ep_enable()
557 return -EINVAL; in dwc2_ep_enable()
561 if (ep->bmAttributes != desc->bmAttributes in dwc2_ep_enable()
562 && ep->bmAttributes != USB_ENDPOINT_XFER_BULK in dwc2_ep_enable()
563 && desc->bmAttributes != USB_ENDPOINT_XFER_INT) { in dwc2_ep_enable()
565 debug("%s: %s type mismatch\n", __func__, _ep->name); in dwc2_ep_enable()
566 return -EINVAL; in dwc2_ep_enable()
570 if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK && in dwc2_ep_enable()
571 le16_to_cpu(get_unaligned(&desc->wMaxPacketSize)) > in dwc2_ep_enable()
572 ep_maxpacket(ep)) || !get_unaligned(&desc->wMaxPacketSize)) { in dwc2_ep_enable()
574 debug("%s: bad %s maxpacket\n", __func__, _ep->name); in dwc2_ep_enable()
575 return -ERANGE; in dwc2_ep_enable()
578 dev = ep->dev; in dwc2_ep_enable()
579 if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) { in dwc2_ep_enable()
582 return -ESHUTDOWN; in dwc2_ep_enable()
585 ep->stopped = 0; in dwc2_ep_enable()
586 ep->desc = desc; in dwc2_ep_enable()
587 ep->pio_irqs = 0; in dwc2_ep_enable()
588 ep->ep.maxpacket = le16_to_cpu(get_unaligned(&desc->wMaxPacketSize)); in dwc2_ep_enable()
594 spin_lock_irqsave(&ep->dev->lock, flags); in dwc2_ep_enable()
596 spin_unlock_irqrestore(&ep->dev->lock, flags); in dwc2_ep_enable()
599 __func__, _ep->name, ep->stopped, ep->ep.maxpacket); in dwc2_ep_enable()
614 if (!_ep || !ep->desc) { in dwc2_ep_disable()
616 _ep ? ep->ep.name : NULL); in dwc2_ep_disable()
617 return -EINVAL; in dwc2_ep_disable()
620 spin_lock_irqsave(&ep->dev->lock, flags); in dwc2_ep_disable()
623 nuke(ep, -ESHUTDOWN); in dwc2_ep_disable()
625 ep->desc = 0; in dwc2_ep_disable()
626 ep->stopped = 1; in dwc2_ep_disable()
628 spin_unlock_irqrestore(&ep->dev->lock, flags); in dwc2_ep_disable()
630 debug("%s: disabled %s\n", __func__, _ep->name); in dwc2_ep_disable()
639 debug("%s: %s %p\n", __func__, ep->name, ep); in dwc2_alloc_request()
646 INIT_LIST_HEAD(&req->queue); in dwc2_alloc_request()
648 return &req->req; in dwc2_alloc_request()
658 WARN_ON(!list_empty(&req->queue)); in dwc2_free_request()
672 if (!_ep || ep->ep.name == ep0name) in dwc2_dequeue()
673 return -EINVAL; in dwc2_dequeue()
675 spin_lock_irqsave(&ep->dev->lock, flags); in dwc2_dequeue()
678 list_for_each_entry(req, &ep->queue, queue) { in dwc2_dequeue()
679 if (&req->req == _req) in dwc2_dequeue()
682 if (&req->req != _req) { in dwc2_dequeue()
683 spin_unlock_irqrestore(&ep->dev->lock, flags); in dwc2_dequeue()
684 return -EINVAL; in dwc2_dequeue()
687 done(ep, req, -ECONNRESET); in dwc2_dequeue()
689 spin_unlock_irqrestore(&ep->dev->lock, flags); in dwc2_dequeue()
704 return -ENODEV; in dwc2_fifo_status()
711 return -EOPNOTSUPP; in dwc2_fifo_status()
724 if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) { in dwc2_fifo_flush()
733 /* current versions must always be self-powered */
762 .name = "ep1in-bulk",
777 .name = "ep2out-bulk",
792 .name = "ep3in-int",
807 * probe - binds to the platform device
817 dev->pdata = pdata; in dwc2_udc_probe()
819 reg = (struct dwc2_usbotg_reg *)pdata->regs_otg; in dwc2_udc_probe()
821 /* regs_otg = (void *)pdata->regs_otg; */ in dwc2_udc_probe()
823 dev->gadget.is_dualspeed = 1; /* Hack only*/ in dwc2_udc_probe()
824 dev->gadget.is_otg = 0; in dwc2_udc_probe()
825 dev->gadget.is_a_peripheral = 0; in dwc2_udc_probe()
826 dev->gadget.b_hnp_enable = 0; in dwc2_udc_probe()
827 dev->gadget.a_hnp_support = 0; in dwc2_udc_probe()
828 dev->gadget.a_alt_hnp_support = 0; in dwc2_udc_probe()
837 return -ENOMEM; in dwc2_udc_probe()
849 u32 intr_status = readl(&reg->gintsts); in usb_gadget_handle_interrupts()
850 u32 gintmsk = readl(&reg->gintmsk); in usb_gadget_handle_interrupts()