diff mbox

imx: RS-485 problems during TX, maybe DMA related

Message ID 20170108180609.GB24155@archie.localdomain (mailing list archive)
State New, archived
Headers show

Commit Message

Clemens Gruber Jan. 8, 2017, 6:06 p.m. UTC
Hi Fabio,

On Sun, Jan 08, 2017 at 12:30:24AM -0200, Fabio Estevam wrote:
> Hi Clemens,
> 
> On Sat, Jan 7, 2017 at 9:06 PM, Clemens Gruber
> <clemens.gruber@pqgruber.com> wrote:
> 
> > Just remuxed GPIO signals to these pads, applied your two patches and
> > used rts-gpios in the DT but I still see the same problem :/
> >
> > When transmit something, I get doubled characters, then zeros and at the
> > end garbled data of previous transmissions, same as described in my
> > first post (Logic analyzer: https://pqgruber.com/rs485_results.png)
> > The data is always 4096 bytes long, this explains why the echo command
> > is blocking for about 4 seconds (<- 4096 bytes at a baudrate of 9600).
> > The TE line is also high until all 4096 bytes are sent.
> >
> > I think this comes from the UART_XMIT_SIZE which is defined to the page
> > size.
> > Maybe there is something wrong in imx_transmit_buffer and leads to the
> > whole circular buffer being sent out all the time, not stopping..
> >
> > Do these debug logs tell you anything?
> > https://gist.github.com/clemensg/1ac5ee8a8ea32acc9145c5aa8407aea5
> >
> > I am analyzing the signals coming directly from the i.MX6Q, so this must
> > be a software problem, but I don't understand why it works for you, if
> > we use the same software.
> >
> > Do you use any other patches on top of mainline and do you use the SDMA
> > scripts from the ROM?
> 
> No, I use the original 4.9 + the two patches I sent. Yes, I do use the
> SDMA scripts from ROM.
> 
> Here is the procedure I did to try to reproduce the issue you reported:
> 
> (The rs485conf is available at:
> https://github.com/mniestroj/rs485conf/blob/master/main.c )
> 
> First of all I enable rs485 for ttymxc3 using the rs485conf application:
> 
> root@imx6qsabresd:/home# ./rs485conf  /dev/ttymxc3 -e 1
> [   27.106517] random: crng init done
> = Current configuration:
> RS485 enabled:                false
> RTS on send:                  high
> RTS after send:               low
> RTS delay before send:        0
> RTS delay after send:         0
> Receive during sending data:  true
> 
> = New configuration:
> RS485 enabled:                true
> RTS on send:                  high
> RTS after send:               low
> RTS delay before send:        0
> RTS delay after send:         0
> Receive during sending data:  true
> 
> = Saved configuration:
> RS485 enabled:                true
> RTS on send:                  high
> RTS after send:               low
> RTS delay before send:        0
> RTS delay after send:         0
> Receive during sending data:  true
> root@imx6qsabresd:/ho
> 
> Then
> 
> root@imx6qsabresd:/home# echo A > /dev/ttymxc3
> 
> (wait 10 seconds)
> 
> root@imx6qsabresd:/home# echo B > /dev/ttymxc3
> 
> (wait 10 seconds)
> 
> root@imx6qsabresd:/home# echo C > /dev/ttymxc3
> 
> On the serial console at 9600bps only the:
> A
> B
> C
> 
> are seen, so not duplicated characters, nor noise is seen on the console.

I just did the experiment with your configuration and the rs485conf tool
you mentioned.
But still, no luck :(

What's the revision of the i.MX6Q on your board? Mine is 1.5 (TO 1.3)

Another example: If I run the following on the board..

while true; do
  echo ABCDEFGHIJKLM > /dev/ttymxc4
  sleep 0.5
  echo abc > /dev/ttymxc4 > /dev/ttymxc4
  sleep 0.5
done

Many transmits contain garbled (doubled and sometimes also extended to
a length of 4096 bytes, containing zeros) data.
I can see a few transmissions that are sent correctly, though.

Interesting side note: With the following patch, the problems disappear:

--

Regards,
Clemens

Comments

Fabio Estevam Jan. 8, 2017, 9:46 p.m. UTC | #1
On Sun, Jan 8, 2017 at 4:06 PM, Clemens Gruber
<clemens.gruber@pqgruber.com> wrote:

> I just did the experiment with your configuration and the rs485conf tool
> you mentioned.
> But still, no luck :(
>
> What's the revision of the i.MX6Q on your board? Mine is 1.5 (TO 1.3)

Mine is a mx6solo rev1.1.

> Another example: If I run the following on the board..
>
> while true; do
>   echo ABCDEFGHIJKLM > /dev/ttymxc4
>   sleep 0.5
>   echo abc > /dev/ttymxc4 > /dev/ttymxc4

There is a typo here, this should be:
echo abc > /dev/ttymxc4

Fixed it locally.

>   sleep 0.5
> done
>
> Many transmits contain garbled (doubled and sometimes also extended to
> a length of 4096 bytes, containing zeros) data.
> I can see a few transmissions that are sent correctly, though.

This script runs correctly here and no issue is seen on the console.

Not sure why you get TXEN high for so long in your case.

> Interesting side note: With the following patch, the problems disappear:
>
> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> index 451e50f6d77a..eb9f0ce6c34a 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c
> @@ -1270,8 +1270,10 @@ static int imx_startup(struct uart_port *port)
>         writel(temp & ~UCR4_DREN, sport->port.membase + UCR4);
>
>         /* Can we enable the DMA support? */
> +#if 0
>         if (!uart_console(port) && !sport->dma_is_inited)
>                 imx_uart_dma_init(sport);
> +#endif

Looks like you disabled DMA.

Regards,

Fabio Estevam
Clemens Gruber Jan. 11, 2017, 12:33 a.m. UTC | #2
Hi Fabio,

On Sun, Jan 08, 2017 at 07:46:29PM -0200, Fabio Estevam wrote:
> > What's the revision of the i.MX6Q on your board? Mine is 1.5 (TO 1.3)
> 
> Mine is a mx6solo rev1.1.

Could it be dependent upon SMP? Do you have an i.MX6Q board around to
try?

--

I made a few interesting discoveries in the meantime:

1) If I do not enable UCR4_TCEN, the data on TXD is fine. Of course the
TE pin does not toggle in that case, but it shows that the problem has
something to do with the actions taking place after the transmit
complete interrupt and not with the hardware or DMA internals.

2) I added a few custom printks when doing echo A > /dev/ttymxc4 in
RS-485 mode:

imx_start_tx
imx_dma_tx: tx_bytes=2, xmit->tail=0, xmit->head=2
imx_dma_tx: dma_tx_nents=1
imx-uart 21f4000.serial: TX: prepare to send 2 bytes by DMA
imx_transmit_buffer: xmit->tail set to 1, xmit->head=2
imx_transmit_buffer: xmit->tail set to 2, xmit->head=2
imx_stop_tx (returns immediately because dma_is_txing)
^ repeats multiple times
imx_stop_tx (goes through)
dma_tx_callback: xmit->tail=2 tx_bytes=2
dma_tx_callback: xmit->tail set to 4
imx-uart 21f4000.serial: we finish the TX DMA.
dma_tx_callback: xmit->tail=4 icount.tx=4
imx_dma_tx: tx_bytes=4094, xmit->tail=4, xmit->head=2		(!!)
imx_dma_tx: dma_tx_nents=2
..

That's why the data is garbled in that way: It wraps around the circular
buffer. xmit->tail jumps over xmit->head, which explains why I first see
the correct characters, then again followed by many zeros and at the end
again the correct characters.

Regards,
Clemens
Fabio Estevam Jan. 11, 2017, 11:51 a.m. UTC | #3
Hi Clemens,

On Tue, Jan 10, 2017 at 10:33 PM, Clemens Gruber
<clemens.gruber@pqgruber.com> wrote:
> Hi Fabio,
>
> On Sun, Jan 08, 2017 at 07:46:29PM -0200, Fabio Estevam wrote:
>> > What's the revision of the i.MX6Q on your board? Mine is 1.5 (TO 1.3)
>>
>> Mine is a mx6solo rev1.1.
>
> Could it be dependent upon SMP? Do you have an i.MX6Q board around to
> try?

Unfortunately the only hardware I can test RS485 is based on mx6solo.

Adding Tim Harvey, who could probably test RS485 on MX6Q.

Regards,

Fabio Estevam
diff mbox

Patch

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 451e50f6d77a..eb9f0ce6c34a 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1270,8 +1270,10 @@  static int imx_startup(struct uart_port *port)
 	writel(temp & ~UCR4_DREN, sport->port.membase + UCR4);
 
 	/* Can we enable the DMA support? */
+#if 0
 	if (!uart_console(port) && !sport->dma_is_inited)
 		imx_uart_dma_init(sport);
+#endif
 
 	spin_lock_irqsave(&sport->port.lock, flags);
 	/* Reset fifo's and state machines */