for (k = 0x80; k <= 0x9c; k += 4)
__raw_writeb(ffd5[k], intcs_ffd5 + k);
}
+
+static unsigned short e694[0x200];
+static unsigned short e695[0x200];
+
+void sh7372_intca_suspend(void)
+{
+ int k;
+
+ for (k = 0x00; k <= 0x38; k += 4)
+ e694[k] = __raw_readw(0xe6940000 + k);
+
+ for (k = 0x80; k <= 0xb4; k += 4)
+ e694[k] = __raw_readb(0xe6940000 + k);
+
+ for (k = 0x180; k <= 0x1b4; k += 4)
+ e694[k] = __raw_readb(0xe6940000 + k);
+
+ for (k = 0x00; k <= 0x50; k += 4)
+ e695[k] = __raw_readw(0xe6950000 + k);
+
+ for (k = 0x80; k <= 0xa8; k += 4)
+ e695[k] = __raw_readb(0xe6950000 + k);
+
+ for (k = 0x180; k <= 0x1a8; k += 4)
+ e695[k] = __raw_readb(0xe6950000 + k);
+}
+
+void sh7372_intca_resume(void)
+{
+ int k;
+
+ for (k = 0x00; k <= 0x38; k += 4)
+ __raw_writew(e694[k], 0xe6940000 + k);
+
+ for (k = 0x80; k <= 0xb4; k += 4)
+ __raw_writeb(e694[k], 0xe6940000 + k);
+
+ for (k = 0x180; k <= 0x1b4; k += 4)
+ __raw_writeb(e694[k], 0xe6940000 + k);
+
+ for (k = 0x00; k <= 0x50; k += 4)
+ __raw_writew(e695[k], 0xe6950000 + k);
+
+ for (k = 0x80; k <= 0xa8; k += 4)
+ __raw_writeb(e695[k], 0xe6950000 + k);
+
+ for (k = 0x180; k <= 0x1a8; k += 4)
+ __raw_writeb(e695[k], 0xe6950000 + k);
+}
.bit_shift = 8,
};
+struct sh7372_pm_domain sh7372_a4s = {
+ .genpd.name = "A4S",
+ .bit_shift = 10,
+ .gov = &pm_domain_always_on_gov,
+ .no_debug = true,
+ .stay_on = true,
+};
+
struct sh7372_pm_domain sh7372_a3sp = {
.genpd.name = "A3SP",
.bit_shift = 11,
return 0;
}
-static void sh7372_enter_core_standby(void)
+static void sh7372_set_reset_vector(unsigned long address)
{
/* set reset vector, translate 4k */
- __raw_writel(__pa(sh7372_resume_core_standby_a3sm), SBAR);
+ __raw_writel(address, SBAR);
__raw_writel(0, APARMBAREA);
+}
+
+static void sh7372_enter_core_standby(void)
+{
+ sh7372_set_reset_vector(__pa(sh7372_resume_core_standby_sysc));
/* enter sleep mode with SYSTBCR to 0x10 */
__raw_writel(0x10, SYSTBCR);
#endif
#ifdef CONFIG_SUSPEND
-static void sh7372_enter_a3sm_common(int pllc0_on)
+static void sh7372_enter_sysc(int pllc0_on, unsigned long sleep_mode)
{
- /* set reset vector, translate 4k */
- __raw_writel(__pa(sh7372_resume_core_standby_a3sm), SBAR);
- __raw_writel(0, APARMBAREA);
-
if (pllc0_on)
__raw_writel(0, PLLC01STPCR);
else
__raw_writel(1 << 28, PLLC01STPCR);
- __raw_writel(0, PDNSEL); /* power-down A3SM only, not A4S */
__raw_readl(WUPSFAC); /* read wakeup int. factor before sleep */
- cpu_suspend(0, sh7372_do_idle_a3sm);
+ cpu_suspend(sleep_mode, sh7372_do_idle_sysc);
__raw_readl(WUPSFAC); /* read wakeup int. factor after wakeup */
/* disable reset vector translation */
__raw_writel(0, SBAR);
}
-static int sh7372_a3sm_valid(unsigned long *mskp, unsigned long *msk2p)
+static int sh7372_sysc_valid(unsigned long *mskp, unsigned long *msk2p)
{
unsigned long mstpsr0, mstpsr1, mstpsr2, mstpsr3, mstpsr4;
unsigned long msk, msk2;
*irqcr2p = irqcr2;
}
-static void sh7372_setup_a3sm(unsigned long msk, unsigned long msk2)
+static void sh7372_setup_sysc(unsigned long msk, unsigned long msk2)
{
u16 irqcrx_low, irqcrx_high, irqcry_low, irqcry_high;
unsigned long tmp;
__raw_writel((irqcrx_high << 16) | irqcrx_low, IRQCR3);
__raw_writel((irqcry_high << 16) | irqcry_low, IRQCR4);
}
+
+static void sh7372_enter_a3sm_common(int pllc0_on)
+{
+ sh7372_set_reset_vector(__pa(sh7372_resume_core_standby_sysc));
+ sh7372_enter_sysc(pllc0_on, 1 << 12);
+}
+
+static void sh7372_enter_a4s_common(int pllc0_on)
+{
+ sh7372_intca_suspend();
+ memcpy((void *)SMFRAM, sh7372_resume_core_standby_sysc, 0x100);
+ sh7372_set_reset_vector(SMFRAM);
+ sh7372_enter_sysc(pllc0_on, 1 << 10);
+ sh7372_intca_resume();
+}
+
#endif
#ifdef CONFIG_CPU_IDLE
unsigned long msk, msk2;
/* check active clocks to determine potential wakeup sources */
- if (sh7372_a3sm_valid(&msk, &msk2)) {
-
+ if (sh7372_sysc_valid(&msk, &msk2)) {
/* convert INTC mask and sense to SYSC mask and sense */
- sh7372_setup_a3sm(msk, msk2);
-
- /* enter A3SM sleep with PLLC0 off */
- pr_debug("entering A3SM\n");
- sh7372_enter_a3sm_common(0);
+ sh7372_setup_sysc(msk, msk2);
+
+ if (!sh7372_a3sp.stay_on &&
+ sh7372_a4s.genpd.status == GPD_STATE_POWER_OFF) {
+ /* enter A4S sleep with PLLC0 off */
+ pr_debug("entering A4S\n");
+ sh7372_enter_a4s_common(0);
+ } else {
+ /* enter A3SM sleep with PLLC0 off */
+ pr_debug("entering A3SM\n");
+ sh7372_enter_a3sm_common(0);
+ }
} else {
/* default to Core Standby that supports all wakeup sources */
pr_debug("entering Core Standby\n");