static void omap_hsmmc_config_dma_params(struct omap_hsmmc_host *host,
				       struct mmc_data *data,
				       struct scatterlist *sgl)
{
	int blksz, nblk, dma_ch;

	dma_ch = host->dma_ch;
	if (data->flags & MMC_DATA_WRITE) {
		omap_set_dma_dest_params(dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
			(host->mapbase + OMAP_HSMMC_DATA), 0, 0);
		omap_set_dma_src_params(dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
			sg_dma_address(sgl), 0, 0);
	} else {
		omap_set_dma_src_params(dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
			(host->mapbase + OMAP_HSMMC_DATA), 0, 0);
		omap_set_dma_dest_params(dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
			sg_dma_address(sgl), 0, 0);
	}

	blksz = host->data->blksz;
	nblk = sg_dma_len(sgl) / blksz;

	omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S32,
			blksz / 4, nblk, OMAP_DMA_SYNC_FRAME,
			omap_hsmmc_get_dma_sync_dev(host, data),
			!(data->flags & MMC_DATA_WRITE));

	omap_start_dma(dma_ch);
}
Beispiel #2
0
static int audio_set_dma_params_capture(int channel, dma_addr_t dma_ptr,
					u_int dma_size)
{
	int dt = 0x1;		/* data type 16 */
	int cen = 16;		/* mono */
	int cfn = dma_size / (2 * cen);
	unsigned long src_start;
	int src_port = 0;
	int sync_dev = 0;
	int src_sync = 0;

	FN_IN;

	if (cpu_is_omap16xx()) {
		src_start = (OMAP1610_MCBSP1_BASE + 0x802);
		src_port = OMAP_DMA_PORT_MPUI;
	}
	if (cpu_is_omap24xx()) {
		src_start = AUDIO_MCBSP_DATAREAD;
		sync_dev = AUDIO_DMA_RX;
		src_sync = 1;
	}

	omap_set_dma_src_params(channel, src_port, OMAP_DMA_AMODE_CONSTANT, src_start, 0, 0);
	omap_set_dma_dest_params(channel, 0, OMAP_DMA_AMODE_POST_INC, dma_ptr, 0, 0);
	omap_set_dma_transfer_params(channel, dt, cen, cfn, OMAP_DMA_SYNC_ELEMENT, sync_dev, src_sync);

	FN_OUT(0);
	return 0;
}
static int serial_omap_start_rxdma(struct uart_omap_port *up)
{
	int ret = 0;

	if (up->uart_dma.rx_dma_channel == -1) {
		pm_runtime_get_sync(&up->pdev->dev);
		ret = omap_request_dma(up->uart_dma.uart_dma_rx,
				"UART Rx DMA",
				(void *)uart_rx_dma_callback, up,
				&(up->uart_dma.rx_dma_channel));
		if (ret < 0)
			return ret;

		omap_set_dma_src_params(up->uart_dma.rx_dma_channel, 0,
				OMAP_DMA_AMODE_CONSTANT,
				up->uart_dma.uart_base, 0, 0);
		omap_set_dma_dest_params(up->uart_dma.rx_dma_channel, 0,
				OMAP_DMA_AMODE_POST_INC,
				up->uart_dma.rx_buf_dma_phys, 0, 0);
		omap_set_dma_transfer_params(up->uart_dma.rx_dma_channel,
				OMAP_DMA_DATA_TYPE_S8,
				up->uart_dma.rx_buf_size, 1,
				OMAP_DMA_SYNC_ELEMENT,
				up->uart_dma.uart_dma_rx, 0);
	}
	up->uart_dma.prev_rx_dma_pos = up->uart_dma.rx_buf_dma_phys;
	
	omap_start_dma(up->uart_dma.rx_dma_channel);
	mod_timer(&up->uart_dma.rx_timer, jiffies +
				usecs_to_jiffies(up->uart_dma.rx_poll_rate));
	up->uart_dma.rx_dma_used = true;
	return ret;
}
Beispiel #4
0
static void serial_omap_continue_tx(struct uart_omap_port *up)
{
	struct circ_buf *xmit = &up->port.state->xmit;
	unsigned int start = up->uart_dma.tx_buf_dma_phys
			+ (xmit->tail & (UART_XMIT_SIZE - 1));

	if (uart_circ_empty(xmit))
		return;

	up->uart_dma.tx_buf_size = uart_circ_chars_pending(xmit);
	/*
	 * It is a circular buffer. See if the buffer has wounded back.
	 * If yes it will have to be transferred in two separate dma
	 * transfers
	 */
	if (start + up->uart_dma.tx_buf_size >=
			up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE)
		up->uart_dma.tx_buf_size =
			(up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE) - start;
	omap_set_dma_dest_params(up->uart_dma.tx_dma_channel, 0,
				OMAP_DMA_AMODE_CONSTANT,
				up->uart_dma.uart_base, 0, 0);
	omap_set_dma_src_params(up->uart_dma.tx_dma_channel, 0,
				OMAP_DMA_AMODE_POST_INC, start, 0, 0);
	omap_set_dma_transfer_params(up->uart_dma.tx_dma_channel,
				OMAP_DMA_DATA_TYPE_S8,
				up->uart_dma.tx_buf_size, 1,
				OMAP_DMA_SYNC_ELEMENT,
				up->uart_dma.uart_dma_tx, 0);
	/* FIXME: Cache maintenance needed here? */
	omap_start_dma(up->uart_dma.tx_dma_channel);
}
static void serial_omap_continue_tx(struct uart_omap_port *up)
{
	struct circ_buf *xmit = &up->port.info->xmit;
	int start = up->uart_dma.tx_buf_dma_phys + (xmit->tail & (UART_XMIT_SIZE - 1));
	if (uart_circ_empty(xmit))  {
			return;
	}

	up->uart_dma.tx_buf_size = uart_circ_chars_pending(xmit);
	/* It is a circular buffer. See if the buffer has wounded back.
	* If yes it will have to be transferred in two separate dma
	* transfers
	*/
	if (start + up->uart_dma.tx_buf_size >=
			up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE)
		up->uart_dma.tx_buf_size =
			(up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE) - start;
	omap_set_dma_dest_params(up->uart_dma.tx_dma_channel, 0,
				 OMAP_DMA_AMODE_CONSTANT, UART_BASE(up->pdev->id - 1), 0,0);
	omap_set_dma_src_params(up->uart_dma.tx_dma_channel, 0,
		OMAP_DMA_AMODE_POST_INC, start, 0,0);

	omap_set_dma_transfer_params(up->uart_dma.tx_dma_channel,
				     OMAP_DMA_DATA_TYPE_S8, up->uart_dma.tx_buf_size, 1,
				     OMAP_DMA_SYNC_ELEMENT,
				     uart_dma_tx[(up->pdev->id)-1], 0);

	omap_start_dma(up->uart_dma.tx_dma_channel);
}
static void serial_omap_continue_tx(struct uart_omap_port *up)
{
	struct circ_buf *xmit = &up->port.state->xmit;
	unsigned int start = up->uart_dma.tx_buf_dma_phys
			+ (xmit->tail & (UART_XMIT_SIZE - 1));

	if (uart_circ_empty(xmit))
		return;

	up->uart_dma.tx_buf_size = uart_circ_chars_pending(xmit);
	if (start + up->uart_dma.tx_buf_size >=
			up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE)
		up->uart_dma.tx_buf_size =
			(up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE) - start;
	omap_set_dma_dest_params(up->uart_dma.tx_dma_channel, 0,
				OMAP_DMA_AMODE_CONSTANT,
				up->uart_dma.uart_base, 0, 0);
	omap_set_dma_src_params(up->uart_dma.tx_dma_channel, 0,
				OMAP_DMA_AMODE_POST_INC, start, 0, 0);
	omap_set_dma_transfer_params(up->uart_dma.tx_dma_channel,
				OMAP_DMA_DATA_TYPE_S8,
				up->uart_dma.tx_buf_size, 1,
				OMAP_DMA_SYNC_ELEMENT,
				up->uart_dma.uart_dma_tx, 0);
	
	omap_start_dma(up->uart_dma.tx_dma_channel);
}
static void serial_omap_start_rxdma(struct uart_omap_port *up)
{
#ifdef CONFIG_OMAP3_PM
	/* Disallow OCP bus idle. UART TX irqs are not seen during
	 * bus idle. Alternative is to set kernel timer at fifo
	 * drain rate.
	 */
	unsigned int tmp;
	tmp = (serial_in(up, UART_OMAP_SYSC) & 0x7) | (1 << 3);
	serial_out(up, UART_OMAP_SYSC, tmp); /* no-idle */
#endif
	if (up->uart_dma.rx_dma_channel == 0xFF) {
		omap_request_dma(uart_dma_rx[up->pdev->id-1],"UART Rx DMA",
				(void *)uart_rx_dma_callback,up,
				&(up->uart_dma.rx_dma_channel));
		omap_set_dma_src_params(up->uart_dma.rx_dma_channel, 0,
					OMAP_DMA_AMODE_CONSTANT,
					UART_BASE(up->pdev->id - 1), 0, 0);
		omap_set_dma_dest_params(up->uart_dma.rx_dma_channel, 0,
					OMAP_DMA_AMODE_POST_INC,
					up->uart_dma.rx_buf_dma_phys, 0, 0);
		omap_set_dma_transfer_params(up->uart_dma.rx_dma_channel,
					OMAP_DMA_DATA_TYPE_S8,
					up->uart_dma.rx_buf_size, 1,
					OMAP_DMA_SYNC_ELEMENT,
					uart_dma_rx[up->pdev->id-1], 0);
	}
	up->uart_dma.prev_rx_dma_pos = up->uart_dma.rx_buf_dma_phys;
	omap_writel(0, OMAP34XX_DMA4_BASE +
		OMAP_DMA4_CDAC(up->uart_dma.rx_dma_channel));
	omap_start_dma(up->uart_dma.rx_dma_channel);
	mod_timer(&up->uart_dma.rx_timer, jiffies +
			usecs_to_jiffies(up->uart_dma.rx_timeout));
	up->uart_dma.rx_dma_state = 1;
}
Beispiel #8
0
static void serial_omap_start_tx(struct uart_port *port)
{
	struct uart_omap_port *up = (struct uart_omap_port *)port;
	struct circ_buf *xmit;
	unsigned int start;
	int ret = 0;

	if (!up->use_dma) {
		serial_omap_enable_ier_thri(up);
		return;
	}

	if (up->uart_dma.tx_dma_used)
		return;

	xmit = &up->port.state->xmit;

	if (up->uart_dma.tx_dma_channel == OMAP_UART_DMA_CH_FREE) {
		ret = omap_request_dma(up->uart_dma.uart_dma_tx,
				"UART Tx DMA",
				(void *)uart_tx_dma_callback, up,
				&(up->uart_dma.tx_dma_channel));

		if (ret < 0) {
			serial_omap_enable_ier_thri(up);
			return;
		}
	}
	spin_lock(&(up->uart_dma.tx_lock));
	up->uart_dma.tx_dma_used = true;
	spin_unlock(&(up->uart_dma.tx_lock));

	start = up->uart_dma.tx_buf_dma_phys +
				(xmit->tail & (UART_XMIT_SIZE - 1));

	up->uart_dma.tx_buf_size = uart_circ_chars_pending(xmit);
	/*
	 * It is a circular buffer. See if the buffer has wounded back.
	 * If yes it will have to be transferred in two separate dma
	 * transfers
	 */
	if (start + up->uart_dma.tx_buf_size >=
			up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE)
		up->uart_dma.tx_buf_size =
			(up->uart_dma.tx_buf_dma_phys +
			UART_XMIT_SIZE) - start;

	omap_set_dma_dest_params(up->uart_dma.tx_dma_channel, 0,
				OMAP_DMA_AMODE_CONSTANT,
				up->uart_dma.uart_base, 0, 0);
	omap_set_dma_src_params(up->uart_dma.tx_dma_channel, 0,
				OMAP_DMA_AMODE_POST_INC, start, 0, 0);
	omap_set_dma_transfer_params(up->uart_dma.tx_dma_channel,
				OMAP_DMA_DATA_TYPE_S8,
				up->uart_dma.tx_buf_size, 1,
				OMAP_DMA_SYNC_ELEMENT,
				up->uart_dma.uart_dma_tx, 0);
	/* FIXME: Cache maintenance needed here? */
	omap_start_dma(up->uart_dma.tx_dma_channel);
}
Beispiel #9
0
/***************************************************************************************
 *
 * DMA related functions
 *
 **************************************************************************************/
