serial-tegra.c

Hi,recently I am trying to make my TK1 communicate with dsp through UART.
Dsp sends 32bytes using baud_rate 6Mbps.And there is a 50us break between every 32bytes.Ok it’s just the background.
I read the driver serial-tegra.c and found that :
when eord occurred,in the function tegra_uart_isr will jump to tegra_uart_handle_rx_dma:
case 2 : is_rx_int = true; → ret = tegra_uart_handle_rx_dma(tup);
And in the following function,

tegra_uart_handle_rx_dma

dmaengine_terminate_all may take 30us,really! And that means before program reach

ret = tegra_uart_handle_rx_pio(tup, port);

it may have taken 50us:

time  taken: 50us

maybe the new data have reached in FIFO ,and we have to using PIO_mode to flip the new data into upper_space instead DMA_mode .That’s not reasonable!!!

static int tegra_uart_handle_rx_dma(struct tegra_uart_port *tup)
{
        static struct timeval tstart;
	struct dma_tx_state state;
	struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port);
	struct tty_port *port = &tup->uport.state->port;
	int count;
	int rx_level = 0;
	struct dma_async_tx_descriptor *prev_rx_dma_desc;
	int ret;

	/* Deactivate flow control to stop sender */
	if (tup->rts_active)
		set_rts(tup, false);
        do_gettimeofday(&tstart);
	dmaengine_terminate_all(tup->rx_dma_chan);
	dmaengine_tx_status(tup->rx_dma_chan,  tup->rx_cookie, &state);
	prev_rx_dma_desc = tup->rx_dma_desc;
	count = tup->rx_bytes_requested - state.residue;

	/* If we are here, DMA is stopped */
	if (count) {
		ret = tegra_uart_copy_rx_to_tty(tup, port, count);
		if (ret)         /tegra_uart_handle_rx_pio
			goto skip_pio;
	}
        do_gettimeofday(&tend)
	printk("time  taken: %ld us\n",1000000* (tend.tv_sec - tstart.tv_sec) +(tend.tv_usec - tstart.tv_usec) );
	ret = tegra_uart_handle_rx_pio(tup, port);  //have to use PIO_mode when new data coming in?

skip_pio:
	if (tup->enable_rx_buffer_throttle) {
		rx_level = tty_buffer_get_level(port);
		if (rx_level > 70)
			mod_timer(&tup->timer,
					jiffies + tup->timer_timeout_jiffies);
	}

	if (tty) {
		tty_flip_buffer_push(port);
		tty_kref_put(tty);
	}
	tegra_uart_start_rx_dma(tup);
	async_tx_ack(prev_rx_dma_desc);

	if (tup->enable_rx_buffer_throttle) {
		if ((rx_level <= 70) && tup->rts_active)
			set_rts(tup, true);
	} else if (tup->rts_active)
		set_rts(tup, true);

	return ret;
}