]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00170212: MX6 - Implement a SW workaround for TKT065875
authorRanjani Vaidyanathan <ra5478@freescale.com>
Mon, 12 Dec 2011 18:42:58 +0000 (12:42 -0600)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 24 May 2013 06:33:39 +0000 (08:33 +0200)
Only CPU0 executes WFI followed by ISBs in uncached iRAM.
All other cores execute the regular cpu_do_idle()
This puts a restriction that all interrupts should only be routed to CPU0.
This bug should be fixed in TO1.1.

Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
arch/arm/mach-mx6/cpu.c
arch/arm/mach-mx6/mx6_wfi.S
arch/arm/mach-mx6/system.c

index bfc499328d4f93ab9dd5eca29f0d222fab66bec5..46e22f1138e4c6845edea7e81940fd4a6b5362e9 100644 (file)
@@ -33,7 +33,7 @@
 
 
 void *mx6_wait_in_iram_base;
-void (*mx6_wait_in_iram)(void *ccm_base);
+void (*mx6_wait_in_iram)();
 extern void mx6_wait(void);
 
 
index 88993f01681885e5bf9664a438fcd903718ec8c8..3c6310263b38e555cdb09736fc8ceb87077824d3 100644 (file)
  */
 ENTRY(mx6_wait)
 
-       stmfd   sp!, {r3,r4,r5,r6,r7}     @ Save registers
+       dsb
 
        wfi
 
-       /*Wait for 170ns due to L2 cache errata (TKT065875) */
-       /*System is more stable only if the wait is closer to ~380ns */
-       /* Each IO read takes about 76ns. */
-
-       ldr   r6, [r0]
-       ldr   r6, [r0, #4]
-       ldr   r6, [r0, #8]
-       ldr   r6, [r0, #0xc]
-       ldr   r6, [r0, #0x10]
-       ldr   r6, [r0, #0x14]
-       ldr   r6, [r0, #0x18]
-       ldr   r6, [r0, #0x1c]
-       ldr   r6, [r0, #0x20]
-       ldr   r6, [r0, #0x24]
-
-    /* Restore registers */
-    ldmfd sp!, {r3,r4,r5,r6,r7}
-    mov     pc, lr
+       isb
+       isb
+
+      mov     pc, lr
 
     .type   mx6_do_wait, #object
 ENTRY(mx6_do_wait)
index 69e761c004022c14acebd2a5da3b34e106b5ef84..8d8e0c747263cfee77d2c23511c2da0de44f6c83 100644 (file)
 /* static DEFINE_SPINLOCK(wfi_lock); */
 
 extern unsigned int gpc_wake_irq[4];
+extern int mx6q_revision(void);
 
 /* static unsigned int cpu_idle_mask; */
 
 static void __iomem *gpc_base = IO_ADDRESS(GPC_BASE_ADDR);
 
-extern void (*mx6_wait_in_iram)(void *ccm_base);
+extern void (*mx6_wait_in_iram)();
 extern void mx6_wait(void);
 extern void *mx6_wait_in_iram_base;
 extern bool enable_wait_mode;
@@ -143,13 +144,17 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
        __raw_writel(ccm_clpcr, MXC_CCM_CLPCR);
 }
 
-void arch_idle(void)
+ void arch_idle(void)
 {
        if (enable_wait_mode) {
                if ((num_online_cpus() == num_present_cpus())
                        && mx6_wait_in_iram != NULL) {
                        mxc_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
-                       mx6_wait_in_iram(MXC_CCM_BASE);
+                       if (smp_processor_id() == 0 &&
+                               (mx6q_revision() <= IMX_CHIP_REVISION_1_0))
+                               mx6_wait_in_iram();
+                       else
+                               cpu_do_idle();
                }
        } else
                cpu_do_idle();