static int audio_set_dma_params_play(int channel, dma_addr_t dma_ptr,
				     u_int dma_size)
{
	int dt = 0x1;		/* data type 16 */
	int cen = 32;		/* Stereo */
	int cfn = dma_size / (2 * cen);
	unsigned long dest_start;
	int dest_port = 0;
	int sync_dev = 0;

	FN_IN;

	if (cpu_is_omap16xx()) {
		dest_start = (OMAP1610_MCBSP1_BASE + 0x806);
		dest_port = OMAP_DMA_PORT_MPUI;
	}
	if (cpu_is_omap24xx()) {
		dest_start = AUDIO_MCBSP_DATAWRITE;
		sync_dev = AUDIO_DMA_TX;
	}

	omap_set_dma_dest_params(channel, dest_port, OMAP_DMA_AMODE_CONSTANT, dest_start, 0, 0);
	omap_set_dma_src_params(channel, 0, OMAP_DMA_AMODE_POST_INC, dma_ptr, 0, 0);
	omap_set_dma_transfer_params(channel, dt, cen, cfn, OMAP_DMA_SYNC_ELEMENT, sync_dev, 0);

	FN_OUT(0);
	return 0;
}
Beispiel #10
0
static void serial_omap_start_tx(struct uart_port *port)
{
	struct uart_omap_port *up = (struct uart_omap_port *)port;
#ifdef CONFIG_OMAP3_PM
		/* Disallow OCP bus idle. UART TX irqs are not seen during
		 * bus idle. Alternative is to set kernel timer at fifo
		 * drain rate.
		 */
		unsigned int tmp;
		tmp = (serial_in(up, UART_OMAP_SYSC) & 0x7) | (1 << 3);
		serial_out(up, UART_OMAP_SYSC, tmp); /* no-idle */
#endif

	if (up->use_dma && !(up->port.x_char)) {

		struct circ_buf *xmit = &up->port.info->xmit;
		unsigned int start = up->uart_dma.tx_buf_dma_phys +
				     (xmit->tail & (UART_XMIT_SIZE - 1));
		if (uart_circ_empty(xmit) || up->uart_dma.tx_dma_state)
			return;
		spin_lock(&(up->uart_dma.tx_lock));
		up->uart_dma.tx_dma_state = 1;
		spin_unlock(&(up->uart_dma.tx_lock));

		up->uart_dma.tx_buf_size = uart_circ_chars_pending(xmit);
		/* It is a circular buffer. See if the buffer has wounded back.
		 * If yes it will have to be transferred in two separate dma
		 * transfers */
		if (start + up->uart_dma.tx_buf_size >=
				up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE)
			up->uart_dma.tx_buf_size =
				(up->uart_dma.tx_buf_dma_phys +
				UART_XMIT_SIZE) - start;

		if (up->uart_dma.tx_dma_channel == 0xFF)
			omap_request_dma(uart_dma_tx[up->pdev->id-1],
					"UART Tx DMA",
					(void *)uart_tx_dma_callback, up,
					&(up->uart_dma.tx_dma_channel));
		omap_set_dma_dest_params(up->uart_dma.tx_dma_channel, 0,
					 OMAP_DMA_AMODE_CONSTANT,
					 UART_BASE(up->pdev->id - 1), 0, 0);
		omap_set_dma_src_params(up->uart_dma.tx_dma_channel, 0,
					OMAP_DMA_AMODE_POST_INC, start, 0, 0);

		omap_set_dma_transfer_params(up->uart_dma.tx_dma_channel,
					     OMAP_DMA_DATA_TYPE_S8,
					     up->uart_dma.tx_buf_size, 1,
					     OMAP_DMA_SYNC_ELEMENT,
					     uart_dma_tx[(up->pdev->id)-1], 0);

		omap_start_dma(up->uart_dma.tx_dma_channel);

	} else if (!(up->ier & UART_IER_THRI)) {
		up->ier |= UART_IER_THRI;
		serial_out(up, UART_IER, up->ier);
	}
}
Beispiel #11
0
/*
 * Configure dma src and destination parameters
 */
