diff mbox

[U-Boot] mx6: invalidate D-cache only when booting from USB

Message ID 1432306377-29169-1-git-send-email-vincent.stehle@freescale.com
State Rejected
Delegated to: Stefano Babic
Headers show

Commit Message

Vincent Stehlé May 22, 2015, 2:52 p.m. UTC
Add a detection at runtime of the boot from USB on i.MX6, and invalidate
the D-cache only in that case.

The USB boot detection method is taken from Freescale u-boot commit
1309b1ed78b3 ("ENGR00315499-8 Auto check if boot from usb").

This repairs u-boot when it is built with CONFIG_SKIP_LOWLEVEL_INIT
defined, and is booted from another u-boot, which booted from SD card,
for example.

Signed-off-by: Vincent Stehlé <vincent.stehle@freescale.com>
Cc: Stefano Babic <sbabic@denx.de>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Frank Li <Frank.li@freescale.com>
Cc: Nitin Garg <nitin.garg@freescale.com>
---
 arch/arm/cpu/armv7/mx6/soc.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

Comments

Vincent Stehlé May 22, 2015, 3:37 p.m. UTC | #1
On 05/22/2015 05:15 PM, Li Frank-B20596 wrote:
..
> How about second uboot save in usb mass storage device?

Hi Frank,

I cannot test but I guess this will behave the same as without the
patch, which means that it will probably not boot.

Granted, the detection method in is_boot_from_usb() is an approximation,
but it repairs one case already and should not break anything.

Best regards,

V.
Stefano Babic May 24, 2015, 7:24 a.m. UTC | #2
Hi Vincent,

On 22/05/2015 16:52, Vincent Stehlé wrote:
> Add a detection at runtime of the boot from USB on i.MX6, and invalidate
> the D-cache only in that case.
> 
> The USB boot detection method is taken from Freescale u-boot commit
> 1309b1ed78b3 ("ENGR00315499-8 Auto check if boot from usb").
> 
> This repairs u-boot when it is built with CONFIG_SKIP_LOWLEVEL_INIT
> defined, and is booted from another u-boot, which booted from SD card,
> for example.

Please help me to find the use case. I searched in all i.MX6 boards in
mainline, but none of them is setting CONFIG_SKIP_LOWLEVEL_INIT. Can you
tell me on which board there is this issue ?

> 
> Signed-off-by: Vincent Stehlé <vincent.stehle@freescale.com>
> Cc: Stefano Babic <sbabic@denx.de>
> Cc: Fabio Estevam <fabio.estevam@freescale.com>
> Cc: Frank Li <Frank.li@freescale.com>
> Cc: Nitin Garg <nitin.garg@freescale.com>
> ---
>  arch/arm/cpu/armv7/mx6/soc.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c
> index 21ef9d0..774f078 100644
> --- a/arch/arm/cpu/armv7/mx6/soc.c
> +++ b/arch/arm/cpu/armv7/mx6/soc.c
> @@ -350,6 +350,18 @@ int board_postclk_init(void)
>  	return 0;
>  }
>  
> +/*
> + * Determine if we booted from USB.
> + *
> + * We look at the USBPH0_PWD0.RXPWDRX register to determine if the USB
> + * PHY is powered on or off. If the USB PHY is turned on, we assume that
> + * the ROM booted us from USB.
> + */
> +static bool is_boot_from_usb(void)
> +{
> +	return !(readl(USB_PHY0_BASE_ADDR) & (1<<20));
> +}

This looks like a hack. I understand this can work in your case, but can
we set as general case ? You check power for PHY0, but what about if a
board is using PHY1 ?

Anyway, is it not possible to get the boot storage from the SRC ?

