diff mbox series

[U-Boot,v2,02/11] arm64: zynqmp: mp: Correct the R5 release sequence

Message ID b2e919335b54ca33cfd12e4feadb99dcf649360e.1511265659.git.michal.simek@xilinx.com
State Accepted
Delegated to: Michal Simek
Headers show
Series [U-Boot,v2,01/11] arm64: zynqmp: Remove slcr with mio status pin detection | expand

Commit Message

Michal Simek Nov. 21, 2017, noon UTC
From: Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>

This patch corrects the R5 release sequence by adding the
below steps.
1. Flush dcache to ensure that image loaded into memory.
2. Keep R5 reset just to ensure R5 in reset.
3. Disable caches before accessing TCM as with out this
   A53 can do speculative and may result in ECC failures
   if TCM's are not initialized. So, it is always better
   to disable dcaches before accessing TCM and enable back.

Signed-off-by: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Reported-by: John Linn <linnj@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

Changes in v2: None

 arch/arm/cpu/armv8/zynqmp/mp.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
diff mbox series

Patch

diff --git a/arch/arm/cpu/armv8/zynqmp/mp.c b/arch/arm/cpu/armv8/zynqmp/mp.c
index 76f889ba7d9e..3ea24b47630c 100644
--- a/arch/arm/cpu/armv8/zynqmp/mp.c
+++ b/arch/arm/cpu/armv8/zynqmp/mp.c
@@ -257,22 +257,36 @@  int cpu_release(int nr, int argc, char * const argv[])
 			boot_addr = ZYNQMP_R5_LOVEC_ADDR;
 		}
 
+		/*
+		 * Since we don't know where the user may have loaded the image
+		 * for an R5 we have to flush all the data cache to ensure
+		 * the R5 sees it.
+		 */
+		flush_dcache_all();
+
 		if (!strncmp(argv[1], "lockstep", 8)) {
 			printf("R5 lockstep mode\n");
+			set_r5_reset(LOCK);
 			set_r5_tcm_mode(LOCK);
 			set_r5_halt_mode(HALT, LOCK);
 			set_r5_start(boot_addr);
 			enable_clock_r5();
 			release_r5_reset(LOCK);
+			dcache_disable();
 			write_tcm_boot_trampoline(boot_addr_uniq);
+			dcache_enable();
 			set_r5_halt_mode(RELEASE, LOCK);
 		} else if (!strncmp(argv[1], "split", 5)) {
 			printf("R5 split mode\n");
+			set_r5_reset(SPLIT);
 			set_r5_tcm_mode(SPLIT);
 			set_r5_halt_mode(HALT, SPLIT);
+			set_r5_start(boot_addr);
 			enable_clock_r5();
 			release_r5_reset(SPLIT);
+			dcache_disable();
 			write_tcm_boot_trampoline(boot_addr_uniq);
+			dcache_enable();
 			set_r5_halt_mode(RELEASE, SPLIT);
 		} else {
 			printf("Unsupported mode\n");