[PATCH v3 1/2] serial: zynqmp: Fetch baudrate from dtb and update

Algapally, Santosh Sagar SantoshSagar.Algapally at amd.com
Thu May 18 14:20:22 CEST 2023


Hi Simon,

Thanks,
A Santosh Sagar.

> -----Original Message-----
> From: Simon Glass <sjg at chromium.org>
> Sent: Tuesday, April 25, 2023 11:31 PM
> To: Abbarapu, Venkatesh <venkatesh.abbarapu at amd.com>
> Cc: u-boot at lists.denx.de; Simek, Michal <michal.simek at amd.com>;
> git at xilinx.com; Algapally, Santosh Sagar <SantoshSagar.Algapally at amd.com>
> Subject: Re: [PATCH v3 1/2] serial: zynqmp: Fetch baudrate from dtb and update
> 
> Caution: This message originated from an External Source. Use proper caution
> when opening attachments, clicking links, or responding.
> 
> 
> Hi Venkatesh,
> 
> On Tue, 25 Apr 2023 at 06:05, Venkatesh Yadav Abbarapu
> <venkatesh.abbarapu at amd.com> wrote:
> >
> > From: Algapally Santosh Sagar <santoshsagar.algapally at amd.com>
> >
> > The baudrate configured in .config is taken by default by serial. If
> > change of baudrate is required then the .config needs to changed and
> > u-boot recompilation is required or the u-boot environment needs to be
> > updated.
> >
> > To avoid this, support is added to fetch the baudrate directly from
> > the device tree file and update.
> > The serial, prints the log with the configured baudrate in the dtb.
> > The commit c4df0f6f315c ("arm: mvebu: Espressobin: Set default value
> > for $fdtfile env variable") is taken as reference for changing the
> > default environment variable.
> >
> > The default environment stores the default baudrate value, When
> > default baudrate and dtb baudrate are not same glitches are seen on the
> serial.
> > So, the environment also needs to be updated with the dtb baudrate to
> > avoid the glitches on the serial.
> >
> > Signed-off-by: Algapally Santosh Sagar
> > <santoshsagar.algapally at amd.com>
> > Signed-off-by: Venkatesh Yadav Abbarapu <venkatesh.abbarapu at amd.com>
> > ---
> >  drivers/serial/serial-uclass.c | 32 +++++++++++++++++++++++++++
> >  include/env_default.h          |  7 ++++--
> >  include/env_internal.h         |  2 +-
> >  include/fdtdec.h               |  8 +++++++
> >  include/serial.h               |  1 +
> >  lib/fdtdec.c                   | 40 ++++++++++++++++++++++++++++++++++
> >  6 files changed, 87 insertions(+), 3 deletions(-)
> 
> Can you please add something to doc/ for this feature?

Ok sure
> 
> >
> > diff --git a/drivers/serial/serial-uclass.c
> > b/drivers/serial/serial-uclass.c index 067fae2614..d77d3bda36 100644
> > --- a/drivers/serial/serial-uclass.c
> > +++ b/drivers/serial/serial-uclass.c
> > @@ -154,12 +154,44 @@ static void serial_find_console_or_panic(void)
> >  }
> >  #endif /* CONFIG_SERIAL_PRESENT */
> >
> > +#ifdef CONFIG_SERIAL_DT_BAUD
> 
> Please drop this #ifdef

