This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/AM3358: UART4 DMA not working

Part Number: AM3358


Tool/software: Linux

Hi

Target system: BeagleBone Green

OS: Linux kernel 4.9

Issue:

First, we compile the kernel with UART DMA support disabled (CONFIG_SERIAL_8250_DMA). The UART works correctly.

Then, we enable UART DMA support, and set the following lines in the DTS:


uart4: serial@481a8000 {
compatible = "ti,am3352-uart", "ti,omap3-uart";
ti,hwmods = "uart5";
clock-frequency = <48000000>;
reg = <0x481a8000 0x2000>;
interrupts = <45>;
status = "disabled";
dmas = <&edma 30 0>, <&edma 31 0>;
dma-names = "tx", "rx";
};

and the UART does not work.

Tracing through the kernel, omap_8250_dma_tx_complete() is never called.

Also, in the am33xx.dtsi, only uarts 0-2 have dma channels specified for them. The others do not. Is this due to a hardware limitation?

Thanks

  • Hi,

    Kernel v4.9 is not supported by TI. The latest Linux SDK release from TI is based on kernel v4.4.41: www.ti.com/.../PROCESSOR-SDK-AM335X
  • Hi,

    Thanks for your quick reply. We switched to the 4.4 kernel and re-built it with the details as above, but we still cannot get DMA working on UART4.

    (Note, I had to cherry pick github.com/.../eca02f01be96d2ced5b2314dc4462c32e4ad0366 which is critical to getting rs485 operation working.)

    Could it be something outside the DTS?

    Michael
  • I have asked the software team to check. They will respond here.
  • Hi Michael,

    There shouldn't be any problem for uart4 to work with DMA.

    The dma channels to be used are set in the dtsi file. So my first suggestion is to check if any other module is configured to work with these dmas (30 & 31)...

    Also are you getting any errors upon booting your board?

    Best Regards,
    Yordan
  • Hi Yordan

    I did not see any other modules using these DMA channels (actually, I cut and pasted from another UART that we are not using).

    There are no errors during boot up, but "dmesg | grep serial" reports that each of the devices are identfied as 8250s, not 16c750s which is what the AM335x uses (according to here www.ti.com/.../spruh73). This means that in 8250_port.c, PORT_8250 is used instead of PORT_16570. Hard coding to PORT16570 did not fix this problem though.

    static const struct serial8250_config uart_config[] = {
    	[PORT_UNKNOWN] = {
    		.name		= "unknown",
    		.fifo_size	= 1,
    		.tx_loadsz	= 1,
    	},
    	[PORT_8250] = {
    		.name		= "8250",
    		.fifo_size	= 1,
    		.tx_loadsz	= 1,
    	},
    .......................
    	[PORT_16750] = {
    		.name		= "TI16750",
    		.fifo_size	= 64,
    		.tx_loadsz	= 64,
    		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 |
    				  UART_FCR7_64BYTE,
    		.rxtrig_bytes	= {1, 16, 32, 56},
    		.flags		= UART_CAP_FIFO | UART_CAP_SLEEP | UART_CAP_AFE,
    	},

  • Well at least I can see why the UART is identified as an 8250, from this code:
    /*
    * It claims to be 16C750 compatible however it is a little different.
    * It has EFR and has no FCR7_64byte bit. The AFE (which it claims to
    * have) is enabled via EFR instead of MCR. The type is set here 8250
    * just to get things going. UNKNOWN does not work for a few reasons and
    * we don't need our own type since we don't use 8250's set_termios()
    * or pm callback.
    */

    That said, still just can't get this DMA mode working. :( Could it be RS485 specific?

  • Latest TISDK uses 8250, so this:
    but "dmesg | grep serial" reports that each of the devices are identfied as 8250s, not 16c750s

    is the expected behavior.

    I'm looking into this and will updated when I have any suggestions.

    Best Regards,
    Yordan