[U-Boot] [PATCH v2 0/5] PL01x: baudrate & line control fixes

This patchset fixes the pl01x driver esp for pl011 baudrate & line control.
Changes in v2: - fix the comment style
Vikas Manocha (5): serial: pl01x: pass pl01x_type to set baudrate serial: pl01x: fix pl011 baud rate configuration serial: pl01x: move all line control at same place serial: pl01x: disable as per type of pl01x serial: pl01x: avoid pl01x type check two times
drivers/serial/serial_pl01x.c | 48 ++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 22 deletions(-)

Although we were checking the pl01x type, seems like PL010 type was being passed by mistake.
Signed-off-by: Vikas Manocha vikas.manocha@st.com Acked-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
drivers/serial/serial_pl01x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c index 38dda91..1860289 100644 --- a/drivers/serial/serial_pl01x.c +++ b/drivers/serial/serial_pl01x.c @@ -201,7 +201,7 @@ static void pl01x_serial_init_baud(int baudrate) base_regs = (struct pl01x_regs *)port[CONFIG_CONS_INDEX];
pl01x_generic_serial_init(base_regs, pl01x_type); - pl01x_generic_setbrg(base_regs, TYPE_PL010, clock, baudrate); + pl01x_generic_setbrg(base_regs, pl01x_type, clock, baudrate); }
/*

On Fri, Nov 21, 2014 at 10:34:19AM -0800, Vikas Manocha wrote:
Although we were checking the pl01x type, seems like PL010 type was being passed by mistake.
Signed-off-by: Vikas Manocha vikas.manocha@st.com Acked-by: Simon Glass sjg@chromium.org
Applied to u-boot/master, thanks!

UART_IBRD, UART_FBRD, and UART_LCR_H form a single 30-bit wide register which is updated on a single write strobe generated by a UART_LCR_H write. So, to internally update the content of UART_IBRD or UART_FBRD, a write to UART_LCR_H must always be performed at the end.
Signed-off-by: Vikas Manocha vikas.manocha@st.com Acked-by: Simon Glass sjg@chromium.org ---
Changes in v2: - fixed comment style
drivers/serial/serial_pl01x.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c index 1860289..a58ad8a 100644 --- a/drivers/serial/serial_pl01x.c +++ b/drivers/serial/serial_pl01x.c @@ -122,6 +122,7 @@ static int pl01x_generic_serial_init(struct pl01x_regs *regs, static int pl01x_generic_setbrg(struct pl01x_regs *regs, enum pl01x_type type, int clock, int baudrate) { + unsigned int lcr; switch (type) { case TYPE_PL010: { unsigned int divisor; @@ -175,6 +176,13 @@ static int pl01x_generic_setbrg(struct pl01x_regs *regs, enum pl01x_type type, writel(divider, ®s->pl011_ibrd); writel(fraction, ®s->pl011_fbrd);
+ /* + * Internal update of baud rate register require line + * control register write + */ + lcr = UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN; + writel(lcr, ®s->pl011_lcrh); + /* Finally, enable the UART */ writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | UART_PL011_CR_RXE | UART_PL011_CR_RTS, ®s->pl011_cr);

On Fri, Nov 21, 2014 at 10:34:20AM -0800, Vikas Manocha wrote:
UART_IBRD, UART_FBRD, and UART_LCR_H form a single 30-bit wide register which is updated on a single write strobe generated by a UART_LCR_H write. So, to internally update the content of UART_IBRD or UART_FBRD, a write to UART_LCR_H must always be performed at the end.
Signed-off-by: Vikas Manocha vikas.manocha@st.com Acked-by: Simon Glass sjg@chromium.org
Applied to u-boot/master, thanks!