> +
>  #ifndef CONFIG_SYS_DCACHE_OFF
>  void enable_caches(void)
>  {
> @@ -360,7 +372,8 @@ void enable_caches(void)
>  #endif
>  
>  	/* Avoid random hang when download by usb */
> -	invalidate_dcache_all();
> +	if (is_boot_from_usb())
> +		invalidate_dcache_all();

I cannot understand well this. The correct implementation seems correct
to me. And if you have issues booting with USB, why are you changing the
behavior in all other cases *except* booting from USB, where you rely on
the current implementation invalidating the cache ?

Best regards,
Stefano Babic
Vincent Stehlé May 26, 2015, 3:16 p.m. UTC | #3
Stefano wrote:
> Please help me to find the use case. I searched in all i.MX6 boards in
> mainline, but none of them is setting CONFIG_SKIP_LOWLEVEL_INIT. Can you
> tell me on which board there is this issue ?

Hi Stefano,

Thank you for taking the time to look at this proposed patch.

You are right, this is a "non standard" use case. What I am trying to do
is to boot u-boot with u-boot on i.MX6Q Sabre SD :)

Here are more details on what I would like to do:

1. Boot "old" u-boot from SD card.
2. "old" u-boot loads "new" u-boot from network with 'dhcp' command.
3. "old" u-boot boots "new" u-boot with 'go' command.

This is not so easy to achieve, it seems. I learned that in this
peculiar use case it is necessary to set CONFIG_SKIP_LOWLEVEL_INIT when
building the "new" u-boot, as hinted by the README.

Also I found out that the call to invalidate_dcache_all() would prevent
the boot for the aforementioned use case. "protecting" the call (as done
in Freescale u-boot) "repairs" my use case, and I verified that it does
not alter the boot through USB.

(boot from USB detection code)
> This looks like a hack. I understand this can work in your case, but can
> we set as general case ? You check power for PHY0, but what about if a
> board is using PHY1 ?
> Anyway, is it not possible to get the boot storage from the SRC ?

You are right, the detection code is not perfect. This is the one I
borrowed from Freescale u-boot, though, so it is reasonably tested "in
the field".

About the phy0/phy1 distinction, I think we can boot only from OTG PHY0
so no worry.

About the SRC; I am not sure you can get the desired information from
there, as booting from USB is a ROM "fallback".

(adding a condition to cache invalidation)
> I cannot understand well this. The correct implementation seems correct
> to me. And if you have issues booting with USB, why are you changing the
> behavior in all other cases *except* booting from USB, where you rely on
> the current implementation invalidating the cache ?

In my case, it is NOT booting with USB rather, it is booting from
another u-boot. I discovered that invalidating the caches in this case
breaks the boot.

The current implementation invalidates the cache in all cases for i.MX6,
as it believes it is always booting from the ROM.

As the comments hint that invalidating the caches is necessary only when
booting from USB (from ROM), I tried to restrict a bit more the
invalidation to this "boot from USB" case. The detection is not perfect,
but it is enough to repair my use case, at least.

Best regards,

V.
diff mbox

Patch

diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c
index 21ef9d0..774f078 100644
--- a/arch/arm/cpu/armv7/mx6/soc.c
+++ b/arch/arm/cpu/armv7/mx6/soc.c
@@ -350,6 +350,18 @@  int board_postclk_init(void)
 	return 0;
 }
 
+/*
+ * Determine if we booted from USB.
+ *
+ * We look at the USBPH0_PWD0.RXPWDRX register to determine if the USB
+ * PHY is powered on or off. If the USB PHY is turned on, we assume that
+ * the ROM booted us from USB.
+ */
+static bool is_boot_from_usb(void)
+{
+	return !(readl(USB_PHY0_BASE_ADDR) & (1<<20));
+}
+
 #ifndef CONFIG_SYS_DCACHE_OFF
 void enable_caches(void)
 {
@@ -360,7 +372,8 @@  void enable_caches(void)
 #endif
 
 	/* Avoid random hang when download by usb */
-	invalidate_dcache_all();
+	if (is_boot_from_usb())
+		invalidate_dcache_all();
 
 	/* Enable D-cache. I-cache is already enabled in start.S */
 	dcache_enable();