From patchwork Mon Jul 14 07:10:00 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nobuhiro Iwamatsu X-Patchwork-Id: 4542961 Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id B63A79F295 for ; Mon, 14 Jul 2014 07:10:25 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CC85520120 for ; Mon, 14 Jul 2014 07:10:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E5E4D20117 for ; Mon, 14 Jul 2014 07:10:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753155AbaGNHKX (ORCPT ); Mon, 14 Jul 2014 03:10:23 -0400 Received: from mail-pd0-f172.google.com ([209.85.192.172]:65385 "EHLO mail-pd0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753143AbaGNHKX (ORCPT ); Mon, 14 Jul 2014 03:10:23 -0400 Received: by mail-pd0-f172.google.com with SMTP id w10so4770481pde.31 for ; Mon, 14 Jul 2014 00:10:22 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=uAIRpVixJ2Ttf+NK7TMo7GbOxLoQuqsuWxwVxALhGa4=; b=QqY7CXG68W84E2ISEIfnSfORpjiZBKxdGK9xHii7h7vZBV8jI++KmUucFilzufo3My Q4CsNsn3PMsJ7J8Ymo1ZTZ9iHROldcDM3xn3LwTEcvcmjV7ynji6fGuZxWEth7Pt/Td2 xJsyCH0mB3Lce4D/P3L9/leZVMR0kGRsIYTsLkNDFXWeNH1Yfwl+ZPgFN0SBJX3qihGI jmIrrZ/DBWRUUE7x5beWaE7vAQPLW7qUJqVuhbURfibTcqfYnCTR0oEVCq6xR5ed7ViD 8G2M5F44qmUTtZ7t9mxaBQKBvXf0ikHLWrXpWeCHrkGhcf9rE879YVYykVGowax0VbdA aNzw== X-Gm-Message-State: ALoCoQkjgtk67b4QsihzyylU59WLt+TslbgNemJufVGnyuEq3h5pERU1wzQ0oemlPt6/dAxFTJl0 X-Received: by 10.66.142.135 with SMTP id rw7mr15275827pab.71.1405321822122; Mon, 14 Jul 2014 00:10:22 -0700 (PDT) Received: from xps-iwamatsu.renesas.com (49.14.32.202.bf.2iij.net. [202.32.14.49]) by mx.google.com with ESMTPSA id gi1sm9792864pbd.15.2014.07.14.00.10.19 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 14 Jul 2014 00:10:21 -0700 (PDT) From: Nobuhiro Iwamatsu To: linux-sh@vger.kernel.org Cc: gregkh@linuxfoundation.org, linux-serial@vger.kernel.org, horms+renesas@verge.net.au, magnus.damm@gmail.com, Nobuhiro Iwamatsu Subject: [PATCH 3/3] serial: sh-sci: Add calculation recive margin for HSCIF Date: Mon, 14 Jul 2014 16:10:00 +0900 Message-Id: <1405321800-18114-3-git-send-email-nobuhiro.iwamatsu.yj@renesas.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1405321800-18114-1-git-send-email-nobuhiro.iwamatsu.yj@renesas.com> References: <1405321800-18114-1-git-send-email-nobuhiro.iwamatsu.yj@renesas.com> Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham 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 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 --- drivers/tty/serial/sh-sci.c | 77 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 59 insertions(+), 18 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 7f571a8..d879c0c 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1783,13 +1783,30 @@ static unsigned int sci_scbrr_calc(struct sci_port *s, unsigned int bps, return ((freq + 16 * bps) / (32 * bps) - 1); } +/* calculate frame length from SMR */ +static int sci_baud_calc_frame_len(unsigned int smr_val) +{ + int len = 10; + + if (smr_val & SCSMR_CHR) + len--; + if (smr_val & SCSMR_PE) + len++; + if (smr_val & SCSMR_STOP) + len++; + + return len; +} + + /* calculate sample rate, BRR, and clock select for HSCIF */ static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, int *brr, unsigned int *srr, - unsigned int *cks) + unsigned int *cks, int frame_len) { - int sr, c, br, err; + int sr, c, br, err, recv_margin; int min_err = 1000; /* 100% */ + int recv_max_margin = 0; /* Find the combination of sample rate and clock select with the smallest deviation from the desired baud rate. */ @@ -1802,12 +1819,35 @@ static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, err = DIV_ROUND_CLOSEST(freq, ((br + 1) * bps * sr * (1 << (2 * c + 1)) / 1000)) - 1000; + if (err < 0) + continue; + + /* Calc recv margin + * M: Receive margin (%) + * N: Ratio of bit rate to clock (N = sampling rate) + * D: Clock duty (D = 0 to 1.0) + * L: Frame length (L = 9 to 12) + * F: Absolute value of clock frequency deviation + * + * M = |(0.5 - 1 / 2 * N) - ((L - 0.5) * F) - + * (|D - 0.5| / N * (1 + F))| + * NOTE: Usually, treat D for 0.5, F is 0 by this + * calculation. + */ + recv_margin = abs((500 - + DIV_ROUND_CLOSEST(1000, sr << 1)) / 10); if (min_err > err) { min_err = err; - *brr = br; - *srr = sr - 1; - *cks = c; - } + recv_max_margin = recv_margin; + } else if ((min_err == err) && + (recv_margin > recv_max_margin)) + recv_max_margin = recv_margin; + else + continue; + + *brr = br; + *srr = sr - 1; + *cks = c; } } @@ -1841,10 +1881,19 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, { struct sci_port *s = to_sci_port(port); struct plat_sci_reg *reg; - unsigned int baud, smr_val, max_baud, cks = 0; + unsigned int baud, smr_val = 0, max_baud, cks = 0; int t = -1; unsigned int srr = 15; + if ((termios->c_cflag & CSIZE) == CS7) + smr_val |= SCSMR_CHR; + if (termios->c_cflag & PARENB) + smr_val |= SCSMR_PE; + if (termios->c_cflag & PARODD) + smr_val |= SCSMR_PE | SCSMR_ODD; + if (termios->c_cflag & CSTOPB) + smr_val |= SCSMR_STOP; + /* * earlyprintk comes here early on with port->uartclk set to zero. * the clock framework is not up and running at this point so here @@ -1858,8 +1907,9 @@ 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) { + int frame_len = sci_baud_calc_frame_len(smr_val); sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, - &cks); + &cks, frame_len); } else { t = sci_scbrr_calc(s, baud, port->uartclk); for (cks = 0; t >= 256 && cks <= 3; cks++) @@ -1871,16 +1921,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, sci_reset(port); - smr_val = serial_port_in(port, SCSMR) & 3; - - if ((termios->c_cflag & CSIZE) == CS7) - smr_val |= SCSMR_CHR; - if (termios->c_cflag & PARENB) - smr_val |= SCSMR_PE; - if (termios->c_cflag & PARODD) - smr_val |= SCSMR_PE | SCSMR_ODD; - if (termios->c_cflag & CSTOPB) - smr_val |= SCSMR_STOP; + smr_val |= serial_port_in(port, SCSMR) & 3; uart_update_timeout(port, termios->c_cflag, baud);