diff options
| -rw-r--r-- | arch/mips/jz4740/reset.c | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/arch/mips/jz4740/reset.c b/arch/mips/jz4740/reset.c index 5f1fb95c0d0d..6c0da5afcf17 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 | |||
| 24 | static void jz4740_halt(void) | 27 | static 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 | ||
| 61 | static void jz4740_power_off(void) | 68 | static 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 | ||
| 77 | static 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 | ||
