[COMMON] serial: samsung: modify UART UDIVSLOT calculation method
authormyung-su.cha <myung-su.cha@samsung.com>
Wed, 21 Mar 2018 08:54:47 +0000 (17:54 +0900)
committermyung-su.cha <myung-su.cha@samsung.com>
Wed, 9 May 2018 12:14:45 +0000 (21:14 +0900)
Set UDIVSLOT to the lowest error rate.

Change-Id: I82ae10969a7048730d1d380cf6867c1d1792563a
Signed-off-by: myung-su.cha <myung-su.cha@samsung.com>
drivers/tty/serial/samsung.c

index 036500aee7aa241d675e0ab11ff6f08815e8d2b4..3a3fe28547424cee8e5cfddc0a316db3df606df7 100644 (file)
@@ -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);