2 * sh7372 Power management support
4 * Copyright (C) 2011 Magnus Damm
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
12 #include <linux/suspend.h>
13 #include <linux/cpuidle.h>
14 #include <linux/module.h>
15 #include <linux/list.h>
16 #include <linux/err.h>
17 #include <linux/slab.h>
18 #include <asm/system.h>
20 #include <asm/tlbflush.h>
21 #include <mach/common.h>
23 #define SMFRAM 0xe6a70000
24 #define SYSTBCR 0xe6150024
25 #define SBAR 0xe6180020
26 #define APARMBAREA 0xe6f10020
28 static void sh7372_enter_core_standby(void)
30 void __iomem
*smfram
= (void __iomem
*)SMFRAM
;
32 __raw_writel(0, APARMBAREA
); /* translate 4k */
33 __raw_writel(__pa(sh7372_cpu_resume
), SBAR
); /* set reset vector */
34 __raw_writel(0x10, SYSTBCR
); /* enable core standby */
36 __raw_writel(0, smfram
+ 0x3c); /* clear page table address */
41 /* if page table address is non-NULL then we have been powered down */
42 if (__raw_readl(smfram
+ 0x3c)) {
43 __raw_writel(__raw_readl(smfram
+ 0x40),
44 __va(__raw_readl(smfram
+ 0x3c)));
47 set_cr(__raw_readl(smfram
+ 0x38));
50 __raw_writel(0, SYSTBCR
); /* disable core standby */
51 __raw_writel(0, SBAR
); /* disable reset vector translation */
54 #ifdef CONFIG_CPU_IDLE
55 static void sh7372_cpuidle_setup(struct cpuidle_device
*dev
)
57 struct cpuidle_state
*state
;
58 int i
= dev
->state_count
;
60 state
= &dev
->states
[i
];
61 snprintf(state
->name
, CPUIDLE_NAME_LEN
, "C2");
62 strncpy(state
->desc
, "Core Standby Mode", CPUIDLE_DESC_LEN
);
63 state
->exit_latency
= 10;
64 state
->target_residency
= 20 + 10;
65 state
->power_usage
= 1; /* perhaps not */
67 state
->flags
|= CPUIDLE_FLAG_TIME_VALID
;
68 shmobile_cpuidle_modes
[i
] = sh7372_enter_core_standby
;
70 dev
->state_count
= i
+ 1;
73 static void sh7372_cpuidle_init(void)
75 shmobile_cpuidle_setup
= sh7372_cpuidle_setup
;
78 static void sh7372_cpuidle_init(void) {}
82 static int sh7372_enter_suspend(suspend_state_t suspend_state
)
84 sh7372_enter_core_standby();
88 static void sh7372_suspend_init(void)
90 shmobile_suspend_ops
.enter
= sh7372_enter_suspend
;
93 static void sh7372_suspend_init(void) {}
96 #define DBGREG1 0xe6100020
97 #define DBGREG9 0xe6100040
99 void __init
sh7372_pm_init(void)
101 /* enable DBG hardware block to kick SYSC */
102 __raw_writel(0x0000a500, DBGREG9
);
103 __raw_writel(0x0000a501, DBGREG9
);
104 __raw_writel(0x00000000, DBGREG1
);
106 sh7372_suspend_init();
107 sh7372_cpuidle_init();