Receive line control uses same setting as transmit line control, also one lcrh write is effective for both baud rate & receive line control internal update.
Signed-off-by: Vikas Manocha vikas.manocha@st.com Acked-by: Simon Glass sjg@chromium.org ---
Changes in v2: - fixed comment style
drivers/serial/serial_pl01x.c | 44 ++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 23 deletions(-)
diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c index a58ad8a..fb11210 100644 --- a/drivers/serial/serial_pl01x.c +++ b/drivers/serial/serial_pl01x.c @@ -72,8 +72,6 @@ static int pl01x_tstc(struct pl01x_regs *regs) static int pl01x_generic_serial_init(struct pl01x_regs *regs, enum pl01x_type type) { - unsigned int lcr; - #ifdef CONFIG_PL011_SERIAL_FLUSH_ON_INIT if (type == TYPE_PL011) { /* Empty RX fifo if necessary */ @@ -87,15 +85,28 @@ static int pl01x_generic_serial_init(struct pl01x_regs *regs, /* First, disable everything */ writel(0, ®s->pl010_cr);
- /* Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled */ - lcr = UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN; - writel(lcr, ®s->pl011_lcrh); - switch (type) { case TYPE_PL010: break; - case TYPE_PL011: { + case TYPE_PL011: + break; + default: + return -EINVAL; + } + + return 0; +} + +static int set_line_control(struct pl01x_regs *regs) +{ + unsigned int lcr; + /* + * Internal update of baud rate register require line + * control register write + */ + lcr = UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN; #ifdef CONFIG_PL011_SERIAL_RLCR + { int i;
/* @@ -107,22 +118,15 @@ static int pl01x_generic_serial_init(struct pl01x_regs *regs, writel(lcr, ®s->fr);
writel(lcr, ®s->pl011_rlcr); - /* lcrh needs to be set again for change to be effective */ - writel(lcr, ®s->pl011_lcrh); -#endif - break; - } - default: - return -EINVAL; } - +#endif + writel(lcr, ®s->pl011_lcrh); return 0; }
static int pl01x_generic_setbrg(struct pl01x_regs *regs, enum pl01x_type type, int clock, int baudrate) { - unsigned int lcr; switch (type) { case TYPE_PL010: { unsigned int divisor; @@ -176,13 +180,7 @@ static int pl01x_generic_setbrg(struct pl01x_regs *regs, enum pl01x_type type, writel(divider, ®s->pl011_ibrd); writel(fraction, ®s->pl011_fbrd);
- /* - * Internal update of baud rate register require line - * control register write - */ - lcr = UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN; - writel(lcr, ®s->pl011_lcrh); - + set_line_control(regs); /* Finally, enable the UART */ writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | UART_PL011_CR_RXE | UART_PL011_CR_RTS, ®s->pl011_cr);

On Fri, Nov 21, 2014 at 10:34:21AM -0800, Vikas Manocha wrote:
Receive line control uses same setting as transmit line control, also one lcrh write is effective for both baud rate & receive line control internal update.
Signed-off-by: Vikas Manocha vikas.manocha@st.com Acked-by: Simon Glass sjg@chromium.org
Applied to u-boot/master, thanks!

pl010 & pl011 have different control register offsets, setting it as per the pl01x type.
Signed-off-by: Vikas Manocha vikas.manocha@st.com Acked-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
drivers/serial/serial_pl01x.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c index fb11210..2a6b61d 100644 --- a/drivers/serial/serial_pl01x.c +++ b/drivers/serial/serial_pl01x.c @@ -82,13 +82,14 @@ static int pl01x_generic_serial_init(struct pl01x_regs *regs, } #endif
- /* First, disable everything */ - writel(0, ®s->pl010_cr); - switch (type) { case TYPE_PL010: + /* disable everything */ + writel(0, ®s->pl010_cr); break; case TYPE_PL011: + /* disable everything */ + writel(0, ®s->pl011_cr); break; default: return -EINVAL;

On Fri, Nov 21, 2014 at 10:34:22AM -0800, Vikas Manocha wrote:
pl010 & pl011 have different control register offsets, setting it as per the pl01x type.
Signed-off-by: Vikas Manocha vikas.manocha@st.com Acked-by: Simon Glass sjg@chromium.org
Applied to u-boot/master, thanks!

Signed-off-by: Vikas Manocha vikas.manocha@st.com Acked-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
drivers/serial/serial_pl01x.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c index 2a6b61d..e1bf496 100644 --- a/drivers/serial/serial_pl01x.c +++ b/drivers/serial/serial_pl01x.c @@ -72,22 +72,19 @@ static int pl01x_tstc(struct pl01x_regs *regs) static int pl01x_generic_serial_init(struct pl01x_regs *regs, enum pl01x_type type) { + switch (type) { + case TYPE_PL010: + /* disable everything */ + writel(0, ®s->pl010_cr); + break; + case TYPE_PL011: #ifdef CONFIG_PL011_SERIAL_FLUSH_ON_INIT - if (type == TYPE_PL011) { /* Empty RX fifo if necessary */ if (readl(®s->pl011_cr) & UART_PL011_CR_UARTEN) { while (!(readl(®s->fr) & UART_PL01x_FR_RXFE)) readl(®s->dr); } - } #endif - - switch (type) { - case TYPE_PL010: - /* disable everything */ - writel(0, ®s->pl010_cr); - break; - case TYPE_PL011: /* disable everything */ writel(0, ®s->pl011_cr); break;

On Fri, Nov 21, 2014 at 10:34:23AM -0800, Vikas Manocha wrote:
Signed-off-by: Vikas Manocha vikas.manocha@st.com Acked-by: Simon Glass sjg@chromium.org
Applied to u-boot/master, thanks!
participants (2)
-
Tom Rini
-
Vikas Manocha