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;
}