[U-Boot] [PATCH v2] dm: core: Add option to configure an offset for the address translation

Simon Glass sjg at chromium.org
Mon Dec 14 15:59:22 CET 2015


Hi Stefan,

On 14 December 2015 at 02:20, Stefan Roese <sr at denx.de> wrote:
> Some platforms need to ability to configure an offset to the standard
> addresses extracted from the device-tree. This patch allows this by
> adding a function to DM to configure this offset (if needed).
>
> Signed-off-by: Stefan Roese <sr at denx.de>
> Cc: Simon Glass <sjg at chromium.org>
> ---
> v2:
> - Change translation_offset type from u32 to fdt_addr_t
> - Add comments to function declarations
>
>  drivers/core/device.c | 33 +++++++++++++++++++++------------
>  drivers/core/root.c   | 32 ++++++++++++++++++++++++++++++++
>  include/dm/device.h   | 21 +++++++++++++++++++++
>  3 files changed, 74 insertions(+), 12 deletions(-)

Acked-by: Simon Glass <sjg at chromium.org>

Please see a few nits below.

>
> diff --git a/drivers/core/device.c b/drivers/core/device.c
> index 758f390..41fbbc6 100644
> --- a/drivers/core/device.c
> +++ b/drivers/core/device.c
> @@ -597,22 +597,31 @@ fdt_addr_t dev_get_addr(struct udevice *dev)
>                  * Use the full-fledged translate function for complex
>                  * bus setups.
>                  */
> -               return fdt_translate_address((void *)gd->fdt_blob,
> +               addr = fdt_translate_address((void *)gd->fdt_blob,
>                                              dev->of_offset, reg);
> +       } else {
> +               /*
> +                * Use the "simple" translate function for less complex
> +                * bus setups.
> +                */
> +               addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
> +                                                       dev->parent->of_offset,
> +                                                       dev->of_offset, "reg",
> +                                                       0, NULL);
> +               if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) {
> +                       if (device_get_uclass_id(dev->parent) ==
> +                           UCLASS_SIMPLE_BUS)
> +                               addr = simple_bus_translate(dev->parent, addr);
> +               }
>         }
>
>         /*
> -        * Use the "simple" translate function for less complex
> -        * bus setups.
> -        */
> -       addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
> -                                               dev->parent->of_offset,
> -                                               dev->of_offset, "reg",
> -                                               0, NULL);
> -       if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) {
> -               if (device_get_uclass_id(dev->parent) == UCLASS_SIMPLE_BUS)
> -                       addr = simple_bus_translate(dev->parent, addr);
> -       }
> +        * Some platforms need a special address translation. Those
> +        * platforms (e.g. mvebu in SPL) can configure a translation
> +        * offset in the DM by calling dm_set_translation_offset() that
> +        * will get added to all addresses returned by dev_get_addr().
> +        */
> +       addr += dm_get_translation_offset();
>
>         return addr;
>  #else
> diff --git a/drivers/core/root.c b/drivers/core/root.c
> index e7b1f24..bbf0d72 100644
> --- a/drivers/core/root.c
> +++ b/drivers/core/root.c
> @@ -23,6 +23,10 @@
>
>  DECLARE_GLOBAL_DATA_PTR;
>
> +struct root_priv {
> +       fdt_addr_t translation_offset;

Comment for this.

> +};
> +
>  static const struct driver_info root_info = {
>         .name           = "root_driver",
>  };
> @@ -37,6 +41,33 @@ struct udevice *dm_root(void)
>         return gd->dm_root;
>  }
>
> +fdt_addr_t dm_get_translation_offset(void)
> +{
> +       struct udevice *root;
> +
> +       root = dm_root();
> +       if (root) {

This will always be non-NULL since it is not valid to call this before
driver model is running.

> +               struct root_priv *priv = dev_get_priv(root);
> +
> +               return priv->translation_offset;
> +       }
> +
> +       /* No offset as default */
> +       return 0;
> +}
> +
> +void dm_set_translation_offset(fdt_addr_t offs)
> +{
> +       struct udevice *root;
> +
> +       root = dm_root();
> +       if (root) {

Same here.

> +               struct root_priv *priv = dev_get_priv(root);
> +
> +               priv->translation_offset = offs;
> +       }
> +}
> +
>  #if defined(CONFIG_NEEDS_MANUAL_RELOC)
>  void fix_drivers(void)
>  {
> @@ -228,6 +259,7 @@ int dm_init_and_scan(bool pre_reloc_only)
>  U_BOOT_DRIVER(root_driver) = {
>         .name   = "root_driver",
>         .id     = UCLASS_ROOT,
> +       .priv_auto_alloc_size = sizeof(struct root_priv),
>  };
>
>  /* This is the root uclass */
> diff --git a/include/dm/device.h b/include/dm/device.h
> index 7fb9935..d9fc7fb 100644
> --- a/include/dm/device.h
> +++ b/include/dm/device.h
> @@ -776,4 +776,25 @@ static inline void devm_kfree(struct udevice *dev, void *ptr)
>
>  #endif /* ! CONFIG_DEVRES */
>
> +/**
> + * dm_set_translation_offset() - Set translation offset
> + * @offs: Translation offset
> + *
> + * Some platforms need a special address translation. Those
> + * platforms (e.g. mvebu in SPL) can configure a translation
> + * offset in the DM by calling this function. It will be
> + * added to all addresses returned in dev_get_addr().
> + */
> +void dm_set_translation_offset(fdt_addr_t offs);
> +
> +/**
> + * dm_get_translation_offset() - Get translation offset
> + *
> + * This function returns the translation offset that can
> + * be configured by calling dm_set_translation_offset().
> + *
> + * @return translation offset for the device address (0 as default).
> + */
> +fdt_addr_t dm_get_translation_offset(void);
> +
>  #endif
> --
> 2.6.4
>

Regards,
Simon


More information about the U-Boot mailing list