static int mmc_omap_config_dma_param(int sync_dir, struct mmc_omap_host *host,
				struct mmc_data *data)
{
	if (sync_dir == 0) {
		omap_set_dma_dest_params(host->dma_ch, 0,
			OMAP_DMA_AMODE_CONSTANT,
			(host->mapbase + OMAP_HSMMC_DATA), 0, 0);
		omap_set_dma_src_params(host->dma_ch, 0,
			OMAP_DMA_AMODE_POST_INC,
			sg_dma_address(&data->sg[0]), 0, 0);
	} else {
		omap_set_dma_src_params(host->dma_ch, 0,
			OMAP_DMA_AMODE_CONSTANT,
			(host->mapbase + OMAP_HSMMC_DATA), 0, 0);
		omap_set_dma_dest_params(host->dma_ch, 0,
			OMAP_DMA_AMODE_POST_INC,
			sg_dma_address(&data->sg[0]), 0, 0);
	}
	return 0;
}
Beispiel #12
0
static void omap1610_irda_start_rx_dma(struct omap1610_irda *si)
{
	/* Configure DMA */
	omap_set_dma_src_params(si->rx_dma_channel, 0x3, 0x0, (unsigned long)UART3_RHR);

	omap_enable_dma_irq(si->rx_dma_channel, 0x01);

	omap_set_dma_dest_params(si->rx_dma_channel, 0x0, 0x1,
				 si->rx_buf_dma_phys);

	omap_set_dma_transfer_params(si->rx_dma_channel, 0x0, 4096, 0x1, 0x0);

	omap_start_dma(si->rx_dma_channel);
}
Beispiel #13
0
static int audio_set_dma_params_capture(int channel, dma_addr_t dma_ptr,
					u_int dma_size)
{
	int dt = 0x1;		/* data type 16 */
	int cen = 32;		/* stereo */
	int cfn = dma_size / (2 * cen);

	FN_IN;
	omap_set_dma_src_params(channel, 0x05, 0x00,
				(OMAP1510_MCBSP1_BASE + 0x02),
				0, 0);
	omap_set_dma_dest_params(channel, 0x00, 0x01, dma_ptr, 0, 0);
	omap_set_dma_transfer_params(channel, dt, cen, cfn, 0x00, 0, 0);
	FN_OUT(0);
	return 0;
}
Beispiel #14
0
void omap_set_dma_params(int lch, struct omap_dma_channel_params *params)
{
	omap_set_dma_transfer_params(lch, params->data_type,
								 params->elem_count, params->frame_count,
								 params->sync_mode, params->trigger,
								 params->src_or_dst_synch);
	omap_set_dma_src_params(lch, params->src_port,
							params->src_amode, params->src_start,
							params->src_ei, params->src_fi);
	
	omap_set_dma_dest_params(lch, params->dst_port,
							 params->dst_amode, params->dst_start,
							 params->dst_ei, params->dst_fi);
	if (params->read_prio || params->write_prio)
		omap_dma_set_prio_lch(lch, params->read_prio,
							  params->write_prio);
}
Beispiel #15
0
static void set_dma_dest_params(int dma_ch, struct omap1_cam_buf *buf,
		enum omap1_cam_vb_mode vb_mode)
{
	dma_addr_t dma_addr;
	unsigned int block_size;

	if (vb_mode == OMAP1_CAM_DMA_CONTIG) {
		dma_addr = videobuf_to_dma_contig(&buf->vb);
		block_size = buf->vb.size;
	} else {
		if (WARN_ON(!buf->sgbuf)) {
			buf->result = VIDEOBUF_ERROR;
			return;
		}
		dma_addr = sg_dma_address(buf->sgbuf);
		if (WARN_ON(!dma_addr)) {
			buf->sgbuf = NULL;
			buf->result = VIDEOBUF_ERROR;
			return;
		}
		block_size = sg_dma_len(buf->sgbuf);
		if (WARN_ON(!block_size)) {
			buf->sgbuf = NULL;
			buf->result = VIDEOBUF_ERROR;
			return;
		}
		if (unlikely(buf->bytes_left < block_size))
			block_size = buf->bytes_left;
		if (WARN_ON(dma_addr & (DMA_FRAME_SIZE(vb_mode) *
				DMA_ELEMENT_SIZE - 1))) {
			dma_addr = ALIGN(dma_addr, DMA_FRAME_SIZE(vb_mode) *
					DMA_ELEMENT_SIZE);
			block_size &= ~(DMA_FRAME_SIZE(vb_mode) *
					DMA_ELEMENT_SIZE - 1);
		}
		buf->bytes_left -= block_size;
		buf->sgcount++;
	}

