From e58d2cc3dd2a785b3d36069ae11d4b28b5b620f2 Mon Sep 17 00:00:00 2001 From: "myung-su.cha" Date: Wed, 21 Mar 2018 17:54:47 +0900 Subject: [PATCH] [COMMON] serial: samsung: modify UART UDIVSLOT calculation method Set UDIVSLOT to the lowest error rate. Change-Id: I82ae10969a7048730d1d380cf6867c1d1792563a Signed-off-by: myung-su.cha --- drivers/tty/serial/samsung.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 036500aee7aa..3a3fe2854742 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -911,6 +911,8 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, unsigned int ulcon; unsigned int umcon; unsigned int udivslot = 0; + unsigned int real_baud_rd, real_baud_ru = 0; + int calc_deviation_rd, calc_deviation_ru = 0; /* * We don't support modem control lines. @@ -938,6 +940,27 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, if (ourport->info->has_divslot) { unsigned int div = ourport->baudclk_rate / baud; + /* + * Find udivslot of the lowest error rate + * + * udivslot cannot be round-up to 0 because quot is fixed + */ + if((div & 15) != 15) { + real_baud_rd = ourport->baudclk_rate / div; + real_baud_ru = ourport->baudclk_rate / (div + 1); + + calc_deviation_rd = baud - real_baud_rd; + calc_deviation_ru = baud - real_baud_ru; + + if(calc_deviation_rd < 0) + calc_deviation_rd = -calc_deviation_rd; + if(calc_deviation_ru < 0) + calc_deviation_ru = -calc_deviation_ru; + + if(calc_deviation_rd > calc_deviation_ru) + div = div + 1; + } + if (cfg->has_fracval) { udivslot = (div & 15); dbg("fracval = %04x\n", udivslot); -- 2.20.1