[PATCH] ARM: 2691/1: PXA27x sleep fixes take 2
Patch from Todd Poynor PXA27x sleep fixes: * set additional sleep/wakeup registers for Mainstone boards. * move CKEN=0 to pxa25x-specific code; that value is harmful on pxa27x. * save/restore additional registers, including some found necessary for C5 processors and/or newer blob versions. * enable future support of additional sleep modes for PXA27x (eg, standby, deep sleep). * split off cpu-specific sleep processing between pxa27x and pxa25x into separate files (partly in preparation for additional sleep modes). Includes fixes from David Burrage. Signed-off-by: Todd Poynor Signed-off-by: Nicolas Pitre Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
718a30a5cf
commit
8775420d2f
|
@ -304,6 +304,15 @@ static void __init mainstone_map_io(void)
|
||||||
PWER = 0xC0000002;
|
PWER = 0xC0000002;
|
||||||
PRER = 0x00000002;
|
PRER = 0x00000002;
|
||||||
PFER = 0x00000002;
|
PFER = 0x00000002;
|
||||||
|
/* for use I SRAM as framebuffer. */
|
||||||
|
PSLR |= 0xF04;
|
||||||
|
PCFR = 0x66;
|
||||||
|
/* For Keypad wakeup. */
|
||||||
|
KPC &=~KPC_ASACT;
|
||||||
|
KPC |=KPC_AS;
|
||||||
|
PKWR = 0x000FD000;
|
||||||
|
/* Need read PKWR back after set it. */
|
||||||
|
PKWR;
|
||||||
}
|
}
|
||||||
|
|
||||||
MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
|
MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
|
||||||
|
|
|
@ -29,9 +29,6 @@
|
||||||
*/
|
*/
|
||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
|
|
||||||
extern void pxa_cpu_suspend(void);
|
|
||||||
extern void pxa_cpu_resume(void);
|
|
||||||
|
|
||||||
#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
|
#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
|
||||||
#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
|
#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
|
||||||
|
|
||||||
|
@ -63,6 +60,12 @@ enum { SLEEP_SAVE_START = 0,
|
||||||
SLEEP_SAVE_ICMR,
|
SLEEP_SAVE_ICMR,
|
||||||
SLEEP_SAVE_CKEN,
|
SLEEP_SAVE_CKEN,
|
||||||
|
|
||||||
|
#ifdef CONFIG_PXA27x
|
||||||
|
SLEEP_SAVE_MDREFR,
|
||||||
|
SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER,
|
||||||
|
SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR,
|
||||||
|
#endif
|
||||||
|
|
||||||
SLEEP_SAVE_CKSUM,
|
SLEEP_SAVE_CKSUM,
|
||||||
|
|
||||||
SLEEP_SAVE_SIZE
|
SLEEP_SAVE_SIZE
|
||||||
|
@ -75,9 +78,7 @@ static int pxa_pm_enter(suspend_state_t state)
|
||||||
unsigned long checksum = 0;
|
unsigned long checksum = 0;
|
||||||
struct timespec delta, rtc;
|
struct timespec delta, rtc;
|
||||||
int i;
|
int i;
|
||||||
|
extern void pxa_cpu_pm_enter(suspend_state_t state);
|
||||||
if (state != PM_SUSPEND_MEM)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
#ifdef CONFIG_IWMMXT
|
#ifdef CONFIG_IWMMXT
|
||||||
/* force any iWMMXt context to ram **/
|
/* force any iWMMXt context to ram **/
|
||||||
|
@ -100,16 +101,17 @@ static int pxa_pm_enter(suspend_state_t state)
|
||||||
SAVE(GAFR2_L); SAVE(GAFR2_U);
|
SAVE(GAFR2_L); SAVE(GAFR2_U);
|
||||||
|
|
||||||
#ifdef CONFIG_PXA27x
|
#ifdef CONFIG_PXA27x
|
||||||
|
SAVE(MDREFR);
|
||||||
SAVE(GPLR3); SAVE(GPDR3); SAVE(GRER3); SAVE(GFER3); SAVE(PGSR3);
|
SAVE(GPLR3); SAVE(GPDR3); SAVE(GRER3); SAVE(GFER3); SAVE(PGSR3);
|
||||||
SAVE(GAFR3_L); SAVE(GAFR3_U);
|
SAVE(GAFR3_L); SAVE(GAFR3_U);
|
||||||
|
SAVE(PWER); SAVE(PCFR); SAVE(PRER);
|
||||||
|
SAVE(PFER); SAVE(PKWR);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SAVE(ICMR);
|
SAVE(ICMR);
|
||||||
ICMR = 0;
|
ICMR = 0;
|
||||||
|
|
||||||
SAVE(CKEN);
|
SAVE(CKEN);
|
||||||
CKEN = 0;
|
|
||||||
|
|
||||||
SAVE(PSTR);
|
SAVE(PSTR);
|
||||||
|
|
||||||
/* Note: wake up source are set up in each machine specific files */
|
/* Note: wake up source are set up in each machine specific files */
|
||||||
|
@ -123,16 +125,13 @@ static int pxa_pm_enter(suspend_state_t state)
|
||||||
/* Clear sleep reset status */
|
/* Clear sleep reset status */
|
||||||
RCSR = RCSR_SMR;
|
RCSR = RCSR_SMR;
|
||||||
|
|
||||||
/* set resume return address */
|
|
||||||
PSPR = virt_to_phys(pxa_cpu_resume);
|
|
||||||
|
|
||||||
/* before sleeping, calculate and save a checksum */
|
/* before sleeping, calculate and save a checksum */
|
||||||
for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)
|
for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)
|
||||||
checksum += sleep_save[i];
|
checksum += sleep_save[i];
|
||||||
sleep_save[SLEEP_SAVE_CKSUM] = checksum;
|
sleep_save[SLEEP_SAVE_CKSUM] = checksum;
|
||||||
|
|
||||||
/* *** go zzz *** */
|
/* *** go zzz *** */
|
||||||
pxa_cpu_suspend();
|
pxa_cpu_pm_enter(state);
|
||||||
|
|
||||||
/* after sleeping, validate the checksum */
|
/* after sleeping, validate the checksum */
|
||||||
checksum = 0;
|
checksum = 0;
|
||||||
|
@ -145,7 +144,7 @@ static int pxa_pm_enter(suspend_state_t state)
|
||||||
LUB_HEXLED = 0xbadbadc5;
|
LUB_HEXLED = 0xbadbadc5;
|
||||||
#endif
|
#endif
|
||||||
while (1)
|
while (1)
|
||||||
pxa_cpu_suspend();
|
pxa_cpu_pm_enter(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ensure not to come back here if it wasn't intended */
|
/* ensure not to come back here if it wasn't intended */
|
||||||
|
@ -162,8 +161,11 @@ static int pxa_pm_enter(suspend_state_t state)
|
||||||
RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2);
|
RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2);
|
||||||
|
|
||||||
#ifdef CONFIG_PXA27x
|
#ifdef CONFIG_PXA27x
|
||||||
|
RESTORE(MDREFR);
|
||||||
RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE_GPLEVEL(3);
|
RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE_GPLEVEL(3);
|
||||||
RESTORE(GPDR3); RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3);
|
RESTORE(GPDR3); RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3);
|
||||||
|
RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER);
|
||||||
|
RESTORE(PFER); RESTORE(PKWR);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PSSR = PSSR_RDH | PSSR_PH;
|
PSSR = PSSR_RDH | PSSR_PH;
|
||||||
|
@ -197,7 +199,9 @@ unsigned long sleep_phys_sp(void *sp)
|
||||||
*/
|
*/
|
||||||
static int pxa_pm_prepare(suspend_state_t state)
|
static int pxa_pm_prepare(suspend_state_t state)
|
||||||
{
|
{
|
||||||
return 0;
|
extern int pxa_cpu_pm_prepare(suspend_state_t state);
|
||||||
|
|
||||||
|
return pxa_cpu_pm_prepare(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -102,3 +102,32 @@ unsigned int get_lcdclk_frequency_10khz(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
|
EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
|
||||||
|
|
||||||
|
|
||||||
|
int pxa_cpu_pm_prepare(suspend_state_t state)
|
||||||
|
{
|
||||||
|
switch (state) {
|
||||||
|
case PM_SUSPEND_MEM:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pxa_cpu_pm_enter(suspend_state_t state)
|
||||||
|
{
|
||||||
|
extern void pxa_cpu_suspend(unsigned int);
|
||||||
|
extern void pxa_cpu_resume(void);
|
||||||
|
|
||||||
|
CKEN = 0;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case PM_SUSPEND_MEM:
|
||||||
|
/* set resume return address */
|
||||||
|
PSPR = virt_to_phys(pxa_cpu_resume);
|
||||||
|
pxa_cpu_suspend(3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -120,6 +120,38 @@ EXPORT_SYMBOL(get_clk_frequency_khz);
|
||||||
EXPORT_SYMBOL(get_memclk_frequency_10khz);
|
EXPORT_SYMBOL(get_memclk_frequency_10khz);
|
||||||
EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
|
EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
|
||||||
|
|
||||||
|
int pxa_cpu_pm_prepare(suspend_state_t state)
|
||||||
|
{
|
||||||
|
switch (state) {
|
||||||
|
case PM_SUSPEND_MEM:
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pxa_cpu_pm_enter(suspend_state_t state)
|
||||||
|
{
|
||||||
|
extern void pxa_cpu_standby(void);
|
||||||
|
extern void pxa_cpu_suspend(unsigned int);
|
||||||
|
extern void pxa_cpu_resume(void);
|
||||||
|
|
||||||
|
CKEN = CKEN22_MEMC | CKEN9_OSTIMER;
|
||||||
|
|
||||||
|
/* ensure voltage-change sequencer not initiated, which hangs */
|
||||||
|
PCFR &= ~PCFR_FVC;
|
||||||
|
|
||||||
|
/* Clear edge-detect status register. */
|
||||||
|
PEDR = 0xDF12FE1B;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case PM_SUSPEND_MEM:
|
||||||
|
/* set resume return address */
|
||||||
|
PSPR = virt_to_phys(pxa_cpu_resume);
|
||||||
|
pxa_cpu_suspend(3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* device registration specific to PXA27x.
|
* device registration specific to PXA27x.
|
||||||
|
|
Loading…
Reference in New Issue