summaryrefslogtreecommitdiff
path: root/drivers/tty/serial
diff options
context:
space:
mode:
authorDong Aisheng <aisheng.dong@nxp.com>2017-09-05 17:06:29 +0800
committerLeonard Crestez <leonard.crestez@nxp.com>2018-08-24 12:41:33 +0300
commit16fa278f435062d2fb50aacd67cdc9e18c9627ee (patch)
tree325567093ca9be63fe5452c6e29a665e50610179 /drivers/tty/serial
parent0e694c16661bcedf7a6759d9ad82eca337331d4d (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.c29
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))