From nobody Mon Jun 15 10:19:08 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6D702C433EF for ; Fri, 29 Apr 2022 20:40:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1380977AbiD2Unw (ORCPT ); Fri, 29 Apr 2022 16:43:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34302 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1359728AbiD2Uni (ORCPT ); Fri, 29 Apr 2022 16:43:38 -0400 Received: from angie.orcam.me.uk (angie.orcam.me.uk [IPv6:2001:4190:8020::34]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 5C0B315719; Fri, 29 Apr 2022 13:40:19 -0700 (PDT) Received: by angie.orcam.me.uk (Postfix, from userid 500) id A56B192009D; Fri, 29 Apr 2022 22:40:18 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by angie.orcam.me.uk (Postfix) with ESMTP id 9F1A892009B; Fri, 29 Apr 2022 21:40:18 +0100 (BST) Date: Fri, 29 Apr 2022 21:40:18 +0100 (BST) From: "Maciej W. Rozycki" To: Greg Kroah-Hartman , Jiri Slaby , Palmer Dabbelt , Paul Walmsley cc: Damien Le Moal , linux-serial@vger.kernel.org, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/2] serial: sifive: Report actual baud base rather than fixed 115200 In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The base baud value reported is supposed to be the highest baud rate=20 that can be set for a serial port. The SiFive FU740-C000 SOC's on-chip=20 UART supports baud rates of up to 1/16 of the input clock rate, which is=20 the bus clock `tlclk'[1], often at 130MHz in the case of the HiFive=20 Unmatched board. However the sifive UART driver reports a fixed value of 115200 instead: 10010000.serial: ttySIF0 at MMIO 0x10010000 (irq =3D 1, base_baud =3D 11520= 0) is a SiFive UART v0 10011000.serial: ttySIF1 at MMIO 0x10011000 (irq =3D 2, base_baud =3D 11520= 0) is a SiFive UART v0 even though we already support setting higher baud rates, e.g.: $ tty /dev/ttySIF1 $ stty speed 230400 The baud base value is computed by the serial core by dividing the UART=20 clock recorded in `struct uart_port' by 16, which is also the minimum=20 value of the clock divider supported, so correct the baud base value=20 reported by setting the UART clock recorded to the input clock rate=20 rather than 115200: 10010000.serial: ttySIF0 at MMIO 0x10010000 (irq =3D 1, base_baud =3D 81250= 00) is a SiFive UART v0 10011000.serial: ttySIF1 at MMIO 0x10011000 (irq =3D 2, base_baud =3D 81250= 00) is a SiFive UART v0 References: [1] "SiFive FU740-C000 Manual", v1p3, SiFive, Inc., August 13, 2021,=20 Section 16.9 "Baud Rate Divisor Register (div)", pp.143-144 Signed-off-by: Maciej W. Rozycki Fixes: 1f1496a923b6 ("riscv: Fix sifive serial driver") --- drivers/tty/serial/sifive.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) linux-serial-sifive-base-baud.diff Index: linux-macro/drivers/tty/serial/sifive.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- linux-macro.orig/drivers/tty/serial/sifive.c +++ linux-macro/drivers/tty/serial/sifive.c @@ -998,7 +998,7 @@ static int sifive_serial_probe(struct pl /* Set up clock divider */ ssp->clkin_rate =3D clk_get_rate(ssp->clk); ssp->baud_rate =3D SIFIVE_DEFAULT_BAUD_RATE; - ssp->port.uartclk =3D ssp->baud_rate * 16; + ssp->port.uartclk =3D ssp->clkin_rate; __ssp_update_div(ssp); =20 platform_set_drvdata(pdev, ssp); From nobody Mon Jun 15 10:19:08 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 73BE1C433F5 for ; Fri, 29 Apr 2022 20:40:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229597AbiD2UoE (ORCPT ); Fri, 29 Apr 2022 16:44:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34642 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1380993AbiD2Uns (ORCPT ); Fri, 29 Apr 2022 16:43:48 -0400 Received: from angie.orcam.me.uk (angie.orcam.me.uk [IPv6:2001:4190:8020::34]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id DE11065404; Fri, 29 Apr 2022 13:40:26 -0700 (PDT) Received: by angie.orcam.me.uk (Postfix, from userid 500) id 1D9FD92009C; Fri, 29 Apr 2022 22:40:26 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by angie.orcam.me.uk (Postfix) with ESMTP id 169AD92009B; Fri, 29 Apr 2022 21:40:26 +0100 (BST) Date: Fri, 29 Apr 2022 21:40:26 +0100 (BST) From: "Maciej W. Rozycki" To: Greg Kroah-Hartman , Jiri Slaby , Palmer Dabbelt , Paul Walmsley cc: Damien Le Moal , linux-serial@vger.kernel.org, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/2] serial: sifive: Remove duplicate `clkin_rate' setting In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The `clkin_rate' member of `struct sifive_serial_port' now duplicates=20 `uartclk' from nested `struct uart_port', so use `uartclk' throughout=20 and remove `clkin_rate'. Signed-off-by: Maciej W. Rozycki --- drivers/tty/serial/sifive.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) linux-serial-sifive-uartclk.diff Index: linux-macro/drivers/tty/serial/sifive.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- linux-macro.orig/drivers/tty/serial/sifive.c +++ linux-macro/drivers/tty/serial/sifive.c @@ -148,7 +148,6 @@ * @port: struct uart_port embedded in this struct * @dev: struct device * * @ier: shadowed copy of the interrupt enable register - * @clkin_rate: input clock to the UART IP block. * @baud_rate: UART serial line rate (e.g., 115200 baud) * @clk: reference to this device's clock * @clk_notifier: clock rate change notifier for upstream clock changes @@ -159,7 +158,6 @@ struct sifive_serial_port { struct uart_port port; struct device *dev; unsigned char ier; - unsigned long clkin_rate; unsigned long baud_rate; struct clk *clk; struct notifier_block clk_notifier; @@ -463,7 +461,7 @@ static void __ssp_update_div(struct sifi { u16 div; =20 - div =3D DIV_ROUND_UP(ssp->clkin_rate, ssp->baud_rate) - 1; + div =3D DIV_ROUND_UP(ssp->port.uartclk, ssp->baud_rate) - 1; =20 __ssp_writel(div, SIFIVE_SERIAL_DIV_OFFS, ssp); } @@ -648,8 +646,8 @@ static int sifive_serial_clk_notifier(st udelay(DIV_ROUND_UP(12 * 1000 * 1000, ssp->baud_rate)); } =20 - if (event =3D=3D POST_RATE_CHANGE && ssp->clkin_rate !=3D cnd->new_rate) { - ssp->clkin_rate =3D cnd->new_rate; + if (event =3D=3D POST_RATE_CHANGE && ssp->port.uartclk !=3D cnd->new_rate= ) { + ssp->port.uartclk =3D cnd->new_rate; __ssp_update_div(ssp); } =20 @@ -678,7 +676,8 @@ static void sifive_serial_set_termios(st __ssp_set_stop_bits(ssp, nstop); =20 /* Set line rate */ - rate =3D uart_get_baud_rate(port, termios, old, 0, ssp->clkin_rate / 16); + rate =3D uart_get_baud_rate(port, termios, old, 0, + ssp->port.uartclk / 16); __ssp_update_baud_rate(ssp, rate); =20 spin_lock_irqsave(&ssp->port.lock, flags); @@ -996,9 +995,8 @@ static int sifive_serial_probe(struct pl } =20 /* Set up clock divider */ - ssp->clkin_rate =3D clk_get_rate(ssp->clk); + ssp->port.uartclk =3D clk_get_rate(ssp->clk); ssp->baud_rate =3D SIFIVE_DEFAULT_BAUD_RATE; - ssp->port.uartclk =3D ssp->clkin_rate; __ssp_update_div(ssp); =20 platform_set_drvdata(pdev, ssp);