static void configure_channel(struct dma_channel *channel, u16 packet_sz, u8 mode, dma_addr_t dma_addr, u32 len) { struct musb_dma_channel *musb_channel = channel->private_data; struct musb_dma_controller *controller = musb_channel->controller; void __iomem *mbase = controller->base; u8 bchannel = musb_channel->idx; u16 csr = 0; DBG(4, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n", channel, packet_sz, dma_addr, len, mode); if (musb_channel->sysdma_channel != -1) { /* System DMA */ /* RX: set src = FIFO */ omap_set_dma_transfer_params(musb_channel->sysdma_channel, OMAP_DMA_DATA_TYPE_S8, len ? len : 1, 1, /* One frame */ OMAP_DMA_SYNC_ELEMENT, OMAP24XX_DMA_NO_DEVICE, 0); /* Src Sync */ omap_set_dma_src_params(musb_channel->sysdma_channel, 0, OMAP_DMA_AMODE_CONSTANT, MUSB_FIFO_ADDRESS(musb_channel->epnum), 0, 0); omap_set_dma_dest_params(musb_channel->sysdma_channel, 0, OMAP_DMA_AMODE_POST_INC, dma_addr, 0, 0); omap_set_dma_dest_data_pack(musb_channel->sysdma_channel, 1); omap_set_dma_dest_burst_mode(musb_channel->sysdma_channel, OMAP_DMA_DATA_BURST_16); omap_start_dma(musb_channel->sysdma_channel); } else { /* Mentor DMA */ if (mode) { csr |= 1 << MUSB_HSDMA_MODE1_SHIFT; BUG_ON(len < packet_sz); if (packet_sz >= 64) { csr |= MUSB_HSDMA_BURSTMODE_INCR16 << MUSB_HSDMA_BURSTMODE_SHIFT; } else if (packet_sz >= 32) { csr |= MUSB_HSDMA_BURSTMODE_INCR8 << MUSB_HSDMA_BURSTMODE_SHIFT; } else if (packet_sz >= 16) { csr |= MUSB_HSDMA_BURSTMODE_INCR4 << MUSB_HSDMA_BURSTMODE_SHIFT; } } csr |= (musb_channel->epnum << MUSB_HSDMA_ENDPOINT_SHIFT) | (1 << MUSB_HSDMA_ENABLE_SHIFT) | (1 << MUSB_HSDMA_IRQENABLE_SHIFT) | (musb_channel->transmit ? (1 << MUSB_HSDMA_TRANSMIT_SHIFT) : 0); /* address/count */ musb_write_hsdma_addr(mbase, bchannel, dma_addr); musb_write_hsdma_count(mbase, bchannel, len); /* control (this should start things) */ musb_writew(mbase, MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_CONTROL), csr); } }
static void musb_sdma_channel_program(struct musb *musb, struct musb_dma_channel *musb_channel, dma_addr_t dma_addr, u32 len) { u16 frame = len; int data_type = OMAP_DMA_DATA_TYPE_S8; switch (dma_addr & 0x3) { case 0: if ((len % 4) == 0) { data_type = OMAP_DMA_DATA_TYPE_S32; frame = len / 4; break; } case 2: if ((len % 2) == 0) { data_type = OMAP_DMA_DATA_TYPE_S16; frame = len / 2; break; } case 1: case 3: default: data_type = OMAP_DMA_DATA_TYPE_S8; frame = len; break; } /* set transfer parameters */ omap_set_dma_transfer_params(musb_channel->sysdma_channel, data_type, len ? frame : 1, 1, /* One frame */ OMAP_DMA_SYNC_FRAME, OMAP24XX_DMA_NO_DEVICE, 0); /* Src Sync */ if (!musb_channel->transmit) { /* RX: set src = FIFO */ omap_set_dma_src_params(musb_channel->sysdma_channel, 0, OMAP_DMA_AMODE_CONSTANT, MUSB_FIFO_ADDRESS(musb->ctrl_phys_base, musb_channel->epnum), 0, 0); omap_set_dma_dest_params(musb_channel->sysdma_channel, 0, OMAP_DMA_AMODE_POST_INC, dma_addr, 0, 0); omap_set_dma_dest_data_pack(musb_channel->sysdma_channel, 1); omap_set_dma_dest_burst_mode(musb_channel->sysdma_channel, OMAP_DMA_DATA_BURST_16); } else if (musb_channel->transmit) { /* TX: set dst = FIFO */ omap_set_dma_src_params(musb_channel->sysdma_channel, 0, OMAP_DMA_AMODE_POST_INC, dma_addr, 0, 0); omap_set_dma_dest_params(musb_channel->sysdma_channel, 0, OMAP_DMA_AMODE_CONSTANT, MUSB_FIFO_ADDRESS(musb->ctrl_phys_base, musb_channel->epnum), 0, 0); omap_set_dma_dest_data_pack(musb_channel->sysdma_channel, 0); omap_set_dma_dest_burst_mode(musb_channel->sysdma_channel, OMAP_DMA_DATA_BURST_DIS); } /* start the system dma */ omap_start_dma(musb_channel->sysdma_channel); }