예제 #1
0
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);
	}
}
예제 #2
0
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);
}