Message ID | 20190118111820.71349-9-anup.patel@wdc.com |
---|---|
State | Superseded |
Delegated to: | Andes |
Headers | show |
Series | SiFive FU540 Support | expand |
On 18.01.19 12:19, Anup Patel wrote: > From: Atish Patra <atish.patra@wdc.com> > > Compute the baud rate multipler with more precision. > > Signed-off-by: Atish Patra <atish.patra@wdc.com> Same here. Alex
> -----Original Message----- > From: Alexander Graf [mailto:agraf@suse.de] > Sent: Friday, January 18, 2019 5:22 PM > To: Anup Patel <Anup.Patel@wdc.com>; Rick Chen <rick@andestech.com>; > Bin Meng <bmeng.cn@gmail.com>; Joe Hershberger > <joe.hershberger@ni.com>; Lukas Auer <lukas.auer@aisec.fraunhofer.de>; > Masahiro Yamada <yamada.masahiro@socionext.com>; Simon Glass > <sjg@chromium.org> > Cc: Palmer Dabbelt <palmer@sifive.com>; Paul Walmsley > <paul.walmsley@sifive.com>; Atish Patra <Atish.Patra@wdc.com>; > Christoph Hellwig <hch@infradead.org>; U-Boot Mailing List <u- > boot@lists.denx.de> > Subject: Re: [PATCH v2 08/11] drivers: serial_sifive: Fix baud rate calculation > > > > On 18.01.19 12:19, Anup Patel wrote: > > From: Atish Patra <atish.patra@wdc.com> > > > > Compute the baud rate multipler with more precision. > > > > Signed-off-by: Atish Patra <atish.patra@wdc.com> > > Same here. > > Alex Sure, I will add my SoB. Regards, Anup
On Fri, 2019-01-18 at 11:19 +0000, Anup Patel wrote: > From: Atish Patra <atish.patra@wdc.com> > > Compute the baud rate multipler with more precision. > > Signed-off-by: Atish Patra <atish.patra@wdc.com> > Reviewed-by: Alexander Graf <agraf@suse.de> > --- > drivers/serial/serial_sifive.c | 28 ++++++++++++++++++++++++++-- > 1 file changed, 26 insertions(+), 2 deletions(-) > Reviewed-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
diff --git a/drivers/serial/serial_sifive.c b/drivers/serial/serial_sifive.c index 341728a690..ea4d35d48c 100644 --- a/drivers/serial/serial_sifive.c +++ b/drivers/serial/serial_sifive.c @@ -33,16 +33,40 @@ struct uart_sifive { }; struct sifive_uart_platdata { - unsigned int clock; + unsigned long clock; int saved_input_char; struct uart_sifive *regs; }; +/** + * Find minimum divisor divides in_freq to max_target_hz; + * Based on uart driver n SiFive FSBL. + * + * f_baud = f_in / (div + 1) => div = (f_in / f_baud) - 1 + * The nearest integer solution requires rounding up as to not exceed + * max_target_hz. + * div = ceil(f_in / f_baud) - 1 + * = floor((f_in - 1 + f_baud) / f_baud) - 1 + * This should not overflow as long as (f_in - 1 + f_baud) does not exceed + * 2^32 - 1, which is unlikely since we represent frequencies in kHz. + */ +static inline unsigned int uart_min_clk_divisor(unsigned long in_freq, + unsigned long max_target_hz) +{ + unsigned long quotient = + (in_freq + max_target_hz - 1) / (max_target_hz); + /* Avoid underflow */ + if (quotient == 0) + return 0; + else + return quotient - 1; +} + /* Set up the baud rate in gd struct */ static void _sifive_serial_setbrg(struct uart_sifive *regs, unsigned long clock, unsigned long baud) { - writel((u32)((clock / baud) - 1), ®s->div); + writel((uart_min_clk_divisor(clock, baud)), ®s->div); } static void _sifive_serial_init(struct uart_sifive *regs)