diff mbox

[U-Boot,2/5] ls2080: Disable dcache during ddr init

Message ID 1463142095-182586-3-git-send-email-agraf@suse.de
State Superseded
Delegated to: York Sun
Headers show

Commit Message

Alexander Graf May 13, 2016, 12:21 p.m. UTC
While trying something completely different I saw the DDR probe hang on
boot reliably depending on how big my code ended up. Adding simple "nop"
instructions in my code (completely unrelated) flow made the DDR probe
work again.

So we're accessing some RAM - probably the page table - and rely on the
cache to give us a correct view of the world while DRAM gets initialized.

This patch just disables dcache while we're initializing the memory controller,
resolving all system hangs for me so far.

Signed-off-by: Alexander Graf <agraf@suse.de>

---

I guess the "real" solution would be to find out what exactly gets accessed in
such a case and then just map whatever it is into SRAM. Or maybe qixis_reset
doesn't fully reset something in the cache tolopogy and that wants to get
flushed out when we don't have ram yet? I don't know...
---
 board/freescale/ls2080a/ddr.c    | 2 ++
 board/freescale/ls2080aqds/ddr.c | 2 ++
 board/freescale/ls2080ardb/ddr.c | 2 ++
 3 files changed, 6 insertions(+)

Comments

York Sun May 13, 2016, 4:28 p.m. UTC | #1
On 05/13/2016 05:21 AM, Alexander Graf wrote:
> While trying something completely different I saw the DDR probe hang on
> boot reliably depending on how big my code ended up. Adding simple "nop"
> instructions in my code (completely unrelated) flow made the DDR probe
> work again.
> 
> So we're accessing some RAM - probably the page table - and rely on the
> cache to give us a correct view of the world while DRAM gets initialized.
> 
> This patch just disables dcache while we're initializing the memory controller,
> resolving all system hangs for me so far.
> 
> Signed-off-by: Alexander Graf <agraf@suse.de>
> 
> ---
> 
> I guess the "real" solution would be to find out what exactly gets accessed in
> such a case and then just map whatever it is into SRAM. Or maybe qixis_reset
> doesn't fully reset something in the cache tolopogy and that wants to get
> flushed out when we don't have ram yet? I don't know...
> ---
>  board/freescale/ls2080a/ddr.c    | 2 ++
>  board/freescale/ls2080aqds/ddr.c | 2 ++
>  board/freescale/ls2080ardb/ddr.c | 2 ++
>  3 files changed, 6 insertions(+)
> 
> diff --git a/board/freescale/ls2080a/ddr.c b/board/freescale/ls2080a/ddr.c
> index 1827ddc..a02aa64 100644
> --- a/board/freescale/ls2080a/ddr.c
> +++ b/board/freescale/ls2080a/ddr.c
> @@ -165,7 +165,9 @@ phys_size_t initdram(int board_type)
>  	puts("Initializing DDR....");
>  
>  	puts("using SPD\n");
> +	dcache_disable();
>  	dram_size = fsl_ddr_sdram();
> +	set_sctlr(get_sctlr() | (CR_C|CR_M));

Alex,

I can't agree with the proposed change. Having dcache has major speed boost
during initializing, especially when we run it on an emulator. As you suggested
in the note, the root cause needs to be identified. Qixis_reset has nothing to
do with cache. It is a board-level FPGA control.

York
Alexander Graf May 13, 2016, 7:43 p.m. UTC | #2
On 13.05.16 18:28, York Sun wrote:
> On 05/13/2016 05:21 AM, Alexander Graf wrote:
>> While trying something completely different I saw the DDR probe hang on
>> boot reliably depending on how big my code ended up. Adding simple "nop"
>> instructions in my code (completely unrelated) flow made the DDR probe
>> work again.
>>
>> So we're accessing some RAM - probably the page table - and rely on the
>> cache to give us a correct view of the world while DRAM gets initialized.
>>
>> This patch just disables dcache while we're initializing the memory controller,
>> resolving all system hangs for me so far.
>>
>> Signed-off-by: Alexander Graf <agraf@suse.de>
>>
>> ---
>>
>> I guess the "real" solution would be to find out what exactly gets accessed in
>> such a case and then just map whatever it is into SRAM. Or maybe qixis_reset
>> doesn't fully reset something in the cache tolopogy and that wants to get
>> flushed out when we don't have ram yet? I don't know...
>> ---
>>  board/freescale/ls2080a/ddr.c    | 2 ++
>>  board/freescale/ls2080aqds/ddr.c | 2 ++
>>  board/freescale/ls2080ardb/ddr.c | 2 ++
>>  3 files changed, 6 insertions(+)
>>
>> diff --git a/board/freescale/ls2080a/ddr.c b/board/freescale/ls2080a/ddr.c
>> index 1827ddc..a02aa64 100644
>> --- a/board/freescale/ls2080a/ddr.c
>> +++ b/board/freescale/ls2080a/ddr.c
>> @@ -165,7 +165,9 @@ phys_size_t initdram(int board_type)
>>  	puts("Initializing DDR....");
>>  
>>  	puts("using SPD\n");
>> +	dcache_disable();
>>  	dram_size = fsl_ddr_sdram();
>> +	set_sctlr(get_sctlr() | (CR_C|CR_M));
> 
> Alex,
> 
> I can't agree with the proposed change. Having dcache has major speed boost
> during initializing, especially when we run it on an emulator. As you suggested
> in the note, the root cause needs to be identified. Qixis_reset has nothing to
> do with cache. It is a board-level FPGA control.

