From patchwork Thu Nov 19 18:38:49 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geert Uytterhoeven X-Patchwork-Id: 7660761 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 96E10BF90C for ; Thu, 19 Nov 2015 18:56:44 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C4FE620498 for ; Thu, 19 Nov 2015 18:56:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D5BC720497 for ; Thu, 19 Nov 2015 18:56:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758821AbbKSSzq (ORCPT ); Thu, 19 Nov 2015 13:55:46 -0500 Received: from michel.telenet-ops.be ([195.130.137.88]:33883 "EHLO michel.telenet-ops.be" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758783AbbKSSzn (ORCPT ); Thu, 19 Nov 2015 13:55:43 -0500 Received: from ayla.of.borg ([84.195.106.123]) by michel.telenet-ops.be with bizsmtp id jWvi1r0052fm56U06Wvibi; Thu, 19 Nov 2015 19:55:42 +0100 Received: from ramsan.of.borg ([192.168.97.29] helo=ramsan) by ayla.of.borg with esmtp (Exim 4.82) (envelope-from ) id 1ZzU6q-0004YX-Ei; Thu, 19 Nov 2015 19:39:04 +0100 Received: from geert by ramsan with local (Exim 4.82) (envelope-from ) id 1ZzU70-0000FI-VA; Thu, 19 Nov 2015 19:39:14 +0100 From: Geert Uytterhoeven To: Greg Kroah-Hartman , Simon Horman , Magnus Damm , Yoshinori Sato , Laurent Pinchart Cc: linux-serial@vger.kernel.org, linux-sh@vger.kernel.org, linux-kernel@vger.kernel.org, Geert Uytterhoeven Subject: [PATCH 10/25] serial: sh-sci: Improve bit rate error calculation for HSCIF Date: Thu, 19 Nov 2015 19:38:49 +0100 Message-Id: <1447958344-836-11-git-send-email-geert+renesas@glider.be> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1447958344-836-1-git-send-email-geert+renesas@glider.be> References: <1447958344-836-1-git-send-email-geert+renesas@glider.be> Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The algorithm to find the best parameters for the requested bit rate calculates the relative bit rate error, using "(br * b) / 1000". For small "br * b", this has two problems: - The quotient may be zero, leading to a division by zero error, - This may introduce a large rounding error. Switch from relative to absolute bit rate error calculation to fix this. The default baud rate generator values can be removed, as there will always be one set of values that gives the smallest absolute error. Print the best set of values when debugging. Signed-off-by: Geert Uytterhoeven --- drivers/tty/serial/sh-sci.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 97a0f8ef5adc55a2..f35c209afd127c02 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1867,12 +1867,13 @@ static unsigned int sci_scbrr_calc(struct sci_port *s, unsigned int bps, } /* calculate sample rate, BRR, and clock select for HSCIF */ -static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, int *brr, +static void sci_baud_calc_hscif(struct sci_port *s, unsigned int bps, + unsigned long freq, int *brr, unsigned int *srr, unsigned int *cks) { unsigned int sr, br, a, b, c; int err, recv_margin; - int min_err = 1000; /* 100% */ + int min_err = INT_MAX; int recv_max_margin = 0; /* Find the combination of sample rate and clock select with the @@ -1887,7 +1888,7 @@ static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, int *brr, b = a * bps; br = DIV_ROUND_CLOSEST(freq, b); br = clamp(br, 1U, 256U); - err = DIV_ROUND_CLOSEST(freq, (br * b) / 1000) - 1000; + err = DIV_ROUND_CLOSEST(freq, br * a) - bps; /* Calc recv margin * M: Receive margin (%) * N: Ratio of bit rate to clock (N = sampling rate) @@ -1917,13 +1918,8 @@ static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, int *brr, } } - if (min_err == 1000) { - WARN_ON(1); - /* use defaults */ - *brr = 255; - *srr = 15; - *cks = 0; - } + dev_dbg(s->port.dev, "BRR: %u%+d bps using N %u SR %u cks %u\n", bps, + min_err, *brr, *srr + 1, *cks); } static void sci_reset(struct uart_port *port) @@ -1973,7 +1969,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, baud = uart_get_baud_rate(port, termios, old, 0, max_baud); if (likely(baud && port->uartclk)) { if (s->cfg->type == PORT_HSCIF) { - sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, + sci_baud_calc_hscif(s, baud, port->uartclk, &t, &srr, &cks); } else { t = sci_scbrr_calc(s, baud, port->uartclk);