コード例 #1
0
ファイル: dma.c プロジェクト: 0x0f/android-tegra-nv-2.6.39
/*
 * Circular dma chain management
 */
void stmp3xxx_dma_free_chain(struct stmp37xx_circ_dma_chain *chain)
{
	int i;

	for (i = 0; i < chain->total_count; i++)
		stmp3xxx_dma_free_command(
			STMP3XXX_DMA(chain->channel, chain->bus),
			&chain->chain[i]);
}
コード例 #2
0
static void stmp3xxx_mmc_dma_release(struct stmp3xxx_mmc_host *host)
{
	stmp3xxx_dma_reset_channel(host->dmach);

	dma_free_coherent(host->dev, SSP_BUFFER_SIZE, host->dma_buf,
			  host->dma_buf_phys);

	stmp3xxx_dma_free_command(host->dmach, &host->dma_desc);
	stmp3xxx_dma_release(host->dmach);
}
コード例 #3
0
ファイル: dma.c プロジェクト: 0x0f/android-tegra-nv-2.6.39
int stmp3xxx_dma_make_chain(int ch, struct stmp37xx_circ_dma_chain *chain,
			    struct stmp3xxx_dma_descriptor descriptors[],
			    unsigned items)
{
	int i;
	int err = 0;

	if (items == 0)
		return err;

	for (i = 0; i < items; i++) {
		err = stmp3xxx_dma_allocate_command(ch, &descriptors[i]);
		if (err) {
			WARN_ON(err);
			/*
			 * Couldn't allocate the whole chain.
			 * deallocate what has been allocated
			 */
			if (i) {
				do {
					stmp3xxx_dma_free_command(ch,
								  &descriptors
								  [i]);
				} while (i-- > 0);
			}
			return err;
		}

		/* link them! */
		if (i > 0) {
			descriptors[i - 1].next_descr = &descriptors[i];
			descriptors[i - 1].command->next =
						descriptors[i].handle;
		}
	}

	/* make list circular */
	descriptors[items - 1].next_descr = &descriptors[0];
	descriptors[items - 1].command->next = descriptors[0].handle;

	chain->total_count = items;
	chain->chain = descriptors;
	chain->free_index = 0;
	chain->active_index = 0;
	chain->cooked_index = 0;
	chain->free_count = items;
	chain->active_count = 0;
	chain->cooked_count = 0;
	chain->bus = STMP3XXX_DMA_BUS(ch);
	chain->channel = STMP3XXX_DMA_CHANNEL(ch);
	return err;
}
コード例 #4
0
void stmp3xxx_lcdif_dma_release(void)
{
	int i;

	if (stmp378x_lcd_master) {
		stmp3xxx_clearl(BM_LCDIF_CTRL_LCDIF_MASTER,
				REGS_LCDIF_BASE + HW_LCDIF_CTRL);
		return;
	}

	for (i = 0; i < dma_chain_info_pos; i++)
		stmp3xxx_dma_free_command(STMP3XXX_DMA
					  (LCD_DMA_CHANNEL, STMP3XXX_BUS_APBH),
					  &video_dma_descriptor[i]);
	stmp3xxx_dma_release(STMP3XXX_DMA(LCD_DMA_CHANNEL, STMP3XXX_BUS_APBH));

	dma_chain_info_pos = 0;
}
コード例 #5
0
/* Allocate and initialize rx and tx DMA chains */
static inline int stmp_appuart_dma_init(struct stmp_appuart_port *s)
{
	int err = 0;
	struct stmp3xxx_dma_descriptor *t = &s->tx_desc;
#ifndef RX_CHAIN
	struct stmp3xxx_dma_descriptor *r = &s->rx_desc;
#else
	int i;
#endif

	err = stmp3xxx_dma_request(s->dma_rx, s->dev, s->dev->bus_id);
	if (err)
		goto out;
	err = stmp3xxx_dma_request(s->dma_tx, s->dev, s->dev->bus_id);
	if (err)
		goto out1;

#ifndef RX_CHAIN
	err = stmp3xxx_dma_allocate_command(s->dma_rx, r);
	if (err)
		goto out2;
#endif
	err = stmp3xxx_dma_allocate_command(s->dma_tx, t);
	if (err)
		goto out3;
	t->virtual_buf_ptr = dma_alloc_coherent(s->dev,
					   TX_BUFFER_SIZE,
					   &t->command->buf_ptr,
					   GFP_DMA);
	if (!t->virtual_buf_ptr)
		goto out4;
#ifdef DEBUG
	memset(t->virtual_buf_ptr, 0x4B, TX_BUFFER_SIZE);
#endif

#ifndef RX_CHAIN
	r->virtual_buf_ptr = dma_alloc_coherent(s->dev,
					   RX_BUFFER_SIZE,
					   &r->command->buf_ptr,
					   GFP_DMA);
	if (!r->virtual_buf_ptr)
		goto out5;
#ifdef DEBUG
	memset(r->virtual_buf_ptr, 0x4C, RX_BUFFER_SIZE);
#endif
#else
	stmp3xxx_dma_make_chain(s->dma_rx, &s->rx_chain, s->rxd, RX_CHAIN);
	for (i = 0; i < RX_CHAIN; i++) {
		struct stmp3xxx_dma_descriptor *r = s->rxd + i;

		r->command->cmd =
			BF_APBX_CHn_CMD_XFER_COUNT(RX_BUFFER_SIZE) |
			BF_APBX_CHn_CMD_CMDWORDS(1) |
			BM_APBX_CHn_CMD_WAIT4ENDCMD |
			BM_APBX_CHn_CMD_SEMAPHORE |
			BM_APBX_CHn_CMD_IRQONCMPLT |
			BM_APBX_CHn_CMD_CHAIN |
			BF_APBX_CHn_CMD_COMMAND(
				BV_APBX_CHn_CMD_COMMAND__DMA_WRITE);
		r->virtual_buf_ptr = dma_alloc_coherent(s->dev,
					   RX_BUFFER_SIZE,
					   &r->command->buf_ptr,
					   GFP_DMA);
		r->command->pio_words[0] = /* BM_UARTAPP_CTRL0_RUN | */
			BF_UARTAPP_CTRL0_XFER_COUNT(RX_BUFFER_SIZE)|
			BM_UARTAPP_CTRL0_RXTO_ENABLE |
			BF_UARTAPP_CTRL0_RXTIMEOUT(3);
	}
#endif
	return 0;

	/*
	 * would be necessary on other error paths

	dma_free_coherent( s->dev, RX_BUFFER_SIZE, r->virtual_buf_ptr,
			   r->command->buf_ptr);
	*/
out5:
	dma_free_coherent(s->dev, TX_BUFFER_SIZE, t->virtual_buf_ptr,
			   t->command->buf_ptr);
out4:
	stmp3xxx_dma_free_command(s->dma_tx, t);
out3:
#ifndef RX_CHAIN
	stmp3xxx_dma_free_command(s->dma_rx, r);
#endif
out2:
	stmp3xxx_dma_release(s->dma_tx);
out1:
	stmp3xxx_dma_release(s->dma_rx);
out:
	WARN_ON(err);
	return err;
}