Lines Matching refs:udc

201 	struct bcm63xx_udc		*udc;  member
226 struct bcm63xx_udc *udc; member
343 static inline u32 usbd_readl(struct bcm63xx_udc *udc, u32 off) in usbd_readl() argument
345 return bcm_readl(udc->usbd_regs + off); in usbd_readl()
348 static inline void usbd_writel(struct bcm63xx_udc *udc, u32 val, u32 off) in usbd_writel() argument
350 bcm_writel(val, udc->usbd_regs + off); in usbd_writel()
353 static inline u32 usb_dma_readl(struct bcm63xx_udc *udc, u32 off) in usb_dma_readl() argument
355 return bcm_readl(udc->iudma_regs + off); in usb_dma_readl()
358 static inline void usb_dma_writel(struct bcm63xx_udc *udc, u32 val, u32 off) in usb_dma_writel() argument
360 bcm_writel(val, udc->iudma_regs + off); in usb_dma_writel()
363 static inline u32 usb_dmac_readl(struct bcm63xx_udc *udc, u32 off, int chan) in usb_dmac_readl() argument
365 return bcm_readl(udc->iudma_regs + IUDMA_DMAC_OFFSET + off + in usb_dmac_readl()
369 static inline void usb_dmac_writel(struct bcm63xx_udc *udc, u32 val, u32 off, in usb_dmac_writel() argument
372 bcm_writel(val, udc->iudma_regs + IUDMA_DMAC_OFFSET + off + in usb_dmac_writel()
376 static inline u32 usb_dmas_readl(struct bcm63xx_udc *udc, u32 off, int chan) in usb_dmas_readl() argument
378 return bcm_readl(udc->iudma_regs + IUDMA_DMAS_OFFSET + off + in usb_dmas_readl()
382 static inline void usb_dmas_writel(struct bcm63xx_udc *udc, u32 val, u32 off, in usb_dmas_writel() argument
385 bcm_writel(val, udc->iudma_regs + IUDMA_DMAS_OFFSET + off + in usb_dmas_writel()
389 static inline void set_clocks(struct bcm63xx_udc *udc, bool is_enabled) in set_clocks() argument
392 clk_enable(udc->usbh_clk); in set_clocks()
393 clk_enable(udc->usbd_clk); in set_clocks()
396 clk_disable(udc->usbd_clk); in set_clocks()
397 clk_disable(udc->usbh_clk); in set_clocks()
414 static void bcm63xx_ep_dma_select(struct bcm63xx_udc *udc, int idx) in bcm63xx_ep_dma_select() argument
416 u32 val = usbd_readl(udc, USBD_CONTROL_REG); in bcm63xx_ep_dma_select()
420 usbd_writel(udc, val, USBD_CONTROL_REG); in bcm63xx_ep_dma_select()
432 static void bcm63xx_set_stall(struct bcm63xx_udc *udc, struct bcm63xx_ep *bep, in bcm63xx_set_stall() argument
440 usbd_writel(udc, val, USBD_STALL_REG); in bcm63xx_set_stall()
450 static void bcm63xx_fifo_setup(struct bcm63xx_udc *udc) in bcm63xx_fifo_setup() argument
452 int is_hs = udc->gadget.speed == USB_SPEED_HIGH; in bcm63xx_fifo_setup()
461 bcm63xx_ep_dma_select(udc, i >> 1); in bcm63xx_fifo_setup()
467 usbd_writel(udc, val, USBD_RXFIFO_CONFIG_REG); in bcm63xx_fifo_setup()
468 usbd_writel(udc, in bcm63xx_fifo_setup()
476 usbd_writel(udc, val, USBD_TXFIFO_CONFIG_REG); in bcm63xx_fifo_setup()
477 usbd_writel(udc, in bcm63xx_fifo_setup()
481 usbd_readl(udc, USBD_TXFIFO_EPSIZE_REG); in bcm63xx_fifo_setup()
490 static void bcm63xx_fifo_reset_ep(struct bcm63xx_udc *udc, int ep_num) in bcm63xx_fifo_reset_ep() argument
494 bcm63xx_ep_dma_select(udc, ep_num); in bcm63xx_fifo_reset_ep()
496 val = usbd_readl(udc, USBD_CONTROL_REG); in bcm63xx_fifo_reset_ep()
498 usbd_writel(udc, val, USBD_CONTROL_REG); in bcm63xx_fifo_reset_ep()
499 usbd_readl(udc, USBD_CONTROL_REG); in bcm63xx_fifo_reset_ep()
506 static void bcm63xx_fifo_reset(struct bcm63xx_udc *udc) in bcm63xx_fifo_reset() argument
511 bcm63xx_fifo_reset_ep(udc, i); in bcm63xx_fifo_reset()
518 static void bcm63xx_ep_init(struct bcm63xx_udc *udc) in bcm63xx_ep_init() argument
528 bcm63xx_ep_dma_select(udc, cfg->ep_num); in bcm63xx_ep_init()
531 usbd_writel(udc, val, USBD_EPNUM_TYPEMAP_REG); in bcm63xx_ep_init()
541 static void bcm63xx_ep_setup(struct bcm63xx_udc *udc) in bcm63xx_ep_setup() argument
545 usbd_writel(udc, USBD_CSR_SETUPADDR_DEF, USBD_CSR_SETUPADDR_REG); in bcm63xx_ep_setup()
549 int max_pkt = udc->gadget.speed == USB_SPEED_HIGH ? in bcm63xx_ep_setup()
553 udc->iudma[i].max_pkt = max_pkt; in bcm63xx_ep_setup()
557 usb_ep_set_maxpacket_limit(&udc->bep[idx].ep, max_pkt); in bcm63xx_ep_setup()
562 (udc->cfg << USBD_CSR_EP_CFG_SHIFT) | in bcm63xx_ep_setup()
563 (udc->iface << USBD_CSR_EP_IFACE_SHIFT) | in bcm63xx_ep_setup()
564 (udc->alt_iface << USBD_CSR_EP_ALTIFACE_SHIFT) | in bcm63xx_ep_setup()
566 usbd_writel(udc, val, USBD_CSR_EP_REG(idx)); in bcm63xx_ep_setup()
583 static void iudma_write(struct bcm63xx_udc *udc, struct iudma_ch *iudma, in iudma_write() argument
646 usb_dmac_writel(udc, ENETDMAC_CHANCFG_EN_MASK, in iudma_write()
659 static int iudma_read(struct bcm63xx_udc *udc, struct iudma_ch *iudma) in iudma_read() argument
693 static void iudma_reset_channel(struct bcm63xx_udc *udc, struct iudma_ch *iudma) in iudma_reset_channel() argument
700 bcm63xx_fifo_reset_ep(udc, max(0, iudma->ep_num)); in iudma_reset_channel()
703 usb_dmac_writel(udc, 0, ENETDMAC_CHANCFG_REG, ch_idx); in iudma_reset_channel()
705 while (usb_dmac_readl(udc, ENETDMAC_CHANCFG_REG, ch_idx) & in iudma_reset_channel()
711 bcm63xx_fifo_reset_ep(udc, iudma->ep_num); in iudma_reset_channel()
714 dev_err(udc->dev, "can't reset IUDMA channel %d\n", in iudma_reset_channel()
719 dev_warn(udc->dev, "forcibly halting IUDMA channel %d\n", in iudma_reset_channel()
721 usb_dmac_writel(udc, ENETDMAC_CHANCFG_BUFHALT_MASK, in iudma_reset_channel()
725 usb_dmac_writel(udc, ~0, ENETDMAC_IR_REG, ch_idx); in iudma_reset_channel()
736 usb_dmac_writel(udc, ENETDMAC_IR_BUFDONE_MASK, in iudma_reset_channel()
738 usb_dmac_writel(udc, 8, ENETDMAC_MAXBURST_REG, ch_idx); in iudma_reset_channel()
740 usb_dmas_writel(udc, iudma->bd_ring_dma, ENETDMAS_RSTART_REG, ch_idx); in iudma_reset_channel()
741 usb_dmas_writel(udc, 0, ENETDMAS_SRAM2_REG, ch_idx); in iudma_reset_channel()
749 static int iudma_init_channel(struct bcm63xx_udc *udc, unsigned int ch_idx) in iudma_init_channel() argument
751 struct iudma_ch *iudma = &udc->iudma[ch_idx]; in iudma_init_channel()
760 bep = &udc->bep[iudma->ep_num]; in iudma_init_channel()
766 iudma->udc = udc; in iudma_init_channel()
773 iudma->bd_ring = dmam_alloc_coherent(udc->dev, in iudma_init_channel()
789 static int iudma_init(struct bcm63xx_udc *udc) in iudma_init() argument
793 usb_dma_writel(udc, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG); in iudma_init()
796 rc = iudma_init_channel(udc, i); in iudma_init()
799 iudma_reset_channel(udc, &udc->iudma[i]); in iudma_init()
802 usb_dma_writel(udc, BIT(BCM63XX_NUM_IUDMA)-1, ENETDMA_GLB_IRQMASK_REG); in iudma_init()
812 static void iudma_uninit(struct bcm63xx_udc *udc) in iudma_uninit() argument
816 usb_dma_writel(udc, 0, ENETDMA_GLB_IRQMASK_REG); in iudma_uninit()
819 iudma_reset_channel(udc, &udc->iudma[i]); in iudma_uninit()
821 usb_dma_writel(udc, 0, ENETDMA_CFG_REG); in iudma_uninit()
833 static void bcm63xx_set_ctrl_irqs(struct bcm63xx_udc *udc, bool enable_irqs) in bcm63xx_set_ctrl_irqs() argument
837 usbd_writel(udc, 0, USBD_STATUS_REG); in bcm63xx_set_ctrl_irqs()
844 usbd_writel(udc, enable_irqs ? val : 0, USBD_EVENT_IRQ_MASK_REG); in bcm63xx_set_ctrl_irqs()
845 usbd_writel(udc, val, USBD_EVENT_IRQ_STATUS_REG); in bcm63xx_set_ctrl_irqs()
859 static void bcm63xx_select_phy_mode(struct bcm63xx_udc *udc, bool is_device) in bcm63xx_select_phy_mode() argument
861 u32 val, portmask = BIT(udc->pd->port_no); in bcm63xx_select_phy_mode()
899 static void bcm63xx_select_pullup(struct bcm63xx_udc *udc, bool is_on) in bcm63xx_select_pullup() argument
901 u32 val, portmask = BIT(udc->pd->port_no); in bcm63xx_select_pullup()
918 static void bcm63xx_uninit_udc_hw(struct bcm63xx_udc *udc) in bcm63xx_uninit_udc_hw() argument
920 set_clocks(udc, true); in bcm63xx_uninit_udc_hw()
921 iudma_uninit(udc); in bcm63xx_uninit_udc_hw()
922 set_clocks(udc, false); in bcm63xx_uninit_udc_hw()
924 clk_put(udc->usbd_clk); in bcm63xx_uninit_udc_hw()
925 clk_put(udc->usbh_clk); in bcm63xx_uninit_udc_hw()
932 static int bcm63xx_init_udc_hw(struct bcm63xx_udc *udc) in bcm63xx_init_udc_hw() argument
937 udc->ep0_ctrl_buf = devm_kzalloc(udc->dev, BCM63XX_MAX_CTRL_PKT, in bcm63xx_init_udc_hw()
939 if (!udc->ep0_ctrl_buf) in bcm63xx_init_udc_hw()
942 INIT_LIST_HEAD(&udc->gadget.ep_list); in bcm63xx_init_udc_hw()
944 struct bcm63xx_ep *bep = &udc->bep[i]; in bcm63xx_init_udc_hw()
949 list_add_tail(&bep->ep.ep_list, &udc->gadget.ep_list); in bcm63xx_init_udc_hw()
952 bep->udc = udc; in bcm63xx_init_udc_hw()
957 udc->gadget.ep0 = &udc->bep[0].ep; in bcm63xx_init_udc_hw()
958 list_del(&udc->bep[0].ep.ep_list); in bcm63xx_init_udc_hw()
960 udc->gadget.speed = USB_SPEED_UNKNOWN; in bcm63xx_init_udc_hw()
961 udc->ep0state = EP0_SHUTDOWN; in bcm63xx_init_udc_hw()
963 udc->usbh_clk = clk_get(udc->dev, "usbh"); in bcm63xx_init_udc_hw()
964 if (IS_ERR(udc->usbh_clk)) in bcm63xx_init_udc_hw()
967 udc->usbd_clk = clk_get(udc->dev, "usbd"); in bcm63xx_init_udc_hw()
968 if (IS_ERR(udc->usbd_clk)) { in bcm63xx_init_udc_hw()
969 clk_put(udc->usbh_clk); in bcm63xx_init_udc_hw()
973 set_clocks(udc, true); in bcm63xx_init_udc_hw()
978 usbd_writel(udc, val, USBD_CONTROL_REG); in bcm63xx_init_udc_hw()
986 if (udc->gadget.max_speed == USB_SPEED_HIGH) in bcm63xx_init_udc_hw()
990 usbd_writel(udc, val, USBD_STRAPS_REG); in bcm63xx_init_udc_hw()
992 bcm63xx_set_ctrl_irqs(udc, false); in bcm63xx_init_udc_hw()
994 usbd_writel(udc, 0, USBD_EVENT_IRQ_CFG_LO_REG); in bcm63xx_init_udc_hw()
998 usbd_writel(udc, val, USBD_EVENT_IRQ_CFG_HI_REG); in bcm63xx_init_udc_hw()
1000 rc = iudma_init(udc); in bcm63xx_init_udc_hw()
1001 set_clocks(udc, false); in bcm63xx_init_udc_hw()
1003 bcm63xx_uninit_udc_hw(udc); in bcm63xx_init_udc_hw()
1024 struct bcm63xx_udc *udc = bep->udc; in bcm63xx_ep_enable() local
1031 if (!udc->driver) in bcm63xx_ep_enable()
1034 spin_lock_irqsave(&udc->lock, flags); in bcm63xx_ep_enable()
1036 spin_unlock_irqrestore(&udc->lock, flags); in bcm63xx_ep_enable()
1043 iudma_reset_channel(udc, iudma); in bcm63xx_ep_enable()
1046 bcm63xx_set_stall(udc, bep, false); in bcm63xx_ep_enable()
1047 clear_bit(bep->ep_num, &udc->wedgemap); in bcm63xx_ep_enable()
1052 spin_unlock_irqrestore(&udc->lock, flags); in bcm63xx_ep_enable()
1063 struct bcm63xx_udc *udc = bep->udc; in bcm63xx_ep_disable() local
1071 spin_lock_irqsave(&udc->lock, flags); in bcm63xx_ep_disable()
1073 spin_unlock_irqrestore(&udc->lock, flags); in bcm63xx_ep_disable()
1078 iudma_reset_channel(udc, iudma); in bcm63xx_ep_disable()
1085 usb_gadget_unmap_request(&udc->gadget, &breq->req, in bcm63xx_ep_disable()
1090 spin_unlock_irqrestore(&udc->lock, flags); in bcm63xx_ep_disable()
1092 spin_lock_irqsave(&udc->lock, flags); in bcm63xx_ep_disable()
1097 spin_unlock_irqrestore(&udc->lock, flags); in bcm63xx_ep_disable()
1147 struct bcm63xx_udc *udc = bep->udc; in bcm63xx_udc_queue() local
1159 if (bep == &udc->bep[0]) { in bcm63xx_udc_queue()
1161 if (udc->ep0_reply) in bcm63xx_udc_queue()
1164 udc->ep0_reply = req; in bcm63xx_udc_queue()
1165 schedule_work(&udc->ep0_wq); in bcm63xx_udc_queue()
1169 spin_lock_irqsave(&udc->lock, flags); in bcm63xx_udc_queue()
1175 rc = usb_gadget_map_request(&udc->gadget, req, bep->iudma->is_tx); in bcm63xx_udc_queue()
1179 iudma_write(udc, bep->iudma, breq); in bcm63xx_udc_queue()
1183 spin_unlock_irqrestore(&udc->lock, flags); in bcm63xx_udc_queue()
1199 struct bcm63xx_udc *udc = bep->udc; in bcm63xx_udc_dequeue() local
1204 spin_lock_irqsave(&udc->lock, flags); in bcm63xx_udc_dequeue()
1211 usb_gadget_unmap_request(&udc->gadget, &breq->req, bep->iudma->is_tx); in bcm63xx_udc_dequeue()
1214 iudma_reset_channel(udc, bep->iudma); in bcm63xx_udc_dequeue()
1222 iudma_write(udc, bep->iudma, next); in bcm63xx_udc_dequeue()
1229 spin_unlock_irqrestore(&udc->lock, flags); in bcm63xx_udc_dequeue()
1247 struct bcm63xx_udc *udc = bep->udc; in bcm63xx_udc_set_halt() local
1250 spin_lock_irqsave(&udc->lock, flags); in bcm63xx_udc_set_halt()
1251 bcm63xx_set_stall(udc, bep, !!value); in bcm63xx_udc_set_halt()
1253 spin_unlock_irqrestore(&udc->lock, flags); in bcm63xx_udc_set_halt()
1267 struct bcm63xx_udc *udc = bep->udc; in bcm63xx_udc_set_wedge() local
1270 spin_lock_irqsave(&udc->lock, flags); in bcm63xx_udc_set_wedge()
1271 set_bit(bep->ep_num, &udc->wedgemap); in bcm63xx_udc_set_wedge()
1272 bcm63xx_set_stall(udc, bep, true); in bcm63xx_udc_set_wedge()
1273 spin_unlock_irqrestore(&udc->lock, flags); in bcm63xx_udc_set_wedge()
1301 static int bcm63xx_ep0_setup_callback(struct bcm63xx_udc *udc, in bcm63xx_ep0_setup_callback() argument
1306 spin_unlock_irq(&udc->lock); in bcm63xx_ep0_setup_callback()
1307 rc = udc->driver->setup(&udc->gadget, ctrl); in bcm63xx_ep0_setup_callback()
1308 spin_lock_irq(&udc->lock); in bcm63xx_ep0_setup_callback()
1324 static int bcm63xx_ep0_spoof_set_cfg(struct bcm63xx_udc *udc) in bcm63xx_ep0_spoof_set_cfg() argument
1331 ctrl.wValue = cpu_to_le16(udc->cfg); in bcm63xx_ep0_spoof_set_cfg()
1335 rc = bcm63xx_ep0_setup_callback(udc, &ctrl); in bcm63xx_ep0_spoof_set_cfg()
1337 dev_warn_ratelimited(udc->dev, in bcm63xx_ep0_spoof_set_cfg()
1339 udc->cfg); in bcm63xx_ep0_spoof_set_cfg()
1348 static int bcm63xx_ep0_spoof_set_iface(struct bcm63xx_udc *udc) in bcm63xx_ep0_spoof_set_iface() argument
1355 ctrl.wValue = cpu_to_le16(udc->alt_iface); in bcm63xx_ep0_spoof_set_iface()
1356 ctrl.wIndex = cpu_to_le16(udc->iface); in bcm63xx_ep0_spoof_set_iface()
1359 rc = bcm63xx_ep0_setup_callback(udc, &ctrl); in bcm63xx_ep0_spoof_set_iface()
1361 dev_warn_ratelimited(udc->dev, in bcm63xx_ep0_spoof_set_iface()
1363 udc->iface, udc->alt_iface); in bcm63xx_ep0_spoof_set_iface()
1374 static void bcm63xx_ep0_map_write(struct bcm63xx_udc *udc, int ch_idx, in bcm63xx_ep0_map_write() argument
1378 struct iudma_ch *iudma = &udc->iudma[ch_idx]; in bcm63xx_ep0_map_write()
1380 BUG_ON(udc->ep0_request); in bcm63xx_ep0_map_write()
1381 udc->ep0_request = req; in bcm63xx_ep0_map_write()
1385 usb_gadget_map_request(&udc->gadget, req, iudma->is_tx); in bcm63xx_ep0_map_write()
1386 iudma_write(udc, iudma, breq); in bcm63xx_ep0_map_write()
1395 static void bcm63xx_ep0_complete(struct bcm63xx_udc *udc, in bcm63xx_ep0_complete() argument
1402 spin_unlock_irq(&udc->lock); in bcm63xx_ep0_complete()
1403 req->complete(&udc->bep[0].ep, req); in bcm63xx_ep0_complete()
1404 spin_lock_irq(&udc->lock); in bcm63xx_ep0_complete()
1414 static void bcm63xx_ep0_nuke_reply(struct bcm63xx_udc *udc, int is_tx) in bcm63xx_ep0_nuke_reply() argument
1416 struct usb_request *req = udc->ep0_reply; in bcm63xx_ep0_nuke_reply()
1418 udc->ep0_reply = NULL; in bcm63xx_ep0_nuke_reply()
1419 usb_gadget_unmap_request(&udc->gadget, req, is_tx); in bcm63xx_ep0_nuke_reply()
1420 if (udc->ep0_request == req) { in bcm63xx_ep0_nuke_reply()
1421 udc->ep0_req_completed = 0; in bcm63xx_ep0_nuke_reply()
1422 udc->ep0_request = NULL; in bcm63xx_ep0_nuke_reply()
1424 bcm63xx_ep0_complete(udc, req, -ESHUTDOWN); in bcm63xx_ep0_nuke_reply()
1432 static int bcm63xx_ep0_read_complete(struct bcm63xx_udc *udc) in bcm63xx_ep0_read_complete() argument
1434 struct usb_request *req = udc->ep0_request; in bcm63xx_ep0_read_complete()
1436 udc->ep0_req_completed = 0; in bcm63xx_ep0_read_complete()
1437 udc->ep0_request = NULL; in bcm63xx_ep0_read_complete()
1451 static void bcm63xx_ep0_internal_request(struct bcm63xx_udc *udc, int ch_idx, in bcm63xx_ep0_internal_request() argument
1454 struct usb_request *req = &udc->ep0_ctrl_req.req; in bcm63xx_ep0_internal_request()
1456 req->buf = udc->ep0_ctrl_buf; in bcm63xx_ep0_internal_request()
1460 bcm63xx_ep0_map_write(udc, ch_idx, req); in bcm63xx_ep0_internal_request()
1471 static enum bcm63xx_ep0_state bcm63xx_ep0_do_setup(struct bcm63xx_udc *udc) in bcm63xx_ep0_do_setup() argument
1474 struct usb_ctrlrequest *ctrl = (void *)udc->ep0_ctrl_buf; in bcm63xx_ep0_do_setup()
1476 rc = bcm63xx_ep0_read_complete(udc); in bcm63xx_ep0_do_setup()
1479 dev_err(udc->dev, "missing SETUP packet\n"); in bcm63xx_ep0_do_setup()
1493 dev_warn_ratelimited(udc->dev, in bcm63xx_ep0_do_setup()
1499 rc = bcm63xx_ep0_setup_callback(udc, ctrl); in bcm63xx_ep0_do_setup()
1501 bcm63xx_set_stall(udc, &udc->bep[0], true); in bcm63xx_ep0_do_setup()
1524 static int bcm63xx_ep0_do_idle(struct bcm63xx_udc *udc) in bcm63xx_ep0_do_idle() argument
1526 if (udc->ep0_req_reset) { in bcm63xx_ep0_do_idle()
1527 udc->ep0_req_reset = 0; in bcm63xx_ep0_do_idle()
1528 } else if (udc->ep0_req_set_cfg) { in bcm63xx_ep0_do_idle()
1529 udc->ep0_req_set_cfg = 0; in bcm63xx_ep0_do_idle()
1530 if (bcm63xx_ep0_spoof_set_cfg(udc) >= 0) in bcm63xx_ep0_do_idle()
1531 udc->ep0state = EP0_IN_FAKE_STATUS_PHASE; in bcm63xx_ep0_do_idle()
1532 } else if (udc->ep0_req_set_iface) { in bcm63xx_ep0_do_idle()
1533 udc->ep0_req_set_iface = 0; in bcm63xx_ep0_do_idle()
1534 if (bcm63xx_ep0_spoof_set_iface(udc) >= 0) in bcm63xx_ep0_do_idle()
1535 udc->ep0state = EP0_IN_FAKE_STATUS_PHASE; in bcm63xx_ep0_do_idle()
1536 } else if (udc->ep0_req_completed) { in bcm63xx_ep0_do_idle()
1537 udc->ep0state = bcm63xx_ep0_do_setup(udc); in bcm63xx_ep0_do_idle()
1538 return udc->ep0state == EP0_IDLE ? -EAGAIN : 0; in bcm63xx_ep0_do_idle()
1539 } else if (udc->ep0_req_shutdown) { in bcm63xx_ep0_do_idle()
1540 udc->ep0_req_shutdown = 0; in bcm63xx_ep0_do_idle()
1541 udc->ep0_req_completed = 0; in bcm63xx_ep0_do_idle()
1542 udc->ep0_request = NULL; in bcm63xx_ep0_do_idle()
1543 iudma_reset_channel(udc, &udc->iudma[IUDMA_EP0_RXCHAN]); in bcm63xx_ep0_do_idle()
1544 usb_gadget_unmap_request(&udc->gadget, in bcm63xx_ep0_do_idle()
1545 &udc->ep0_ctrl_req.req, 0); in bcm63xx_ep0_do_idle()
1549 udc->ep0state = EP0_SHUTDOWN; in bcm63xx_ep0_do_idle()
1550 } else if (udc->ep0_reply) { in bcm63xx_ep0_do_idle()
1556 dev_warn(udc->dev, "nuking unexpected reply\n"); in bcm63xx_ep0_do_idle()
1557 bcm63xx_ep0_nuke_reply(udc, 0); in bcm63xx_ep0_do_idle()
1571 static int bcm63xx_ep0_one_round(struct bcm63xx_udc *udc) in bcm63xx_ep0_one_round() argument
1573 enum bcm63xx_ep0_state ep0state = udc->ep0state; in bcm63xx_ep0_one_round()
1574 bool shutdown = udc->ep0_req_reset || udc->ep0_req_shutdown; in bcm63xx_ep0_one_round()
1576 switch (udc->ep0state) { in bcm63xx_ep0_one_round()
1579 bcm63xx_ep0_internal_request(udc, IUDMA_EP0_RXCHAN, in bcm63xx_ep0_one_round()
1584 return bcm63xx_ep0_do_idle(udc); in bcm63xx_ep0_one_round()
1595 if (udc->ep0_reply) { in bcm63xx_ep0_one_round()
1596 bcm63xx_ep0_map_write(udc, IUDMA_EP0_TXCHAN, in bcm63xx_ep0_one_round()
1597 udc->ep0_reply); in bcm63xx_ep0_one_round()
1611 if (udc->ep0_req_completed) { in bcm63xx_ep0_one_round()
1612 udc->ep0_reply = NULL; in bcm63xx_ep0_one_round()
1613 bcm63xx_ep0_read_complete(udc); in bcm63xx_ep0_one_round()
1620 iudma_reset_channel(udc, &udc->iudma[IUDMA_EP0_TXCHAN]); in bcm63xx_ep0_one_round()
1621 bcm63xx_ep0_nuke_reply(udc, 1); in bcm63xx_ep0_one_round()
1628 if (udc->ep0_reply) { in bcm63xx_ep0_one_round()
1629 bcm63xx_ep0_map_write(udc, IUDMA_EP0_RXCHAN, in bcm63xx_ep0_one_round()
1630 udc->ep0_reply); in bcm63xx_ep0_one_round()
1638 if (udc->ep0_req_completed) { in bcm63xx_ep0_one_round()
1639 udc->ep0_reply = NULL; in bcm63xx_ep0_one_round()
1640 bcm63xx_ep0_read_complete(udc); in bcm63xx_ep0_one_round()
1643 bcm63xx_ep0_internal_request(udc, IUDMA_EP0_TXCHAN, 0); in bcm63xx_ep0_one_round()
1646 iudma_reset_channel(udc, &udc->iudma[IUDMA_EP0_RXCHAN]); in bcm63xx_ep0_one_round()
1647 bcm63xx_ep0_nuke_reply(udc, 0); in bcm63xx_ep0_one_round()
1661 if (udc->ep0_req_completed) { in bcm63xx_ep0_one_round()
1662 bcm63xx_ep0_read_complete(udc); in bcm63xx_ep0_one_round()
1665 iudma_reset_channel(udc, &udc->iudma[IUDMA_EP0_TXCHAN]); in bcm63xx_ep0_one_round()
1666 udc->ep0_request = NULL; in bcm63xx_ep0_one_round()
1685 struct usb_request *r = udc->ep0_reply; in bcm63xx_ep0_one_round()
1693 bcm63xx_ep0_complete(udc, r, 0); in bcm63xx_ep0_one_round()
1694 udc->ep0_reply = NULL; in bcm63xx_ep0_one_round()
1702 if (udc->ep0state == ep0state) in bcm63xx_ep0_one_round()
1705 udc->ep0state = ep0state; in bcm63xx_ep0_one_round()
1725 struct bcm63xx_udc *udc = container_of(w, struct bcm63xx_udc, ep0_wq); in bcm63xx_ep0_process() local
1726 spin_lock_irq(&udc->lock); in bcm63xx_ep0_process()
1727 while (bcm63xx_ep0_one_round(udc) == 0) in bcm63xx_ep0_process()
1729 spin_unlock_irq(&udc->lock); in bcm63xx_ep0_process()
1742 struct bcm63xx_udc *udc = gadget_to_udc(gadget); in bcm63xx_udc_get_frame() local
1744 return (usbd_readl(udc, USBD_STATUS_REG) & in bcm63xx_udc_get_frame()
1757 struct bcm63xx_udc *udc = gadget_to_udc(gadget); in bcm63xx_udc_pullup() local
1761 spin_lock_irqsave(&udc->lock, flags); in bcm63xx_udc_pullup()
1762 if (is_on && udc->ep0state == EP0_SHUTDOWN) { in bcm63xx_udc_pullup()
1763 udc->gadget.speed = USB_SPEED_UNKNOWN; in bcm63xx_udc_pullup()
1764 udc->ep0state = EP0_REQUEUE; in bcm63xx_udc_pullup()
1765 bcm63xx_fifo_setup(udc); in bcm63xx_udc_pullup()
1766 bcm63xx_fifo_reset(udc); in bcm63xx_udc_pullup()
1767 bcm63xx_ep_setup(udc); in bcm63xx_udc_pullup()
1769 bitmap_zero(&udc->wedgemap, BCM63XX_NUM_EP); in bcm63xx_udc_pullup()
1771 bcm63xx_set_stall(udc, &udc->bep[i], false); in bcm63xx_udc_pullup()
1773 bcm63xx_set_ctrl_irqs(udc, true); in bcm63xx_udc_pullup()
1776 } else if (!is_on && udc->ep0state != EP0_SHUTDOWN) { in bcm63xx_udc_pullup()
1779 udc->ep0_req_shutdown = 1; in bcm63xx_udc_pullup()
1780 spin_unlock_irqrestore(&udc->lock, flags); in bcm63xx_udc_pullup()
1783 schedule_work(&udc->ep0_wq); in bcm63xx_udc_pullup()
1784 if (udc->ep0state == EP0_SHUTDOWN) in bcm63xx_udc_pullup()
1788 bcm63xx_set_ctrl_irqs(udc, false); in bcm63xx_udc_pullup()
1789 cancel_work_sync(&udc->ep0_wq); in bcm63xx_udc_pullup()
1793 spin_unlock_irqrestore(&udc->lock, flags); in bcm63xx_udc_pullup()
1805 struct bcm63xx_udc *udc = gadget_to_udc(gadget); in bcm63xx_udc_start() local
1811 if (!udc) in bcm63xx_udc_start()
1813 if (udc->driver) in bcm63xx_udc_start()
1816 spin_lock_irqsave(&udc->lock, flags); in bcm63xx_udc_start()
1818 set_clocks(udc, true); in bcm63xx_udc_start()
1819 bcm63xx_fifo_setup(udc); in bcm63xx_udc_start()
1820 bcm63xx_ep_init(udc); in bcm63xx_udc_start()
1821 bcm63xx_ep_setup(udc); in bcm63xx_udc_start()
1822 bcm63xx_fifo_reset(udc); in bcm63xx_udc_start()
1823 bcm63xx_select_phy_mode(udc, true); in bcm63xx_udc_start()
1825 udc->driver = driver; in bcm63xx_udc_start()
1827 udc->gadget.dev.of_node = udc->dev->of_node; in bcm63xx_udc_start()
1829 spin_unlock_irqrestore(&udc->lock, flags); in bcm63xx_udc_start()
1841 struct bcm63xx_udc *udc = gadget_to_udc(gadget); in bcm63xx_udc_stop() local
1844 spin_lock_irqsave(&udc->lock, flags); in bcm63xx_udc_stop()
1846 udc->driver = NULL; in bcm63xx_udc_stop()
1856 bcm63xx_select_phy_mode(udc, false); in bcm63xx_udc_stop()
1857 set_clocks(udc, false); in bcm63xx_udc_stop()
1859 spin_unlock_irqrestore(&udc->lock, flags); in bcm63xx_udc_stop()
1884 static void bcm63xx_update_cfg_iface(struct bcm63xx_udc *udc) in bcm63xx_update_cfg_iface() argument
1886 u32 reg = usbd_readl(udc, USBD_STATUS_REG); in bcm63xx_update_cfg_iface()
1888 udc->cfg = (reg & USBD_STATUS_CFG_MASK) >> USBD_STATUS_CFG_SHIFT; in bcm63xx_update_cfg_iface()
1889 udc->iface = (reg & USBD_STATUS_INTF_MASK) >> USBD_STATUS_INTF_SHIFT; in bcm63xx_update_cfg_iface()
1890 udc->alt_iface = (reg & USBD_STATUS_ALTINTF_MASK) >> in bcm63xx_update_cfg_iface()
1892 bcm63xx_ep_setup(udc); in bcm63xx_update_cfg_iface()
1902 static int bcm63xx_update_link_speed(struct bcm63xx_udc *udc) in bcm63xx_update_link_speed() argument
1904 u32 reg = usbd_readl(udc, USBD_STATUS_REG); in bcm63xx_update_link_speed()
1905 enum usb_device_speed oldspeed = udc->gadget.speed; in bcm63xx_update_link_speed()
1909 udc->gadget.speed = USB_SPEED_HIGH; in bcm63xx_update_link_speed()
1912 udc->gadget.speed = USB_SPEED_FULL; in bcm63xx_update_link_speed()
1916 udc->gadget.speed = USB_SPEED_UNKNOWN; in bcm63xx_update_link_speed()
1917 dev_err(udc->dev, in bcm63xx_update_link_speed()
1922 if (udc->gadget.speed != oldspeed) { in bcm63xx_update_link_speed()
1923 dev_info(udc->dev, "link up, %s-speed mode\n", in bcm63xx_update_link_speed()
1924 udc->gadget.speed == USB_SPEED_HIGH ? "high" : "full"); in bcm63xx_update_link_speed()
1942 static void bcm63xx_update_wedge(struct bcm63xx_udc *udc, bool new_status) in bcm63xx_update_wedge() argument
1946 for_each_set_bit(i, &udc->wedgemap, BCM63XX_NUM_EP) { in bcm63xx_update_wedge()
1947 bcm63xx_set_stall(udc, &udc->bep[i], new_status); in bcm63xx_update_wedge()
1949 clear_bit(i, &udc->wedgemap); in bcm63xx_update_wedge()
1963 struct bcm63xx_udc *udc = dev_id; in bcm63xx_udc_ctrl_isr() local
1967 stat = usbd_readl(udc, USBD_EVENT_IRQ_STATUS_REG) & in bcm63xx_udc_ctrl_isr()
1968 usbd_readl(udc, USBD_EVENT_IRQ_MASK_REG); in bcm63xx_udc_ctrl_isr()
1970 usbd_writel(udc, stat, USBD_EVENT_IRQ_STATUS_REG); in bcm63xx_udc_ctrl_isr()
1972 spin_lock(&udc->lock); in bcm63xx_udc_ctrl_isr()
1976 if (!(usbd_readl(udc, USBD_EVENTS_REG) & in bcm63xx_udc_ctrl_isr()
1978 udc->gadget.speed != USB_SPEED_UNKNOWN) in bcm63xx_udc_ctrl_isr()
1979 dev_info(udc->dev, "link down\n"); in bcm63xx_udc_ctrl_isr()
1981 udc->gadget.speed = USB_SPEED_UNKNOWN; in bcm63xx_udc_ctrl_isr()
1985 bcm63xx_fifo_setup(udc); in bcm63xx_udc_ctrl_isr()
1986 bcm63xx_fifo_reset(udc); in bcm63xx_udc_ctrl_isr()
1987 bcm63xx_ep_setup(udc); in bcm63xx_udc_ctrl_isr()
1989 bcm63xx_update_wedge(udc, false); in bcm63xx_udc_ctrl_isr()
1991 udc->ep0_req_reset = 1; in bcm63xx_udc_ctrl_isr()
1992 schedule_work(&udc->ep0_wq); in bcm63xx_udc_ctrl_isr()
1996 if (bcm63xx_update_link_speed(udc)) { in bcm63xx_udc_ctrl_isr()
1997 bcm63xx_fifo_setup(udc); in bcm63xx_udc_ctrl_isr()
1998 bcm63xx_ep_setup(udc); in bcm63xx_udc_ctrl_isr()
2000 bcm63xx_update_wedge(udc, true); in bcm63xx_udc_ctrl_isr()
2003 bcm63xx_update_cfg_iface(udc); in bcm63xx_udc_ctrl_isr()
2004 udc->ep0_req_set_cfg = 1; in bcm63xx_udc_ctrl_isr()
2005 schedule_work(&udc->ep0_wq); in bcm63xx_udc_ctrl_isr()
2008 bcm63xx_update_cfg_iface(udc); in bcm63xx_udc_ctrl_isr()
2009 udc->ep0_req_set_iface = 1; in bcm63xx_udc_ctrl_isr()
2010 schedule_work(&udc->ep0_wq); in bcm63xx_udc_ctrl_isr()
2012 spin_unlock(&udc->lock); in bcm63xx_udc_ctrl_isr()
2014 if (disconnected && udc->driver) in bcm63xx_udc_ctrl_isr()
2015 udc->driver->disconnect(&udc->gadget); in bcm63xx_udc_ctrl_isr()
2016 else if (bus_reset && udc->driver) in bcm63xx_udc_ctrl_isr()
2017 usb_gadget_udc_reset(&udc->gadget, udc->driver); in bcm63xx_udc_ctrl_isr()
2035 struct bcm63xx_udc *udc = iudma->udc; in bcm63xx_udc_data_isr() local
2042 spin_lock(&udc->lock); in bcm63xx_udc_data_isr()
2044 usb_dmac_writel(udc, ENETDMAC_IR_BUFDONE_MASK, in bcm63xx_udc_data_isr()
2047 rc = iudma_read(udc, iudma); in bcm63xx_udc_data_isr()
2052 req = udc->ep0_request; in bcm63xx_udc_data_isr()
2060 udc->ep0_req_completed = 1; in bcm63xx_udc_data_isr()
2062 schedule_work(&udc->ep0_wq); in bcm63xx_udc_data_isr()
2068 iudma_write(udc, iudma, breq); in bcm63xx_udc_data_isr()
2089 iudma_write(udc, iudma, next); in bcm63xx_udc_data_isr()
2092 iudma_write(udc, iudma, breq); in bcm63xx_udc_data_isr()
2096 spin_unlock(&udc->lock); in bcm63xx_udc_data_isr()
2099 usb_gadget_unmap_request(&udc->gadget, req, iudma->is_tx); in bcm63xx_udc_data_isr()
2120 struct bcm63xx_udc *udc = s->private; in bcm63xx_usbd_dbg_show() local
2122 if (!udc->driver) in bcm63xx_usbd_dbg_show()
2126 bcm63xx_ep0_state_names[udc->ep0state]); in bcm63xx_usbd_dbg_show()
2128 udc->ep0_req_reset ? "reset " : "", in bcm63xx_usbd_dbg_show()
2129 udc->ep0_req_set_cfg ? "set_cfg " : "", in bcm63xx_usbd_dbg_show()
2130 udc->ep0_req_set_iface ? "set_iface " : "", in bcm63xx_usbd_dbg_show()
2131 udc->ep0_req_shutdown ? "shutdown " : "", in bcm63xx_usbd_dbg_show()
2132 udc->ep0_request ? "pending " : "", in bcm63xx_usbd_dbg_show()
2133 udc->ep0_req_completed ? "completed " : "", in bcm63xx_usbd_dbg_show()
2134 udc->ep0_reply ? "reply " : ""); in bcm63xx_usbd_dbg_show()
2136 udc->cfg, udc->iface, udc->alt_iface); in bcm63xx_usbd_dbg_show()
2139 usbd_readl(udc, USBD_CONTROL_REG), in bcm63xx_usbd_dbg_show()
2140 usbd_readl(udc, USBD_STRAPS_REG), in bcm63xx_usbd_dbg_show()
2141 usbd_readl(udc, USBD_STATUS_REG)); in bcm63xx_usbd_dbg_show()
2143 usbd_readl(udc, USBD_EVENTS_REG), in bcm63xx_usbd_dbg_show()
2144 usbd_readl(udc, USBD_STALL_REG)); in bcm63xx_usbd_dbg_show()
2158 struct bcm63xx_udc *udc = s->private; in bcm63xx_iudma_dbg_show() local
2162 if (!udc->driver) in bcm63xx_iudma_dbg_show()
2166 struct iudma_ch *iudma = &udc->iudma[ch_idx]; in bcm63xx_iudma_dbg_show()
2185 usb_dmac_readl(udc, ENETDMAC_CHANCFG_REG, ch_idx), in bcm63xx_iudma_dbg_show()
2186 usb_dmac_readl(udc, ENETDMAC_IR_REG, ch_idx), in bcm63xx_iudma_dbg_show()
2187 usb_dmac_readl(udc, ENETDMAC_IRMASK_REG, ch_idx), in bcm63xx_iudma_dbg_show()
2188 usb_dmac_readl(udc, ENETDMAC_MAXBURST_REG, ch_idx)); in bcm63xx_iudma_dbg_show()
2190 sram2 = usb_dmas_readl(udc, ENETDMAS_SRAM2_REG, ch_idx); in bcm63xx_iudma_dbg_show()
2191 sram3 = usb_dmas_readl(udc, ENETDMAS_SRAM3_REG, ch_idx); in bcm63xx_iudma_dbg_show()
2193 usb_dmas_readl(udc, ENETDMAS_RSTART_REG, ch_idx), in bcm63xx_iudma_dbg_show()
2196 usb_dmas_readl(udc, ENETDMAS_SRAM4_REG, ch_idx)); in bcm63xx_iudma_dbg_show()
2260 static void bcm63xx_udc_init_debugfs(struct bcm63xx_udc *udc) in bcm63xx_udc_init_debugfs() argument
2267 root = debugfs_create_dir(udc->gadget.name, NULL); in bcm63xx_udc_init_debugfs()
2271 usbd = debugfs_create_file("usbd", 0400, root, udc, in bcm63xx_udc_init_debugfs()
2275 iudma = debugfs_create_file("iudma", 0400, root, udc, in bcm63xx_udc_init_debugfs()
2280 udc->debugfs_root = root; in bcm63xx_udc_init_debugfs()
2281 udc->debugfs_usbd = usbd; in bcm63xx_udc_init_debugfs()
2282 udc->debugfs_iudma = iudma; in bcm63xx_udc_init_debugfs()
2289 dev_err(udc->dev, "debugfs is not available\n"); in bcm63xx_udc_init_debugfs()
2298 static void bcm63xx_udc_cleanup_debugfs(struct bcm63xx_udc *udc) in bcm63xx_udc_cleanup_debugfs() argument
2300 debugfs_remove(udc->debugfs_iudma); in bcm63xx_udc_cleanup_debugfs()
2301 debugfs_remove(udc->debugfs_usbd); in bcm63xx_udc_cleanup_debugfs()
2302 debugfs_remove(udc->debugfs_root); in bcm63xx_udc_cleanup_debugfs()
2303 udc->debugfs_iudma = NULL; in bcm63xx_udc_cleanup_debugfs()
2304 udc->debugfs_usbd = NULL; in bcm63xx_udc_cleanup_debugfs()
2305 udc->debugfs_root = NULL; in bcm63xx_udc_cleanup_debugfs()
2323 struct bcm63xx_udc *udc; in bcm63xx_udc_probe() local
2327 udc = devm_kzalloc(dev, sizeof(*udc), GFP_KERNEL); in bcm63xx_udc_probe()
2328 if (!udc) in bcm63xx_udc_probe()
2331 platform_set_drvdata(pdev, udc); in bcm63xx_udc_probe()
2332 udc->dev = dev; in bcm63xx_udc_probe()
2333 udc->pd = pd; in bcm63xx_udc_probe()
2341 udc->usbd_regs = devm_ioremap_resource(dev, res); in bcm63xx_udc_probe()
2342 if (IS_ERR(udc->usbd_regs)) in bcm63xx_udc_probe()
2343 return PTR_ERR(udc->usbd_regs); in bcm63xx_udc_probe()
2346 udc->iudma_regs = devm_ioremap_resource(dev, res); in bcm63xx_udc_probe()
2347 if (IS_ERR(udc->iudma_regs)) in bcm63xx_udc_probe()
2348 return PTR_ERR(udc->iudma_regs); in bcm63xx_udc_probe()
2350 spin_lock_init(&udc->lock); in bcm63xx_udc_probe()
2351 INIT_WORK(&udc->ep0_wq, bcm63xx_ep0_process); in bcm63xx_udc_probe()
2353 udc->gadget.ops = &bcm63xx_udc_ops; in bcm63xx_udc_probe()
2354 udc->gadget.name = dev_name(dev); in bcm63xx_udc_probe()
2357 udc->gadget.max_speed = USB_SPEED_HIGH; in bcm63xx_udc_probe()
2359 udc->gadget.max_speed = USB_SPEED_FULL; in bcm63xx_udc_probe()
2362 rc = bcm63xx_init_udc_hw(udc); in bcm63xx_udc_probe()
2375 dev_name(dev), udc) < 0) { in bcm63xx_udc_probe()
2388 dev_name(dev), &udc->iudma[i]) < 0) { in bcm63xx_udc_probe()
2394 bcm63xx_udc_init_debugfs(udc); in bcm63xx_udc_probe()
2395 rc = usb_add_gadget_udc(dev, &udc->gadget); in bcm63xx_udc_probe()
2399 bcm63xx_udc_cleanup_debugfs(udc); in bcm63xx_udc_probe()
2401 bcm63xx_uninit_udc_hw(udc); in bcm63xx_udc_probe()
2411 struct bcm63xx_udc *udc = platform_get_drvdata(pdev); in bcm63xx_udc_remove() local
2413 bcm63xx_udc_cleanup_debugfs(udc); in bcm63xx_udc_remove()
2414 usb_del_gadget_udc(&udc->gadget); in bcm63xx_udc_remove()
2415 BUG_ON(udc->driver); in bcm63xx_udc_remove()
2417 bcm63xx_uninit_udc_hw(udc); in bcm63xx_udc_remove()