Yes, this patch is mostly FYI. I'm more than happy to not have it
applied - FWIW it's sheer luck that my compiler happened to emit the
instructions in the right place for things to work without any of the
other patches ;). So we might as well rely on luck with the others applied.


Alex
Prabhakar Kushwaha May 18, 2016, 12:17 p.m. UTC | #3
Hi Alex,


> -----Original Message-----
> From: U-Boot [mailto:u-boot-bounces@lists.denx.de] On Behalf Of
> Alexander Graf
> Sent: Friday, May 13, 2016 5:52 PM
> To: u-boot@lists.denx.de
> Subject: [U-Boot] [PATCH 2/5] ls2080: Disable dcache during ddr init
> 
> While trying something completely different I saw the DDR probe hang on
> boot reliably depending on how big my code ended up. Adding simple "nop"
> instructions in my code (completely unrelated) flow made the DDR probe
> work again.
> 
> So we're accessing some RAM - probably the page table - and rely on the
> cache to give us a correct view of the world while DRAM gets initialized.
> 
> This patch just disables dcache while we're initializing the memory controller,
> resolving all system hangs for me so far.
> 
> Signed-off-by: Alexander Graf <agraf@suse.de>
> 

While testing Linux with your patch set, I found Linux boot crashing. 

I tried git-bisect and find out this patch is creating problem
It is very strange!!

--prabhakar


