UART errors: "Rx FIFO overrun" and "overwrite!"

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

UART errors: "Rx FIFO overrun" and "overwrite!"

12,801 Views
danilozecchin
Contributor I

Hi everyone!

I am testing IMX6's quad cpu UARTs over a custom Debian image (using the last imx.c driver) and I am having the following errors reported in kernel log (from dmseg):

imx-uart 21ec000.serial: Rx FIFO overrun

imx-uart 21ec000.serial: overwrite!

** They did not appeared consecutively.

When any of them happens, I have incomplete or bad transferences. For the test, I have configured the port #2 (UART2) to be used at 230400 speed rate and in raw mode (no control, no parity, no breaks). I have built the test program using termios.h and ioctl too.

I was wondering if anyone could tell me the reason of that errors and how could I solve them. Also, I would like to know if there is any other tool to use these ports in order to get realtime performance over them.

Thanks in advance.

Regards

Labels (2)
0 Kudos
Reply
5 Replies

4,072 Views
yaoshilee
Contributor I

Try this patch 

--- a/drivers/dma/imx-sdma.c

+++ b/drivers/dma/imx-sdma.c

@@ -511,6 +511,7 @@ static struct platform_device_id sdma_devtypes[] = {

        }

};

MODULE_DEVICE_TABLE(platform, sdma_devtypes);

+static int sdma_resume_channel(struct sdma_channel *sdmac);

 

static const struct of_device_id sdma_dt_ids[] = {

        { .compatible = "fsl,imx6sx-sdma", .data = &sdma_imx6sx, },

@@ -701,6 +702,8 @@ static void sdma_update_channel_loop(struct sdma_channel *sdmac)

                        /* restore mode.count after counter readed */

                        sdmac->chn_real_count = bd->mode.count;

                        bd->mode.count = sdmac->chn_count;

+                       if (sdmac->status== 3)

+                       sdma_resume_channel(sdmac);

                }

 

                sdma_handle_channel_loop(sdmac);

@@ -975,6 +978,8 @@ static int sdma_pause_channel(struct sdma_channel *sdmac)

        return 0;

}

0 Kudos
Reply

4,072 Views
michaelguntli
Contributor IV

yaoshilee‌ this actually resumes the DMA channel in case of an error, correct?
Why haven't you used the constants to express what the check actually does? I assume "sdmac->status== 3" checks for DMA_ERROR?

kernel-imx\include\linux\dmaengine.h

/**
* enum dma_status - DMA transaction status
* @DMA_COMPLETE: transaction completed
* @DMA_IN_PROGRESS: transaction not yet processed
* @DMA_PAUSED: transaction is paused
* @DMA_ERROR: transaction failed
*/
enum dma_status {
DMA_COMPLETE,
DMA_IN_PROGRESS,
DMA_PAUSED,
DMA_ERROR,
};

The entire function now actually looks like this:

static void sdma_update_channel_loop(struct sdma_channel *sdmac) {
    struct sdma_buffer_descriptor *bd;

    /*
    * loop mode. Iterate over descriptors, re-setup them and
    * call callback function.
    */
    while (1) {
        bd = &sdmac->bd[sdmac->buf_tail];

        if (bd->mode.status & BD_DONE)
            break;

        if (bd->mode.status & BD_RROR)
            sdmac->status = DMA_ERROR;

        bd->mode.status |= BD_DONE;
        sdmac->buf_tail++;
        sdmac->buf_tail %= sdmac->num_bd;
        if (sdmac->peripheral_type == IMX_DMATYPE_UART) {
            /* restore mode.count after counter readed */
            sdmac->chn_real_count = bd->mode.count;
            bd->mode.count = sdmac->chn_count;
            if (sdmac->status == DMA_ERROR)
                sdma_resume_channel(sdmac);
        }

        sdma_handle_channel_loop(sdmac);
    }
}

0 Kudos
Reply

4,072 Views
igorpadykov
NXP Employee
NXP Employee

Hi Danilo

it may be suggested to use UART handshaking control signals (RTS,CTS),

so when Rx FIFO reaches some level, control line signals to transmitter to stop transmission.

Issue is caused by processor buses bandwidth limitation, since UART is low priority

other bus masters consumes all available bus traffic. Probably increasing cpu/ddr operating

frequency or decreasing LCD/VPU/GPU frame rate also may help.

Best regards

igor

-----------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

-----------------------------------------------------------------------------------------------------------------------

4,072 Views
danilozecchin
Contributor I

Thanks very much Igor for the response.

I have read the Linux development manual and I have noticed that it is recommended to use hardware flow control (specially for DMA). Our main problem is that our source device (the one that we connect to) does not implement this protocol communication (only pins for rx and tx). It waits a command and then as a response it sends a stream of bytes.

So we should do what you have recommended, since we do not use LCD or GPU unit. Here I need some help, please could you tell me how I can increase cpu/ddr operating frecuency? Also, is there any way to disable GPU/VPU/LCD?

Thanks again.

Regards.

0 Kudos
Reply

4,072 Views
shmulikfridman
Contributor I

Hi,

I encountered the same problem. did you solved it?

0 Kudos
Reply