]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00221902 [MX6]Fix udelay inaccurate issue during suspend/resume
authorAnson Huang <b20788@freescale.com>
Wed, 29 Aug 2012 19:10:07 +0000 (03:10 +0800)
committerOliver Wendt <ow@karo-electronics.de>
Mon, 30 Sep 2013 12:12:53 +0000 (14:12 +0200)
When system enter suspend, we increase CPUFreq to the highest point
without update the global loops_per_jiffy, it will lead to udelay
inaccurate during the last phase of suspend/resume.

WB counter and RBC counter need at least two 32K cycles to finish,
here we add 80us for safe.

Signed-off-by: Anson Huang <b20788@freescale.com>
arch/arm/mach-mx6/system.c
arch/arm/plat-mxc/cpufreq.c

index 686c58c1e0e5d9275b4457a4aef6060f3d2138a6..800c7cc4e8bd0eef3574473945f2d552c510a10c 100644 (file)
@@ -195,7 +195,7 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
                        __raw_writel(__raw_readl(MXC_CCM_CCR) &
                                (~MXC_CCM_CCR_WB_COUNT_MASK) &
                                (~MXC_CCM_CCR_REG_BYPASS_CNT_MASK), MXC_CCM_CCR);
-                       udelay(60);
+                       udelay(80);
                        /* Reconfigurate WB and RBC counter */
                        __raw_writel(__raw_readl(MXC_CCM_CCR) |
                                (0x1 << MXC_CCM_CCR_WB_COUNT_OFFSET) |
index 6e6353abee1c8d1886f90e69f1c4837df83a6a6a..bdc89f007349206412148fca67d5c12c203b4d88 100755 (executable)
@@ -248,8 +248,11 @@ void mxc_cpufreq_suspend(void)
        pre_suspend_rate = clk_get_rate(cpu_clk);
        /*set flag and raise up cpu frequency if needed*/
        cpu_freq_suspend_in = 1;
-       if (pre_suspend_rate != (imx_freq_table[0].frequency * 1000))
+       if (pre_suspend_rate != (imx_freq_table[0].frequency * 1000)) {
                        set_cpu_freq(imx_freq_table[0].frequency * 1000);
+                       loops_per_jiffy = cpufreq_scale(loops_per_jiffy,
+                               pre_suspend_rate / 1000, imx_freq_table[0].frequency);
+       }
        cpu_freq_suspend_in = 2;
        mutex_unlock(&set_cpufreq_lock);
 
@@ -259,8 +262,11 @@ void mxc_cpufreq_resume(void)
 {
        mutex_lock(&set_cpufreq_lock);
        cpu_freq_suspend_in = 1;
-       if (clk_get_rate(cpu_clk) != pre_suspend_rate)
+       if (clk_get_rate(cpu_clk) != pre_suspend_rate) {
                set_cpu_freq(pre_suspend_rate);
+               loops_per_jiffy = cpufreq_scale(loops_per_jiffy,
+                       imx_freq_table[0].frequency, pre_suspend_rate / 1000);
+       }
        cpu_freq_suspend_in = 0;
        mutex_unlock(&set_cpufreq_lock);
 }
@@ -270,16 +276,22 @@ void mxc_cpufreq_resume(void)
 static int mxc_cpufreq_suspend(struct cpufreq_policy *policy)
 {
        pre_suspend_rate = clk_get_rate(cpu_clk);
-       if (pre_suspend_rate != (imx_freq_table[0].frequency * 1000))
+       if (pre_suspend_rate != (imx_freq_table[0].frequency * 1000)) {
                set_cpu_freq(imx_freq_table[0].frequency * 1000);
+               loops_per_jiffy = cpufreq_scale(loops_per_jiffy,
+                       pre_suspend_rate / 1000, imx_freq_table[0].frequency);
+       }
 
        return 0;
 }
 
 static int mxc_cpufreq_resume(struct cpufreq_policy *policy)
 {
-       if (clk_get_rate(cpu_clk) != pre_suspend_rate)
+       if (clk_get_rate(cpu_clk) != pre_suspend_rate) {
                set_cpu_freq(pre_suspend_rate);
+               loops_per_jiffy = cpufreq_scale(loops_per_jiffy,
+                       imx_freq_table[0].frequency, pre_suspend_rate / 1000);
+       }
        return 0;
 }
 #endif