diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/idle/mrst_s0i3.c | 29 | ||||
-rw-r--r-- | drivers/idle/mrst_s0i3.h | 2 | ||||
-rw-r--r-- | drivers/idle/mrst_s0i3_asm.S | 7 |
3 files changed, 21 insertions, 17 deletions
diff --git a/drivers/idle/mrst_s0i3.c b/drivers/idle/mrst_s0i3.c index 6bd9f37659f..a5a350e4c11 100644 --- a/drivers/idle/mrst_s0i3.c +++ b/drivers/idle/mrst_s0i3.c @@ -217,6 +217,16 @@ static void s0i3_poke_other_cpu(void) #define SUB_SYS_D0I2_VALUE 0x00aaaaaa #define WAKE_ENABLE_VALUE 0x0786 /* 0x4786? */ #define SUSPEND_GFX 0xc +#define PM_S0I3_COMMAND \ + ((0 << 31) | /* Reserved */ \ + (0 << 30) | /* Core must be idle */ \ + (0xc2 << 22) | /* ACK C6 trigger */ \ + (3 << 19) | /* Trigger on DMI message */ \ + (3 << 16) | /* Enter S0i3 */ \ + (0 << 13) | /* Numeric mode ID (sw) */ \ + (3 << 9) | /* Trigger mode */ \ + (0 << 8) | /* Do not interrupt */ \ + (1 << 0)) /* Set configuration */ static void s0i3_wait_for_pmu(void) { @@ -224,28 +234,19 @@ static void s0i3_wait_for_pmu(void) cpu_relax(); } -static void s0i3_prep_pmu(void) +noinline static void s0i3_prep_pmu(void) { s0i3_wait_for_pmu(); + /* Clear any possible error conditions */ + writel(0x300, &pmu_reg->pm_ics); + /* Program the wakeup */ writel(WAKE_ENABLE_VALUE, &pmu_reg->pm_wkc[0]); writel(AUTO_CLK_GATE_VALUE, &pmu_reg->pm_wssc[0]); /* Clock gate Langwell */ writel(SUB_SYS_D0I2_VALUE, &pmu_reg->pm_ssc[0]); - - /* Do this when S0i3 is entered */ - writel((0 << 31) | /* Reserved */ - (0 << 30) | /* Core must be idle */ - (0xc2 << 22) | /* ACK C6 trigger */ - (3 << 19) | /* Trigger on DMI message */ - (3 << 16) | /* Enter S0i3 */ - (0 << 13) | /* Numeric mode ID (sw) */ - (3 << 9) | /* Trigger mode */ - (0 << 8) | /* Do not interrupt */ - (1 << 0), /* Set configuration */ - &pmu_reg->pm_cmd); } static inline void s0i3_update_wake_pointer(void) @@ -260,7 +261,7 @@ static noinline void do_s0i3(void) s0i3_save_msrs(); save_processor_state(); s0i3_prep_pmu(); - if (mrst_s0i3_entry()) { + if (mrst_s0i3_entry(PM_S0I3_COMMAND, &pmu_reg->pm_cmd)) { s0i3_restore_msrs(); restore_processor_state(); s0i3_restore_lapic(); diff --git a/drivers/idle/mrst_s0i3.h b/drivers/idle/mrst_s0i3.h index ee6b1b2ba74..574626ffb15 100644 --- a/drivers/idle/mrst_s0i3.h +++ b/drivers/idle/mrst_s0i3.h @@ -30,7 +30,7 @@ int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state); int mrst_s0i3_idle(struct cpuidle_device *dev, struct cpuidle_state *state); -int mrst_s0i3_entry(void); +int mrst_s0i3_entry(u32 regval, volatile u32 *regaddr); void mrst_s0i3_resume(void); #endif /* __ASSEMBLY__ */ diff --git a/drivers/idle/mrst_s0i3_asm.S b/drivers/idle/mrst_s0i3_asm.S index 10872fa4a3c..4561a53c347 100644 --- a/drivers/idle/mrst_s0i3_asm.S +++ b/drivers/idle/mrst_s0i3_asm.S @@ -37,7 +37,9 @@ ENTRY(mrst_s0i3_entry) pushl %ebp pushl %ebx - movl %esp, %esi + movl %esp, %ebp + movl %eax, %esi /* Command code to write to PM_CMD */ + movl %edx, %edi /* Linear address of the PM_CMD register */ sldt %eax pushl %eax @@ -89,13 +91,14 @@ ENTRY(mrst_s0i3_entry) movl $MRST_C6_HINTS_EAX, %eax movl $MRST_C6_HINTS_ECX, %ecx + movl %esi, (%edi) sti mwait /* If MWAIT wakes us up, assume something happened... */ cli /* jmp simulate_resume */ - movl %esi, %esp + movl %ebp, %esp xorl %eax, %eax /* Not really S0i3 */ popl %ebx |