diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-s5pv210/include/mach/map.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-s5pv210/include/mach/pm-core.h | 30 | ||||
-rw-r--r-- | arch/arm/mach-s5pv210/include/mach/regs-gpio.h | 90 | ||||
-rw-r--r-- | arch/arm/mach-s5pv210/include/mach/regs-irq.h | 6 | ||||
-rw-r--r-- | arch/arm/mach-s5pv210/include/mach/regs-mem.h | 28 | ||||
-rw-r--r-- | arch/arm/mach-s5pv210/mach-herring.c | 3 | ||||
-rw-r--r-- | arch/arm/plat-s5p/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/plat-s5p/include/plat/pm.h | 217 | ||||
-rw-r--r-- | arch/arm/plat-s5p/irq-pm.c | 18 | ||||
-rw-r--r-- | arch/arm/plat-s5p/pm.c | 256 | ||||
-rw-r--r-- | arch/arm/plat-s5p/sleep.S | 319 |
11 files changed, 904 insertions, 72 deletions
diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h index 4f7894e..c14f594 100644 --- a/arch/arm/mach-s5pv210/include/mach/map.h +++ b/arch/arm/mach-s5pv210/include/mach/map.h @@ -78,6 +78,11 @@ #define S5PV210_PA_DMC0 0xF0000000 #define S5PV210_PA_DMC1 0xF1400000 +#define S5P_VA_VIC0 (S3C_VA_IRQ + 0x0) +#define S5P_VA_VIC1 (S3C_VA_IRQ + 0x10000) +#define S5P_VA_VIC2 (S3C_VA_IRQ + 0x20000) +#define S5P_VA_VIC3 (S3C_VA_IRQ + 0x30000) + #define S5PV210_PA_LCD (0xF8000000) #define S5P_PA_LCD S5PV210_PA_LCD #define S5PV210_SZ_LCD SZ_1M diff --git a/arch/arm/mach-s5pv210/include/mach/pm-core.h b/arch/arm/mach-s5pv210/include/mach/pm-core.h index e8d394f..a93c1a2 100644 --- a/arch/arm/mach-s5pv210/include/mach/pm-core.h +++ b/arch/arm/mach-s5pv210/include/mach/pm-core.h @@ -1,14 +1,11 @@ /* linux/arch/arm/mach-s5pv210/include/mach/pm-core.h * * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com + * http://www.samsung.com/ * - * Based on arch/arm/mach-s3c2410/include/mach/pm-core.h, - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S5PV210 - PM core support for arch/arm/plat-s5p/pm.c + * Based on arch/arm/plat-s3c24xx/include/plat/pm-core.h, + * Copyright 2008-2009 Simtec Electronics Ben Dooks <ben@simtec.co.uk> + * S5P series driver for power management * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -17,27 +14,38 @@ static inline void s3c_pm_debug_init_uart(void) { - /* nothing here yet */ } static inline void s3c_pm_arch_prepare_irqs(void) { __raw_writel(s3c_irqwake_intmask, S5P_WAKEUP_MASK); __raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK); + + /* ack any outstanding external interrupts before we go to sleep */ + } static inline void s3c_pm_arch_stop_clocks(void) { - /* nothing here yet */ } +static void s3c_pm_show_resume_irqs(int start, unsigned long which, + unsigned long mask); + static inline void s3c_pm_arch_show_resume_irqs(void) { - /* nothing here yet */ } +/* make these defines, we currently do not have any need to change + * the IRQ wake controls depending on the CPU we are running on */ + +/* 2009.04.27 by icarus : don't use this definition, use extern var */ +#if 0 +#define s3c_irqwake_eintallow (0xFFFFFFFF) +#define s3c_irqwake_intallow (0) +#endif + static inline void s3c_pm_arch_update_uart(void __iomem *regs, struct pm_uart_save *save) { - /* nothing here yet */ } diff --git a/arch/arm/mach-s5pv210/include/mach/regs-gpio.h b/arch/arm/mach-s5pv210/include/mach/regs-gpio.h index 5c786a9..1669549 100644 --- a/arch/arm/mach-s5pv210/include/mach/regs-gpio.h +++ b/arch/arm/mach-s5pv210/include/mach/regs-gpio.h @@ -75,155 +75,155 @@ #define S5PV210_ETC4_BASE (S5P_VA_GPIO + 0x660) #define S5PV210_GPA0_INT_CON (S5P_VA_GPIO + 0x700) -#define S5PV210_GPA0_INTFLTCON0 (S5P_VA_GPIO + 0x800) -#define S5PV210_GPA0_INTFLTCON1 (S5P_VA_GPIO + 0x804) +#define S5PV210_GPA0_INT_FLTCON0 (S5P_VA_GPIO + 0x800) +#define S5PV210_GPA0_INT_FLTCON1 (S5P_VA_GPIO + 0x804) #define S5PV210_GPA0_INT_MASK (S5P_VA_GPIO + 0x900) #define S5PV210_GPA0_INT_PEND (S5P_VA_GPIO + 0xA00) #define S5PV210_GPA0_INT_FIXPRI (S5P_VA_GPIO + 0xB14) #define S5PV210_GPA1_INT_CON (S5P_VA_GPIO + 0x704) -#define S5PV210_GPA1_INTFLTCON0 (S5P_VA_GPIO + 0x808) -#define S5PV210_GPA1_INTFLTCON1 (S5P_VA_GPIO + 0x80C) +#define S5PV210_GPA1_INT_FLTCON0 (S5P_VA_GPIO + 0x808) +#define S5PV210_GPA1_INT_FLTCON1 (S5P_VA_GPIO + 0x80C) #define S5PV210_GPA1_INT_MASK (S5P_VA_GPIO + 0x904) #define S5PV210_GPA1_INT_PEND (S5P_VA_GPIO + 0xA04) #define S5PV210_GPA1_INT_FIXPRI (S5P_VA_GPIO + 0xB18) #define S5PV210_GPB_INT_CON (S5P_VA_GPIO + 0x708) -#define S5PV210_GPB_INTFLTCON0 (S5P_VA_GPIO + 0x810) -#define S5PV210_GPB_INTFLTCON1 (S5P_VA_GPIO + 0x814) +#define S5PV210_GPB_INT_FLTCON0 (S5P_VA_GPIO + 0x810) +#define S5PV210_GPB_INT_FLTCON1 (S5P_VA_GPIO + 0x814) #define S5PV210_GPB_INT_MASK (S5P_VA_GPIO + 0x908) #define S5PV210_GPB_INT_PEND (S5P_VA_GPIO + 0xA08) #define S5PV210_GPB_INT_FIXPRI (S5P_VA_GPIO + 0xB1C) #define S5PV210_GPC0_INT_CON (S5P_VA_GPIO + 0x70C) -#define S5PV210_GPC0_INTFLTCON0 (S5P_VA_GPIO + 0x818) -#define S5PV210_GPC0_INTFLTCON1 (S5P_VA_GPIO + 0x81C) +#define S5PV210_GPC0_INT_FLTCON0 (S5P_VA_GPIO + 0x818) +#define S5PV210_GPC0_INT_FLTCON1 (S5P_VA_GPIO + 0x81C) #define S5PV210_GPC0_INT_MASK (S5P_VA_GPIO + 0x90C) #define S5PV210_GPC0_INT_PEND (S5P_VA_GPIO + 0xA0C) #define S5PV210_GPC0_INT_FIXPRI (S5P_VA_GPIO + 0xB20) #define S5PV210_GPC1_INT_CON (S5P_VA_GPIO + 0x710) -#define S5PV210_GPC1_INTFLTCON0 (S5P_VA_GPIO + 0x820) -#define S5PV210_GPC1_INTFLTCON1 (S5P_VA_GPIO + 0x824) +#define S5PV210_GPC1_INT_FLTCON0 (S5P_VA_GPIO + 0x820) +#define S5PV210_GPC1_INT_FLTCON1 (S5P_VA_GPIO + 0x824) #define S5PV210_GPC1_INT_MASK (S5P_VA_GPIO + 0x910) #define S5PV210_GPC1_INT_PEND (S5P_VA_GPIO + 0xA10) #define S5PV210_GPC1_INT_FIXPRI (S5P_VA_GPIO + 0xB24) #define S5PV210_GPD0_INT_CON (S5P_VA_GPIO + 0x714) -#define S5PV210_GPD0_INTFLTCON0 (S5P_VA_GPIO + 0x828) -#define S5PV210_GPD0_INTFLTCON1 (S5P_VA_GPIO + 0x82C) +#define S5PV210_GPD0_INT_FLTCON0 (S5P_VA_GPIO + 0x828) +#define S5PV210_GPD0_INT_FLTCON1 (S5P_VA_GPIO + 0x82C) #define S5PV210_GPD0_INT_MASK (S5P_VA_GPIO + 0x914) #define S5PV210_GPD0_INT_PEND (S5P_VA_GPIO + 0xA14) #define S5PV210_GPD0_INT_FIXPRI (S5P_VA_GPIO + 0xB28) #define S5PV210_GPD1_INT_CON (S5P_VA_GPIO + 0x718) -#define S5PV210_GPD1_INTFLTCON0 (S5P_VA_GPIO + 0x830) -#define S5PV210_GPD1_INTFLTCON1 (S5P_VA_GPIO + 0x834) +#define S5PV210_GPD1_INT_FLTCON0 (S5P_VA_GPIO + 0x830) +#define S5PV210_GPD1_INT_FLTCON1 (S5P_VA_GPIO + 0x834) #define S5PV210_GPD1_INT_MASK (S5P_VA_GPIO + 0x918) #define S5PV210_GPD1_INT_PEND (S5P_VA_GPIO + 0xA18) #define S5PV210_GPD1_INT_FIXPRI (S5P_VA_GPIO + 0xB2C) #define S5PV210_GPE0_INT_CON (S5P_VA_GPIO + 0x71C) -#define S5PV210_GPE0_INTFLTCON0 (S5P_VA_GPIO + 0x838) -#define S5PV210_GPE0_INTFLTCON1 (S5P_VA_GPIO + 0x83C) +#define S5PV210_GPE0_INT_FLTCON0 (S5P_VA_GPIO + 0x838) +#define S5PV210_GPE0_INT_FLTCON1 (S5P_VA_GPIO + 0x83C) #define S5PV210_GPE0_INT_MASK (S5P_VA_GPIO + 0x91C) #define S5PV210_GPE0_INT_PEND (S5P_VA_GPIO + 0xA1C) #define S5PV210_GPE0_INT_FIXPRI (S5P_VA_GPIO + 0xB30) #define S5PV210_GPE1_INT_CON (S5P_VA_GPIO + 0x720) -#define S5PV210_GPE1_INTFLTCON0 (S5P_VA_GPIO + 0x840) -#define S5PV210_GPE1_INTFLTCON1 (S5P_VA_GPIO + 0x844) +#define S5PV210_GPE1_INT_FLTCON0 (S5P_VA_GPIO + 0x840) +#define S5PV210_GPE1_INT_FLTCON1 (S5P_VA_GPIO + 0x844) #define S5PV210_GPE1_INT_MASK (S5P_VA_GPIO + 0x920) #define S5PV210_GPE1_INT_PEND (S5P_VA_GPIO + 0xA20) #define S5PV210_GPE1_INT_FIXPRI (S5P_VA_GPIO + 0xB34) #define S5PV210_GPF0_INT_CON (S5P_VA_GPIO + 0x724) -#define S5PV210_GPF0_INTFLTCON0 (S5P_VA_GPIO + 0x848) -#define S5PV210_GPF0_INTFLTCON1 (S5P_VA_GPIO + 0x84C) +#define S5PV210_GPF0_INT_FLTCON0 (S5P_VA_GPIO + 0x848) +#define S5PV210_GPF0_INT_FLTCON1 (S5P_VA_GPIO + 0x84C) #define S5PV210_GPF0_INT_MASK (S5P_VA_GPIO + 0x924) #define S5PV210_GPF0_INT_PEND (S5P_VA_GPIO + 0xA24) #define S5PV210_GPF0_INT_FIXPRI (S5P_VA_GPIO + 0xB38) #define S5PV210_GPF1_INT_CON (S5P_VA_GPIO + 0x728) -#define S5PV210_GPF1_INTFLTCON0 (S5P_VA_GPIO + 0x850) -#define S5PV210_GPF1_INTFLTCON1 (S5P_VA_GPIO + 0x854) +#define S5PV210_GPF1_INT_FLTCON0 (S5P_VA_GPIO + 0x850) +#define S5PV210_GPF1_INT_FLTCON1 (S5P_VA_GPIO + 0x854) #define S5PV210_GPF1_INT_MASK (S5P_VA_GPIO + 0x928) #define S5PV210_GPF1_INT_PEND (S5P_VA_GPIO + 0xA28) #define S5PV210_GPF1_INT_FIXPRI (S5P_VA_GPIO + 0xB3C) #define S5PV210_GPF2_INT_CON (S5P_VA_GPIO + 0x72C) -#define S5PV210_GPF2_INTFLTCON0 (S5P_VA_GPIO + 0x858) -#define S5PV210_GPF2_INTFLTCON1 (S5P_VA_GPIO + 0x85C) +#define S5PV210_GPF2_INT_FLTCON0 (S5P_VA_GPIO + 0x858) +#define S5PV210_GPF2_INT_FLTCON1 (S5P_VA_GPIO + 0x85C) #define S5PV210_GPF2_INT_MASK (S5P_VA_GPIO + 0x92C) #define S5PV210_GPF2_INT_PEND (S5P_VA_GPIO + 0xA2C) #define S5PV210_GPF2_INT_FIXPRI (S5P_VA_GPIO + 0xB40) #define S5PV210_GPF3_INT_CON (S5P_VA_GPIO + 0x730) -#define S5PV210_GPF3_INTFLTCON0 (S5P_VA_GPIO + 0x860) -#define S5PV210_GPF3_INTFLTCON1 (S5P_VA_GPIO + 0x864) +#define S5PV210_GPF3_INT_FLTCON0 (S5P_VA_GPIO + 0x860) +#define S5PV210_GPF3_INT_FLTCON1 (S5P_VA_GPIO + 0x864) #define S5PV210_GPF3_INT_MASK (S5P_VA_GPIO + 0x930) #define S5PV210_GPF3_INT_PEND (S5P_VA_GPIO + 0xA30) #define S5PV210_GPF3_INT_FIXPRI (S5P_VA_GPIO + 0xB44) #define S5PV210_GPG0_INT_CON (S5P_VA_GPIO + 0x734) -#define S5PV210_GPG0_INTFLTCON0 (S5P_VA_GPIO + 0x868) -#define S5PV210_GPG0_INTFLTCON1 (S5P_VA_GPIO + 0x86C) +#define S5PV210_GPG0_INT_FLTCON0 (S5P_VA_GPIO + 0x868) +#define S5PV210_GPG0_INT_FLTCON1 (S5P_VA_GPIO + 0x86C) #define S5PV210_GPG0_INT_MASK (S5P_VA_GPIO + 0x934) #define S5PV210_GPG0_INT_PEND (S5P_VA_GPIO + 0xA34) #define S5PV210_GPG0_INT_FIXPRI (S5P_VA_GPIO + 0xB48) #define S5PV210_GPG1_INT_CON (S5P_VA_GPIO + 0x738) -#define S5PV210_GPG1_INTFLTCON0 (S5P_VA_GPIO + 0x870) -#define S5PV210_GPG1_INTFLTCON1 (S5P_VA_GPIO + 0x874) +#define S5PV210_GPG1_INT_FLTCON0 (S5P_VA_GPIO + 0x870) +#define S5PV210_GPG1_INT_FLTCON1 (S5P_VA_GPIO + 0x874) #define S5PV210_GPG1_INT_MASK (S5P_VA_GPIO + 0x938) #define S5PV210_GPG1_INT_PEND (S5P_VA_GPIO + 0xA38) #define S5PV210_GPG1_INT_FIXPRI (S5P_VA_GPIO + 0xB4C) #define S5PV210_GPG2_INT_CON (S5P_VA_GPIO + 0x73C) -#define S5PV210_GPG2_INTFLTCON0 (S5P_VA_GPIO + 0x878) -#define S5PV210_GPG2_INTFLTCON1 (S5P_VA_GPIO + 0x87C) +#define S5PV210_GPG2_INT_FLTCON0 (S5P_VA_GPIO + 0x878) +#define S5PV210_GPG2_INT_FLTCON1 (S5P_VA_GPIO + 0x87C) #define S5PV210_GPG2_INT_MASK (S5P_VA_GPIO + 0x93C) #define S5PV210_GPG2_INT_PEND (S5P_VA_GPIO + 0xA3C) #define S5PV210_GPG2_INT_FIXPRI (S5P_VA_GPIO + 0xB50) #define S5PV210_GPG3_INT_CON (S5P_VA_GPIO + 0x740) -#define S5PV210_GPG3_INTFLTCON0 (S5P_VA_GPIO + 0x880) -#define S5PV210_GPG3_INTFLTCON1 (S5P_VA_GPIO + 0x884) +#define S5PV210_GPG3_INT_FLTCON0 (S5P_VA_GPIO + 0x880) +#define S5PV210_GPG3_INT_FLTCON1 (S5P_VA_GPIO + 0x884) #define S5PV210_GPG3_INT_MASK (S5P_VA_GPIO + 0x940) #define S5PV210_GPG3_INT_PEND (S5P_VA_GPIO + 0xA40) #define S5PV210_GPG3_INT_FIXPRI (S5P_VA_GPIO + 0xB54) #define S5PV210_GPJ0_INT_CON (S5P_VA_GPIO + 0x744) -#define S5PV210_GPJ0_INTFLTCON0 (S5P_VA_GPIO + 0x888) -#define S5PV210_GPJ0_INTFLTCON1 (S5P_VA_GPIO + 0x88C) +#define S5PV210_GPJ0_INT_FLTCON0 (S5P_VA_GPIO + 0x888) +#define S5PV210_GPJ0_INT_FLTCON1 (S5P_VA_GPIO + 0x88C) #define S5PV210_GPJ0_INT_MASK (S5P_VA_GPIO + 0x944) #define S5PV210_GPJ0_INT_PEND (S5P_VA_GPIO + 0xA44) #define S5PV210_GPJ0_INT_FIXPRI (S5P_VA_GPIO + 0xB58) #define S5PV210_GPJ1_INT_CON (S5P_VA_GPIO + 0x748) -#define S5PV210_GPJ1_INTFLTCON0 (S5P_VA_GPIO + 0x890) -#define S5PV210_GPJ1_INTFLTCON1 (S5P_VA_GPIO + 0x894) +#define S5PV210_GPJ1_INT_FLTCON0 (S5P_VA_GPIO + 0x890) +#define S5PV210_GPJ1_INT_FLTCON1 (S5P_VA_GPIO + 0x894) #define S5PV210_GPJ1_INT_MASK (S5P_VA_GPIO + 0x948) #define S5PV210_GPJ1_INT_PEND (S5P_VA_GPIO + 0xA48) #define S5PV210_GPJ1_INT_FIXPRI (S5P_VA_GPIO + 0xB5C) #define S5PV210_GPJ2_INT_CON (S5P_VA_GPIO + 0x74C) -#define S5PV210_GPJ2_INTFLTCON0 (S5P_VA_GPIO + 0x898) -#define S5PV210_GPJ2_INTFLTCON1 (S5P_VA_GPIO + 0x89C) +#define S5PV210_GPJ2_INT_FLTCON0 (S5P_VA_GPIO + 0x898) +#define S5PV210_GPJ2_INT_FLTCON1 (S5P_VA_GPIO + 0x89C) #define S5PV210_GPJ2_INT_MASK (S5P_VA_GPIO + 0x94C) #define S5PV210_GPJ2_INT_PEND (S5P_VA_GPIO + 0xA4C) #define S5PV210_GPJ2_INT_FIXPRI (S5P_VA_GPIO + 0xB60) #define S5PV210_GPJ3_INT_CON (S5P_VA_GPIO + 0x750) -#define S5PV210_GPJ3_INTFLTCON0 (S5P_VA_GPIO + 0x8A0) -#define S5PV210_GPJ3_INTFLTCON1 (S5P_VA_GPIO + 0x8A4) +#define S5PV210_GPJ3_INT_FLTCON0 (S5P_VA_GPIO + 0x8A0) +#define S5PV210_GPJ3_INT_FLTCON1 (S5P_VA_GPIO + 0x8A4) #define S5PV210_GPJ3_INT_MASK (S5P_VA_GPIO + 0x950) #define S5PV210_GPJ3_INT_PEND (S5P_VA_GPIO + 0xA50) #define S5PV210_GPJ3_INT_FIXPRI (S5P_VA_GPIO + 0xB64) #define S5PV210_GPJ4_INT_CON (S5P_VA_GPIO + 0x754) -#define S5PV210_GPJ4_INTFLTCON0 (S5P_VA_GPIO + 0x8A8) -#define S5PV210_GPJ4_INTFLTCON1 (S5P_VA_GPIO + 0x8AC) +#define S5PV210_GPJ4_INT_FLTCON0 (S5P_VA_GPIO + 0x8A8) +#define S5PV210_GPJ4_INT_FLTCON1 (S5P_VA_GPIO + 0x8AC) #define S5PV210_GPJ4_INT_MASK (S5P_VA_GPIO + 0x954) #define S5PV210_GPJ4_INT_PEND (S5P_VA_GPIO + 0xA54) #define S5PV210_GPJ4_INT_FIXPRI (S5P_VA_GPIO + 0xB68) @@ -238,7 +238,7 @@ #define S5P_EINT_CON(x) (S5PV210_EINT30CON + ((x) * 0x4)) #define S5PV210_EINT30FLTCON0 (S5P_VA_GPIO + 0xE80) -#define S5P_EINT_FLTCON(x) (S5PV210_EINT30FLTCON0 + ((x) * 0x4)) +#define S5P_EINT_FLTCON(x,y) (S5PV210_EINT30FLTCON0 + ((x) * 0x8) + ((y) * 0x4)) #define S5PV210_EINT30MASK (S5P_VA_GPIO + 0xF00) #define S5P_EINT_MASK(x) (S5PV210_EINT30MASK + ((x) * 0x4)) diff --git a/arch/arm/mach-s5pv210/include/mach/regs-irq.h b/arch/arm/mach-s5pv210/include/mach/regs-irq.h index 5c3b104..e3b86f1 100644 --- a/arch/arm/mach-s5pv210/include/mach/regs-irq.h +++ b/arch/arm/mach-s5pv210/include/mach/regs-irq.h @@ -16,4 +16,10 @@ #include <asm/hardware/vic.h> #include <mach/map.h> +/* interrupt controller */ +#define S5P_VIC0REG(x) ((x) + S5P_VA_VIC0) +#define S5P_VIC1REG(x) ((x) + S5P_VA_VIC1) +#define S5P_VIC2REG(x) ((x) + S5P_VA_VIC2) +#define S5P_VIC3REG(x) ((x) + S5P_VA_VIC3) + #endif /* __ASM_ARCH_REGS_IRQ_H */ diff --git a/arch/arm/mach-s5pv210/include/mach/regs-mem.h b/arch/arm/mach-s5pv210/include/mach/regs-mem.h new file mode 100644 index 0000000..1c79d54 --- /dev/null +++ b/arch/arm/mach-s5pv210/include/mach/regs-mem.h @@ -0,0 +1,28 @@ +/* linux/arch/arm/mach-s5pv210/include/mach/regs-mem.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5PV210 - Memory Control register definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARCH_REGS_MEM_H +#define __ASM_ARCH_REGS_MEM_H __FILE__ + +#include <mach/map.h> + +#define S5P_MEMREG(x) (S5P_VA_SROMC + (x)) + +#define S5P_SROM_BW S5P_MEMREG(0x00) +#define S5P_SROM_BC0 S5P_MEMREG(0x04) +#define S5P_SROM_BC1 S5P_MEMREG(0x08) +#define S5P_SROM_BC2 S5P_MEMREG(0x0C) +#define S5P_SROM_BC3 S5P_MEMREG(0x10) +#define S5P_SROM_BC4 S5P_MEMREG(0x14) +#define S5P_SROM_BC5 S5P_MEMREG(0x18) + +#endif /* __ASM_ARCH_REGS_MEM_H */ diff --git a/arch/arm/mach-s5pv210/mach-herring.c b/arch/arm/mach-s5pv210/mach-herring.c index 70af092..849ec08 100644 --- a/arch/arm/mach-s5pv210/mach-herring.c +++ b/arch/arm/mach-s5pv210/mach-herring.c @@ -3045,10 +3045,13 @@ static void __init herring_machine_init(void) s3c_adc_set_platdata(&s3c_adc_platform); #endif +#if 0 /* will be initialized at pm.c */ #if defined(CONFIG_PM) s3c_pm_init(); // s5pc11x_pm_init(); #endif +#endif + #ifdef CONFIG_VIDEO_FIMC /* fimc */ s3c_fimc0_set_platdata(&fimc_plat); diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile index 33b6a34..b0adbfc 100644 --- a/arch/arm/plat-s5p/Makefile +++ b/arch/arm/plat-s5p/Makefile @@ -40,6 +40,10 @@ obj-$(CONFIG_S5P_DEV_CSIS1) += dev-csis1.o obj-$(CONFIG_S5P_DEV_USB_EHCI) += dev-ehci.o obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o +obj-$(CONFIG_PM) += pm.o +obj-$(CONFIG_PM) += irq-pm.o +obj-$(CONFIG_PM) += sleep.o + ifdef CONFIG_S5P_HIGH_RES_TIMERS ifdef CONFIG_HRT_RTC obj-y += hr-time-rtc.o diff --git a/arch/arm/plat-s5p/include/plat/pm.h b/arch/arm/plat-s5p/include/plat/pm.h new file mode 100644 index 0000000..9c62446 --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/pm.h @@ -0,0 +1,217 @@ +/* linux/arch/arm/plat-s5p/include/plat/pm.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Based on arch/arm/plat-s3c/include/plat/pm.h, + * Copyright 2008-2009 Simtec Electronics Ben Dooks <ben@simtec.co.uk> + * S5P series device definition for power management + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifdef CONFIG_S5P_LPAUDIO +#include <linux/wakelock.h> +#include <mach/cpuidle.h> +#endif /* CONFIG_S5P_LPAUDIO */ + +#ifdef CONFIG_PM + +extern __init int s3c_pm_init(void); + +#else + +static inline int s3c_pm_init(void) +{ + return 0; +} +#endif + +#ifdef CONFIG_S3C2410_PM_DEBUG +extern void printascii(const char *); +#endif + +extern void s3c_pm_dbg(const char *fmt, ...); + +/* configuration for the IRQ mask over sleep */ +extern unsigned long s3c_irqwake_intmask; +extern unsigned long s3c_irqwake_eintmask; + +/* IRQ masks for IRQs allowed to go to sleep (see irq.c) */ +extern unsigned long s3c_irqwake_intallow; +extern unsigned long s3c_irqwake_eintallow; + +/* per-cpu sleep functions */ + +extern void (*pm_cpu_prep)(void); +extern void (*pm_cpu_sleep)(void); + +/* Flags for PM Control */ + +extern unsigned long s3c_pm_flags; + +extern unsigned char pm_uart_udivslot; /* true to save UART UDIVSLOT */ + +/* from sleep.S */ + +extern int s3c_cpu_save(unsigned long *saveblk); +extern void s3c_cpu_resume(void); + +extern void s3c2410_cpu_suspend(void); + +extern unsigned long s3c_sleep_save_phys; + +#define SLEEP_MODE 0 +#define IDLE2_MODE 1 + +/* sleep save info */ + +/** + * struct sleep_save - save information for shared peripherals. + * @reg: Pointer to the register to save. + * @val: Holder for the value saved from reg. + * + * This describes a list of registers which is used by the pm core and + * other subsystem to save and restore register values over suspend. + */ +struct sleep_save { + void __iomem *reg; + unsigned long val; +}; + +#define SAVE_ITEM(x) \ + { .reg = (x) } + +/** + * struct pm_uart_save - save block for core UART + * @ulcon: Save value for S3C2410_ULCON + * @ucon: Save value for S3C2410_UCON + * @ufcon: Save value for S3C2410_UFCON + * @umcon: Save value for S3C2410_UMCON + * @ubrdiv: Save value for S3C2410_UBRDIV + * + * Save block for UART registers to be held over sleep and restored if they + * are needed (say by debug). +*/ +struct pm_uart_save { + u32 ulcon; + u32 ucon; + u32 ufcon; + u32 umcon; + u32 ubrdiv; + u32 udivslot; +}; + +/* helper functions to save/restore lists of registers. */ + +extern int s5p_irq_suspend(struct sys_device *dev, pm_message_t state); +extern int s5p_irq_resume(struct sys_device *dev); + +/* PM debug functions */ + +#ifdef CONFIG_S3C2410_PM_DEBUG +/** + * s3c_pm_dbg() - low level debug function for use in suspend/resume. + * @msg: The message to print. + * + * This function is used mainly to debug the resume process before the system + * can rely on printk/console output. It uses the low-level debugging output + * routine printascii() to do its work. + */ +extern void s3c_pm_dbg(const char *msg, ...); + +#define S3C_PMDBG(fmt...) s3c_pm_dbg(fmt) +#else +#define S3C_PMDBG(fmt...) printk(KERN_INFO fmt) +#endif + +#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK +/** + * s3c_pm_debug_smdkled() - Debug PM suspend/resume via SMDK Board LEDs + * @set: set bits for the state of the LEDs + * @clear: clear bits for the state of the LEDs. + */ +extern void s3c_pm_debug_smdkled(u32 set, u32 clear); + +#else +static inline void s3c_pm_debug_smdkled(u32 set, u32 clear) { } +#endif /* CONFIG_S3C_PM_DEBUG_LED_SMDK */ + +/* suspend memory checking */ + +#ifdef CONFIG_S3C2410_PM_CHECK +extern void s3c_pm_check_prepare(void); +extern void s3c_pm_check_restore(void); +extern void s3c_pm_check_cleanup(void); +extern void s3c_pm_check_store(void); +#else +#define s3c_pm_check_prepare() do { } while (0) +#define s3c_pm_check_restore() do { } while (0) +#define s3c_pm_check_cleanup() do { } while (0) +#define s3c_pm_check_store() do { } while (0) +#endif + +extern void s3c_pm_do_save(struct sleep_save *ptr, int count); +extern void s3c_pm_do_restore(struct sleep_save *ptr, int count); +extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count); + +#ifdef CONFIG_PM +extern int s3c_irqext_wake(unsigned int irqno, unsigned int state); +extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state); +extern int s3c24xx_irq_resume(struct sys_device *dev); +#else +#define s3c_irqext_wake NULL +#define s3c24xx_irq_suspend NULL +#define s3c24xx_irq_resume NULL +#endif + +/** + * s3c_pm_configure_extint() - ensure pins are correctly set for IRQ + * + * Setup all the necessary GPIO pins for waking the system on external + * interrupt. + */ +extern void s3c_pm_configure_extint(void); + +/** + * s3c_pm_restore_gpios() - restore the state of the gpios after sleep. + * + * Restore the state of the GPIO pins after sleep, which may involve ensuring + * that we do not glitch the state of the pins from that the bootloader's + * resume code has done. +*/ +extern void s3c_pm_restore_gpios(void); + +/** + * s3c_pm_save_gpios() - save the state of the GPIOs for restoring after sleep. + * + * Save the GPIO states for resotration on resume. See s3c_pm_restore_gpios(). + */ +extern void s3c_pm_save_gpios(void); + +/** + * s3c_pm_cb_flushcache - callback for assembly code + * + * Callback to issue flush_cache_all() as this call is + * not a directly callable object. + */ +extern void s3c_pm_cb_flushcache(void); + +extern void s3c_pm_save_core(void); +extern void s3c_pm_restore_core(void); + +#if defined(CONFIG_MACH_S5PC110_P1) +enum ENUM_PM_WAKEUP_STAT +{ + PM_WAKEUP_NONE, + PM_POWER_KEY, + PM_VOLUME_UP, + PM_VOLUME_DOWN +}; + +extern int s3c_pm_get_wakeup_stat(void); +extern void s3c_pm_clear_wakeup_stat(void); +#endif // CONFIG_MACH_S5PC110_P1 + diff --git a/arch/arm/plat-s5p/irq-pm.c b/arch/arm/plat-s5p/irq-pm.c index 327acb3..5397d93 100644 --- a/arch/arm/plat-s5p/irq-pm.c +++ b/arch/arm/plat-s5p/irq-pm.c @@ -61,19 +61,19 @@ static struct sleep_save eint_save[] = { SAVE_ITEM(S5P_EINT_CON(2)), SAVE_ITEM(S5P_EINT_CON(3)), - SAVE_ITEM(S5P_EINT_FLTCON(0)), - SAVE_ITEM(S5P_EINT_FLTCON(1)), - SAVE_ITEM(S5P_EINT_FLTCON(2)), - SAVE_ITEM(S5P_EINT_FLTCON(3)), - SAVE_ITEM(S5P_EINT_FLTCON(4)), - SAVE_ITEM(S5P_EINT_FLTCON(5)), - SAVE_ITEM(S5P_EINT_FLTCON(6)), - SAVE_ITEM(S5P_EINT_FLTCON(7)), - SAVE_ITEM(S5P_EINT_MASK(0)), SAVE_ITEM(S5P_EINT_MASK(1)), SAVE_ITEM(S5P_EINT_MASK(2)), SAVE_ITEM(S5P_EINT_MASK(3)), + + SAVE_ITEM(S5P_EINT_FLTCON(0,0)), + SAVE_ITEM(S5P_EINT_FLTCON(0,1)), + SAVE_ITEM(S5P_EINT_FLTCON(1,0)), + SAVE_ITEM(S5P_EINT_FLTCON(1,1)), + SAVE_ITEM(S5P_EINT_FLTCON(2,0)), + SAVE_ITEM(S5P_EINT_FLTCON(2,1)), + SAVE_ITEM(S5P_EINT_FLTCON(3,0)), + SAVE_ITEM(S5P_EINT_FLTCON(3,1)), }; int s3c24xx_irq_suspend(void) diff --git a/arch/arm/plat-s5p/pm.c b/arch/arm/plat-s5p/pm.c index d15dc47..242c16b 100644 --- a/arch/arm/plat-s5p/pm.c +++ b/arch/arm/plat-s5p/pm.c @@ -1,24 +1,252 @@ /* linux/arch/arm/plat-s5p/pm.c * * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com + * http://www.samsung.com/ * * S5P Power Manager (Suspend-To-RAM) support * - * Based on arch/arm/plat-s3c24xx/pm.c - * Copyright (c) 2004,2006 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> + * Based on arch/arm/mach-pxa/pm.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include <linux/init.h> #include <linux/suspend.h> +#include <linux/errno.h> +#include <linux/time.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/crc32.h> +#include <linux/ioport.h> +#include <linux/delay.h> +#include <linux/serial_core.h> +#include <linux/io.h> +#include <linux/platform_device.h> + +#include <asm/cacheflush.h> +#include <mach/hardware.h> + +#include <plat/map-base.h> +#include <plat/regs-serial.h> +#include <plat/regs-timer.h> +#include <mach/regs-clock.h> +#include <plat/gpio-cfg.h> +#include <mach/regs-mem.h> +#include <mach/regs-irq.h> +#include <mach/regs-gpio.h> +#include <linux/gpio.h> +#include <asm/mach/time.h> + #include <plat/pm.h> +#include <mach/irqs.h> #define PFX "s5p pm: " +static struct sleep_save core_save[] = { +/* PLL Control */ + SAVE_ITEM(S5P_APLL_CON), + SAVE_ITEM(S5P_MPLL_CON), + SAVE_ITEM(S5P_EPLL_CON), + SAVE_ITEM(S5P_VPLL_CON), +/* Clock source */ + SAVE_ITEM(S5P_CLK_SRC0), + SAVE_ITEM(S5P_CLK_SRC1), + SAVE_ITEM(S5P_CLK_SRC2), + SAVE_ITEM(S5P_CLK_SRC3), + SAVE_ITEM(S5P_CLK_SRC4), + SAVE_ITEM(S5P_CLK_SRC5), + SAVE_ITEM(S5P_CLK_SRC6), +/* Clock source Mask */ + SAVE_ITEM(S5P_CLK_SRC_MASK0), + SAVE_ITEM(S5P_CLK_SRC_MASK1), +/* Clock Divider */ + SAVE_ITEM(S5P_CLK_DIV0), + SAVE_ITEM(S5P_CLK_DIV1), + SAVE_ITEM(S5P_CLK_DIV2), + SAVE_ITEM(S5P_CLK_DIV3), + SAVE_ITEM(S5P_CLK_DIV4), + SAVE_ITEM(S5P_CLK_DIV5), + SAVE_ITEM(S5P_CLK_DIV6), + SAVE_ITEM(S5P_CLK_DIV7), +/* Clock Main Main Gate */ + SAVE_ITEM(S5P_CLKGATE_MAIN0), + SAVE_ITEM(S5P_CLKGATE_MAIN1), + SAVE_ITEM(S5P_CLKGATE_MAIN2), +/* Clock source Peri Gate */ + SAVE_ITEM(S5P_CLKGATE_PERI0), + SAVE_ITEM(S5P_CLKGATE_PERI1), +/* Clock source SCLK Gate */ + SAVE_ITEM(S5P_CLKGATE_SCLK0), + SAVE_ITEM(S5P_CLKGATE_SCLK1), +/* Clock IP Clock gate */ + SAVE_ITEM(S5P_CLKGATE_IP0), + SAVE_ITEM(S5P_CLKGATE_IP1), + SAVE_ITEM(S5P_CLKGATE_IP2), + SAVE_ITEM(S5P_CLKGATE_IP3), + SAVE_ITEM(S5P_CLKGATE_IP4), +/* Clock Blcok and Bus gate */ + SAVE_ITEM(S5P_CLKGATE_BLOCK), + SAVE_ITEM(S5P_CLKGATE_BUS0), +/* Clock ETC */ + SAVE_ITEM(S5P_CLK_OUT), + SAVE_ITEM(S5P_MDNIE_SEL), +/* PWM Register */ + SAVE_ITEM(S3C2410_TCFG0), + SAVE_ITEM(S3C2410_TCFG1), + SAVE_ITEM(S3C64XX_TINT_CSTAT), + SAVE_ITEM(S3C2410_TCON), + SAVE_ITEM(S3C2410_TCNTB(0)), + SAVE_ITEM(S3C2410_TCMPB(0)), + SAVE_ITEM(S3C2410_TCNTO(0)), +}; + +static struct sleep_save sromc_save[] = { + SAVE_ITEM(S5P_SROM_BW), + SAVE_ITEM(S5P_SROM_BC0), + SAVE_ITEM(S5P_SROM_BC1), + SAVE_ITEM(S5P_SROM_BC2), + SAVE_ITEM(S5P_SROM_BC3), + SAVE_ITEM(S5P_SROM_BC4), + SAVE_ITEM(S5P_SROM_BC5), +}; + +static struct sleep_save gpio_save_ext[] = { + + SAVE_ITEM(S5P_EINT_CON(0)), + SAVE_ITEM(S5P_EINT_CON(1)), + SAVE_ITEM(S5P_EINT_CON(2)), + SAVE_ITEM(S5P_EINT_CON(3)), + + SAVE_ITEM(S5P_EINT_MASK(0)), + SAVE_ITEM(S5P_EINT_MASK(1)), + SAVE_ITEM(S5P_EINT_MASK(2)), + SAVE_ITEM(S5P_EINT_MASK(3)), + + SAVE_ITEM(S5P_EINT_FLTCON(0,0)), + SAVE_ITEM(S5P_EINT_FLTCON(0,1)), + SAVE_ITEM(S5P_EINT_FLTCON(1,0)), + SAVE_ITEM(S5P_EINT_FLTCON(1,1)), + SAVE_ITEM(S5P_EINT_FLTCON(2,0)), + SAVE_ITEM(S5P_EINT_FLTCON(2,1)), + SAVE_ITEM(S5P_EINT_FLTCON(3,0)), + SAVE_ITEM(S5P_EINT_FLTCON(3,1)), +}; + +/*gpio group interrupt*/ +static struct sleep_save gpio_save_gpio_int[] = { + + SAVE_ITEM(S5PV210_GPA0_INT_CON), + SAVE_ITEM(S5PV210_GPA1_INT_CON), + SAVE_ITEM(S5PV210_GPB_INT_CON), + SAVE_ITEM(S5PV210_GPC0_INT_CON), + SAVE_ITEM(S5PV210_GPC1_INT_CON), + SAVE_ITEM(S5PV210_GPD0_INT_CON), + SAVE_ITEM(S5PV210_GPD1_INT_CON), + SAVE_ITEM(S5PV210_GPE0_INT_CON), + SAVE_ITEM(S5PV210_GPE1_INT_CON), + SAVE_ITEM(S5PV210_GPF0_INT_CON), + SAVE_ITEM(S5PV210_GPF1_INT_CON), + SAVE_ITEM(S5PV210_GPF2_INT_CON), + SAVE_ITEM(S5PV210_GPF3_INT_CON), + SAVE_ITEM(S5PV210_GPG0_INT_CON), + SAVE_ITEM(S5PV210_GPG1_INT_CON), + SAVE_ITEM(S5PV210_GPG2_INT_CON), + SAVE_ITEM(S5PV210_GPG3_INT_CON), + SAVE_ITEM(S5PV210_GPJ0_INT_CON), + SAVE_ITEM(S5PV210_GPJ1_INT_CON), + SAVE_ITEM(S5PV210_GPJ2_INT_CON), + SAVE_ITEM(S5PV210_GPJ3_INT_CON), + SAVE_ITEM(S5PV210_GPJ4_INT_CON), + + SAVE_ITEM(S5PV210_GPA0_INT_MASK), + SAVE_ITEM(S5PV210_GPA1_INT_MASK), + SAVE_ITEM(S5PV210_GPB_INT_MASK), + SAVE_ITEM(S5PV210_GPC0_INT_MASK), + SAVE_ITEM(S5PV210_GPC1_INT_MASK), + SAVE_ITEM(S5PV210_GPD0_INT_MASK), + SAVE_ITEM(S5PV210_GPD1_INT_MASK), + SAVE_ITEM(S5PV210_GPE0_INT_MASK), + SAVE_ITEM(S5PV210_GPE1_INT_MASK), + SAVE_ITEM(S5PV210_GPF0_INT_MASK), + SAVE_ITEM(S5PV210_GPF1_INT_MASK), + SAVE_ITEM(S5PV210_GPF2_INT_MASK), + SAVE_ITEM(S5PV210_GPF3_INT_MASK), + SAVE_ITEM(S5PV210_GPG0_INT_MASK), + SAVE_ITEM(S5PV210_GPG1_INT_MASK), + SAVE_ITEM(S5PV210_GPG2_INT_MASK), + SAVE_ITEM(S5PV210_GPG3_INT_MASK), + SAVE_ITEM(S5PV210_GPJ0_INT_MASK), + SAVE_ITEM(S5PV210_GPJ1_INT_MASK), + SAVE_ITEM(S5PV210_GPJ2_INT_MASK), + SAVE_ITEM(S5PV210_GPJ3_INT_MASK), + SAVE_ITEM(S5PV210_GPJ4_INT_MASK), + + SAVE_ITEM(S5PV210_GPA0_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPA0_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPA1_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPA1_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPB_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPB_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPC0_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPC0_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPC1_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPC1_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPD0_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPD0_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPD1_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPD1_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPE0_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPE0_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPE1_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPE1_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPF0_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPF0_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPF1_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPF1_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPF2_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPF2_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPF3_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPF3_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPG0_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPG0_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPG1_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPG1_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPG2_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPG2_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPG3_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPG3_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPJ0_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPJ0_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPJ1_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPJ1_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPJ2_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPJ2_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPJ3_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPJ3_INT_FLTCON1), + SAVE_ITEM(S5PV210_GPJ4_INT_FLTCON0), + SAVE_ITEM(S5PV210_GPJ4_INT_FLTCON1), + +}; + +/* this lot should be really saved by the IRQ code */ +/* VICXADDRESSXX initilaization to be needed */ +static struct sleep_save irq_save[] = { + SAVE_ITEM(S5P_VIC0REG(VIC_INT_SELECT)), + SAVE_ITEM(S5P_VIC1REG(VIC_INT_SELECT)), + SAVE_ITEM(S5P_VIC2REG(VIC_INT_SELECT)), + SAVE_ITEM(S5P_VIC3REG(VIC_INT_SELECT)), + SAVE_ITEM(S5P_VIC0REG(VIC_INT_ENABLE)), + SAVE_ITEM(S5P_VIC1REG(VIC_INT_ENABLE)), + SAVE_ITEM(S5P_VIC2REG(VIC_INT_ENABLE)), + SAVE_ITEM(S5P_VIC3REG(VIC_INT_ENABLE)), + SAVE_ITEM(S5P_VIC0REG(VIC_INT_SOFT)), + SAVE_ITEM(S5P_VIC1REG(VIC_INT_SOFT)), + SAVE_ITEM(S5P_VIC2REG(VIC_INT_SOFT)), + SAVE_ITEM(S5P_VIC3REG(VIC_INT_SOFT)), +}; + /* s3c_pm_configure_extint * * configure all external interrupt pins @@ -26,16 +254,30 @@ void s3c_pm_configure_extint(void) { - /* nothing here yet */ + + /* for each of the external interrupts (EINT0..EINT15) we + * need to check wether it is an external interrupt source, + * and then configure it as an input if it is not + */ + __raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK); } + void s3c_pm_restore_core(void) { - /* nothing here yet */ + s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save)); + s3c_pm_do_restore(sromc_save, ARRAY_SIZE(sromc_save)); + s3c_pm_do_restore(gpio_save_ext, ARRAY_SIZE(gpio_save_ext)); + s3c_pm_do_restore(gpio_save_gpio_int, ARRAY_SIZE(gpio_save_gpio_int)); + s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); } void s3c_pm_save_core(void) { - /* nothing here yet */ + s3c_pm_do_save(sromc_save, ARRAY_SIZE(sromc_save)); + s3c_pm_do_save(core_save, ARRAY_SIZE(core_save)); + s3c_pm_do_save(gpio_save_ext, ARRAY_SIZE(gpio_save_ext)); + s3c_pm_do_save(gpio_save_gpio_int, ARRAY_SIZE(gpio_save_gpio_int)); + s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); } diff --git a/arch/arm/plat-s5p/sleep.S b/arch/arm/plat-s5p/sleep.S new file mode 100644 index 0000000..db1b819 --- /dev/null +++ b/arch/arm/plat-s5p/sleep.S @@ -0,0 +1,319 @@ +/* linux/arch/arm/plat-s5p/sleep.S + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5PV210 power Manager (Suspend-To-RAM) support + * Based on S3C2410 sleep code by: + * Ben Dooks, (c) 2004 Simtec Electronics + * + * Based on PXA/SA1100 sleep code by: + * Nicolas Pitre, (c) 2002 Monta Vista Software Inc + * Cliff Brake, (c) 2001 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include <linux/linkage.h> +#include <asm/assembler.h> +#include <mach/hardware.h> +#include <mach/map.h> +#include <asm/asm-offsets.h> +#include <asm/memory.h> +#include <asm/system.h> + +#include <mach/regs-gpio.h> +#include <mach/regs-clock.h> +#include <mach/regs-mem.h> +#include <plat/regs-serial.h> + +#define NO_L2_CLEAN + +/* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not + * reset the UART configuration, only enable if you really need this! +*/ + .text + + /* s3c_cpu_save + * + * entry: + * r0 = save address (virtual addr of s3c_sleep_save_phys) + */ + +ENTRY(s3c_cpu_save) + + stmfd sp!, { r3 - r12, lr } + + mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID + mrc p15, 0, r5, c3, c0, 0 @ Domain ID + mrc p15, 0, r6, c2, c0, 0 @ Translation Table BASE0 + mrc p15, 0, r7, c2, c0, 1 @ Translation Table BASE1 + mrc p15, 0, r8, c2, c0, 2 @ Translation Table Control + mrc p15, 0, r9, c1, c0, 0 @ Control register + mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register + mrc p15, 0, r11, c1, c0, 2 @ Co-processor access controls + mrc p15, 0, r12, c10, c2, 0 @ Read PRRR + mrc p15, 0, r3, c10, c2, 1 @ READ NMRR + + ldr r2, =S5P_INFORM1 + ldr r1, [r2] + cmp r1, #0x0 + bne idle2_save + + stmia r0, { r3 - r13 } + + @@ write our state back to RAM + bl s3c_pm_cb_flushcache + + @@ jump to final code to send system to sleep + ldr r0, =pm_cpu_sleep + @@ldr pc, [ r0 ] + ldr r0, [ r0 ] + mov pc, r0 + +idle2_save: + /* Save CP15 registers */ + stmia r0!, { r3 - r12} + + /* Save SVC status register */ + mrs r2, spsr + str r2, [r0], #4 + + /* Save FIQ mode register */ + mov r1, #PSR_I_BIT | PSR_F_BIT | FIQ_MODE + msr cpsr_c, r1 + mrs r2, spsr + stmia r0!, {r2, r8 - r12, sp, lr } + + /* Save ABT mode register */ + mov r1, #PSR_I_BIT | PSR_F_BIT | ABT_MODE + msr cpsr_c, r1 + mrs r2, spsr + stmia r0!, {r2, sp, lr } + + /* Save IRQ mode register */ + mov r1, #PSR_I_BIT | PSR_F_BIT | IRQ_MODE + msr cpsr_c, r1 + mrs r2, spsr + stmia r0!, {r2, sp, lr } + + /* Save UND mode register */ + mov r1, #PSR_I_BIT | PSR_F_BIT | UND_MODE + msr cpsr_c, r1 + mrs r2, spsr + stmia r0!, {r2, sp, lr } +#if 0 + /* Save SYS mode register */ + mov r1, #PSR_I_BIT | PSR_F_BIT | SYSTEM_MODE + msr cpsr_c, r1 + stmia r0!, {sp, lr } +#endif + /* Return to SVC mode */ + mov r1, #PSR_I_BIT | PSR_F_BIT | SVC_MODE + msr cpsr_c, r1 + + /* Save SVC mode stack pointer register (R13) */ + str r13, [r0] + + mov r0, #0 + ldmfd sp, { r3 - r12, pc } + + @@ return to the caller, after having the MMU + @@ turned on, this restores the last bits from the + @@ stack +resume_with_mmu: +#if defined(NO_L2_CLEAN) + ldr r0, =S5P_INFORM1 + ldr r1, [r0] + cmp r1, #0x0 + beq skip_l2_enable + + mrc p15, 0, r0, c1, c0, 1 @enable L2 cache + orr r0, r0, #(1<<1) + mcr p15, 0, r0, c1, c0, 1 +#endif +skip_l2_enable: + mov r0, #1 + + /* delete added mmu table list */ + ldr r9 , =(PAGE_OFFSET - PHYS_OFFSET) + add r4, r4, r9 + str r12, [r4] + + ldmfd sp!, { r3 - r12, pc } + + .ltorg + + @@ the next bits sit in the .data segment, even though they + @@ happen to be code... the s5pv210_sleep_save_phys needs to be + @@ accessed by the resume code before it can restore the MMU. + @@ This means that the variable has to be close enough for the + @@ code to read it... since the .text segment needs to be RO, + @@ the data segment can be the only place to put this code. + + .data + + .global s3c_sleep_save_phys +s3c_sleep_save_phys: + .word 0 + + + /* sleep magic, to allow the bootloader to check for an valid + * image to resume to. Must be the first word before the + * s5pv210_cpu_resume entry. + */ + + .word 0x2bedf00d + + /* s3c_cpu_resume + * + * resume code entry for bootloader to call + * + * we must put this code here in the data segment as we have no + * other way of restoring the stack pointer after sleep, and we + * must not write to the code segment (code is read-only) + */ + +ENTRY(s3c_cpu_resume) + mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE + msr cpsr_c, r0 + + @@ load UART to allow us to print the two characters for + @@ resume debug + + mov r1, #0 + mcr p15, 0, r1, c8, c7, 0 @@ invalidate TLBs + mcr p15, 0, r1, c7, c5, 0 @@ invalidate I Cache + + ldr r1, =0xe010f008 @ Read INFORM2 register + ldr r0, [r1] @ Load phy_regs_save value + ldr r1, =0xe010f004 @ Read INFORM1 register + ldr r1, [r1] + cmp r1, #0x0 + bne idle2_restore_1 + + ldmia r0, { r3 - r13 } + b common_restore_1 + +idle2_restore_1: + /* Restore CP15 registers */ + ldmia r0!, { r3 - r12 } + +common_restore_1: + mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID + mcr p15, 0, r5, c3, c0, 0 @ Domain ID + + mcr p15, 0, r8, c2, c0, 2 @ Translation Table Control + mcr p15, 0, r7, c2, c0, 1 @ Translation Table BASE1 + mcr p15, 0, r6, c2, c0, 0 @ Translation Table BASE0 + +#if defined(NO_L2_CLEAN) + cmp r1, #0x0 @ if idle2 wakeup + bicne r10, r10, #(1<<1) @ disable L2cache + mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register +#endif + mov r1, #0 + mcr p15, 0, r1, c8, c7, 0 @ Invalidate I & D TLB + + mov r1, #0 @ restore copro access controls + mcr p15, 0, r11, c1, c0, 2 @ Co-processor access controls + mcr p15, 0, r1, c7, c5, 4 + + mcr p15, 0, r12, c10, c2, 0 @ write PRRR + mcr p15, 0, r3, c10, c2, 1 @ write NMRR + + ldr r1, =0xe010f004 @ Read INFORM1 register + ldr r1, [r1] + cmp r1, #0x0 + beq common_restore_2 + + /* Restore SVC status register */ + ldr r2, [r0], #4 + msr spsr, r2 + + /* Restore FIQ mode register */ + mov r1, #PSR_I_BIT | PSR_F_BIT | FIQ_MODE + msr cpsr_c, r1 + ldr r2, [r0], #4 + msr spsr, r2 + ldmia r0!, { r8 - r12, sp, lr } + + /* Restore ABT mode register */ + mov r1, #PSR_I_BIT | PSR_F_BIT | ABT_MODE + msr cpsr_c, r1 + ldr r2, [r0], #4 + msr spsr, r2 + ldmia r0!, { sp, lr } + + /* Restore IRQ mode register */ + mov r1, #PSR_I_BIT | PSR_F_BIT | IRQ_MODE + msr cpsr_c, r1 + ldr r2, [r0], #4 + msr spsr, r2 + ldmia r0!, { sp, lr } + + /* Restore UND mode register */ + mov r1, #PSR_I_BIT | PSR_F_BIT | UND_MODE + msr cpsr_c, r1 + ldr r2, [r0], #4 + msr spsr, r2 + ldmia r0!, { sp, lr } +#if 0 + /* Restore SYS mode register */ + mov r1, #PSR_I_BIT | PSR_F_BIT | SYSTEM_MODE + msr cpsr_c, r1 + ldmia r0!, {sp, lr } +#endif + /* Return to SVC mode */ + mov r1, #PSR_I_BIT | PSR_F_BIT | SVC_MODE + msr cpsr_c, r1 + + /* Restore SVC mode stack pointer register (R13) */ + ldr r13, [r0] + +common_restore_2: + /* calculate first section address into r8 */ + mov r4, r6 + ldr r5, =0x3fff + bic r4, r4, r5 + ldr r11, =0xe010f000 + ldr r10, [r11, #0] + mov r10, r10 ,LSR #18 + bic r10, r10, #0x3 + orr r4, r4, r10 + + /* calculate mmu list value into r9 */ + mov r10, r10, LSL #18 + ldr r5, =0x40e + orr r10, r10, r5 + + /* back up originally data */ + ldr r12, [r4] + + /* Added list about mmu */ + str r10, [r4] + + ldr r2, =resume_with_mmu + mcr p15, 0, r9, c1, c0, 0 @ turn on MMU, etc + + nop + nop + nop + nop + nop @ second-to-last before mmu + + mov pc, r2 @ go back to virtual address + + .ltorg |