static int setdma_tx(struct s3c_ep *ep, struct s3c_request *req) { u32 *buf, ctrl = 0; u32 length, pktcnt; u32 ep_num = ep_index(ep); struct device *dev = &the_controller->dev->dev; buf = req->req.buf + req->req.actual; prefetch(buf); length = req->req.length - req->req.actual; if (ep_num == EP0_CON) length = min(length, (u32)ep_maxpacket(ep)); req->req.actual += length; req->req.dma = dma_map_single(dev, buf, length, DMA_TO_DEVICE); req->mapped = 1; if (length == 0) pktcnt = 1; else pktcnt = (length - 1)/(ep->ep.maxpacket) + 1; #ifdef DED_TX_FIFO /* Flush the endpoint's Tx FIFO */ writel(ep_num<<6, S3C_UDC_OTG_GRSTCTL); writel((ep_num<<6)|0x20, S3C_UDC_OTG_GRSTCTL); while (readl(S3C_UDC_OTG_GRSTCTL) & 0x20) ; /* Write the FIFO number to be used for this endpoint */ ctrl = readl(S3C_UDC_OTG_DIEPCTL(ep_num)); ctrl &= ~DEPCTL_TXFNUM_MASK;; ctrl |= (ep_num << DEPCTL_TXFNUM_BIT); writel(ctrl , S3C_UDC_OTG_DIEPCTL(ep_num)); #endif writel(virt_to_phys(buf), S3C_UDC_OTG_DIEPDMA(ep_num)); writel((pktcnt<<19)|(length<<0), S3C_UDC_OTG_DIEPTSIZ(ep_num)); ctrl = readl(S3C_UDC_OTG_DIEPCTL(ep_num)); writel(DEPCTL_EPENA|DEPCTL_CNAK|ctrl, S3C_UDC_OTG_DIEPCTL(ep_num)); #ifndef DED_TX_FIFO ctrl = readl(S3C_UDC_OTG_DIEPCTL(EP0_CON)); ctrl = (ctrl&~(EP_MASK<<DEPCTL_NEXT_EP_BIT))|(ep_num<<DEPCTL_NEXT_EP_BIT); writel(ctrl, S3C_UDC_OTG_DIEPCTL(EP0_CON)); #endif 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(S3C_UDC_OTG_DIEPDMA(ep_num)), readl(S3C_UDC_OTG_DIEPTSIZ(ep_num)), readl(S3C_UDC_OTG_DIEPCTL(ep_num)), buf, pktcnt, length); return length; }
static int setdma_tx(struct s3c_ep *ep, struct s3c_request *req) { u32 *buf, ctrl = 0; u32 length, pktcnt; u32 ep_num = ep_index(ep); buf = req->req.buf + req->req.actual; prefetch(buf); length = req->req.length - req->req.actual; if (ep_num == EP0_CON) { length = min(length, (u32)ep_maxpacket(ep)); } req->req.actual += length; dma_cache_maint(buf, length, DMA_TO_DEVICE); if (length == 0) pktcnt = 1; else pktcnt = (length - 1)/(ep->ep.maxpacket) + 1; #ifdef DED_TX_FIFO /* Write the FIFO number to be used for this endpoint */ ctrl = readl(S3C_UDC_OTG_DIEPCTL(ep_num)); ctrl &= ~DEPCTL_TXFNUM_MASK;; ctrl |= (ep_num << DEPCTL_TXFNUM_BIT); writel(ctrl , S3C_UDC_OTG_DIEPCTL(ep_num)); #endif writel(virt_to_phys(buf), S3C_UDC_OTG_DIEPDMA(ep_num)); writel((pktcnt<<19)|(length<<0), S3C_UDC_OTG_DIEPTSIZ(ep_num)); ctrl = readl(S3C_UDC_OTG_DIEPCTL(ep_num)); writel(DEPCTL_EPENA|DEPCTL_CNAK|ctrl, S3C_UDC_OTG_DIEPCTL(ep_num)); ctrl = readl(S3C_UDC_OTG_DIEPCTL(EP0_CON)); ctrl = (ctrl&~(EP_MASK<<DEPCTL_NEXT_EP_BIT))|(ep_num<<DEPCTL_NEXT_EP_BIT); writel(ctrl, S3C_UDC_OTG_DIEPCTL(EP0_CON)); 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(S3C_UDC_OTG_DIEPDMA(ep_num)), readl(S3C_UDC_OTG_DIEPTSIZ(ep_num)), readl(S3C_UDC_OTG_DIEPCTL(ep_num)), buf, pktcnt, length); return length; }
static inline void s3c_udc_ep0_zlp(void) { u32 ep_ctrl; writel(virt_to_phys(&usb_ctrl), S3C_UDC_OTG_DIEPDMA(EP0_CON)); writel((1<<19 | 0<<0), S3C_UDC_OTG_DIEPTSIZ(EP0_CON)); ep_ctrl = readl(S3C_UDC_OTG_DIEPCTL(EP0_CON)); writel(ep_ctrl|DEPCTL_EPENA|DEPCTL_CNAK, S3C_UDC_OTG_DIEPCTL(EP0_CON)); DEBUG_EP0("%s:EP0 ZLP DIEPCTL0 = 0x%x\n", __func__, readl(S3C_UDC_OTG_DIEPCTL(EP0_CON))); }
static inline void s3c_udc_ep0_zlp(struct s3c_udc *dev) { u32 ep_ctrl; __raw_writel(dev->usb_ctrl_dma, dev->regs + S3C_UDC_OTG_DIEPDMA(EP0_CON)); __raw_writel((1<<19 | 0<<0), dev->regs + S3C_UDC_OTG_DIEPTSIZ(EP0_CON)); ep_ctrl = __raw_readl(dev->regs + S3C_UDC_OTG_DIEPCTL(EP0_CON)); __raw_writel(ep_ctrl | DEPCTL_EPENA | DEPCTL_CNAK, dev->regs + S3C_UDC_OTG_DIEPCTL(EP0_CON)); DEBUG_EP0("%s:EP0 ZLP DIEPCTL0 = 0x%x\n", __func__, __raw_readl(dev->regs + S3C_UDC_OTG_DIEPCTL(EP0_CON))); }
static inline void s3c_udc_ep0_zlp(void) { u32 ep_ctrl; writel(virt_to_phys(&usb_ctrl), S3C_UDC_OTG_DIEPDMA(EP0_CON)); writel((1<<19| 0<<0), S3C_UDC_OTG_DIEPTSIZ(EP0_CON)); ep_ctrl = readl(S3C_UDC_OTG_DIEPCTL(EP0_CON)); writel(ep_ctrl|DEPCTL_EPENA|DEPCTL_CNAK, S3C_UDC_OTG_DIEPCTL(EP0_CON)); if (currentusbstatus == USBSTATUS_VTP) printk("TETHERING::s3c_udc_ep0_zlp\n"); DEBUG_EP0("%s:EP0 ZLP DIEPCTL0 = 0x%x\n", __func__, readl(S3C_UDC_OTG_DIEPCTL(EP0_CON))); }
static int setdma_tx(struct s3c_ep *ep, struct s3c_request *req) { u32 *buf, ctrl = 0; u32 length, pktcnt; u32 ep_num = ep_index(ep); struct s3c_udc *udc = ep->dev; struct device *dev = &udc->dev->dev; aligned_map_buf(req, ep_is_in(ep)); buf = req->req.buf + req->req.actual; prefetch(buf); length = req->req.length - req->req.actual; if (ep_num == EP0_CON) length = min_t(u32, length, (u32)ep_maxpacket(ep)); req->req.actual += length; req->req.dma = dma_map_single(dev, buf, length, DMA_TO_DEVICE); req->mapped = 1; if (length == 0) pktcnt = 1; else pktcnt = (length - 1)/(ep->ep.maxpacket) + 1; #ifdef DED_TX_FIFO /* Write the FIFO number to be used for this endpoint */ ctrl = __raw_readl(udc->regs + S3C_UDC_OTG_DIEPCTL(ep_num)); ctrl &= ~DEPCTL_TXFNUM_MASK; ctrl |= (ep_num << DEPCTL_TXFNUM_BIT); __raw_writel(ctrl , udc->regs + S3C_UDC_OTG_DIEPCTL(ep_num)); #endif __raw_writel(virt_to_phys(buf), udc->regs + S3C_UDC_OTG_DIEPDMA(ep_num)); __raw_writel((pktcnt<<19)|(length<<0), udc->regs + S3C_UDC_OTG_DIEPTSIZ(ep_num)); ctrl = __raw_readl(udc->regs + S3C_UDC_OTG_DIEPCTL(ep_num)); if ((ctrl & DEPCTL_TYPE_MASK) == DEPCTL_ISO_TYPE) { if (ctrl & DEPCTL_EO_FRNUM) ctrl |= DEPCTL_SETD0PID; else ctrl |= DEPCTL_SETD1PID; } __raw_writel(DEPCTL_EPENA|DEPCTL_CNAK|ctrl, udc->regs + S3C_UDC_OTG_DIEPCTL(ep_num)); #ifndef DED_TX_FIFO ctrl = __raw_readl(udc->regs + S3C_UDC_OTG_DIEPCTL(EP0_CON)); ctrl = (ctrl & ~(EP_MASK<<DEPCTL_NEXT_EP_BIT)) | (ep_num<<DEPCTL_NEXT_EP_BIT); __raw_writel(ctrl, udc->regs + S3C_UDC_OTG_DIEPCTL(EP0_CON)); #endif 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, __raw_readl(udc->regs + S3C_UDC_OTG_DIEPDMA(ep_num)), __raw_readl(udc->regs + S3C_UDC_OTG_DIEPTSIZ(ep_num)), __raw_readl(udc->regs + S3C_UDC_OTG_DIEPCTL(ep_num)), buf, pktcnt, length); req->written_bytes = length; return length; }