	omap_set_dma_dest_params(dma_ch,
		OMAP_DMA_PORT_EMIFF, OMAP_DMA_AMODE_POST_INC, dma_addr, 0, 0);
	omap_set_dma_transfer_params(dma_ch,
		OMAP_DMA_DATA_TYPE_S32, DMA_FRAME_SIZE(vb_mode),
		block_size >> (DMA_FRAME_SHIFT(vb_mode) + DMA_ELEMENT_SHIFT),
		DMA_SYNC, 0, 0);
}
Beispiel #16
0
static void omap_start_tx_dma(struct omap_irda *omap_ir, int size)
{
	/* Configure DMA */
	omap_set_dma_dest_params(omap_ir->tx_dma_channel, 0x03, 0x0,
				omap_ir->pdata->dest_start, 0, 0);

	omap_enable_dma_irq(omap_ir->tx_dma_channel, 0x01);

	omap_set_dma_src_params(omap_ir->tx_dma_channel, 0x0, 0x1,
				omap_ir->tx_buf_dma_phys,
				0, 0);

	omap_set_dma_transfer_params(omap_ir->tx_dma_channel, 0x0, size, 0x1,
				0x0, omap_ir->pdata->tx_trigger, 0);

	/* Start DMA */
	omap_start_dma(omap_ir->tx_dma_channel);
}
Beispiel #17
0
static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
					 const unsigned char *buffer,
					 int offset, size_t count)
{
	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
	struct onenand_chip *this = mtd->priv;
	dma_addr_t dma_src, dma_dst;
	int bram_offset;

	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
	/* DMA is not used.  Revisit PM requirements before enabling it. */
	if (1 || (c->dma_channel < 0) ||
	    ((void *) buffer >= (void *) high_memory) || (bram_offset & 3) ||
	    (((unsigned int) buffer) & 3) || (count < 1024) || (count & 3)) {
		memcpy((__force void *)(this->base + bram_offset), buffer,
		       count);
		return 0;
	}

	dma_src = dma_map_single(&c->pdev->dev, (void *) buffer, count,
				 DMA_TO_DEVICE);
	dma_dst = c->phys_base + bram_offset;
	if (dma_mapping_error(&c->pdev->dev, dma_src)) {
		dev_err(&c->pdev->dev,
			"Couldn't DMA map a %d byte buffer\n",
			count);
		return -1;
	}

	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S16,
				     count / 2, 1, 0, 0, 0);
	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
				dma_src, 0, 0);
	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
				 dma_dst, 0, 0);

	INIT_COMPLETION(c->dma_done);
	omap_start_dma(c->dma_channel);
	wait_for_completion(&c->dma_done);

	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);

	return 0;
}
Beispiel #18
0
static void omap_irda_start_rx_dma(struct omap_irda *omap_ir)
{
	/* Configure DMA */
	omap_set_dma_src_params(omap_ir->rx_dma_channel, 0x3, 0x0,
				omap_ir->pdata->src_start,
				0, 0);

	omap_enable_dma_irq(omap_ir->rx_dma_channel, 0x01);

	omap_set_dma_dest_params(omap_ir->rx_dma_channel, 0x0, 0x1,
				omap_ir->rx_buf_dma_phys,
				0, 0);

	omap_set_dma_transfer_params(omap_ir->rx_dma_channel, 0x0,
				IRDA_SKB_MAX_MTU, 0x1,
				0x0, omap_ir->pdata->rx_trigger, 0);

	omap_start_dma(omap_ir->rx_dma_channel);
}
/*
 *  ======== SCPY_configure ========
 *  Configure a transfer on the SDMA handle
 */