Will drop
> 
> > +int serial_get_valid_baudrate(int baud) {
> > +       int i;
> > +
> > +       for (i = 0; i < ARRAY_SIZE(baudrate_table); ++i) {
> > +               if (baud == baudrate_table[i])
> > +                       return 0;
> > +       }
> > +
> > +       return -EINVAL;
> > +}
> > +#endif
> > +
> >  /* Called prior to relocation */
> >  int serial_init(void)
> >  {
> >  #if CONFIG_IS_ENABLED(SERIAL_PRESENT)
> >         serial_find_console_or_panic();
> >         gd->flags |= GD_FLG_SERIAL_READY;
> > +#ifdef CONFIG_SERIAL_DT_BAUD
> 
> if (IS_ENABLED(CONFIG_SERIAL_DT_BAUD)

On using this 
 if (IS_ENABLED(CONFIG_SERIAL_DT_BAUD))
The variables declared below are getting compiled and the below warning is thrown. So, not changing this. 

drivers/serial/serial-uclass.c: In function 'serial_init':
drivers/serial/serial-uclass.c:189:21: warning: initialization discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
  189 |         char *ptr = &default_environment[0];

> 
> You also should add a Kconfig option. I suggest naming it OF_SERIAL_BOARD
> since we typically put an OF_ prefix on such options.
> 

Will change SERIAL_DT_BAUD to OF_SERIAL_DT_BAUD

> > +       int ret = 0;
> > +       char *ptr = &default_environment[0];
> > +
> > +       /*
> > +        * Fetch the baudrate from the dtb and update the value in the
> > +        * default environment.
> > +        */
> > +       ret = fdtdec_get_baud_from_dtb(gd->fdt_blob);
> > +       if (ret != -EINVAL && ret != -EFAULT) {
> > +               gd->baudrate = ret;
> > +
> > +               while (*ptr != '\0' && *(ptr + 1) != '\0')
> > +                       ptr++;
> > +               ptr += 2;
> > +               sprintf(ptr, "baudrate=%d", gd->baudrate);
> > +       }
> > +#endif
> >         serial_setbrg();
> >  #endif
> >
> > diff --git a/include/env_default.h b/include/env_default.h index
> > c0df39d62f..4f286ffc9e 100644
> > --- a/include/env_default.h
> > +++ b/include/env_default.h
> > @@ -23,7 +23,7 @@ env_t embedded_environment
> __UBOOT_ENV_SECTION__(environment) = {
> >         {
> >  #elif defined(DEFAULT_ENV_INSTANCE_STATIC)
> >  static char default_environment[] = { -#elif
> > defined(DEFAULT_ENV_IS_RW)
> > +#elif defined(CONFIG_DEFAULT_ENV_IS_RW)
> >  char default_environment[] = {
> >  #else
> >  const char default_environment[] = {
> > @@ -44,7 +44,7 @@ const char default_environment[] = {  #if
> > defined(CONFIG_BOOTDELAY)
> >         "bootdelay="    __stringify(CONFIG_BOOTDELAY)   "\0"
> >  #endif
> > -#if defined(CONFIG_BAUDRATE) && (CONFIG_BAUDRATE >= 0)
> > +#if !defined(CONFIG_SERIAL_DT_BAUD) && defined(CONFIG_BAUDRATE) &&
> > +(CONFIG_BAUDRATE >= 0)
> >         "baudrate="     __stringify(CONFIG_BAUDRATE)    "\0"
> >  #endif
> >  #ifdef CONFIG_LOADS_ECHO
> > @@ -120,6 +120,9 @@ const char default_environment[] = {  #endif
> > #ifdef CFG_EXTRA_ENV_SETTINGS
> >         CFG_EXTRA_ENV_SETTINGS
> > +#endif
> > +#ifdef CONFIG_SERIAL_DT_BAUD
> > +       "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
> 
> What is this for?

The padding is needed at the end of default environment for baudrate when environment is writable.

> 
> >  #endif
> >         "\0"
> >  #else /* CONFIG_USE_DEFAULT_ENV_FILE */ diff --git
> > a/include/env_internal.h b/include/env_internal.h index
> > 6a69494646..fcb464263f 100644
> > --- a/include/env_internal.h
> > +++ b/include/env_internal.h
> > @@ -89,7 +89,7 @@ typedef struct environment_s {  extern env_t
> > embedded_environment;  #endif /* ENV_IS_EMBEDDED */
> >
> > -#ifdef DEFAULT_ENV_IS_RW
> > +#ifdef CONFIG_DEFAULT_ENV_IS_RW
> 
> What is this change for?

This is done as DEFAULT_ENV_IS_RW is moved to Kconfig.
> 
> >  extern char default_environment[];
> >  #else
> >  extern const char default_environment[]; diff --git
> > a/include/fdtdec.h b/include/fdtdec.h index aa61a0fca1..48937a7a46
> > 100644
> > --- a/include/fdtdec.h
> > +++ b/include/fdtdec.h
> > @@ -657,6 +657,14 @@ int fdtdec_get_alias_seq(const void *blob, const char
> *base, int node,
> >   */
> >  int fdtdec_get_alias_highest_id(const void *blob, const char *base);
> 
> Could you make this an ofnode_...() function instead? Then you can call
> ofnode_read_chosen_string() from your function.
> 
> We are trying to drop the fdtdec API.

Will change

> 
> >
> > +/**
> > + * Get baudrate from the dtb
> > + *
> > + * @param blob         Device tree blob (if NULL, then error is returned)
> > + * @return Baud rate value, or -ve error .
> 
> Return: Baud ...
> 
> (we changed to that syntax to work with Sphinx)
> 
> But this should become ofnode_read_baud(void)
> 
> Exported functions should be documented in the header file, not the C file
> 
Will do

> > + */
> > +int fdtdec_get_baud_from_dtb(const void *blob);
> > +
> >  /**
> >   * Get a property from the /chosen node
> >   *
> > diff --git a/include/serial.h b/include/serial.h index
> > 42bdf3759c..48834b517c 100644
> > --- a/include/serial.h
> > +++ b/include/serial.h
> > @@ -337,6 +337,7 @@ int serial_setconfig(struct udevice *dev, uint config);
> >   */
> >  int serial_getinfo(struct udevice *dev, struct serial_device_info
> > *info);
> >
> > +int serial_get_valid_baudrate(int baud);
> 
> check_valid_baudrate() would be better since it is checking the provided rate,
> not returning a valid rate (as I understand it).
> 
> This needs function docs

Ok sure 

> >  void atmel_serial_initialize(void);
> >  void mcf_serial_initialize(void);
> >  void mpc85xx_serial_initialize(void); diff --git a/lib/fdtdec.c
> > b/lib/fdtdec.c index 0827e16859..2fcc12148e 100644
> > --- a/lib/fdtdec.c
> > +++ b/lib/fdtdec.c
> > @@ -570,6 +570,46 @@ int fdtdec_get_alias_highest_id(const void *blob,
> const char *base)
> >         return max;
> >  }
> >
> > +#ifdef CONFIG_SERIAL_DT_BAUD
> > +int fdtdec_get_baud_from_dtb(const void *blob) {
> > +       const char *str, *p, *baud_start;
> > +       u32 baud;
> > +
> > +       if (!blob)
> > +               return -EFAULT;
> > +
> > +       str = fdtdec_get_chosen_prop(blob, "stdout-path");
> > +       if (!str)
> > +               return -EINVAL;
> > +
> > +       p = strchr(str, ':');
> > +       if (!p)
> > +               return -EINVAL;
> > +
> > +       baud = 0;
> > +       baud_start = p + 1;
> 
> It would help to have a comment about the format you are parsing, e.g.
> an example string.
> 
> I thought it was something like: "serial0:115200n8" in which case I think you
> could do:
> 
> p = strchr(str, ':')
> if (p) {
>    uint baud = dectoul(p + 1, NULL);
> 
>    ...
> 
> }

Will do

> > +       while (*baud_start != '\0') {
> > +               /*
> > +                * Uart binding is <baud>{<parity>{<bits>{...}}}
> > +                * So the baudrate either is the whole string, or
> > +                * ends in the parity characters.
> > +                */
> > +               if (*baud_start == 'n' || *baud_start == 'o' ||
> > +                   *baud_start == 'e')
> > +                       break;
> > +
> > +               baud = baud * 10 + (*baud_start - '0');
> > +               baud_start++;
> > +       }
> > +
> > +       if (serial_get_valid_baudrate(baud) == -EINVAL)
> > +               return -EINVAL;
> 
> ret = func ...
> if (ret)
>    return ret
> 
> (i.e. don't change the error number, and catch all errors that it might return)
>

Ok sure
 
> > +
> > +       return baud;
> > +}
> > +#endif
> > +
> >  const char *fdtdec_get_chosen_prop(const void *blob, const char
> > *name)  {
> >         int chosen_node;
> > --
> > 2.17.1
> >
> 
> Regards,
> Simon

Will do the changes and send v4


More information about the U-Boot mailing list