int setdma_tx(struct s3c_ep *ep, struct s3c_request *req) { u32 *buf, ctrl = 0; u32 length, pktcnt; u32 ep_num = ep_index(ep); u32 *p = the_controller->dma_buf[ep_index(ep)+1]; buf = req->req.buf + req->req.actual; length = req->req.length - req->req.actual; if (ep_num == EP0_CON) length = min(length, (u32)ep_maxpacket(ep)); ep->len = length; ep->dma_buf = buf; memcpy(p, ep->dma_buf, length); flush_dcache_range((unsigned long) p , (unsigned long) p + DMA_BUFFER_SIZE); if (length == 0) pktcnt = 1; else pktcnt = (length - 1)/(ep->ep.maxpacket) + 1; /* Flush the endpoint's Tx FIFO */ writel(TX_FIFO_NUMBER(ep->fifo_num), ®->grstctl); writel(TX_FIFO_NUMBER(ep->fifo_num) | TX_FIFO_FLUSH, ®->grstctl); while (readl(®->grstctl) & TX_FIFO_FLUSH) ; writel(the_controller->dma_addr[ep_index(ep)+1], ®->in_endp[ep_num].diepdma); writel(DIEPT_SIZ_PKT_CNT(pktcnt) | DIEPT_SIZ_XFER_SIZE(length), ®->in_endp[ep_num].dieptsiz); ctrl = readl(®->in_endp[ep_num].diepctl); /* Write the FIFO number to be used for this endpoint */ ctrl &= DIEPCTL_TX_FIFO_NUM_MASK; ctrl |= DIEPCTL_TX_FIFO_NUM(ep->fifo_num); /* Clear reserved (Next EP) bits */ ctrl = (ctrl&~(EP_MASK<<DEPCTL_NEXT_EP_BIT)); writel(DEPCTL_EPENA|DEPCTL_CNAK|ctrl, ®->in_endp[ep_num].diepctl); debug_cond(DEBUG_IN_EP, "%s:EP%d TX DMA start : DIEPDMA0 = 0x%x," "DIEPTSIZ0 = 0x%x, DIEPCTL0 = 0x%x\n" "\tbuf = 0x%p, pktcnt = %d, xfersize = %d\n", __func__, ep_num, readl(®->in_endp[ep_num].diepdma), readl(®->in_endp[ep_num].dieptsiz), readl(®->in_endp[ep_num].diepctl), buf, pktcnt, length); return length; }
static inline void dwc2_udc_ep0_zlp(struct dwc2_udc *dev) { u32 ep_ctrl; writel(usb_ctrl_dma_addr, ®->in_endp[EP0_CON].diepdma); writel(DIEPT_SIZ_PKT_CNT(1), ®->in_endp[EP0_CON].dieptsiz); ep_ctrl = readl(®->in_endp[EP0_CON].diepctl); writel(ep_ctrl|DEPCTL_EPENA|DEPCTL_CNAK, ®->in_endp[EP0_CON].diepctl); debug_cond(DEBUG_EP0 != 0, "%s:EP0 ZLP DIEPCTL0 = 0x%x\n", __func__, readl(®->in_endp[EP0_CON].diepctl)); dev->ep0state = WAIT_FOR_IN_COMPLETE; }
static inline void s3c_udc_ep0_zlp(struct s3c_udc *dev) { u32 ep_ctrl; flush_dcache_range((unsigned long) usb_ctrl_dma_addr, (unsigned long) usb_ctrl_dma_addr + DMA_BUFFER_SIZE); writel(usb_ctrl_dma_addr, ®->in_endp[EP0_CON].diepdma); writel(DIEPT_SIZ_PKT_CNT(1), ®->in_endp[EP0_CON].dieptsiz); ep_ctrl = readl(®->in_endp[EP0_CON].diepctl); writel(ep_ctrl|DEPCTL_EPENA|DEPCTL_CNAK, ®->in_endp[EP0_CON].diepctl); debug_cond(DEBUG_EP0 != 0, "%s:EP0 ZLP DIEPCTL0 = 0x%x\n", __func__, readl(®->in_endp[EP0_CON].diepctl)); dev->ep0state = WAIT_FOR_IN_COMPLETE; }