[PORT FROM R2]mid_pmu: increase delay while looping for c6 write access bit check
authorIllyas Mansoor <illyas.mansoor@intel.com>
Tue, 17 Jan 2012 14:30:40 +0000 (20:00 +0530)
committerbuildbot <buildbot@intel.com>
Fri, 20 Jan 2012 16:28:56 +0000 (08:28 -0800)
BZ: 17718

Based on Continente, Christophe <christophe.continente@intel.com> initial
patch #31029, that puts infinite delay while checking c6 write access bit, the
black screen issue while charging is not seen even after 200+ hours of
running, while without the patch #31029 it is observed within 15+ hours

On this observation I'm putting this delay of upto 500usecs in
1usec granularity, while looping for c6 write access bit set,
also we wait for pm_msic bit to be set indicating that the PM_CMD processing
has started in SCU.

Based on Onkalo Samu's suggestion added c6offload bit clear in
pmu_sc_irq for s0ix command completion interrupts.

The reason for clearing c6 offload bit in pm_sc_irq is for the following:

There could be a previous s0i3 command submitted and c6offload bit might
have been set and also c6 offload write access bit is also set by SCU
but because of need_reschd() set we may skip mwait(C6), the next time
a normal C6 happens *after* pm_scu_irq P-unit may errorneously do c6
offload.

Change-Id: I0ebab3fdb97763aacee62007eb95f0f31b6fb9e2
Signed-off-by: Illyas Mansoor <illyas.mansoor@intel.com>
Reviewed-on: http://android.intel.com:8080/32177
Reviewed-by: Hogander, Jouni <jouni.hogander@intel.com>
Tested-by: Martin, LoicX <loicx.martin@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
arch/x86/platform/mfld/pmu.c

index d182b40..19a03bd 100755 (executable)
@@ -999,7 +999,7 @@ EXPORT_SYMBOL(release_scu_ready_sem);
 int mfld_s0ix_enter(int s0ix_state)
 {
        struct pmu_ss_states cur_pmsss;
-       int num_retry = 15000, ret = 0;
+       int num_retry = 500, ret = 0;
        u32 s0ix_value, ssw_val;
 
        /* check if we can acquire scu_ready_sem
@@ -1083,6 +1083,18 @@ int mfld_s0ix_enter(int s0ix_state)
        /* issue a command to SCU */
        writel(s0ix_value, &mid_pmu_cxt->pmu_reg->pm_cmd);
 
+       do {
+               if (readl(&mid_pmu_cxt->pmu_reg->pm_msic))
+                       break;
+
+               cpu_relax();
+       } while (num_retry--);
+
+       if (!num_retry && !readl(&mid_pmu_cxt->pmu_reg->pm_msic))
+               WARN(1, "%s: pm_msic not set.\n", __func__);
+
+       num_retry = 500;
+
        /* At this point we have committed an S0ix command
         * will have to wait for the SCU s0ix complete
         * intertupt to proceed further.
@@ -1095,6 +1107,8 @@ int mfld_s0ix_enter(int s0ix_state)
                        ssw_val = readl(mid_pmu_cxt->base_addr.offload_reg);
                        if ((ssw_val & C6OFFLOAD_BIT_MASK) ==  C6OFFLOAD_BIT)
                                break;
+
+                       udelay(1);
                } while (num_retry--);
 
                if (likely((ssw_val & C6OFFLOAD_BIT_MASK) ==  C6OFFLOAD_BIT))
@@ -1185,6 +1199,8 @@ static irqreturn_t pmu_sc_irq(int irq, void *ignored)
 
                mid_pmu_cxt->s0ix_entered = 0;
 
+               clear_c6offload_bit();
+
                /* S0ix case release it */
                up(&mid_pmu_cxt->scu_ready_sem);
        }