All of lore.kernel.org
 help / color / mirror / Atom feed
From: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 1/1] serial/ns16550: check UART mode for TEMT value
Date: Sat, 22 Dec 2012 04:40:41 +0100	[thread overview]
Message-ID: <50D52BB9.8050408@collabora.co.uk> (raw)
In-Reply-To: <1356144348.24276.12@snotra>

Hi Scott, thank you for your feedback.

On 12/22/2012 03:45 AM, Scott Wood wrote:
> On 12/21/2012 03:21:46 AM, Javier Martinez Canillas wrote:
>> On ns16550, the Transmitter Empty (TEMT) Bit is used to
>> indicate when the Transmitter Holding Register (THR) and
>> the Transmitter Shift Register (TSR) are both empty.
>> 
>> But ns16550 UART has two operation modes (16450 and FIFO)
>> and the TEMT bit logic value set is different on each mode.
>> 
>> On 16450, the TEMT bit is set to 1 when both THR and TSR are
>> empty and is set to 0 on FIFO mode.
> 
> When you say "on 16450", do you mean "in 16450 mode"?
>

Yes, that's what I meant. I'm not a native English speaker so sorry if I have
some grammatic errors in my comments.

>> So, checking the TEMT value without checking the current mode
>> and assuming a logical value of 1, can lead to U-Boot to hang
>> forever if the UART is initialized on FIFO mode by default.
> 
>  From the 16550 docs:
> 
>    Bit 6 This bit is the Transmitter Empty (TEMT) indicator Bit 6 is set
>    to a logic 1 whenever the Transmitter Holding Regis- ter (THR) and  
> the
>    Transmitter Shift Register (TSR) are both empty It is reset to a  
> logic
>    0 whenever either the THR or TSR contains a data character In the  
> FIFO
>    mode this bit is set to one whenever the transmitter FIFO and shift
>    register are both empty
> 
> Maybe the 16550 implementation you're using is doing something wrong?
> 

Could be, I'm using a board with an TI OMAP3 SoC which has an NS16650 UART.

Now I read again the NS16650 documentation [1] and you are right. I
misunderstood and thought that on FIFO mode the TEMT bit was set to 0 when the
both THR and TSR were empty and that this was causing U-Boot to hang.

BTW I realized that this is only an issue for SPL, if you build that check for
the non-SPL build, it works.

With this patch my board boots:

diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index bbd91ca..a3ef8a5 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -36,8 +36,10 @@

 void NS16550_init(NS16550_t com_port, int baud_divisor)
 {
+#ifndef CONFIG_SPL_BUILD
        while (!(serial_in(&com_port->lsr) & UART_LSR_TEMT))
                ;
+#endif

        serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier);
 #if (defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)) || \

>> Signed-off-by: Javier Martinez Canillas  
>> <javier.martinez@collabora.co.uk>
>> ---
>>  drivers/serial/ns16550.c |    4 +++-
>>  1 files changed, 3 insertions(+), 1 deletions(-)
>> 
>> diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
>> index bbd91ca..d75d814 100644
>> --- a/drivers/serial/ns16550.c
>> +++ b/drivers/serial/ns16550.c
>> @@ -36,7 +36,9 @@
>> 
>>  void NS16550_init(NS16550_t com_port, int baud_divisor)
>>  {
>> -	while (!(serial_in(&com_port->lsr) & UART_LSR_TEMT))
>> +	int mode = serial_in(&com_port->fcr) & UART_FCR_FIFO_EN;
>> +
>> +	while (!(serial_in(&com_port->lsr) & UART_LSR_TEMT ^ mode))
>>  		;
> 
> Please don't make the reader know the relative prededence of & and ^,  
> and
> don't use ^ in obfuscatory ways.  It's not even any different from | as
> used above -- except that | wouldn't break if TEMT and FIFO_EN had the  
> same
> value -- so why do you need the exclusive form?
> 

Ok, sorry. I didn't think that knowing the precedence of bitwise operator was
obfuscated and the ^ was because I misunderstood the NS16550 docs and thought
that UART_LSR_TEMT would be 0 in FIFO mode.

> BTW, when I saw the problem that necessitated this, FIFO was enabled, so
> this is no better than reverting the patch.
> 
> -Scott
> 

Either way works for me, I just want to boot my board :-)

But if I'm the only one having this issue maybe is just my hardware behaving
badly. I'll ask other OMAP3 users if they can boot with mainline U-Boot to
confirm this.

Best regards,
Javier

[1]:http://www.ti.com/lit/ds/symlink/pc16550d.pdf

  reply	other threads:[~2012-12-22  3:40 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-12-21  9:21 [U-Boot] [PATCH 1/1] serial/ns16550: check UART mode for TEMT value Javier Martinez Canillas
2012-12-22  2:45 ` Scott Wood
2012-12-22  3:40   ` Javier Martinez Canillas [this message]
     [not found] <CAAwP0s0y=hPh3FrTSLptd_5UnbYGTV47s=6hVkR8aL0-Z_Ejeg@mail.gmail.com>
2013-01-03  2:58 ` Scott Wood
2013-01-03 21:04   ` Tom Rini
2013-01-07 11:37     ` Javier Martinez Canillas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=50D52BB9.8050408@collabora.co.uk \
    --to=javier.martinez@collabora.co.uk \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.