diff options
author | Dong Aisheng <aisheng.dong@nxp.com> | 2017-09-05 17:06:29 +0800 |
---|---|---|
committer | Leonard Crestez <leonard.crestez@nxp.com> | 2018-08-24 12:41:33 +0300 |
commit | 16fa278f435062d2fb50aacd67cdc9e18c9627ee (patch) | |
tree | 325567093ca9be63fe5452c6e29a665e50610179 /drivers/tty/serial | |
parent | 0e694c16661bcedf7a6759d9ad82eca337331d4d (diff) |
MLK-17491-3 serial: fsl_lpuart: lpuart32_serial_setbrg cleanup and handle error
1) Add code comments for the algorithm idea
2) code cleanups
3) Give a warn one find unacceptable baud rate difference of more
than 3%
No function level change.
Acked-by: Fugang Duan <fugang.duan@nxp.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r-- | drivers/tty/serial/fsl_lpuart.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index eb6b6f0aeae5..9da8a9acd614 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1639,21 +1639,35 @@ lpuart32_serial_setbrg(struct lpuart_port *sport, unsigned int baudrate) u32 sbr, osr, baud_diff, tmp_osr, tmp_sbr, tmp_diff, tmp; u32 clk = sport->port.uartclk; + /* + * The idea is to use the best OSR (over-sampling rate) possible. + * Note, OSR is typically hard-set to 16 in other LPUART instantiations. + * Loop to find the best OSR value possible, one that generates minimum + * baud_diff iterate through the rest of the supported values of OSR. + * + * Calculation Formula: + * Baud Rate = baud clock / ((OSR+1) × SBR) + */ baud_diff = baudrate; osr = 0; sbr = 0; + for (tmp_osr = 4; tmp_osr <= 32; tmp_osr++) { + /* calculate the temporary sbr value */ tmp_sbr = (clk / (baudrate * tmp_osr)); if (tmp_sbr == 0) tmp_sbr = 1; - /*calculate difference in actual buad w/ current values */ - tmp_diff = (clk / (tmp_osr * tmp_sbr)); - tmp_diff = tmp_diff - baudrate; + /* + * calculate the baud rate difference based on the temporary + * osr and sbr values + */ + tmp_diff = clk / (tmp_osr * tmp_sbr) - baudrate; /* select best values between sbr and sbr+1 */ - if (tmp_diff > (baudrate - (clk / (tmp_osr * (tmp_sbr + 1))))) { - tmp_diff = baudrate - (clk / (tmp_osr * (tmp_sbr + 1))); + tmp = clk / (tmp_osr * (tmp_sbr + 1)); + if (tmp_diff > (baudrate - tmp)) { + tmp_diff = baudrate - tmp; tmp_sbr++; } @@ -1667,6 +1681,11 @@ lpuart32_serial_setbrg(struct lpuart_port *sport, unsigned int baudrate) } } + /* handle buadrate outside acceptable rate */ + if (baud_diff > ((baudrate / 100) * 3)) + dev_warn(sport->port.dev, + "unacceptable baud rate difference of more than 3%%\n"); + tmp = lpuart32_read(sport->port.membase + UARTBAUD); if ((osr > 3) && (osr < 8)) |