void SCPY_configure(IRES_SDMA_Handle handle, SCPY_Params * params)
{
    /* SCPY_configure should be called with only one logicalChannel */ 
    int logicalChannel = handle->channel->chanNum; 
    unsigned int dmaAddr = (unsigned int)(handle->channel->addr);

    CMEM_init();
    
    omap_set_dma_transfer_params(logicalChannel, dmaAddr, 
            params->transfer->dataType, params->transfer->elemCount, 
            params->transfer->frameCount);


    omap_set_dma_src_params(logicalChannel, dmaAddr, 
            params->src->addr_mode, CMEM_getPhys((void *)(params->src->addr)),
            params->src->elem_index, params->src->frame_index);

    omap_set_dma_dest_params(logicalChannel, dmaAddr, 
            params->dst->addr_mode, CMEM_getPhys((void *)(params->dst->addr)),
            params->dst->elem_index, params->dst->frame_index);

    CMEM_exit();
}
Beispiel #20
0
static void omap1610_start_tx_dma(struct omap1610_irda *si, int size)
{
	__ECHO_IN;

	/* Configure DMA */
	omap_set_dma_dest_params(si->tx_dma_channel, 0x03, 0x0, (unsigned long)UART3_THR);

	omap_enable_dma_irq(si->tx_dma_channel, 0x01);

	omap_set_dma_src_params(si->tx_dma_channel, 0x0, 0x1,
				si->tx_buf_dma_phys);

	omap_set_dma_transfer_params(si->tx_dma_channel, 0x0, size, 0x1, 0x0);

	HDBG1(1);

	/* Start DMA */
	omap_start_dma(si->tx_dma_channel);

	HDBG1(1);

	__ECHO_OUT;
}
Beispiel #21
0
static int serial_omap_start_rxdma(struct uart_omap_port *up)
{
	int ret = 0;

	if (up->uart_dma.rx_dma_channel == -1) {
		ret = omap_request_dma(up->uart_dma.uart_dma_rx,
				"UART Rx DMA",
				(void *)uart_rx_dma_callback, up,
				&(up->uart_dma.rx_dma_channel));
		if (ret < 0)
			return ret;

		omap_set_dma_src_params(up->uart_dma.rx_dma_channel, 0,
				OMAP_DMA_AMODE_CONSTANT,
				up->uart_dma.uart_base, 0, 0);
		omap_set_dma_dest_params(up->uart_dma.rx_dma_channel, 0,
				OMAP_DMA_AMODE_POST_INC,
				up->uart_dma.rx_buf_dma_phys, 0, 0);
		omap_set_dma_transfer_params(up->uart_dma.rx_dma_channel,
				OMAP_DMA_DATA_TYPE_S8,
				up->uart_dma.rx_buf_size, 1,
				OMAP_DMA_SYNC_ELEMENT,
				up->uart_dma.uart_dma_rx, 0);
	}
	up->uart_dma.prev_rx_dma_pos = up->uart_dma.rx_buf_dma_phys;
	/* FIXME: Cache maintenance needed here? */
	omap_start_dma(up->uart_dma.rx_dma_channel);
	mod_timer(&up->uart_dma.rx_timer, jiffies +
				usecs_to_jiffies(up->uart_dma.rx_poll_rate));
	up->uart_dma.rx_dma_used = true;

	if (up->plat_hold_wakelock)
		(up->plat_hold_wakelock(up, WAKELK_RX));

	return ret;
}
Beispiel #22
0
/* Prepare to transfer the next segment of a scatterlist */
static void
mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data)
{
	int dma_ch = host->dma_ch;
	unsigned long data_addr;
	u16 buf, frame;
	u32 count;
	struct scatterlist *sg = &data->sg[host->sg_idx];
	int src_port = 0;
	int dst_port = 0;
	int sync_dev = 0;

	data_addr = host->phys_base + OMAP_MMC_REG_DATA;
	frame = data->blksz;
	count = sg_dma_len(sg);

	if ((data->blocks == 1) && (count > data->blksz))
		count = frame;

	host->dma_len = count;

	/* FIFO is 16x2 bytes on 15xx, and 32x2 bytes on 16xx and 24xx.
	 * Use 16 or 32 word frames when the blocksize is at least that large.
	 * Blocksize is usually 512 bytes; but not for some SD reads.
	 */
	if (cpu_is_omap15xx() && frame > 32)
		frame = 32;
	else if (frame > 64)
		frame = 64;
	count /= frame;
	frame >>= 1;

	if (!(data->flags & MMC_DATA_WRITE)) {
		buf = 0x800f | ((frame - 1) << 8);

		if (cpu_class_is_omap1()) {
			src_port = OMAP_DMA_PORT_TIPB;
			dst_port = OMAP_DMA_PORT_EMIFF;
		}
		if (cpu_is_omap24xx())
			sync_dev = OMAP24XX_DMA_MMC1_RX;

		omap_set_dma_src_params(dma_ch, src_port,
					OMAP_DMA_AMODE_CONSTANT,
					data_addr, 0, 0);
		omap_set_dma_dest_params(dma_ch, dst_port,
					 OMAP_DMA_AMODE_POST_INC,
					 sg_dma_address(sg), 0, 0);
		omap_set_dma_dest_data_pack(dma_ch, 1);
		omap_set_dma_dest_burst_mode(dma_ch, OMAP_DMA_DATA_BURST_4);
	} else {
		buf = 0x0f80 | ((frame - 1) << 0);

		if (cpu_class_is_omap1()) {
			src_port = OMAP_DMA_PORT_EMIFF;
			dst_port = OMAP_DMA_PORT_TIPB;
		}
		if (cpu_is_omap24xx())
			sync_dev = OMAP24XX_DMA_MMC1_TX;

		omap_set_dma_dest_params(dma_ch, dst_port,
					 OMAP_DMA_AMODE_CONSTANT,
					 data_addr, 0, 0);
		omap_set_dma_src_params(dma_ch, src_port,
					OMAP_DMA_AMODE_POST_INC,
					sg_dma_address(sg), 0, 0);
		omap_set_dma_src_data_pack(dma_ch, 1);
		omap_set_dma_src_burst_mode(dma_ch, OMAP_DMA_DATA_BURST_4);
	}

	/* Max limit for DMA frame count is 0xffff */
	BUG_ON(count > 0xffff);

	OMAP_MMC_WRITE(host, BUF, buf);
	omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S16,
				     frame, count, OMAP_DMA_SYNC_FRAME,
				     sync_dev, 0);
}
static void serial_omap_start_tx(struct uart_port *port)
{
	struct uart_omap_port *up = (struct uart_omap_port *)port;
	struct omap_uart_port_info *pdata = up->pdev->dev.platform_data;
	struct circ_buf *xmit;
	unsigned int start;
	int ret = 0;

	if (!up->use_dma) {
		pm_runtime_get_sync(&up->pdev->dev);
		serial_omap_enable_ier_thri(up);
		if (pdata && pdata->set_noidle)
			pdata->set_noidle(up->pdev);
		pm_runtime_mark_last_busy(&up->pdev->dev);
		pm_runtime_put_autosuspend(&up->pdev->dev);
		return;
	}

	if (up->uart_dma.tx_dma_used)
		return;

	xmit = &up->port.state->xmit;

	if (up->uart_dma.tx_dma_channel == OMAP_UART_DMA_CH_FREE) {
		pm_runtime_get_sync(&up->pdev->dev);
		ret = omap_request_dma(up->uart_dma.uart_dma_tx,
				"UART Tx DMA",
				(void *)uart_tx_dma_callback, up,
				&(up->uart_dma.tx_dma_channel));

		if (ret < 0) {
			serial_omap_enable_ier_thri(up);
			return;
		}
	}
	spin_lock(&(up->uart_dma.tx_lock));
	up->uart_dma.tx_dma_used = true;
	spin_unlock(&(up->uart_dma.tx_lock));

	start = up->uart_dma.tx_buf_dma_phys +
				(xmit->tail & (UART_XMIT_SIZE - 1));

	up->uart_dma.tx_buf_size = uart_circ_chars_pending(xmit);
	if (start + up->uart_dma.tx_buf_size >=
			up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE)
		up->uart_dma.tx_buf_size =
			(up->uart_dma.tx_buf_dma_phys +
			UART_XMIT_SIZE) - start;

	omap_set_dma_dest_params(up->uart_dma.tx_dma_channel, 0,
				OMAP_DMA_AMODE_CONSTANT,
				up->uart_dma.uart_base, 0, 0);
	omap_set_dma_src_params(up->uart_dma.tx_dma_channel, 0,
				OMAP_DMA_AMODE_POST_INC, start, 0, 0);
	omap_set_dma_transfer_params(up->uart_dma.tx_dma_channel,
				OMAP_DMA_DATA_TYPE_S8,
				up->uart_dma.tx_buf_size, 1,
				OMAP_DMA_SYNC_ELEMENT,
				up->uart_dma.uart_dma_tx, 0);
	
	omap_start_dma(up->uart_dma.tx_dma_channel);
}
Beispiel #24
0
int omap_vout_prepare_vrfb(struct omap_vout_device *vout,
				struct videobuf_buffer *vb)
{
	dma_addr_t dmabuf;
	struct vid_vrfb_dma *tx;
	enum dss_rotation rotation;
	u32 dest_frame_index = 0, src_element_index = 0;
	u32 dest_element_index = 0, src_frame_index = 0;
	u32 elem_count = 0, frame_count = 0, pixsize = 2;

	if (!is_rotation_enabled(vout))
		return 0;

	dmabuf = vout->buf_phy_addr[vb->i];
	/* If rotation is enabled, copy input buffer into VRFB
	 * memory space using DMA. We are copying input buffer
	 * into VRFB memory space of desired angle and DSS will
	 * read image VRFB memory for 0 degree angle
	 */
	pixsize = vout->bpp * vout->vrfb_bpp;
	/*
	 * DMA transfer in double index mode
	 */

