Lines Matching +full:idle +full:- +full:halt

1 // SPDX-License-Identifier: GPL-2.0+
6 * Dante Su <dantesu@faraday-tech.com>
73 return (id <= 0) ? -1 : ((id - 1) & 0x03); in ep_to_fifo()
79 struct fotg210_regs *regs = chip->regs; in ep_reset()
83 setbits_le32(&regs->iep[ep - 1], IEP_RESET); in ep_reset()
85 clrbits_le32(&regs->iep[ep - 1], IEP_RESET); in ep_reset()
87 clrbits_le32(&regs->iep[ep - 1], IEP_STALL); in ep_reset()
90 setbits_le32(&regs->oep[ep - 1], OEP_RESET); in ep_reset()
92 clrbits_le32(&regs->oep[ep - 1], OEP_RESET); in ep_reset()
94 clrbits_le32(&regs->oep[ep - 1], OEP_STALL); in ep_reset()
102 struct fotg210_regs *regs = chip->regs; in fotg210_reset()
105 chip->state = USB_STATE_POWERED; in fotg210_reset()
108 writel(DEVCTRL_EN, &regs->dev_ctrl); in fotg210_reset()
111 chip->addr = 0; in fotg210_reset()
112 writel(0, &regs->dev_addr); in fotg210_reset()
114 /* set idle counter to 7ms */ in fotg210_reset()
115 writel(7, &regs->idle); in fotg210_reset()
118 writel(IMR_MASK, &regs->imr); in fotg210_reset()
119 writel(GIMR_MASK, &regs->gimr); in fotg210_reset()
120 writel(GIMR0_MASK, &regs->gimr0); in fotg210_reset()
121 writel(GIMR1_MASK, &regs->gimr1); in fotg210_reset()
122 writel(GIMR2_MASK, &regs->gimr2); in fotg210_reset()
125 writel(ISR_MASK, &regs->isr); in fotg210_reset()
126 writel(0, &regs->gisr); in fotg210_reset()
127 writel(0, &regs->gisr0); in fotg210_reset()
128 writel(0, &regs->gisr1); in fotg210_reset()
129 writel(0, &regs->gisr2); in fotg210_reset()
132 setbits_le32(&regs->dev_ctrl, DEVCTRL_RESET); in fotg210_reset()
134 if (readl(&regs->dev_ctrl) & DEVCTRL_RESET) { in fotg210_reset()
136 return -1; in fotg210_reset()
140 setbits_le32(&regs->cxfifo, CXFIFO_CXFIFOCLR); in fotg210_reset()
142 if (readl(&regs->cxfifo) & CXFIFO_CXFIFOCLR) { in fotg210_reset()
144 return -1; in fotg210_reset()
147 /* create static ep-fifo map (EP1 <-> FIFO0, EP2 <-> FIFO1 ...) */ in fotg210_reset()
148 writel(EPMAP14_DEFAULT, &regs->epmap14); in fotg210_reset()
149 writel(EPMAP58_DEFAULT, &regs->epmap58); in fotg210_reset()
150 writel(FIFOMAP_DEFAULT, &regs->fifomap); in fotg210_reset()
151 writel(0, &regs->fifocfg); in fotg210_reset()
153 writel(CFG_EPX_MAX_PACKET_SIZE, &regs->iep[i]); in fotg210_reset()
154 writel(CFG_EPX_MAX_PACKET_SIZE, &regs->oep[i]); in fotg210_reset()
159 writel(FIFOCSR_RESET, &regs->fifocsr[i]); in fotg210_reset()
161 if (readl(&regs->fifocsr[i]) & FIFOCSR_RESET) { in fotg210_reset()
163 return -1; in fotg210_reset()
167 /* enable only device interrupt and triggered at level-high */ in fotg210_reset()
168 writel(IMR_IRQLH | IMR_HOST | IMR_OTG, &regs->imr); in fotg210_reset()
169 writel(ISR_MASK, &regs->isr); in fotg210_reset()
171 writel(GIMR0_CXOUT | GIMR0_CXIN, &regs->gimr0); in fotg210_reset()
173 writel(GIMR1_MASK, &regs->gimr1); in fotg210_reset()
174 /* disable wakeup+idle+dma+zlp interrupts */ in fotg210_reset()
176 | GIMR2_ZLPRX | GIMR2_ZLPTX, &regs->gimr2); in fotg210_reset()
178 writel(0, &regs->gimr); in fotg210_reset()
181 writel(3, &regs->idle); in fotg210_reset()
183 /* turn-on device interrupts */ in fotg210_reset()
184 setbits_le32(&regs->dev_ctrl, DEVCTRL_GIRQ_EN); in fotg210_reset()
191 struct fotg210_regs *regs = chip->regs; in fotg210_cxwait()
192 int ret = -1; in fotg210_cxwait()
196 if ((readl(&regs->cxfifo) & mask) != mask) in fotg210_cxwait()
210 struct fotg210_chip *chip = ep->chip; in fotg210_dma()
211 struct fotg210_regs *regs = chip->regs; in fotg210_dma()
213 uint8_t *buf = req->req.buf + req->req.actual; in fotg210_dma()
214 uint32_t len = req->req.length - req->req.actual; in fotg210_dma()
215 int fifo = ep_to_fifo(chip, ep->id); in fotg210_dma()
216 int ret = -EBUSY; in fotg210_dma()
219 if (len > ep->maxpacket) in fotg210_dma()
220 len = ep->maxpacket; in fotg210_dma()
224 if (!(readl(&regs->dma_ctrl) & DMACTRL_START)) { in fotg210_dma()
231 req->req.status = ret; in fotg210_dma()
236 if (ep->desc->bEndpointAddress & USB_DIR_IN) in fotg210_dma()
241 writel(virt_to_phys(buf), &regs->dma_addr); in fotg210_dma()
243 if (ep->desc->bEndpointAddress & USB_DIR_IN) { in fotg210_dma()
244 if (ep->id == 0) { in fotg210_dma()
248 writel(DMAFIFO_CX, &regs->dma_fifo); in fotg210_dma()
252 writel(DMAFIFO_FIFO(fifo), &regs->dma_fifo); in fotg210_dma()
254 writel(DMACTRL_LEN(len) | DMACTRL_MEM2FIFO, &regs->dma_ctrl); in fotg210_dma()
258 if (ep->id == 0) { in fotg210_dma()
259 writel(DMAFIFO_CX, &regs->dma_fifo); in fotg210_dma()
261 blen = CXFIFO_BYTES(readl(&regs->cxfifo)); in fotg210_dma()
264 writel(DMAFIFO_FIFO(fifo), &regs->dma_fifo); in fotg210_dma()
265 blen = FIFOCSR_BYTES(readl(&regs->fifocsr[fifo])); in fotg210_dma()
268 writel(DMACTRL_LEN(len) | DMACTRL_FIFO2MEM, &regs->dma_ctrl); in fotg210_dma()
272 setbits_le32(&regs->dma_ctrl, DMACTRL_START); in fotg210_dma()
275 ret = -EBUSY; in fotg210_dma()
277 tmp = readl(&regs->gisr2); in fotg210_dma()
297 writel(DMACTRL_ABORT | DMACTRL_CLRFF, &regs->dma_ctrl); in fotg210_dma()
299 writel(0, &regs->gisr2); in fotg210_dma()
300 writel(0, &regs->dma_fifo); in fotg210_dma()
302 req->req.status = ret; in fotg210_dma()
304 req->req.actual += len; in fotg210_dma()
306 printf("fotg210: ep%d dma error(code=%d)\n", ep->id, ret); in fotg210_dma()
323 struct fotg210_regs *regs = chip->regs; in fotg210_setup()
329 if (chip->state == USB_STATE_POWERED) { in fotg210_setup()
330 chip->state = USB_STATE_DEFAULT; in fotg210_setup()
331 if (readl(&regs->otgcsr) & OTGCSR_DEV_B) { in fotg210_setup()
332 /* Mini-B */ in fotg210_setup()
333 if (readl(&regs->dev_ctrl) & DEVCTRL_HS) { in fotg210_setup()
335 chip->gadget.speed = USB_SPEED_HIGH; in fotg210_setup()
337 writel(SOFMTR_TMR(1100), &regs->sof_mtr); in fotg210_setup()
340 chip->gadget.speed = USB_SPEED_FULL; in fotg210_setup()
342 writel(SOFMTR_TMR(10000), &regs->sof_mtr); in fotg210_setup()
345 printf("fotg210: mini-A?\n"); in fotg210_setup()
350 writel(DMAFIFO_CX, &regs->dma_fifo); in fotg210_setup()
352 tmp[0] = readl(&regs->ep0_data); in fotg210_setup()
353 tmp[1] = readl(&regs->ep0_data); in fotg210_setup()
355 writel(0, &regs->dma_fifo); in fotg210_setup()
357 if (req->bRequestType & USB_DIR_IN) in fotg210_setup()
364 if ((req->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { in fotg210_setup()
365 switch (req->bRequest) { in fotg210_setup()
367 debug("fotg210: set_cfg(%d)\n", req->wValue & 0x00FF); in fotg210_setup()
368 if (!(req->wValue & 0x00FF)) { in fotg210_setup()
369 chip->state = USB_STATE_ADDRESS; in fotg210_setup()
370 writel(chip->addr, &regs->dev_addr); in fotg210_setup()
372 chip->state = USB_STATE_CONFIGURED; in fotg210_setup()
373 writel(chip->addr | DEVADDR_CONF, in fotg210_setup()
374 &regs->dev_addr); in fotg210_setup()
380 debug("fotg210: set_addr(0x%04X)\n", req->wValue); in fotg210_setup()
381 chip->state = USB_STATE_ADDRESS; in fotg210_setup()
382 chip->addr = req->wValue & DEVADDR_ADDR_MASK; in fotg210_setup()
384 writel(chip->addr, &regs->dev_addr); in fotg210_setup()
389 req->bRequestType & 0x03, req->wValue); in fotg210_setup()
390 switch (req->wValue) { in fotg210_setup()
391 case 0: /* [Endpoint] halt */ in fotg210_setup()
392 ep_reset(chip, req->wIndex); in fotg210_setup()
395 case 1: /* [Device] remote wake-up */ in fotg210_setup()
405 req->wValue, req->wIndex & 0xf); in fotg210_setup()
406 switch (req->wValue) { in fotg210_setup()
407 case 0: /* Endpoint Halt */ in fotg210_setup()
408 id = req->wIndex & 0xf; in fotg210_setup()
409 setbits_le32(&regs->iep[id - 1], IEP_STALL); in fotg210_setup()
410 setbits_le32(&regs->oep[id - 1], OEP_STALL); in fotg210_setup()
436 } /* if ((req->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) */ in fotg210_setup()
438 if (ret == CX_IDLE && chip->driver->setup) { in fotg210_setup()
439 if (chip->driver->setup(&chip->gadget, req) < 0) in fotg210_setup()
447 setbits_le32(&regs->cxfifo, CXFIFO_CXFIN); in fotg210_setup()
451 setbits_le32(&regs->cxfifo, CXFIFO_CXSTALL | CXFIFO_CXFIN); in fotg210_setup()
463 * fifo - FIFO id
464 * zlp - zero length packet
468 struct fotg210_regs *regs = chip->regs; in fotg210_recv()
469 struct fotg210_ep *ep = chip->ep + ep_id; in fotg210_recv()
473 if (ep->stopped || (ep->desc->bEndpointAddress & USB_DIR_IN)) { in fotg210_recv()
474 printf("fotg210: ep%d recv, invalid!\n", ep->id); in fotg210_recv()
478 if (list_empty(&ep->queue)) { in fotg210_recv()
479 printf("fotg210: ep%d recv, drop!\n", ep->id); in fotg210_recv()
483 req = list_first_entry(&ep->queue, struct fotg210_request, queue); in fotg210_recv()
485 if (len < ep->ep.maxpacket || req->req.length <= req->req.actual) { in fotg210_recv()
486 list_del_init(&req->queue); in fotg210_recv()
487 if (req->req.complete) in fotg210_recv()
488 req->req.complete(&ep->ep, &req->req); in fotg210_recv()
491 if (ep->id > 0 && list_empty(&ep->queue)) { in fotg210_recv()
492 setbits_le32(&regs->gimr1, in fotg210_recv()
493 GIMR1_FIFO_RX(ep_to_fifo(chip, ep->id))); in fotg210_recv()
504 struct fotg210_chip *chip = ep->chip; in fotg210_ep_enable()
505 struct fotg210_regs *regs = chip->regs; in fotg210_ep_enable()
506 int id = ep_to_fifo(chip, ep->id); in fotg210_ep_enable()
507 int in = (desc->bEndpointAddress & USB_DIR_IN) ? 1 : 0; in fotg210_ep_enable()
510 || desc->bDescriptorType != USB_DT_ENDPOINT in fotg210_ep_enable()
511 || le16_to_cpu(desc->wMaxPacketSize) == 0) { in fotg210_ep_enable()
513 return -EINVAL; in fotg210_ep_enable()
516 ep->desc = desc; in fotg210_ep_enable()
517 ep->stopped = 0; in fotg210_ep_enable()
520 setbits_le32(&regs->fifomap, FIFOMAP(id, FIFOMAP_IN)); in fotg210_ep_enable()
522 switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { in fotg210_ep_enable()
524 return -EINVAL; in fotg210_ep_enable()
527 setbits_le32(&regs->fifocfg, in fotg210_ep_enable()
532 setbits_le32(&regs->fifocfg, in fotg210_ep_enable()
537 setbits_le32(&regs->fifocfg, in fotg210_ep_enable()
548 struct fotg210_chip *chip = ep->chip; in fotg210_ep_disable()
549 struct fotg210_regs *regs = chip->regs; in fotg210_ep_disable()
550 int id = ep_to_fifo(chip, ep->id); in fotg210_ep_disable()
552 ep->desc = NULL; in fotg210_ep_disable()
553 ep->stopped = 1; in fotg210_ep_disable()
555 clrbits_le32(&regs->fifocfg, FIFOCFG(id, FIFOCFG_CFG_MASK)); in fotg210_ep_disable()
556 clrbits_le32(&regs->fifomap, FIFOMAP(id, FIFOMAP_DIR_MASK)); in fotg210_ep_disable()
568 INIT_LIST_HEAD(&req->queue); in fotg210_ep_alloc_request()
570 return &req->req; in fotg210_ep_alloc_request()
586 struct fotg210_chip *chip = ep->chip; in fotg210_ep_queue()
587 struct fotg210_regs *regs = chip->regs; in fotg210_ep_queue()
591 if (!_req || !_req->complete || !_req->buf in fotg210_ep_queue()
592 || !list_empty(&req->queue)) { in fotg210_ep_queue()
593 printf("fotg210: invalid request to ep%d\n", ep->id); in fotg210_ep_queue()
594 return -EINVAL; in fotg210_ep_queue()
597 if (!chip || chip->state == USB_STATE_SUSPENDED) { in fotg210_ep_queue()
599 return -EINVAL; in fotg210_ep_queue()
602 req->req.actual = 0; in fotg210_ep_queue()
603 req->req.status = -EINPROGRESS; in fotg210_ep_queue()
605 if (req->req.length == 0) { in fotg210_ep_queue()
606 req->req.status = 0; in fotg210_ep_queue()
607 if (req->req.complete) in fotg210_ep_queue()
608 req->req.complete(&ep->ep, &req->req); in fotg210_ep_queue()
612 if (ep->id == 0) { in fotg210_ep_queue()
615 if (len < ep->ep.maxpacket) in fotg210_ep_queue()
617 if (ep->desc->bEndpointAddress & USB_DIR_IN) in fotg210_ep_queue()
619 } while (req->req.length > req->req.actual); in fotg210_ep_queue()
621 if (ep->desc->bEndpointAddress & USB_DIR_IN) { in fotg210_ep_queue()
624 if (len < ep->ep.maxpacket) in fotg210_ep_queue()
626 } while (req->req.length > req->req.actual); in fotg210_ep_queue()
628 list_add_tail(&req->queue, &ep->queue); in fotg210_ep_queue()
629 clrbits_le32(&regs->gimr1, in fotg210_ep_queue()
630 GIMR1_FIFO_RX(ep_to_fifo(chip, ep->id))); in fotg210_ep_queue()
634 if (ep->id == 0 || (ep->desc->bEndpointAddress & USB_DIR_IN)) { in fotg210_ep_queue()
635 if (req->req.complete) in fotg210_ep_queue()
636 req->req.complete(&ep->ep, &req->req); in fotg210_ep_queue()
648 list_for_each_entry(req, &ep->queue, queue) { in fotg210_ep_dequeue()
649 if (&req->req == _req) in fotg210_ep_dequeue()
652 if (&req->req != _req) in fotg210_ep_dequeue()
653 return -EINVAL; in fotg210_ep_dequeue()
656 list_del_init(&req->queue); in fotg210_ep_dequeue()
659 if (req->req.status == -EINPROGRESS) { in fotg210_ep_dequeue()
660 req->req.status = -ECONNRESET; in fotg210_ep_dequeue()
661 if (req->req.complete) in fotg210_ep_dequeue()
662 req->req.complete(_ep, &req->req); in fotg210_ep_dequeue()
668 static int fotg210_ep_halt(struct usb_ep *_ep, int halt) in fotg210_ep_halt() argument
671 struct fotg210_chip *chip = ep->chip; in fotg210_ep_halt()
672 struct fotg210_regs *regs = chip->regs; in fotg210_ep_halt()
673 int ret = -1; in fotg210_ep_halt()
675 debug("fotg210: ep%d halt=%d\n", ep->id, halt); in fotg210_ep_halt()
678 if (ep->id > 0 && ep->id <= CFG_NUM_ENDPOINTS) { in fotg210_ep_halt()
679 if (halt) { in fotg210_ep_halt()
683 if (ep->desc->bEndpointAddress & USB_DIR_IN) { in fotg210_ep_halt()
684 setbits_le32(&regs->iep[ep->id - 1], in fotg210_ep_halt()
687 setbits_le32(&regs->oep[ep->id - 1], in fotg210_ep_halt()
691 if (ep->desc->bEndpointAddress & USB_DIR_IN) { in fotg210_ep_halt()
692 clrbits_le32(&regs->iep[ep->id - 1], in fotg210_ep_halt()
695 clrbits_le32(&regs->oep[ep->id - 1], in fotg210_ep_halt()
710 struct fotg210_regs *regs = chip->regs; in pullup()
713 if (!chip->pullup) { in pullup()
714 chip->state = USB_STATE_POWERED; in pullup()
715 chip->pullup = 1; in pullup()
717 setbits_le32(&regs->dev_ctrl, DEVCTRL_EN); in pullup()
719 clrbits_le32(&regs->phy_tmsr, PHYTMSR_UNPLUG); in pullup()
722 chip->state = USB_STATE_NOTATTACHED; in pullup()
723 chip->pullup = 0; in pullup()
724 chip->addr = 0; in pullup()
725 writel(chip->addr, &regs->dev_addr); in pullup()
727 setbits_le32(&regs->phy_tmsr, PHYTMSR_UNPLUG); in pullup()
729 clrbits_le32(&regs->dev_ctrl, DEVCTRL_EN); in pullup()
752 regs = chip->regs; in fotg210_get_frame()
754 return SOFFNR_FNR(readl(&regs->sof_fnr)); in fotg210_get_frame()
837 struct fotg210_regs *regs = chip->regs; in usb_gadget_handle_interrupts()
840 isr = readl(&regs->isr) & (~readl(&regs->imr)); in usb_gadget_handle_interrupts()
841 gisr = readl(&regs->gisr) & (~readl(&regs->gimr)); in usb_gadget_handle_interrupts()
845 writel(ISR_DEV, &regs->isr); in usb_gadget_handle_interrupts()
849 st = readl(&regs->gisr0); in usb_gadget_handle_interrupts()
854 * HW v1.10.0-: It's a R/W register (write 0 clear) in usb_gadget_handle_interrupts()
856 writel(st & GISR0_CXABORT, &regs->gisr0); in usb_gadget_handle_interrupts()
857 writel(0, &regs->gisr0); in usb_gadget_handle_interrupts()
868 setbits_le32(&regs->cxfifo, CXFIFO_CXFIN); in usb_gadget_handle_interrupts()
873 st = readl(&regs->gisr1); in usb_gadget_handle_interrupts()
882 st = readl(&regs->gisr2); in usb_gadget_handle_interrupts()
887 * HW v1.10.0-: It's a R/W register (write 0 clear) in usb_gadget_handle_interrupts()
889 writel(st, &regs->gisr2); in usb_gadget_handle_interrupts()
890 writel(0, &regs->gisr2); in usb_gadget_handle_interrupts()
916 if (!driver || !driver->bind || !driver->setup) { in usb_gadget_register_driver()
918 return -EINVAL; in usb_gadget_register_driver()
921 INIT_LIST_HEAD(&chip->gadget.ep_list); in usb_gadget_register_driver()
923 struct fotg210_ep *ep = chip->ep + i; in usb_gadget_register_driver()
925 ep->ep.maxpacket = ep->maxpacket; in usb_gadget_register_driver()
926 INIT_LIST_HEAD(&ep->queue); in usb_gadget_register_driver()
928 if (ep->id == 0) { in usb_gadget_register_driver()
929 ep->stopped = 0; in usb_gadget_register_driver()
931 ep->stopped = 1; in usb_gadget_register_driver()
932 list_add_tail(&ep->ep.ep_list, &chip->gadget.ep_list); in usb_gadget_register_driver()
938 return -EINVAL; in usb_gadget_register_driver()
941 ret = driver->bind(&chip->gadget); in usb_gadget_register_driver()
943 debug("fotg210: driver->bind() returned %d\n", ret); in usb_gadget_register_driver()
946 chip->driver = driver; in usb_gadget_register_driver()
955 driver->unbind(&chip->gadget); in usb_gadget_unregister_driver()
956 chip->driver = NULL; in usb_gadget_unregister_driver()