[U-Boot] [PATCH] riscv : serial: use rx watermark to indicate rx data is present

Anup Patel anup at brainfault.org
Wed Jul 10 04:33:28 UTC 2019


On Tue, Jul 9, 2019 at 5:55 PM Sagar Shrikant Kadam
<sagar.kadam at sifive.com> wrote:
>
> In y-modem transfer mode, tstc/getc fail to check if there is any
> data available / received in RX FIFO, and so y-modem transfer never
> succeeds. Using receive watermark bit within ip register fixes the
> issue.
>
> This patch is based on commit c7392b7bc4e1 ("Use the RX watermark
> interrupt pending bit for TSTC") available at[1]
>
> [1] https://github.com/sifive/HiFive_U-Boot/tree/regression
>
> Signed-off-by: Sagar Shrikant Kadam <sagar.kadam at sifive.com>
> ---
>
>  drivers/serial/serial_sifive.c | 23 +++++++----------------
>  1 file changed, 7 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/serial/serial_sifive.c b/drivers/serial/serial_sifive.c
> index fdfef69..c142ccd 100644
> --- a/drivers/serial/serial_sifive.c
> +++ b/drivers/serial/serial_sifive.c
> @@ -22,6 +22,9 @@ DECLARE_GLOBAL_DATA_PTR;
>  #define UART_TXCTRL_TXEN       0x1
>  #define UART_RXCTRL_RXEN       0x1
>
> +/* IP register */
> +#define UART_IP_RXWM            0x2
> +
>  struct uart_sifive {
>         u32 txfifo;
>         u32 rxfifo;
> @@ -34,7 +37,6 @@ struct uart_sifive {
>
>  struct sifive_uart_platdata {
>         unsigned long clock;
> -       int saved_input_char;
>         struct uart_sifive *regs;
>  };
>
> @@ -94,7 +96,7 @@ static int _sifive_serial_getc(struct uart_sifive *regs)
>                 return -EAGAIN;
>         ch &= UART_RXFIFO_DATA;
>
> -       return (!ch) ? -EAGAIN : ch;
> +       return ch;
>  }
>
>  static int sifive_serial_setbrg(struct udevice *dev, int baudrate)
> @@ -133,7 +135,6 @@ static int sifive_serial_probe(struct udevice *dev)
>         if (gd->flags & GD_FLG_RELOC)
>                 return 0;
>
> -       platdata->saved_input_char = 0;
>         _sifive_serial_init(platdata->regs);
>
>         return 0;
> @@ -145,12 +146,6 @@ static int sifive_serial_getc(struct udevice *dev)
>         struct sifive_uart_platdata *platdata = dev_get_platdata(dev);
>         struct uart_sifive *regs = platdata->regs;
>
> -       if (platdata->saved_input_char > 0) {
> -               c = platdata->saved_input_char;
> -               platdata->saved_input_char = 0;
> -               return c;
> -       }
> -
>         while ((c = _sifive_serial_getc(regs)) == -EAGAIN) ;
>
>         return c;
> @@ -171,14 +166,10 @@ static int sifive_serial_pending(struct udevice *dev, bool input)
>         struct sifive_uart_platdata *platdata = dev_get_platdata(dev);
>         struct uart_sifive *regs = platdata->regs;
>
> -       if (input) {
> -               if (platdata->saved_input_char > 0)
> -                       return 1;
> -               platdata->saved_input_char = _sifive_serial_getc(regs);
> -               return (platdata->saved_input_char > 0) ? 1 : 0;
> -       } else {
> +       if (input)
> +               return (readl(&regs->ip) & UART_IP_RXWM);
> +       else
>                 return !!(readl(&regs->txfifo) & UART_TXFIFO_FULL);
> -       }
>  }
>
>  static int sifive_serial_ofdata_to_platdata(struct udevice *dev)
> --
> 2.7.4
>

Looks good to me.

Reviewed-by: Anup Patel <anup.patel at wdc.com>
Tested-by: Anup Patel <anup.patel at wdc.com>

Regards,
Anup


More information about the U-Boot mailing list