diff mbox

[U-Boot] dm: core: Add platform specific bus translation function

Message ID 566A651F.5080408@denx.de
State Changes Requested
Delegated to: Simon Glass
Headers show

Commit Message

Stefan Roese Dec. 11, 2015, 5:54 a.m. UTC
Hi Simon,

On 11.12.2015 05:45, Stefan Roese wrote:
> Hi Simon,
>
> On 10.12.2015 16:36, Simon Glass wrote:
>> Hi Stefan,
>>
>> On 9 December 2015 at 23:58, Stefan Roese <sr@denx.de> wrote:
>>> Hi Simon,
>>>
>>>
>>> On 08.12.2015 03:46, Simon Glass wrote:
>>>>
>>>> Hi Stefan,
>>>>
>>>> On 4 December 2015 at 00:45, Stefan Roese <sr@denx.de> wrote:
>>>>>
>>>>> Hi Simon,
>>>>>
>>>>> On 03.12.2015 18:21, Simon Glass wrote:
>>>>>>
>>>>>> Hi Stefan,
>>>>>>
>>>>>> On 3 December 2015 at 04:31, Stefan Roese <sr@denx.de> wrote:
>>>>>>>
>>>>>>>
>>>>>>> Hi Simon,
>>>>>>>
>>>>>>> On 02.12.2015 18:45, Simon Glass wrote:
>>>>>>>>
>>>>>>>> Hi Stefan,
>>>>>>>>
>>>>>>>> On 2 December 2015 at 10:43, Stefan Roese <sr@denx.de> wrote:
>>>>>>>>>
>>>>>>>>> Hi Simon,
>>>>>>>>>
>>>>>>>>> ( Last mail for tonight - a glass of quite nice red wine is
>>>>>>>>> waiting for me ... ;) )
>>>>>>>>>
>>>>>>>>
>>>>>>>> That's the only sad thing about me being so many hours behind.
>>>>>>>> Still I
>>>>>>>> can do the same thing with people in Asia I suppose :-)
>>>>>>>
>>>>>>>
>>>>>>> Right. I'm not sure about the wine quality in Asia though... ;)
>>>>>>>
>>>>>>>>>
>>>>>>>>> On 02.12.2015 17:53, Simon Glass wrote:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Hi Stefan,
>>>>>>>>>>
>>>>>>>>>> On 2 December 2015 at 09:00, Stefan Roese <sr@denx.de> wrote:
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Hi Simon,
>>>>>>>>>>>
>>>>>>>>>>> On 02.12.2015 16:50, Simon Glass wrote:
>>>>>>>>>>>
>>>>>>>>>>> <snip>
>>>>>>>>>>>
>>>>>>>>>>>>>> I think it would be better to make it depend on whether
>>>>>>>>>>>>>> the bit
>>>>>>>>>>>>>> is
>>>>>>>>>>>>>> flipped, rather than whether you are in SPL or not.
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> You simply can't detect if this "bit is flipped". You just
>>>>>>>>>>>>> have
>>>>>>>>>>>>> to know. This is a long lasting ugly thing on some Marvell
>>>>>>>>>>>>> patforms. Here the comment from armada-xp-gp.dts:
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Can you point me to the place in U-Boot where this bit is
>>>>>>>>>>>> flipped?
>>>>>>>>>>>> Something, somewhere has to make the change. So something
>>>>>>>>>>>> has to
>>>>>>>>>>>> know.
>>>>>>>>>>>> Before it makes the change, the range works one way.
>>>>>>>>>>>> Afterwards it
>>>>>>>>>>>> works another way.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Sure. I've mentioned this before. Its here:
>>>>>>>>>>>
>>>>>>>>>>> arch/arm/mach-mvebu/cpu.c:
>>>>>>>>>>>
>>>>>>>>>>> int arch_cpu_init(void)
>>>>>>>>>>> {
>>>>>>>>>>>              ...
>>>>>>>>>>>
>>>>>>>>>>>              /* Linux expects the internal registers to be at
>>>>>>>>>>> 0xf1000000 */
>>>>>>>>>>>              writel(SOC_REGS_PHY_BASE, INTREG_BASE_ADDR_REG);
>>>>>>>>>>>
>>>>>>>>>>> This is the line that changes the register base address. And
>>>>>>>>>>> to change it back you need to write to the new address, as the
>>>>>>>>>>> address holding this base address is also moved. Quite ugly!
>>>>>>>>>>>
>>>>>>>>>>> So its really right at the start of U-Boot proper.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> OK I see. So really we can determine which way the address
>>>>>>>>>> 'switch'
>>>>>>>>>> it. It's just a case of making the change when we are ready, and
>>>>>>>>>> keeping a record of that.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Yes. But how is the "common code" in dev_get_addr() supposed to
>>>>>>>>> know
>>>>>>>>> which version of U-Boot we are running on? This boils down to some
>>>>>>>>> callback again, or not? Or even worse the ugly #ifdef.
>>>>>>>>
>>>>>>>>
>>>>>>>> You would call a driver-model core function to select the ranges
>>>>>>>> property to prefer. Then driver model will remember this setting
>>>>>>>> and
>>>>>>>> use it.
>>>>>>>
>>>>>>>
>>>>>>> Yes. This can be done. I've taken the time to implement such a
>>>>>>> version. And attached a small patch in a hackish version, just as
>>>>>>> an RFC. As you will see, I've added the "ranges-spl" property to
>>>>>>> some of the DT nodes. And added the DM core functions to enable to
>>>>>>> usage of a different, non-standard "ranges" property name.
>>>>>>>
>>>>>>> All this is not really "clean" and will definitely break non-DM
>>>>>>> usage of fdt_support.c. Not sure where to go from here. I would
>>>>>>> still prefer my first patch version, even though I know that
>>>>>>> you don't like to add this hook / callback into the DM core code.
>>>>>>>
>>>>>>> Let me know what you think.
>>>>>>
>>>>>>
>>>>>> Actually that looks pretty good to me. I think the root uclass needs
>>>>>> to grow a private struct, where you store the ranges name. It is
>>>>>> slightly odd to have fdtdec calling back into DM, but I don't see a
>>>>>> big problem with it. The two are strongly coupled anyway. You can put
>>>>>> an #ifdef CONFIG_DM in fdtdec to solve your problem I suppose.
>>>>>
>>>>>
>>>>> Its not only fdtdec.c but also fdt_support.c that needs this callback
>>>>> into DM. And fdt_support.c is currently not coupled with DM at all.
>>>>> Making this change generic, we really need to exchange all "ranges"
>>>>> occurrences in the whole U-Boot source tree:
>>>>>
>>>>> $ git grep "\"ranges\""
>>>>> arch/powerpc/cpu/mpc85xx/portals.c:             range =
>>>>> fdt_getprop_w(blob, off, "ranges", &len);
>>>>> arch/powerpc/cpu/mpc85xx/portals.c:
>>>>> fdt_setprop_inplace(blob,
>>>>> off, "ranges", range, len);
>>>>> arch/powerpc/cpu/ppc4xx/fdt.c:  rc = fdt_find_and_setprop(blob,
>>>>> ebc_path,
>>>>> "ranges", ranges,
>>>>> arch/sparc/include/asm/prom.h:/* Element of the "ranges" vector */
>>>>> board/ifm/o2dnt2/o2dnt2.c:      prop = fdt_get_property_w(blob, off,
>>>>> "ranges", &len);
>>>>> board/ifm/o2dnt2/o2dnt2.c:              fdt_setprop(blob, off,
>>>>> "ranges",
>>>>> reg2, len);
>>>>> board/intercontrol/digsy_mtc/digsy_mtc.c:       prop =
>>>>> fdt_get_property_w(blob, off, "ranges", &len);
>>>>> board/intercontrol/digsy_mtc/digsy_mtc.c:
>>>>> fdt_setprop(blob,
>>>>> off, "ranges", reg2, len);
>>>>> board/pdm360ng/pdm360ng.c:      rc = fdt_find_and_setprop(blob,
>>>>> "/localbus", "ranges",
>>>>> board/socrates/socrates.c:      rc = fdt_find_and_setprop(blob,
>>>>> "/localbus", "ranges",
>>>>> common/fdt_support.c:   /* Normally, an absence of a "ranges" property
>>>>> means we are
>>>>> common/fdt_support.c:    * /ht nodes with no "ranges" property and
>>>>> a lot
>>>>> of perfectly
>>>>> common/fdt_support.c:    * "ranges" as equivalent to an empty "ranges"
>>>>> property which means
>>>>> common/fdt_suppord0-t.c:   return __of_translate_address(blob,
>>>>> node_offset, in_addr, "ranges");
>>>>> common/fdt_support.c:   prop = fdt_getprop(fdt, node, "ranges",
>>>>> &size);
>>>>> common/fdt_support.c: * a number of the "ranges" property array.
>>>>> common/fdt_support.c:    * The "ranges" property is an array of
>>>>> common/fdt_support.c:   ranges = fdt_getprop(fdt, node, "ranges",
>>>>> &ranges_len);
>>>>> drivers/core/Kconfig:     on some platforms (e.g. MVEBU) using complex
>>>>> "ranges"
>>>>> drivers/core/Kconfig:     on some platforms (e.g. MVEBU) using complex
>>>>> "ranges"
>>>>> drivers/core/simple-bus.c:      ret =
>>>>> fdtdec_get_int_array(gd->fdt_blob,
>>>>> dev->of_offset, "ranges",
>>>>> drivers/pci/pci-uclass.c:       prop = fdt_getprop(blob, node,
>>>>> "ranges",
>>>>> &len);
>>>>>
>>>>> So at least pci-class.c should get changes as well. This looks not
>>>>> really promising to me. So yes, this works, but I think its quite
>>>>> clumsy and generates much more code and necessary changes,
>>>>> especially to the dts files, where all the ranges properties now
>>>>> need to get duplicated.
>>>>>
>>>>>> What about the device tree mailing list. Should I send an email
>>>>>> there?
>>>>>
>>>>>
>>>>> Sure. We could try to ask about their opinion as well.
>>>>
>>>>
>>>> What about the idea of setting up an offset in device core. Is it a
>>>> simple offset?
>>>
>>>
>>> The internal registers are mapped at 0xd00x.xxxx in the SPL case. And
>>> as 0xf10x.xxxx in the main U-Boot case. So this difference can
>>> definitely be described as an offset, yes. Adding 0xdf00.0000 to
>>> all device addresses should work in the SPL case. This is what my
>>> first patch version with the platform specific device address fixup
>>> (with the weak function) does.
>>>
>>> So what do you have in mind? Is some other device offset functionality
>>> acceptable for you?
>>
>> I just mean that you could make a call to the driver model core code
>> to set up this offset, and then dev_get_addr() can handle it
>> automatically from there. A bit like the patch you sent but without
>> the device tree component. It is just the call out to board code from
>> drivers that I am not keen on.
>
> Okay. I'll try to come up with an RFC patch for this.

Please find this RFC patch attached. Its still a bit hackish, as
its on top of the current implementation. But you will get the
idea.

Is this what you had in mind? If yes, I'll gladly send a clean
patch version to the list.

Thanks,
Stefan

Comments

Simon Glass Dec. 11, 2015, 1:30 p.m. UTC | #1
HI Stefan,

On 10 December 2015 at 22:54, Stefan Roese <sr@denx.de> wrote:
>
> Hi Simon,
>
>
> On 11.12.2015 05:45, Stefan Roese wrote:
>>
>> Hi Simon,
>>
>> On 10.12.2015 16:36, Simon Glass wrote:
>>>
>>> Hi Stefan,
>>>
>>> On 9 December 2015 at 23:58, Stefan Roese <sr@denx.de> wrote:
>>>>
>>>> Hi Simon,
>>>>
>>>>
>>>> On 08.12.2015 03:46, Simon Glass wrote:
>>>>>
>>>>>
>>>>> Hi Stefan,
>>>>>
>>>>> On 4 December 2015 at 00:45, Stefan Roese <sr@denx.de> wrote:
>>>>>>
>>>>>>
>>>>>> Hi Simon,
>>>>>>
>>>>>> On 03.12.2015 18:21, Simon Glass wrote:
>>>>>>>
>>>>>>>
>>>>>>> Hi Stefan,
>>>>>>>
>>>>>>> On 3 December 2015 at 04:31, Stefan Roese <sr@denx.de> wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Hi Simon,
>>>>>>>>
>>>>>>>> On 02.12.2015 18:45, Simon Glass wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Hi Stefan,
>>>>>>>>>
>>>>>>>>> On 2 December 2015 at 10:43, Stefan Roese <sr@denx.de> wrote:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Hi Simon,
>>>>>>>>>>
>>>>>>>>>> ( Last mail for tonight - a glass of quite nice red wine is
>>>>>>>>>> waiting for me ... ;) )
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> That's the only sad thing about me being so many hours behind.
>>>>>>>>> Still I
>>>>>>>>> can do the same thing with people in Asia I suppose :-)
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Right. I'm not sure about the wine quality in Asia though... ;)
>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On 02.12.2015 17:53, Simon Glass wrote:
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Hi Stefan,
>>>>>>>>>>>
>>>>>>>>>>> On 2 December 2015 at 09:00, Stefan Roese <sr@denx.de> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Hi Simon,
>>>>>>>>>>>>
>>>>>>>>>>>> On 02.12.2015 16:50, Simon Glass wrote:
>>>>>>>>>>>>
>>>>>>>>>>>> <snip>
>>>>>>>>>>>>
>>>>>>>>>>>>>>> I think it would be better to make it depend on whether
>>>>>>>>>>>>>>> the bit
>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>> flipped, rather than whether you are in SPL or not.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> You simply can't detect if this "bit is flipped". You just
>>>>>>>>>>>>>> have
>>>>>>>>>>>>>> to know. This is a long lasting ugly thing on some Marvell
>>>>>>>>>>>>>> patforms. Here the comment from armada-xp-gp.dts:
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Can you point me to the place in U-Boot where this bit is
>>>>>>>>>>>>> flipped?
>>>>>>>>>>>>> Something, somewhere has to make the change. So something
>>>>>>>>>>>>> has to
>>>>>>>>>>>>> know.
>>>>>>>>>>>>> Before it makes the change, the range works one way.
>>>>>>>>>>>>> Afterwards it
>>>>>>>>>>>>> works another way.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Sure. I've mentioned this before. Its here:
>>>>>>>>>>>>
>>>>>>>>>>>> arch/arm/mach-mvebu/cpu.c:
>>>>>>>>>>>>
>>>>>>>>>>>> int arch_cpu_init(void)
>>>>>>>>>>>> {
>>>>>>>>>>>>              ...
>>>>>>>>>>>>
>>>>>>>>>>>>              /* Linux expects the internal registers to be at
>>>>>>>>>>>> 0xf1000000 */
>>>>>>>>>>>>              writel(SOC_REGS_PHY_BASE, INTREG_BASE_ADDR_REG);
>>>>>>>>>>>>
>>>>>>>>>>>> This is the line that changes the register base address. And
>>>>>>>>>>>> to change it back you need to write to the new address, as the
>>>>>>>>>>>> address holding this base address is also moved. Quite ugly!
>>>>>>>>>>>>
>>>>>>>>>>>> So its really right at the start of U-Boot proper.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> OK I see. So really we can determine which way the address
>>>>>>>>>>> 'switch'
>>>>>>>>>>> it. It's just a case of making the change when we are ready, and
>>>>>>>>>>> keeping a record of that.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Yes. But how is the "common code" in dev_get_addr() supposed to
>>>>>>>>>> know
>>>>>>>>>> which version of U-Boot we are running on? This boils down to some
>>>>>>>>>> callback again, or not? Or even worse the ugly #ifdef.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> You would call a driver-model core function to select the ranges
>>>>>>>>> property to prefer. Then driver model will remember this setting
>>>>>>>>> and
>>>>>>>>> use it.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Yes. This can be done. I've taken the time to implement such a
>>>>>>>> version. And attached a small patch in a hackish version, just as
>>>>>>>> an RFC. As you will see, I've added the "ranges-spl" property to
>>>>>>>> some of the DT nodes. And added the DM core functions to enable to
>>>>>>>> usage of a different, non-standard "ranges" property name.
>>>>>>>>
>>>>>>>> All this is not really "clean" and will definitely break non-DM
>>>>>>>> usage of fdt_support.c. Not sure where to go from here. I would
>>>>>>>> still prefer my first patch version, even though I know that
>>>>>>>> you don't like to add this hook / callback into the DM core code.
>>>>>>>>
>>>>>>>> Let me know what you think.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Actually that looks pretty good to me. I think the root uclass needs
>>>>>>> to grow a private struct, where you store the ranges name. It is
>>>>>>> slightly odd to have fdtdec calling back into DM, but I don't see a
>>>>>>> big problem with it. The two are strongly coupled anyway. You can put
>>>>>>> an #ifdef CONFIG_DM in fdtdec to solve your problem I suppose.
>>>>>>
>>>>>>
>>>>>>
>>>>>> Its not only fdtdec.c but also fdt_support.c that needs this callback
>>>>>> into DM. And fdt_support.c is currently not coupled with DM at all.
>>>>>> Making this change generic, we really need to exchange all "ranges"
>>>>>> occurrences in the whole U-Boot source tree:
>>>>>>
>>>>>> $ git grep "\"ranges\""
>>>>>> arch/powerpc/cpu/mpc85xx/portals.c:             range =
>>>>>> fdt_getprop_w(blob, off, "ranges", &len);
>>>>>> arch/powerpc/cpu/mpc85xx/portals.c:
>>>>>> fdt_setprop_inplace(blob,
>>>>>> off, "ranges", range, len);
>>>>>> arch/powerpc/cpu/ppc4xx/fdt.c:  rc = fdt_find_and_setprop(blob,
>>>>>> ebc_path,
>>>>>> "ranges", ranges,
>>>>>> arch/sparc/include/asm/prom.h:/* Element of the "ranges" vector */
>>>>>> board/ifm/o2dnt2/o2dnt2.c:      prop = fdt_get_property_w(blob, off,
>>>>>> "ranges", &len);
>>>>>> board/ifm/o2dnt2/o2dnt2.c:              fdt_setprop(blob, off,
>>>>>> "ranges",
>>>>>> reg2, len);
>>>>>> board/intercontrol/digsy_mtc/digsy_mtc.c:       prop =
>>>>>> fdt_get_property_w(blob, off, "ranges", &len);
>>>>>> board/intercontrol/digsy_mtc/digsy_mtc.c:
>>>>>> fdt_setprop(blob,
>>>>>> off, "ranges", reg2, len);
>>>>>> board/pdm360ng/pdm360ng.c:      rc = fdt_find_and_setprop(blob,
>>>>>> "/localbus", "ranges",
>>>>>> board/socrates/socrates.c:      rc = fdt_find_and_setprop(blob,
>>>>>> "/localbus", "ranges",
>>>>>> common/fdt_support.c:   /* Normally, an absence of a "ranges" property
>>>>>> means we are
>>>>>> common/fdt_support.c:    * /ht nodes with no "ranges" property and
>>>>>> a lot
>>>>>> of perfectly
>>>>>> common/fdt_support.c:    * "ranges" as equivalent to an empty "ranges"
>>>>>> property which means
>>>>>> common/fdt_suppord0-t.c:   return __of_translate_address(blob,
>>>>>> node_offset, in_addr, "ranges");
>>>>>> common/fdt_support.c:   prop = fdt_getprop(fdt, node, "ranges",
>>>>>> &size);
>>>>>> common/fdt_support.c: * a number of the "ranges" property array.
>>>>>> common/fdt_support.c:    * The "ranges" property is an array of
>>>>>> common/fdt_support.c:   ranges = fdt_getprop(fdt, node, "ranges",
>>>>>> &ranges_len);
>>>>>> drivers/core/Kconfig:     on some platforms (e.g. MVEBU) using complex
>>>>>> "ranges"
>>>>>> drivers/core/Kconfig:     on some platforms (e.g. MVEBU) using complex
>>>>>> "ranges"
>>>>>> drivers/core/simple-bus.c:      ret =
>>>>>> fdtdec_get_int_array(gd->fdt_blob,
>>>>>> dev->of_offset, "ranges",
>>>>>> drivers/pci/pci-uclass.c:       prop = fdt_getprop(blob, node,
>>>>>> "ranges",
>>>>>> &len);
>>>>>>
>>>>>> So at least pci-class.c should get changes as well. This looks not
>>>>>> really promising to me. So yes, this works, but I think its quite
>>>>>> clumsy and generates much more code and necessary changes,
>>>>>> especially to the dts files, where all the ranges properties now
>>>>>> need to get duplicated.
>>>>>>
>>>>>>> What about the device tree mailing list. Should I send an email
>>>>>>> there?
>>>>>>
>>>>>>
>>>>>>
>>>>>> Sure. We could try to ask about their opinion as well.
>>>>>
>>>>>
>>>>>
>>>>> What about the idea of setting up an offset in device core. Is it a
>>>>> simple offset?
>>>>
>>>>
>>>>
>>>> The internal registers are mapped at 0xd00x.xxxx in the SPL case. And
>>>> as 0xf10x.xxxx in the main U-Boot case. So this difference can
>>>> definitely be described as an offset, yes. Adding 0xdf00.0000 to
>>>> all device addresses should work in the SPL case. This is what my
>>>> first patch version with the platform specific device address fixup
>>>> (with the weak function) does.
>>>>
>>>> So what do you have in mind? Is some other device offset functionality
>>>> acceptable for you?
>>>
>>>
>>> I just mean that you could make a call to the driver model core code
>>> to set up this offset, and then dev_get_addr() can handle it
>>> automatically from there. A bit like the patch you sent but without
>>> the device tree component. It is just the call out to board code from
>>> drivers that I am not keen on.
>>
>>
>> Okay. I'll try to come up with an RFC patch for this.
>
>
> Please find this RFC patch attached. Its still a bit hackish, as
> its on top of the current implementation. But you will get the
> idea.
>
> Is this what you had in mind? If yes, I'll gladly send a clean
> patch version to the list.

Yes this looks good - the setting is maintained by driver model rather
than looked up each time with a function call. When you send the patch
can you put the offset in the uclass-private data for root, rather
than in struct udevice?

Regards,
Simon
diff mbox

Patch

From 4b2ba8c142519eff1cce6bd51720b7fd54a0f635 Mon Sep 17 00:00:00 2001
From: Stefan Roese <sr@denx.de>
Date: Fri, 11 Dec 2015 06:04:36 +0100
Subject: [PATCH RFC] dm: Add option to configure an offset for the address
 translation

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>
---
 arch/arm/mach-mvebu/spl.c |  6 ++++++
 drivers/core/device.c     |  4 ++++
 drivers/core/root.c       | 23 +++++++++++++++++++++++
 include/dm/device.h       |  4 ++++
 4 files changed, 37 insertions(+)

diff --git a/arch/arm/mach-mvebu/spl.c b/arch/arm/mach-mvebu/spl.c
index 8edb2f3..fc3f57a 100644
--- a/arch/arm/mach-mvebu/spl.c
+++ b/arch/arm/mach-mvebu/spl.c
@@ -5,6 +5,7 @@ 
  */
 
 #include <common.h>
+#include <dm.h>
 #include <debug_uart.h>
 #include <fdtdec.h>
 #include <spl.h>
@@ -60,6 +61,9 @@  void board_init_f(ulong dummy)
 		hang();
 	}
 
+	/* Use special translation offset for SPL */
+	dm_set_translation_offset(0xd0000000 - 0xf1000000);
+
 	preloader_console_init();
 
 	timer_init();
@@ -86,6 +90,7 @@  void board_init_f(ulong dummy)
 #endif
 }
 
+#if 0
 /*
  * When using DM with DT address translation, this does not work
  * with the standard fdt_translate_address() function on MVEBU
@@ -101,3 +106,4 @@  fdt_addr_t platform_translate_address(void *blob, int node_offset,
 {
 	return (addr & 0x00ffffff) | SOC_REGS_PHY_BASE;
 }
+#endif
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 27c4288..2c95516 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -625,8 +625,12 @@  fdt_addr_t dev_get_addr(struct udevice *dev)
 	 * platforms (e.g. mvebu in SPL) can provide a platform specific
 	 * translation function which is called now.
 	 */
+#if 0
 	addr = platform_translate_address((void *)gd->fdt_blob,
 					  dev->of_offset, addr);
+#else
+	addr += dm_get_translation_offset();
+#endif
 
 	return addr;
 #else
diff --git a/drivers/core/root.c b/drivers/core/root.c
index e7b1f24..218af34 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -37,6 +37,29 @@  struct udevice *dm_root(void)
 	return gd->dm_root;
 }
 
+uint32_t dm_get_translation_offset(void)
+{
+	struct udevice *root;
+
+	root = dm_root();
+	if (root) {
+		if (root->translation_offset)
+			return root->translation_offset;
+	}
+
+	/* No offset as default */
+	return 0;
+}
+
+void dm_set_translation_offset(uint32_t offs)
+{
+	struct udevice *root;
+
+	root = dm_root();
+	if (root)
+		root->translation_offset = offs;
+}
+
 #if defined(CONFIG_NEEDS_MANUAL_RELOC)
 void fix_drivers(void)
 {
diff --git a/include/dm/device.h b/include/dm/device.h
index 7fb9935..26e3258 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -105,6 +105,7 @@  struct udevice {
 #ifdef CONFIG_DEVRES
 	struct list_head devres_head;
 #endif
+	uint32_t translation_offset;
 };
 
 /* Maximum sequence number supported */
@@ -776,4 +777,7 @@  static inline void devm_kfree(struct udevice *dev, void *ptr)
 
 #endif /* ! CONFIG_DEVRES */
 
+uint32_t dm_get_translation_offset(void);
+void dm_set_translation_offset(uint32_t offs);
+
 #endif
-- 
2.6.3