Skip to content

Commit

Permalink
MIPS: JZ4740: reset: Initialize hibernate wakeup counters.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Maarten ter Huurne authored and Ralf Baechle committed Jul 23, 2012
1 parent 56635d7 commit ea3952e
Showing 1 changed file with 44 additions and 5 deletions.
49 changes: 44 additions & 5 deletions arch/mips/jz4740/reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
#include <asm/mach-jz4740/base.h>
#include <asm/mach-jz4740/timer.h>

#include "reset.h"
#include "clock.h"

static void jz4740_halt(void)
{
while (1) {
Expand Down Expand Up @@ -53,21 +56,57 @@ static void jz4740_restart(char *command)
jz4740_halt();
}

#define JZ_REG_RTC_CTRL 0x00
#define JZ_REG_RTC_HIBERNATE 0x20
#define JZ_REG_RTC_CTRL 0x00
#define JZ_REG_RTC_HIBERNATE 0x20
#define JZ_REG_RTC_WAKEUP_FILTER 0x24
#define JZ_REG_RTC_RESET_COUNTER 0x28

#define JZ_RTC_CTRL_WRDY BIT(7)
#define JZ_RTC_CTRL_WRDY BIT(7)
#define JZ_RTC_WAKEUP_FILTER_MASK 0x0000FFE0
#define JZ_RTC_RESET_COUNTER_MASK 0x00000FE0

static void jz4740_power_off(void)
static inline void jz4740_rtc_wait_ready(void __iomem *rtc_base)
{
void __iomem *rtc_base = ioremap(JZ4740_RTC_BASE_ADDR, 0x24);
uint32_t ctrl;

do {
ctrl = readl(rtc_base + JZ_REG_RTC_CTRL);
} while (!(ctrl & JZ_RTC_CTRL_WRDY));
}

static void jz4740_power_off(void)
{
void __iomem *rtc_base = ioremap(JZ4740_RTC_BASE_ADDR, 0x38);
unsigned long wakeup_filter_ticks;
unsigned long reset_counter_ticks;

/*
* Set minimum wakeup pin assertion time: 100 ms.
* Range is 0 to 2 sec if RTC is clocked at 32 kHz.
*/
wakeup_filter_ticks = (100 * jz4740_clock_bdata.rtc_rate) / 1000;
if (wakeup_filter_ticks < JZ_RTC_WAKEUP_FILTER_MASK)
wakeup_filter_ticks &= JZ_RTC_WAKEUP_FILTER_MASK;
else
wakeup_filter_ticks = JZ_RTC_WAKEUP_FILTER_MASK;
jz4740_rtc_wait_ready(rtc_base);
writel(wakeup_filter_ticks, rtc_base + JZ_REG_RTC_WAKEUP_FILTER);

/*
* Set reset pin low-level assertion time after wakeup: 60 ms.
* Range is 0 to 125 ms if RTC is clocked at 32 kHz.
*/
reset_counter_ticks = (60 * jz4740_clock_bdata.rtc_rate) / 1000;
if (reset_counter_ticks < JZ_RTC_RESET_COUNTER_MASK)
reset_counter_ticks &= JZ_RTC_RESET_COUNTER_MASK;
else
reset_counter_ticks = JZ_RTC_RESET_COUNTER_MASK;
jz4740_rtc_wait_ready(rtc_base);
writel(reset_counter_ticks, rtc_base + JZ_REG_RTC_RESET_COUNTER);

jz4740_rtc_wait_ready(rtc_base);
writel(1, rtc_base + JZ_REG_RTC_HIBERNATE);

jz4740_halt();
}

Expand Down

0 comments on commit ea3952e

Please sign in to comment.