[U-Boot] [PATCH] dm: core: Enable optional use of fdt_translate_address()

Simon Glass sjg at chromium.org
Wed Sep 9 20:07:19 CEST 2015


+Stephen

Hi Stefan,

On Thursday, 3 September 2015, Stefan Roese <sr at denx.de> wrote:
>
> The current "simple" address translation simple_bus_translate() is not
> working on some platforms (e.g. MVEBU). As here more complex "ranges"
> properties are used in many nodes (multiple tuples etc). This patch
> enables the optional use of the common fdt_translate_address() function
> which handles this translation correctly.
>
> Signed-off-by: Stefan Roese <sr at denx.de>
> Cc: Simon Glass <sjg at chromium.org>
> Cc: Bin Meng <bmeng.cn at gmail.com>
> Cc: Marek Vasut <marex at denx.de>
> Cc: Masahiro Yamada <yamada.masahiro at socionext.com>
> ---
> v2:
> - Rework code a bit as suggested by Simon. Also added some comments
>   to make the use of the code paths more clear.


While this works I'm reluctant to commit it as is. The call to
fdt_parent_offset() is very slow.

I wonder if this code should be copied into a new file in
drivers/core/, tidied up and updated to use dev->parent?

Other options:
- Add a library to unflatten the tree - but this would not be very
useful in SPL or before relocation due to memory/speed constraints
- Add a helper to find a node parent which uses a cached tree scan to
build a table of previous nodes (or some other means to go backwards
in the tree)
- Worry about it later and go ahead with this patch
>
>
>  drivers/core/Kconfig  | 30 ++++++++++++++++++++++++++++++
>  drivers/core/device.c | 20 ++++++++++++++++++++
>  2 files changed, 50 insertions(+)
>
> diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
> index 41f4e69..15681df 100644
> --- a/drivers/core/Kconfig
> +++ b/drivers/core/Kconfig
> @@ -120,4 +120,34 @@ config SPL_SIMPLE_BUS
>           Supports the 'simple-bus' driver, which is used on some systems
>           in SPL.
>
> +config OF_TRANSLATE
> +       bool "Translate addresses using fdt_translate_address"
> +       depends on DM && OF_CONTROL
> +       default y
> +       help
> +         If this option is enabled, the reg property will be translated
> +         using the fdt_translate_address() function. This is necessary
> +         on some platforms (e.g. MVEBU) using complex "ranges"
> +         properties in many nodes. As this translation is not handled
> +         correctly in the default simple_bus_translate() function.
> +
> +         If this option is not enabled, simple_bus_translate() will be
> +         used for the address translation. This function is faster and
> +         smaller in size than fdt_translate_address().
> +
> +config SPL_OF_TRANSLATE
> +       bool "Translate addresses using fdt_translate_address"
> +       depends on SPL_DM && SPL_OF_CONTROL
> +       default n
> +       help
> +         If this option is enabled, the reg property will be translated
> +         using the fdt_translate_address() function. This is necessary
> +         on some platforms (e.g. MVEBU) using complex "ranges"
> +         properties in many nodes. As this translation is not handled
> +         correctly in the default simple_bus_translate() function.
> +
> +         If this option is not enabled, simple_bus_translate() will be
> +         used for the address translation. This function is faster and
> +         smaller in size than fdt_translate_address().
> +
>  endmenu
> diff --git a/drivers/core/device.c b/drivers/core/device.c
> index 0ccd443..c543203 100644
> --- a/drivers/core/device.c
> +++ b/drivers/core/device.c
> @@ -11,6 +11,7 @@
>
>  #include <common.h>
>  #include <fdtdec.h>
> +#include <fdt_support.h>
>  #include <malloc.h>
>  #include <dm/device.h>
>  #include <dm/device-internal.h>
> @@ -581,6 +582,25 @@ fdt_addr_t dev_get_addr(struct udevice *dev)
>  #if CONFIG_IS_ENABLED(OF_CONTROL)
>         fdt_addr_t addr;
>
> +       if (CONFIG_IS_ENABLED(OF_TRANSLATE)) {
> +               const fdt32_t *reg;
> +
> +               reg = fdt_getprop(gd->fdt_blob, dev->of_offset, "reg", NULL);
> +               if (!reg)
> +                       return FDT_ADDR_T_NONE;
> +
> +               /*
> +                * Use the full-fledged translate function for complex
> +                * bus setups.
> +                */
> +               return fdt_translate_address((void *)gd->fdt_blob,
> +                                            dev->of_offset, reg);
> +       }
> +
> +       /*
> +        * Use the "simple" translate function for less complex
> +        * bus setups.
> +        */
>         addr = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg");
>         if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) {
>                 if (device_get_uclass_id(dev->parent) == UCLASS_SIMPLE_BUS)
> --
> 2.5.1


Regards,
Simon


More information about the U-Boot mailing list