[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Linux version 4.1.8+ (prabhu_kush@OptiPlex-790) (gcc version 4.8.3 20131202 (prerelease) (crosstool-NG linaro-1.13.1-4.8-2013.12 - Linaro GCC 2013.11) ) #1 SMP PREEMPT Wed May 18 17:10:46 IST 2016
[    0.000000] CPU: AArch64 Processor [411fd071] revision 1
[    0.000000] Detected PIPT I-cache on CPU0
[    0.000000] alternatives: enabling workaround for ARM erratum 832075
[    0.000000] alternatives: enabling workaround for ARM erratum 834220
[    0.000000] earlycon: Early serial console at MMIO 0x21c0600 (options '')
[    0.000000] bootconsole [uart0] enabled
[    0.000000] Bad mode in Error handler detected, code 0xbf000000 -- SError
[    0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 4.1.8+ #1
[    0.000000] Hardware name: Freescale Layerscape 2080a RDB Board (DT)
[    0.000000] task: ffff800000b38fc0 ti: ffff800000b2c000 task.ti: ffff800000b2c000
[    0.000000] PC is at setup_arch+0x294/0x5cc
[    0.000000] LR is at setup_arch+0x290/0x5cc
[    0.000000] pc : [<ffff800000aa8610>] lr : [<ffff800000aa860c>] pstate: 000002c5
[    0.000000] sp : ffff800000b2ff30
[    0.000000] x29: ffff800000b2ff30 x28: 00000000a00000e0
[    0.000000] x27: ffff800000081210 x26: 0000000080c70000
[    0.000000] x25: 0000000080c6d000 x24: 0000000080000000
[    0.000000] x23: ffff800000b32000 x22: 0000000000000000
[    0.000000] x21: ffff800000b2ffe8 x20: ffff800000b32000
[    0.000000] x19: ffff800000080000 x18: 0000000001002222
[    0.000000] x17: 0000000000000000 x16: 0000000003010066
[    0.000000] x15: ffffffffffffffff x14: 0ffffffffffffffe
[    0.000000] x13: 0000000000000020 x12: 0000000000000008
[    0.000000] x11: 0000000000000004 x10: 0101010101010101
[    0.000000] x9 : fefefefefefefeff x8 : 7f7f7f7f7f7f7f7f
[    0.000000] x7 : 6466606f64667467 x6 : 0b1a09161f0d0265
[    0.000000] x5 : 65020d1f16091a0b x4 : 0000000000000000
[    0.000000] x3 : 36f6e736f6c65000 x2 : 0000000000000087
[    0.000000] x1 : 0000000000000000 x0 : 0000000000000001
[    0.000000]
[    0.000000] Internal error: Oops - bad mode: 0 [#1] PREEMPT SMP
[    0.000000] Modules linked in:
[    0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 4.1.8+ #1
[    0.000000] Hardware name: Freescale Layerscape 2080a RDB Board (DT)
[    0.000000] task: ffff800000b38fc0 ti: ffff800000b2c000 task.ti: ffff800000b2c000
[    0.000000] PC is at setup_arch+0x294/0x5cc
[    0.000000] LR is at setup_arch+0x290/0x5cc
[    0.000000] pc : [<ffff800000aa8610>] lr : [<ffff800000aa860c>] pstate: 000002c5
[    0.000000] sp : ffff800000b2ff30
[    0.000000] x29: ffff800000b2ff30 x28: 00000000a00000e0
[    0.000000] x27: ffff800000081210 x26: 0000000080c70000
[    0.000000] x25: 0000000080c6d000 x24: 0000000080000000
[    0.000000] x23: ffff800000b32000 x22: 0000000000000000
[    0.000000] x21: ffff800000b2ffe8 x20: ffff800000b32000
[    0.000000] x19: ffff800000080000 x18: 0000000001002222
[    0.000000] x17: 0000000000000000 x16: 0000000003010066
[    0.000000] x15: ffffffffffffffff x14: 0ffffffffffffffe
[    0.000000] x13: 0000000000000020 x12: 0000000000000008
[    0.000000] x11: 0000000000000004 x10: 0101010101010101
[    0.000000] x9 : fefefefefefefeff x8 : 7f7f7f7f7f7f7f7f
[    0.000000] x7 : 6466606f64667467 x6 : 0b1a09161f0d0265
[    0.000000] x5 : 65020d1f16091a0b x4 : 0000000000000000
[    0.000000] x3 : 36f6e736f6c65000 x2 : 0000000000000087
[    0.000000] x1 : 0000000000000000 x0 : 0000000000000001
[    0.000000]
[    0.000000] Process swapper (pid: 0, stack limit = 0xffff800000b2c020)
[    0.000000] Stack: (0xffff800000b2ff30 to 0xffff800000b30000)
[    0.000000] ff20:                                     00b2ffa0 ffff8000 00aa5684 ffff8000
[    0.000000] ff40: 00000001 00000000 00adfb20 ffff8000 9fff9000 00000000 00000000 00000000
[    0.000000] ff60: 00b32000 ffff8000 80000000 00000000 80c6d000 00000000 80c70000 00000000
[    0.000000] ff80: ffffffff ffffffff 00000000 00000000 00000080 00000000 fefefefe fefefefe
[    0.000000] ffa0: 00000000 00000000 800826a0 00000000 fff9e7c0 00000000 00000e12 00000000
[    0.000000] ffc0: 9fff9000 00000000 00000000 00000000 00000000 00000000 80000000 00000000
[    0.000000] ffe0: 00000000 00000000 00ae0348 ffff8000 00000000 00000000 00000000 00000000
[    0.000000] Call trace:
[    0.000000] [<ffff800000aa8610>] setup_arch+0x294/0x5cc
[    0.000000] [<ffff800000aa5680>] start_kernel+0x94/0x3bc
[    0.000000] Code: 940009db 94000957 97fff3e4 d50344ff (9400066f)
[    0.000000] ---[ end trace cb88537fdc8fa200 ]---
[    0.000000] Kernel panic - not syncing: Attempted to kill the idle task!
[    0.000000] ---[ end Kernel panic - not syncing: Attempted to kill the idle task!
diff mbox

Patch

diff --git a/board/freescale/ls2080a/ddr.c b/board/freescale/ls2080a/ddr.c
index 1827ddc..a02aa64 100644
--- a/board/freescale/ls2080a/ddr.c
+++ b/board/freescale/ls2080a/ddr.c
@@ -165,7 +165,9 @@  phys_size_t initdram(int board_type)
 	puts("Initializing DDR....");
 
 	puts("using SPD\n");
+	dcache_disable();
 	dram_size = fsl_ddr_sdram();
+	set_sctlr(get_sctlr() | (CR_C|CR_M));
 
 	return dram_size;
 }
diff --git a/board/freescale/ls2080aqds/ddr.c b/board/freescale/ls2080aqds/ddr.c
index fcb0366..99f4736 100644
--- a/board/freescale/ls2080aqds/ddr.c
+++ b/board/freescale/ls2080aqds/ddr.c
@@ -164,7 +164,9 @@  phys_size_t initdram(int board_type)
 #else
 	puts("Initializing DDR....using SPD\n");
 
+	dcache_disable();
 	dram_size = fsl_ddr_sdram();
+	set_sctlr(get_sctlr() | (CR_C|CR_M));
 #endif
 
 	return dram_size;
diff --git a/board/freescale/ls2080ardb/ddr.c b/board/freescale/ls2080ardb/ddr.c
index a04d21b..7160d97 100644
--- a/board/freescale/ls2080ardb/ddr.c
+++ b/board/freescale/ls2080ardb/ddr.c
@@ -164,7 +164,9 @@  phys_size_t initdram(int board_type)
 #else
 	puts("Initializing DDR....using SPD\n");
 
+	dcache_disable();
 	dram_size = fsl_ddr_sdram();
+	set_sctlr(get_sctlr() | (CR_C|CR_M));
 #endif
 
 	return dram_size;