aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorMaarten ter Huurne <maarten@treewalker.org>2012-03-30 10:18:57 -0400
committerRalf Baechle <ralf@linux-mips.org>2012-07-23 08:56:20 -0400
commitea3952e01c47ac76d71857099cbfc2f487f507d2 (patch)
treeeae5cd5d5ae1a92cc74fc121b1e43e557b5c7228 /arch/mips
parent56635d79932c805f6eb2a775ad1cdf9ace12c2b5 (diff)
MIPS: JZ4740: reset: Initialize hibernate wakeup counters.
In hibernation mode only the wakeup logic and the RTC are left running, so this is what users perceive as power down. If the counters are not initialized, the corresponding pin (typically connected to the power button) has to be asserted for two seconds before the device wakes up. Most users expect a shorter wakeup time. I took the timing values of 100 ms and 60 ms from BouKiCHi's patch for the Dingoo A320 kernel. Signed-off-by: Maarten ter Huurne <maarten@treewalker.org> Cc: Sergei Shtylyov <sshtylyov@mvista.com> Cc: Lars-Peter Clausen <lars@metafoo.de> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3563/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/jz4740/reset.c49
1 files changed, 44 insertions, 5 deletions
diff --git a/arch/mips/jz4740/reset.c b/arch/mips/jz4740/reset.c
index 5f1fb95c0d0..6c0da5afcf1 100644
--- a/arch/mips/jz4740/reset.c
+++ b/arch/mips/jz4740/reset.c
@@ -21,6 +21,9 @@
21#include <asm/mach-jz4740/base.h> 21#include <asm/mach-jz4740/base.h>
22#include <asm/mach-jz4740/timer.h> 22#include <asm/mach-jz4740/timer.h>
23 23
24#include "reset.h"
25#include "clock.h"
26
24static void jz4740_halt(void) 27static void jz4740_halt(void)
25{ 28{
26 while (1) { 29 while (1) {
@@ -53,21 +56,57 @@ static void jz4740_restart(char *command)
53 jz4740_halt(); 56 jz4740_halt();
54} 57}
55 58
56#define JZ_REG_RTC_CTRL 0x00 59#define JZ_REG_RTC_CTRL 0x00
57#define JZ_REG_RTC_HIBERNATE 0x20 60#define JZ_REG_RTC_HIBERNATE 0x20
61#define JZ_REG_RTC_WAKEUP_FILTER 0x24
62#define JZ_REG_RTC_RESET_COUNTER 0x28
58 63
59#define JZ_RTC_CTRL_WRDY BIT(7) 64#define JZ_RTC_CTRL_WRDY BIT(7)
65#define JZ_RTC_WAKEUP_FILTER_MASK 0x0000FFE0
66#define JZ_RTC_RESET_COUNTER_MASK 0x00000FE0
60 67
61static void jz4740_power_off(void) 68static inline void jz4740_rtc_wait_ready(void __iomem *rtc_base)
62{ 69{
63 void __iomem *rtc_base = ioremap(JZ4740_RTC_BASE_ADDR, 0x24);
64 uint32_t ctrl; 70 uint32_t ctrl;
65 71
66 do { 72 do {
67 ctrl = readl(rtc_base + JZ_REG_RTC_CTRL); 73 ctrl = readl(rtc_base + JZ_REG_RTC_CTRL);
68 } while (!(ctrl & JZ_RTC_CTRL_WRDY)); 74 } while (!(ctrl & JZ_RTC_CTRL_WRDY));
75}
69 76
77static void jz4740_power_off(void)
78{
79 void __iomem *rtc_base = ioremap(JZ4740_RTC_BASE_ADDR, 0x38);
80 unsigned long wakeup_filter_ticks;
81 unsigned long reset_counter_ticks;
82
83 /*
84 * Set minimum wakeup pin assertion time: 100 ms.
85 * Range is 0 to 2 sec if RTC is clocked at 32 kHz.
86 */
87 wakeup_filter_ticks = (100 * jz4740_clock_bdata.rtc_rate) / 1000;
88 if (wakeup_filter_ticks < JZ_RTC_WAKEUP_FILTER_MASK)
89 wakeup_filter_ticks &= JZ_RTC_WAKEUP_FILTER_MASK;
90 else
91 wakeup_filter_ticks = JZ_RTC_WAKEUP_FILTER_MASK;
92 jz4740_rtc_wait_ready(rtc_base);
93 writel(wakeup_filter_ticks, rtc_base + JZ_REG_RTC_WAKEUP_FILTER);
94
95 /*
96 * Set reset pin low-level assertion time after wakeup: 60 ms.
97 * Range is 0 to 125 ms if RTC is clocked at 32 kHz.
98 */
99 reset_counter_ticks = (60 * jz4740_clock_bdata.rtc_rate) / 1000;
100 if (reset_counter_ticks < JZ_RTC_RESET_COUNTER_MASK)
101 reset_counter_ticks &= JZ_RTC_RESET_COUNTER_MASK;
102 else
103 reset_counter_ticks = JZ_RTC_RESET_COUNTER_MASK;
104 jz4740_rtc_wait_ready(rtc_base);
105 writel(reset_counter_ticks, rtc_base + JZ_REG_RTC_RESET_COUNTER);
106
107 jz4740_rtc_wait_ready(rtc_base);
70 writel(1, rtc_base + JZ_REG_RTC_HIBERNATE); 108 writel(1, rtc_base + JZ_REG_RTC_HIBERNATE);
109
71 jz4740_halt(); 110 jz4740_halt();
72} 111}
73 112