]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00179582 MX6: Bypass PLL1 during WAIT
authorRanjani Vaidyanathan <ra5478@freescale.com>
Thu, 23 Feb 2012 18:19:23 +0000 (12:19 -0600)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 24 May 2013 06:34:26 +0000 (08:34 +0200)
    When system is going to enter WAIT mode, set PLL1 to 24MHz
    so that ARM is running at 24MHz. This is a SW workaround for
    the WAIT mode issue.

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

index d71c6e2f18e1ddd7005d54b01c657059fe94a07d..38e34f9032aef9ff3f42bc3cf2ec5ca83d6cef74 100644 (file)
@@ -169,6 +169,7 @@ extern char *gp_reg_id;
 extern int epdc_enabled;
 extern void mx6_cpu_regulator_init(void);
 static int max17135_regulator_init(struct max17135 *max17135);
+extern volatile int num_cpu_idle_lock;
 
 enum sd_pad_mode {
        SD_PAD_MODE_LOW_SPEED,
@@ -1999,6 +2000,7 @@ static void __init mx6_arm2_init(void)
                spdif_pads_cnt =  ARRAY_SIZE(mx6dl_arm2_spdif_pads);
                flexcan_pads_cnt = ARRAY_SIZE(mx6dl_arm2_can_pads);
                i2c3_pads_cnt = ARRAY_SIZE(mx6dl_arm2_i2c3_pads);
+               num_cpu_idle_lock = 0xffff0000;
        }
 
        BUG_ON(!common_pads);
index 46f32b0bb43f829f74dd38b2921de2ce0169c843..7f19fd3bfb570d65b840374131589baf6355d75c 100644 (file)
@@ -138,6 +138,7 @@ static int mipi_sensor;
 static int can0_enable;
 static int uart3_en;
 static int tuner_en;
+extern volatile int num_cpu_idle_lock;
 
 static int __init uart3_enable(char *p)
 {
@@ -1317,6 +1318,7 @@ static void __init mx6_board_init(void)
                        i2c3_pads = mx6dl_i2c3_pads_rev_b;
                        i2c3_pads_cnt = ARRAY_SIZE(mx6dl_i2c3_pads_rev_b);
                }
+               num_cpu_idle_lock = 0xffff0000;
        }
 
        BUG_ON(!common_pads);
index 82fb04e391a9266b987dcaf9253321beb4a7434a..a4e06552b6d6e03363d08860a94205457f40fab2 100644 (file)
@@ -199,6 +199,8 @@ static int disable_ldb;
 
 extern char *gp_reg_id;
 extern int epdc_enabled;
+extern volatile int num_cpu_idle_lock;
+
 static int max17135_regulator_init(struct max17135 *max17135);
 
 static const struct esdhc_platform_data mx6q_sabresd_sd2_data __initconst = {
@@ -1485,9 +1487,11 @@ static void __init mx6_sabresd_board_init(void)
        if (cpu_is_mx6q())
                mxc_iomux_v3_setup_multiple_pads(mx6q_sabresd_pads,
                        ARRAY_SIZE(mx6q_sabresd_pads));
-       else if (cpu_is_mx6dl())
+       else if (cpu_is_mx6dl()) {
                mxc_iomux_v3_setup_multiple_pads(mx6dl_sabresd_pads,
                        ARRAY_SIZE(mx6dl_sabresd_pads));
+               num_cpu_idle_lock = 0xffff0000;
+       }
 
 #ifdef CONFIG_FEC_1588
        /* Set GPIO_16 input for IEEE-1588 ts_clk and RMII reference clock
index d4850657f60ce8581d5525217d881828d97f9f6b..8401026981127a5511b7ec40134cc8d10e76eb9f 100644 (file)
 #include "crm_regs.h"
 #include "cpu_op-mx6.h"
 
-
-void *mx6_wait_in_iram_base;
-void (*mx6_wait_in_iram)(void);
-extern void mx6_wait(void);
-
+extern unsigned int num_cpu_idle_lock;
 
 struct cpu_op *(*get_cpu_op)(int *op);
 bool enable_wait_mode;
@@ -128,26 +124,11 @@ static int __init post_cpu_init(void)
        reg &= ~0x1;
        __raw_writel(reg, base);
 
-       /* Allocate IRAM for WAIT code. */
-       /* Move wait routine into iRAM */
-       cpaddr = (unsigned long)iram_alloc(SZ_4K, &iram_paddr);
-       /* Need to remap the area here since we want the memory region
-                to be executable. */
-       mx6_wait_in_iram_base = __arm_ioremap(iram_paddr, SZ_4K,
-                                         MT_MEMORY_NONCACHED);
-       pr_info("cpaddr = %x wait_iram_base=%x\n",
-               (unsigned int)cpaddr, (unsigned int)mx6_wait_in_iram_base);
-
-       /*
-        * Need to run the suspend code from IRAM as the DDR needs
-        * to be put into low power mode manually.
-        */
-       memcpy((void *)cpaddr, mx6_wait, SZ_4K);
-       mx6_wait_in_iram = (void *)mx6_wait_in_iram_base;
-
        gpc_base = MX6_IO_ADDRESS(GPC_BASE_ADDR);
        ccm_base = MX6_IO_ADDRESS(CCM_BASE_ADDR);
 
+       num_cpu_idle_lock = 0x0;
+
        return 0;
 }
 postcore_initcall(post_cpu_init);
