aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorGeert Uytterhoeven <geert+renesas@glider.be>2015-11-16 10:33:22 -0500
committerGeert Uytterhoeven <geert+renesas@glider.be>2015-12-17 05:18:35 -0500
commit6c51332dfc23fc7c2c58244e35d36744db202077 (patch)
tree94c4c23c9e44885410a97b7e5c690c4f3980a6c8 /drivers/tty
parent881a7489f463e59a44417ad89ecb4ea21b2b86cd (diff)
serial: sh-sci: Avoid calculating the receive margin for HSCIF
When assuming D = 0.5 and F = 0, maximizing the receive margin M is equivalent to maximizing the sample rate N. Hence there's no need to calculate the receive margin, as we can obtain the same result by iterating over all possible sample rates in reverse order, and skipping parameter sets that don't provide a lower bit rate error. Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/sh-sci.c51
1 files changed, 24 insertions, 27 deletions
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 306497ee5c32..c3a193616484 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1872,13 +1872,24 @@ static void sci_baud_calc_hscif(struct sci_port *s, unsigned int bps,
1872 unsigned int *srr, unsigned int *cks) 1872 unsigned int *srr, unsigned int *cks)
1873{ 1873{
1874 unsigned int sr, br, prediv, scrate, c; 1874 unsigned int sr, br, prediv, scrate, c;
1875 int err, recv_margin; 1875 int err, min_err = INT_MAX;
1876 int min_err = INT_MAX;
1877 int recv_max_margin = 0;
1878 1876
1879 /* Find the combination of sample rate and clock select with the 1877 /*
1880 smallest deviation from the desired baud rate. */ 1878 * Find the combination of sample rate and clock select with the
1881 for (sr = 8; sr <= 32; sr++) { 1879 * smallest deviation from the desired baud rate.
1880 * Prefer high sample rates to maximise the receive margin.
1881 *
1882 * M: Receive margin (%)
1883 * N: Ratio of bit rate to clock (N = sampling rate)
1884 * D: Clock duty (D = 0 to 1.0)
1885 * L: Frame length (L = 9 to 12)
1886 * F: Absolute value of clock frequency deviation
1887 *
1888 * M = |(0.5 - 1 / 2 * N) - ((L - 0.5) * F) -
1889 * (|D - 0.5| / N * (1 + F))|
1890 * NOTE: Usually, treat D for 0.5, F is 0 by this calculation.
1891 */
1892 for (sr = 32; sr >= 8; sr--) {
1882 for (c = 0; c <= 3; c++) { 1893 for (c = 0; c <= 3; c++) {
1883 /* integerized formulas from HSCIF documentation */ 1894 /* integerized formulas from HSCIF documentation */
1884 prediv = sr * (1 << (2 * c + 1)); 1895 prediv = sr * (1 << (2 * c + 1));
@@ -1898,36 +1909,22 @@ static void sci_baud_calc_hscif(struct sci_port *s, unsigned int bps,
1898 scrate = prediv * bps; 1909 scrate = prediv * bps;
1899 br = DIV_ROUND_CLOSEST(freq, scrate); 1910 br = DIV_ROUND_CLOSEST(freq, scrate);
1900 br = clamp(br, 1U, 256U); 1911 br = clamp(br, 1U, 256U);
1912
1901 err = DIV_ROUND_CLOSEST(freq, br * prediv) - bps; 1913 err = DIV_ROUND_CLOSEST(freq, br * prediv) - bps;
1902 /* Calc recv margin 1914 if (abs(err) >= abs(min_err))
1903 * M: Receive margin (%)
1904 * N: Ratio of bit rate to clock (N = sampling rate)
1905 * D: Clock duty (D = 0 to 1.0)
1906 * L: Frame length (L = 9 to 12)
1907 * F: Absolute value of clock frequency deviation
1908 *
1909 * M = |(0.5 - 1 / 2 * N) - ((L - 0.5) * F) -
1910 * (|D - 0.5| / N * (1 + F))|
1911 * NOTE: Usually, treat D for 0.5, F is 0 by this
1912 * calculation.
1913 */
1914 recv_margin = abs((500 -
1915 DIV_ROUND_CLOSEST(1000, sr << 1)) / 10);
1916 if (abs(min_err) > abs(err)) {
1917 min_err = err;
1918 recv_max_margin = recv_margin;
1919 } else if ((min_err == err) &&
1920 (recv_margin > recv_max_margin))
1921 recv_max_margin = recv_margin;
1922 else
1923 continue; 1915 continue;
1924 1916
1917 min_err = err;
1925 *brr = br - 1; 1918 *brr = br - 1;
1926 *srr = sr - 1; 1919 *srr = sr - 1;
1927 *cks = c; 1920 *cks = c;
1921
1922 if (!err)
1923 goto found;
1928 } 1924 }
1929 } 1925 }
1930 1926
1927found:
1931 dev_dbg(s->port.dev, "BRR: %u%+d bps using N %u SR %u cks %u\n", bps, 1928 dev_dbg(s->port.dev, "BRR: %u%+d bps using N %u SR %u cks %u\n", bps,
1932 min_err, *brr, *srr + 1, *cks); 1929 min_err, *brr, *srr + 1, *cks);
1933} 1930}