aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial
diff options
context:
space:
mode:
authorNobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>2014-07-14 03:10:00 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-07-17 21:14:44 -0400
commit730c4e782c039caf40b467c35f595c005e94220c (patch)
treeec2074519003259f85a19048702d30f01c581f0c /drivers/tty/serial
parentbcb9973a6097652a12660958449301aada41de9c (diff)
serial: sh-sci: Add calculation recive margin for HSCIF
When the error of the same bit rate is detected, we will need to select the recive margin is large. Current code holds the minimum error, it does not have to check the recive margin. This adds this calculation. Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r--drivers/tty/serial/sh-sci.c77
1 files changed, 59 insertions, 18 deletions
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 091b65587c7c..3081e46085ce 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1776,13 +1776,30 @@ static unsigned int sci_scbrr_calc(struct sci_port *s, unsigned int bps,
1776 return ((freq + 16 * bps) / (32 * bps) - 1); 1776 return ((freq + 16 * bps) / (32 * bps) - 1);
1777} 1777}
1778 1778
1779/* calculate frame length from SMR */
1780static int sci_baud_calc_frame_len(unsigned int smr_val)
1781{
1782 int len = 10;
1783
1784 if (smr_val & SCSMR_CHR)
1785 len--;
1786 if (smr_val & SCSMR_PE)
1787 len++;
1788 if (smr_val & SCSMR_STOP)
1789 len++;
1790
1791 return len;
1792}
1793
1794
1779/* calculate sample rate, BRR, and clock select for HSCIF */ 1795/* calculate sample rate, BRR, and clock select for HSCIF */
1780static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, 1796static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq,
1781 int *brr, unsigned int *srr, 1797 int *brr, unsigned int *srr,
1782 unsigned int *cks) 1798 unsigned int *cks, int frame_len)
1783{ 1799{
1784 int sr, c, br, err; 1800 int sr, c, br, err, recv_margin;
1785 int min_err = 1000; /* 100% */ 1801 int min_err = 1000; /* 100% */
1802 int recv_max_margin = 0;
1786 1803
1787 /* Find the combination of sample rate and clock select with the 1804 /* Find the combination of sample rate and clock select with the
1788 smallest deviation from the desired baud rate. */ 1805 smallest deviation from the desired baud rate. */
@@ -1795,12 +1812,35 @@ static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq,
1795 err = DIV_ROUND_CLOSEST(freq, ((br + 1) * bps * sr * 1812 err = DIV_ROUND_CLOSEST(freq, ((br + 1) * bps * sr *
1796 (1 << (2 * c + 1)) / 1000)) - 1813 (1 << (2 * c + 1)) / 1000)) -
1797 1000; 1814 1000;
1815 if (err < 0)
1816 continue;
1817
1818 /* Calc recv margin
1819 * M: Receive margin (%)
1820 * N: Ratio of bit rate to clock (N = sampling rate)
1821 * D: Clock duty (D = 0 to 1.0)
1822 * L: Frame length (L = 9 to 12)
1823 * F: Absolute value of clock frequency deviation
1824 *
1825 * M = |(0.5 - 1 / 2 * N) - ((L - 0.5) * F) -
1826 * (|D - 0.5| / N * (1 + F))|
1827 * NOTE: Usually, treat D for 0.5, F is 0 by this
1828 * calculation.
1829 */
1830 recv_margin = abs((500 -
1831 DIV_ROUND_CLOSEST(1000, sr << 1)) / 10);
1798 if (min_err > err) { 1832 if (min_err > err) {
1799 min_err = err; 1833 min_err = err;
1800 *brr = br; 1834 recv_max_margin = recv_margin;
1801 *srr = sr - 1; 1835 } else if ((min_err == err) &&
1802 *cks = c; 1836 (recv_margin > recv_max_margin))
1803 } 1837 recv_max_margin = recv_margin;
1838 else
1839 continue;
1840
1841 *brr = br;
1842 *srr = sr - 1;
1843 *cks = c;
1804 } 1844 }
1805 } 1845 }
1806 1846
@@ -1834,10 +1874,19 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
1834{ 1874{
1835 struct sci_port *s = to_sci_port(port); 1875 struct sci_port *s = to_sci_port(port);
1836 struct plat_sci_reg *reg; 1876 struct plat_sci_reg *reg;
1837 unsigned int baud, smr_val, max_baud, cks = 0; 1877 unsigned int baud, smr_val = 0, max_baud, cks = 0;
1838 int t = -1; 1878 int t = -1;
1839 unsigned int srr = 15; 1879 unsigned int srr = 15;
1840 1880
1881 if ((termios->c_cflag & CSIZE) == CS7)
1882 smr_val |= SCSMR_CHR;
1883 if (termios->c_cflag & PARENB)
1884 smr_val |= SCSMR_PE;
1885 if (termios->c_cflag & PARODD)
1886 smr_val |= SCSMR_PE | SCSMR_ODD;
1887 if (termios->c_cflag & CSTOPB)
1888 smr_val |= SCSMR_STOP;
1889
1841 /* 1890 /*
1842 * earlyprintk comes here early on with port->uartclk set to zero. 1891 * earlyprintk comes here early on with port->uartclk set to zero.
1843 * the clock framework is not up and running at this point so here 1892 * the clock framework is not up and running at this point so here
@@ -1851,8 +1900,9 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
1851 baud = uart_get_baud_rate(port, termios, old, 0, max_baud); 1900 baud = uart_get_baud_rate(port, termios, old, 0, max_baud);
1852 if (likely(baud && port->uartclk)) { 1901 if (likely(baud && port->uartclk)) {
1853 if (s->cfg->type == PORT_HSCIF) { 1902 if (s->cfg->type == PORT_HSCIF) {
1903 int frame_len = sci_baud_calc_frame_len(smr_val);
1854 sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, 1904 sci_baud_calc_hscif(baud, port->uartclk, &t, &srr,
1855 &cks); 1905 &cks, frame_len);
1856 } else { 1906 } else {
1857 t = sci_scbrr_calc(s, baud, port->uartclk); 1907 t = sci_scbrr_calc(s, baud, port->uartclk);
1858 for (cks = 0; t >= 256 && cks <= 3; cks++) 1908 for (cks = 0; t >= 256 && cks <= 3; cks++)
@@ -1864,16 +1914,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
1864 1914
1865 sci_reset(port); 1915 sci_reset(port);
1866 1916
1867 smr_val = serial_port_in(port, SCSMR) & 3; 1917 smr_val |= serial_port_in(port, SCSMR) & 3;
1868
1869 if ((termios->c_cflag & CSIZE) == CS7)
1870 smr_val |= SCSMR_CHR;
1871 if (termios->c_cflag & PARENB)
1872 smr_val |= SCSMR_PE;
1873 if (termios->c_cflag & PARODD)
1874 smr_val |= SCSMR_PE | SCSMR_ODD;
1875 if (termios->c_cflag & CSTOPB)
1876 smr_val |= SCSMR_STOP;
1877 1918
1878 uart_update_timeout(port, termios->c_cflag, baud); 1919 uart_update_timeout(port, termios->c_cflag, baud);
1879 1920