Message ID | 20170108180609.GB24155@archie.localdomain (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
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
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
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 --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 */