dm: core: Add option to configure an offset for the address translation
authorStefan Roese <sr@denx.de>
Mon, 14 Dec 2015 15:18:15 +0000 (16:18 +0100)
committerSimon Glass <sjg@chromium.org>
Tue, 12 Jan 2016 17:19:09 +0000 (10:19 -0700)
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@denx.de>
Acked-by: Simon Glass <sjg@chromium.org>
Cc: Simon Glass <sjg@chromium.org>
Fixed space before tab:
Signed-off-by: Simon Glass <sjg@chromium.org>
drivers/core/device.c
drivers/core/root.c
include/dm/device.h

index 758f39064cca9a4b288733cce1a1d8c1c00ff3ee..7a02a931edf49da80c0f4596ec5506830618b490 100644 (file)
@@ -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.
+        * 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 = 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);
-       }
+       addr += dm_get_translation_offset();
 
        return addr;
 #else
index e7b1f249682e3c6b282751f4965e2e3944fd999e..13c2713e615391e7ce2fb4194718d6b83f2fdabb 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
+struct root_priv {
+       fdt_addr_t translation_offset;  /* optional translation offset */
+};
+
 static const struct driver_info root_info = {
        .name           = "root_driver",
 };
@@ -37,6 +41,22 @@ struct udevice *dm_root(void)
        return gd->dm_root;
 }
 
+fdt_addr_t dm_get_translation_offset(void)
+{
+       struct udevice *root = dm_root();
+       struct root_priv *priv = dev_get_priv(root);
+
+       return priv->translation_offset;
+}
+
+void dm_set_translation_offset(fdt_addr_t offs)
+{
+       struct udevice *root = dm_root();
+       struct root_priv *priv = dev_get_priv(root);
+
+       priv->translation_offset = offs;
+}
+
 #if defined(CONFIG_NEEDS_MANUAL_RELOC)
 void fix_drivers(void)
 {
@@ -228,6 +248,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 */
index 7fb99356be0d8c979d44640a7013b6d6bc61f540..d9fc7fb953f0fbe3e128de855c4644b130326e27 100644 (file)
@@ -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