index 3c6310263b38e555cdb09736fc8ceb87077824d3..6e2972faa29300b8e05f0d4f3a7a78d40a740725 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -17,6 +17,7 @@
  */
 
 #include <linux/linkage.h>
+#include <mach/hardware.h>
 
 /*
  *  mx6_wait
  */
 ENTRY(mx6_wait)
 
+    push {r4, r5, r6}
+
+      ldr     r2, =ANATOP_BASE_ADDR
+      add   r2, r2, #PERIPBASE_VIRT
+
+    /* get the flags variables into the cache */
+       ldr     r3, [r0]
+
+    /* get CPU ID */
+    mrc     p15,0,r5,c0,c0,5
+    and     r5, r5, #0x3
+
+    mov r4,#0xff
+    strb r4,[r0,r5]
+
+    dsb
+
+    mvn r4, #0x0
+    ldr r3, [r0]
+    cmp r3, r4
+    bne DO_WFI
+
+    mov r4, #0x1
+    ldrex r3, [r1]
+    cmp r3, #0x0
+    strexeq r3, r4, [r1]
+    cmpeq r3, #0x0
+    bne DO_WFI
+
+    mov r3, #0xff
+
+    ldr     r6, =(1 << 16)
+    str     r6, [r2, #0x04]
+
+    /* dmb */
+
+    str r3, [r1]
+
+    dsb
+
+    mvn r4, #0x0
+    ldr r3, [r0]
+    cmp r3, r4
+    movne r3, #0x0
+    strne r6, [r2, #0x08]
+    strne r3, [r1]
+
+DO_WFI:
        dsb
 
        wfi
 
-       isb
-       isb
+    mov r4, #0x0
+    strb r4, [r0, r5]
+
+    dsb
+
+    ldr r3, [r1]
+    cmp r3, #0xff
+    bne DONE
+
+    mov r4, #0x0
+    ldr     r6, =(1 << 16)
+    str r6, [r2, #0x08]
+
+    mov r3, #0x0
+    str r3, [r1]
+
+DONE:
+
+    pop {r4,r5, r6}
 
-      mov     pc, lr
+    /* Restore registers */
+    mov     pc, lr
 
     .type   mx6_do_wait, #object
 ENTRY(mx6_do_wait)
index 0eb6592969ddafe93f98d465b9846ca8f02dc8ac..8210f9a93830cc9fa09ef80fea8ec285bf8b20c3 100644 (file)
@@ -49,9 +49,10 @@ extern int mx6q_revision(void);
 
 static void __iomem *gpc_base = IO_ADDRESS(GPC_BASE_ADDR);
 
-extern void (*mx6_wait_in_iram)(void);
-extern void mx6_wait(void);
-extern void *mx6_wait_in_iram_base;
+volatile unsigned int num_cpu_idle;
+volatile unsigned int num_cpu_idle_lock = 0x0;
+
+extern void mx6_wait(void *num_cpu_idle_lock, void *num_cpu_idle);
 extern bool enable_wait_mode;
 
 void gpc_set_wakeup(unsigned int irq[4])
@@ -159,14 +160,9 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
  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);
-                       if (smp_processor_id() == 0)
-                               mx6_wait_in_iram();
-                       else
-                               cpu_do_idle();
-               }
+               *((char *)(&num_cpu_idle_lock) + smp_processor_id()) = 0x0;
+               mxc_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
+               mx6_wait((void *)&num_cpu_idle_lock, (void *)&num_cpu_idle);
        } else
                cpu_do_idle();
 }