	/* Frame index */
	dest_frame_index = ((MAX_PIXELS_PER_LINE * pixsize) -
			(vout->pix.width * vout->bpp)) + 1;

	/* Source and destination parameters */
	src_element_index = 0;
	src_frame_index = 0;
	dest_element_index = 1;
	/* Number of elements per frame */
	elem_count = vout->pix.width * vout->bpp;
	frame_count = vout->pix.height;
	tx = &vout->vrfb_dma_tx;
	tx->tx_status = 0;
	omap_set_dma_transfer_params(tx->dma_ch, OMAP_DMA_DATA_TYPE_S32,
			(elem_count / 4), frame_count, OMAP_DMA_SYNC_ELEMENT,
			tx->dev_id, 0x0);
	/* src_port required only for OMAP1 */
	omap_set_dma_src_params(tx->dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
			dmabuf, src_element_index, src_frame_index);
	/*set dma source burst mode for VRFB */
	omap_set_dma_src_burst_mode(tx->dma_ch, OMAP_DMA_DATA_BURST_16);
	rotation = calc_rotation(vout);

	/* dest_port required only for OMAP1 */
	omap_set_dma_dest_params(tx->dma_ch, 0, OMAP_DMA_AMODE_DOUBLE_IDX,
			vout->vrfb_context[vb->i].paddr[0], dest_element_index,
			dest_frame_index);
	/*set dma dest burst mode for VRFB */
	omap_set_dma_dest_burst_mode(tx->dma_ch, OMAP_DMA_DATA_BURST_16);
	omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE, 0x20, 0);

	omap_start_dma(tx->dma_ch);
	wait_event_interruptible_timeout(tx->wait, tx->tx_status == 1,
					 VRFB_TX_TIMEOUT);

	if (tx->tx_status == 0) {
		omap_stop_dma(tx->dma_ch);
		return -EINVAL;
	}
	/* Store buffers physical address into an array. Addresses
	 * from this array will be used to configure DSS */
	vout->queued_buf_addr[vb->i] = (u8 *)
		vout->vrfb_context[vb->i].paddr[rotation];
	return 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);
}
Beispiel #26
0
static void OMAPLFBFliepNoLock_HDMI(OMAPLFB_SWAPCHAIN *psSwapChain,
		OMAPLFB_DEVINFO *psDevInfo,
		struct omapfb_info *ofbi,
		struct fb_info *framebuffer,
		unsigned long fb_offset)
{
	struct omap_overlay *ovl_hdmi;
	struct omap_overlay_info info;
	struct omap_overlay *hdmi;
	struct omap_overlay_manager *manager;
	bool overlay_change_requested = false;
	enum omap_dss_overlay_s3d_type  s3d_type_in_video_hdmi = omap_dss_overlay_s3d_none;

	ovl_hdmi = omap_dss_get_overlay(3);
	if(ovl_hdmi->info.enabled)
		s3d_type_in_video_hdmi = ovl_hdmi->info.s3d_type;


	hdmi = psSwapChain->stHdmiTiler.overlay;
	manager = hdmi->manager;
	hdmi->get_overlay_info(hdmi, &info);

	//not good...
	if ( omap_overlay_info_req[hdmi->id].status==2 )
	{

		info.enabled = omap_overlay_info_req[hdmi->id].enabled;
		info.rotation = omap_overlay_info_req[hdmi->id].rotation;
		info.pos_x = omap_overlay_info_req[hdmi->id].pos_x;
		info.pos_y = omap_overlay_info_req[hdmi->id].pos_y;
		info.out_width = omap_overlay_info_req[hdmi->id].out_width;
		info.out_height = omap_overlay_info_req[hdmi->id].out_height;
		info.global_alpha = omap_overlay_info_req[hdmi->id].global_alpha;
		info.zorder = omap_overlay_info_req[hdmi->id].zorder;

		printk("GUI HDMI layer change requested. req_enabled(%d)\n", omap_overlay_info_req[hdmi->id].enabled);
		omap_overlay_info_req[hdmi->id].status = 0;
		overlay_change_requested = true;
	}

	if ( info.enabled )
	{
		mutex_lock(&psSwapChain->stHdmiTiler.lock);
		if ( !psSwapChain->stHdmiTiler.alloc )
		{
//			if ( AllocTilerForHdmi(psSwapChain, psDevInfo) ) {

				ERROR_PRINTK("Tiler memory for HDMI GUI cloning is not allocated\n");
				mutex_unlock(&psSwapChain->stHdmiTiler.lock);
				return;
//			}
		}

		if ( psSwapChain->stHdmiTiler.alloc )	//if Tiler memory is allocated
		{
			unsigned long line_offset;
			unsigned long w, h;
			unsigned long src_stride, dst_stride;
			unsigned long i;
			unsigned char *dst, *src;
			unsigned long pStride;
			u32 j, *src_4, *dst_4, *dst1_4;
			int ch;

			src_stride = psDevInfo->sFBInfo.ulByteStride;
			dst_stride = psSwapChain->stHdmiTiler.vStride;
			line_offset = fb_offset / src_stride;
			h = psDevInfo->sFBInfo.ulHeight;
			w = psDevInfo->sFBInfo.ulWidth;
			pStride = psSwapChain->stHdmiTiler.pStride;

			//Copy
			dst = (unsigned char*)psSwapChain->stHdmiTiler.vAddr +
				(line_offset * dst_stride);

			src = (unsigned char*)framebuffer->screen_base + fb_offset;


			DEBUG_PRINTK("Copy Start h:%d, src:0x%p src_stride:%d, dst:0x%p dst_stride:%d, line offset:%d, pStride:%d\n",
					h, src, src_stride, dst, dst_stride, line_offset, pStride);

			if( psSwapChain->s3d_type==omap_dss_overlay_s3d_side_by_side && s3d_type_in_video_hdmi == omap_dss_overlay_s3d_top_bottom)
			{
				for(j=0; j<h/2; j++)
				{
					src_4  = (u32 *)(src + src_stride*j);
					dst_4   = (u32 *)(dst + dst_stride*2*j);
					dst1_4 = (u32 *)(dst + dst_stride*2*j + w*2);
					for(i=0;i<w/2;i++)
					{
						*dst_4++ = *src_4;
						*dst1_4++ = *src_4++;
						src_4++;
					}
					src_4  = (u32 *)(src + src_stride*j);
					dst_4   = (u32 *)(dst + dst_stride*(2*j+1));
					dst1_4 = (u32 *)(dst + dst_stride*(2*j+1) + w*2);
					for(i=0;i<w/2;i++) {
						*dst_4++ = *src_4;
						*dst1_4++ = *src_4++;
						src_4++;
					}
				}
				info.s3d_type = omap_dss_overlay_s3d_top_bottom;
			}
			else
			{

				if(hdmi_dma.state == HDMI_DMA_DONE)
				{
					ch = hdmi_dma.frame_pos;
					hdmi->get_overlay_info(hdmi, &hdmi_dma.info[ch]);
					hdmi_dma.hdmi = hdmi;

					printk("S:%x\n", psSwapChain->stHdmiTiler.pAddr + (h * pStride * ch));

					omap_set_dma_transfer_params(hdmi_dma.lch, OMAP_DMA_DATA_TYPE_S32,
						src_stride>>2, h, 0, 0, 0);
					omap_set_dma_src_params(hdmi_dma.lch, 0, OMAP_DMA_AMODE_POST_INC,
						framebuffer->fix.smem_start + fb_offset, 1, 1);
					omap_set_dma_dest_params(hdmi_dma.lch, 0, OMAP_DMA_AMODE_DOUBLE_IDX,
						psSwapChain->stHdmiTiler.pAddr + (h * pStride * ch), 1, pStride - src_stride + 1 );
					omap_dma_set_prio_lch(hdmi_dma.lch, DMA_CH_PRIO_HIGH, DMA_CH_PRIO_HIGH);
					omap_set_dma_src_burst_mode(hdmi_dma.lch, OMAP_DMA_DATA_BURST_16);
					omap_set_dma_dest_burst_mode(hdmi_dma.lch, OMAP_DMA_DATA_BURST_16);

					omap_start_dma(hdmi_dma.lch);
					hdmi_dma.state = HDMI_DMA_TRANSFERRING;

					if ( omap_overlay_info_req[hdmi->id].status==2 )
					{
						hdmi_dma.info[ch].enabled = omap_overlay_info_req[hdmi->id].enabled;
						hdmi_dma.info[ch].rotation = omap_overlay_info_req[hdmi->id].rotation;
						hdmi_dma.info[ch].pos_x = omap_overlay_info_req[hdmi->id].pos_x;
						hdmi_dma.info[ch].pos_y = omap_overlay_info_req[hdmi->id].pos_y;
						hdmi_dma.info[ch].out_width = omap_overlay_info_req[hdmi->id].out_width;
						hdmi_dma.info[ch].out_height = omap_overlay_info_req[hdmi->id].out_height;
						hdmi_dma.info[ch].global_alpha = omap_overlay_info_req[hdmi->id].global_alpha;
						hdmi_dma.info[ch].zorder = omap_overlay_info_req[hdmi->id].zorder;
					}
					//fill info

					//@todo not good find another way later
					hdmi_dma.info[ch].color_mode = ofbi->overlays[0]->info.color_mode;
					hdmi_dma.info[ch].paddr = psSwapChain->stHdmiTiler.pAddr + (h * pStride * ch);
					hdmi_dma.info[ch].vaddr = NULL;		//no need
					if ( hdmi_dma.info[ch].rotation==OMAP_DSS_ROT_90 || hdmi_dma.info[ch].rotation==OMAP_DSS_ROT_270 )
					{
						hdmi_dma.info[ch].width = h;
						hdmi_dma.info[ch].height = w;
						hdmi_dma.info[ch].screen_width = h;
					}
					else
					{
						hdmi_dma.info[ch].width =w;
						hdmi_dma.info[ch].height = h;
						hdmi_dma.info[ch].screen_width = w;
					}
					hdmi_dma.info[ch].rotation_type = OMAP_DSS_ROT_TILER;
					hdmi_dma.info[ch].s3d_type = psSwapChain->s3d_type;

					hdmi_dma.curr_frame = hdmi_dma.frame_pos;
					if( ++hdmi_dma.frame_pos >= HDMI_DMA_MAX ) hdmi_dma.frame_pos = 0;

					if( omap_overlay_info_req[hdmi->id].status == 2) {
						omap_overlay_info_req[hdmi->id].status = 0;
					}
				}
				else printk("DOLCOM : DMA busy!!!!!!!!!!!!!!!!!\n");
Beispiel #27
0
static void makeinterlave(struct fb_info *fbi, struct omapfb_info *ofbi, struct omap_overlay *overlay, struct omap_overlay_info *pInfo)
{
	struct InterleaveBuffer* IB;
	struct omap_overlay_info overlay_info = *pInfo;
	IB = findInterleaveBuffer(fbi, &overlay_info);
	if ( IB!=NULL )
	{
#ifdef CONFIG_GFX_DMA_COPY
//LGE_CHANGE_S [[email protected]] 2010-12-27, P920 : For GFX dma copy. 

		if (wait_for_completion_timeout(&gfx_dma[0].compl, msecs_to_jiffies(1000)) == 0) {
			omap_stop_dma(gfx_dma[0].lch);
			DEBUG_PRINTK("GFX DMA: dma timeout while transferring\n");
		}

		omap_set_dma_transfer_params(gfx_dma[0].lch, OMAP_DMA_DATA_TYPE_S32,
			(fbi->fix.line_length>>2), (fbi->var.yres)>>1, 0, 0, 0);
		omap_set_dma_src_params(gfx_dma[0].lch, 0, OMAP_DMA_AMODE_POST_INC,
			overlay_info.paddr, 1, 1);
		omap_set_dma_dest_params(gfx_dma[0].lch, 0, OMAP_DMA_AMODE_DOUBLE_IDX,
			IB->paddr + fbi->fix.line_length, 1, (fbi->fix.line_length) + 1);

		omap_start_dma(gfx_dma[0].lch);
#if 0
		if (wait_for_completion_timeout(&gfx_dma[0].compl, msecs_to_jiffies(1000)) == 0) {
			omap_stop_dma(gfx_dma[0].lch);
			DEBUG_PRINTK("GFX DMA: dma timeout while transferring\n");
		}

		if (wait_for_completion_timeout(&gfx_dma[1].compl, msecs_to_jiffies(1000)) == 0) {
			omap_stop_dma(gfx_dma[1].lch);
			DEBUG_PRINTK("GFX DMA: dma timeout while transferring\n");
		}

		omap_set_dma_transfer_params(gfx_dma[0].lch, OMAP_DMA_DATA_TYPE_S32,
			(fbi->fix.line_length>>2), (fbi->var.yres)>>1, 0, 0, 0);
		omap_set_dma_src_params(gfx_dma[0].lch, 0, OMAP_DMA_AMODE_POST_INC,
			overlay_info.paddr, 1, 1);
		omap_set_dma_dest_params(gfx_dma[0].lch, 0, OMAP_DMA_AMODE_DOUBLE_IDX,
			IB->paddr + fbi->fix.line_length, 1, (fbi->fix.line_length) + 1);

		omap_set_dma_transfer_params(gfx_dma[1].lch, OMAP_DMA_DATA_TYPE_S32,
			(fbi->fix.line_length>>2), (fbi->var.yres)>>1, 0, 0, 0);
		omap_set_dma_src_params(gfx_dma[1].lch, 0, OMAP_DMA_AMODE_POST_INC,
			overlay_info.paddr + (fbi->fix.line_length * (fbi->var.yres>>1)), 1, 1);
		omap_set_dma_dest_params(gfx_dma[1].lch, 0, OMAP_DMA_AMODE_DOUBLE_IDX,
			IB->paddr, 1, (fbi->fix.line_length) + 1);

		omap_start_dma(gfx_dma[0].lch);
		omap_start_dma(gfx_dma[1].lch);
#endif

//LGE_CHANGE_E [[email protected]]
#else
//			memcpy(IB->buffer, overlay_info.vaddr, IB->size);
		{
			//copy interleave
			int stride;
			int height;
			unsigned char *src, *dst;
			int i;

			stride = fbi->fix.line_length;
			height = fbi->var.yres;
			src = overlay_info.vaddr;
			dst = IB->buffer;
//				printk("Interleave Copy line %d address:%p\n", height, IB->buffer);
//				printk("overlay->roation_type : %d\n", overlay_info.rotation_type);
			for(i=0;i<height;i++)
			{
				if ( i < (height/2) )
				{
					//left frame copy to odd line
					unsigned char *odd_line;
					odd_line = dst + stride * (i*2 + 1);
					memcpy(odd_line, src, stride);
				}
				else
				{
					//right frame copy to even line
					unsigned char *even_line;
					even_line = dst + stride * ( (i-height/2) * 2 + 1 -1 );
					memcpy(even_line, src, stride);
				}
				src += stride;
			}
		}
#endif
//			flush_cache_all();
		overlay_info.paddr = IB->paddr;
		overlay_info.vaddr = IB->buffer;
//			printk("S3D : set oerlay paddr:0x%x vaddr 0x%x",
//					overlay_info.paddr,
//					overlay_info.vaddr );
//			if ( cacheflush(IB->buffer, IB->size, DCACHE ) )
//				printk("Interleave buffer flush failed\n");
//			overlay->set_overlay_info(overlay, &overlay_info);
//			return;
	}
	overlay_info.s3d_type = omap_dss_overlay_s3d_interlaced;
	overlay->set_overlay_info(overlay, &overlay_info);
}
Beispiel #28
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);
	}
}
static void omap_nand_dma_transfer(struct mtd_info *mtd, void *addr,
                                         unsigned int u32_count, int is_write)
{
	const int block_size = 16;
	unsigned int block_count, len;
	int dma_ch;
	unsigned long fifo_reg, timeout, jiffies_before, jiffies_spent;
	static unsigned long max_jiffies = 0;

	dma_ch = omap_nand_dma_ch;
	block_count = u32_count * 4 / block_size;
	nand_write_reg(NND_STATUS, 0x0f);
	nand_write_reg(NND_FIFOCTRL, (block_size << 24) | block_count);
	fifo_reg = NAND_BASE + NND_FIFO;
	if (is_write) {
		omap_set_dma_dest_params(dma_ch, OMAP_DMA_PORT_TIPB,
					 OMAP_DMA_AMODE_CONSTANT, fifo_reg,
					 0, 0);
		omap_set_dma_src_params(dma_ch, OMAP_DMA_PORT_EMIFF,
					OMAP_DMA_AMODE_POST_INC,
					virt_to_phys(addr),
					0, 0);
//		omap_set_dma_src_burst_mode(dma_ch, OMAP_DMA_DATA_BURST_4);
		/* Set POSTWRITE bit */
		nand_write_reg(NND_CTRL, nand_read_reg(NND_CTRL) | (1 << 16));
	} else {
		omap_set_dma_src_params(dma_ch, OMAP_DMA_PORT_TIPB,
					OMAP_DMA_AMODE_CONSTANT, fifo_reg,
					0, 0);
		omap_set_dma_dest_params(dma_ch, OMAP_DMA_PORT_EMIFF,
					 OMAP_DMA_AMODE_POST_INC,
					 virt_to_phys(addr),
					 0, 0);
//		omap_set_dma_dest_burst_mode(dma_ch, OMAP_DMA_DATA_BURST_8);
		/* Set PREFETCH bit */
		nand_write_reg(NND_CTRL, nand_read_reg(NND_CTRL) | (1 << 17));
	}
	omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S32, block_size / 4,
				     block_count, OMAP_DMA_SYNC_FRAME,
				     0, 0);
	init_completion(&omap_nand_dma_comp);

	len = u32_count << 2;
	dma_cache_maint(addr, len, DMA_TO_DEVICE);
	omap_start_dma(dma_ch);
	jiffies_before = jiffies;
	timeout = wait_for_completion_timeout(&omap_nand_dma_comp,
					      msecs_to_jiffies(1000));
	jiffies_spent = (unsigned long)((long)jiffies - (long)jiffies_before);
	if (jiffies_spent > max_jiffies)
		max_jiffies = jiffies_spent;

	if (timeout == 0) {
		printk(KERN_WARNING "omap-hw-nand: DMA timeout after %u ms, max. seen latency %u ms\n",
		       jiffies_to_msecs(jiffies_spent),
		       jiffies_to_msecs(max_jiffies));
	}
	if (!is_write)
		dma_cache_maint(addr, len, DMA_FROM_DEVICE);

	nand_write_reg(NND_CTRL, nand_read_reg(NND_CTRL) & ~((1 << 16) | (1 << 17)));
}
Beispiel #30
0
static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
					 const unsigned char *buffer,
					 int offset, size_t count)
{
	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
	struct onenand_chip *this = mtd->priv;
	dma_addr_t dma_src, dma_dst;
	int bram_offset;
	unsigned long timeout;
	void *buf = (void *)buffer;
	volatile unsigned *done;

	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
	if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
		goto out_copy;

	/* panic_write() may be in an interrupt context */
	if (in_interrupt() || oops_in_progress)
		goto out_copy;

	if (buf >= high_memory) {
		struct page *p1;

		if (((size_t)buf & PAGE_MASK) !=
		    ((size_t)(buf + count - 1) & PAGE_MASK))
			goto out_copy;
		p1 = vmalloc_to_page(buf);
		if (!p1)
			goto out_copy;
		buf = page_address(p1) + ((size_t)buf & ~PAGE_MASK);
	}

	dma_src = dma_map_single(&c->pdev->dev, buf, count, DMA_TO_DEVICE);
	dma_dst = c->phys_base + bram_offset;
	if (dma_mapping_error(&c->pdev->dev, dma_src)) {
		dev_err(&c->pdev->dev,
			"Couldn't DMA map a %d byte buffer\n",
			count);
		return -1;
	}

	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
				     count >> 2, 1, 0, 0, 0);
	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
				dma_src, 0, 0);
	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
				 dma_dst, 0, 0);

	INIT_COMPLETION(c->dma_done);
	omap_start_dma(c->dma_channel);

	timeout = jiffies + msecs_to_jiffies(20);
	done = &c->dma_done.done;
	while (time_before(jiffies, timeout))
		if (*done)
			break;

	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);

	if (!*done) {
		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
		goto out_copy;
	}

	return 0;

out_copy:
	memcpy(this->base + bram_offset, buf, count);
	return 0;
}