[PATCH v2] ARM: S5PV210: Add Power Management Support

Kyungmin Park kmpark at infradead.org
Tue Jun 1 00:21:26 EDT 2010


On Tue, Jun 1, 2010 at 1:16 PM, Ben Dooks <ben at trinity.fluff.org> wrote:
> On Tue, Jun 01, 2010 at 12:23:39PM +0900, Kyungmin Park wrote:
>> On Tue, Jun 1, 2010 at 11:03 AM, Ben Dooks <ben-linux at fluff.org> wrote:
>> >
>> > On Tue, Jun 01, 2010 at 10:36:04AM +0900, Kukjin Kim wrote:
>> >> From: Jongpill Lee <boyko.lee at samsung.com>
>> >>
>> >> This patch adds suspend-to-ram support for S5PV210.
>> >>
>> >> Signed-off-by: Jongpill Lee <boyko.lee at samsung.com>
>> >> Signed-off-by: Kukjin Kim <kgene.kim at samsung.com>
>> >> ---
>> >> Changes since v1:
>> >>
>> >> 1. Fixed comments as per comments from Ben Dooks
>> >> 2. Removed redunt #if defined(CONFIG_PM)
>> >> 3. Removed redunt including header files
>> >> 4. Removed <mach/pm.h> and <plat/pm-s5p.h>
>> >> 5. Moved 's5pv210_core_save' into machine directory
>> >> 6. Moved sleep.S into machine directory for S5P SoCs compatibility
>> >> 7. Added CF retension configuration when wake-up
>> >>
>> >> This patch is based on Linus' master (2.6.35-rc1)
>> >>
>> >>  arch/arm/mach-s5pv210/Kconfig                   |    6 +
>> >>  arch/arm/mach-s5pv210/Makefile                  |    1 +
>> >>  arch/arm/mach-s5pv210/include/mach/pm-core.h    |   44 ++++++
>> >>  arch/arm/mach-s5pv210/include/mach/regs-clock.h |    5 +-
>> >>  arch/arm/mach-s5pv210/mach-smdkc110.c           |    2 +
>> >>  arch/arm/mach-s5pv210/mach-smdkv210.c           |    3 +
>> >>  arch/arm/mach-s5pv210/pm.c                      |  180 +++++++++++++++++++++++
>> >>  arch/arm/mach-s5pv210/sleep.S                   |  166 +++++++++++++++++++++
>> >>  arch/arm/plat-s5p/Makefile                      |    2 +
>> >>  arch/arm/plat-s5p/include/plat/irqs.h           |    2 +
>> >>  arch/arm/plat-s5p/irq-pm.c                      |  108 ++++++++++++++
>> >>  arch/arm/plat-s5p/pm.c                          |   52 +++++++
>> >>  arch/arm/plat-samsung/pm-gpio.c                 |    4 +-
>> >>  13 files changed, 572 insertions(+), 3 deletions(-)
>> >>  create mode 100644 arch/arm/mach-s5pv210/include/mach/pm-core.h
>> >>  create mode 100644 arch/arm/mach-s5pv210/pm.c
>> >>  create mode 100644 arch/arm/mach-s5pv210/sleep.S
>> >>  create mode 100644 arch/arm/plat-s5p/irq-pm.c
>> >>  create mode 100644 arch/arm/plat-s5p/pm.c
>> >>
>> >> diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
>> >> index 0761eac..86cca1b 100644
>> >> --- a/arch/arm/mach-s5pv210/Kconfig
>> >> +++ b/arch/arm/mach-s5pv210/Kconfig
>> >> @@ -14,6 +14,7 @@ config CPU_S5PV210
>> >>       select PLAT_S5P
>> >>       select S3C_PL330_DMA
>> >>       select S5P_EXT_INT
>> >> +     select S5PV210_PM if PM
>> >>       help
>> >>         Enable S5PV210 CPU support
>> >>
>> >> @@ -88,4 +89,9 @@ config MACH_SMDKC110
>> >>         Machine support for Samsung SMDKC110
>> >>         S5PC110(MCP) is one of package option of S5PV210
>> >>
>> >> +config S5PV210_PM
>> >> +     bool
>> >> +     help
>> >> +       Power Management code common to S5PV210
>> >> +
>> >>  endif
>> >> diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
>> >> index 30be9a6..59382ec 100644
>> >> --- a/arch/arm/mach-s5pv210/Makefile
>> >> +++ b/arch/arm/mach-s5pv210/Makefile
>> >> @@ -14,6 +14,7 @@ obj-                                :=
>> >>
>> >>  obj-$(CONFIG_CPU_S5PV210)    += cpu.o init.o clock.o dma.o gpiolib.o
>> >>  obj-$(CONFIG_CPU_S5PV210)    += setup-i2c0.o
>> >> +obj-$(CONFIG_S5PV210_PM)     += pm.o sleep.o
>> >>
>> >>  # machine support
>> >>
>> >> diff --git a/arch/arm/mach-s5pv210/include/mach/pm-core.h b/arch/arm/mach-s5pv210/include/mach/pm-core.h
>> >> new file mode 100644
>> >> index 0000000..ca3f827
>> >> --- /dev/null
>> >> +++ b/arch/arm/mach-s5pv210/include/mach/pm-core.h
>> >> @@ -0,0 +1,44 @@
>> >> +/* linux/arch/arm/mach-s5pv210/include/mach/pm-core.h
>> >> + *
>> >> + * Copyright (c) 2010 Samsung Electronics Co., Ltd.
>> >> + *           http://www.samsung.com
>> >> + *
>> >> + * Based on arch/arm/mach-s3c2410/include/mach/pm-core.h,
>> >> + * Copyright 2008 Simtec Electronics
>> >> + *      Ben Dooks <ben at simtec.co.uk>
>> >> + *      http://armlinux.simtec.co.uk/
>> >> + *
>> >> + * S5PV210 - PM core support for arch/arm/plat-s5p/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.
>> >> +*/
>> >> +
>> >> +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);
>> >> +}
>> >> +
>> >> +static inline void s3c_pm_arch_stop_clocks(void)
>> >> +{
>> >> +     /* nothing here yet */
>> >> +}
>> >> +
>> >> +static inline void s3c_pm_arch_show_resume_irqs(void)
>> >> +{
>> >> +     /* nothing here yet */
>> >> +}
>> >> +
>> >> +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-clock.h b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
>> >> index 2a25ab4..f4a443a 100644
>> >> --- a/arch/arm/mach-s5pv210/include/mach/regs-clock.h
>> >> +++ b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
>> >> @@ -157,8 +157,11 @@
>> >>  #define S5P_SLEEP_CFG_USBOSC_EN              (1 << 1)
>> >>
>> >>  /* OTHERS Resgister */
>> >> +#define S5P_OTHERS_RET_IO            (1 << 31)
>> >> +#define S5P_OTHERS_RET_CF            (1 << 30)
>> >> +#define S5P_OTHERS_RET_MMC           (1 << 29)
>> >> +#define S5P_OTHERS_RET_UART          (1 << 28)
>> >>  #define S5P_OTHERS_USB_SIG_MASK              (1 << 16)
>> >> -#define S5P_OTHERS_MIPI_DPHY_EN              (1 << 28)
>> >>
>> >>  /* MIPI */
>> >>  #define S5P_MIPI_DPHY_EN             (3)
>> >> diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c
>> >> index 4c8903c..ebb4832 100644
>> >> --- a/arch/arm/mach-s5pv210/mach-smdkc110.c
>> >> +++ b/arch/arm/mach-s5pv210/mach-smdkc110.c
>> >> @@ -25,6 +25,7 @@
>> >>  #include <plat/s5pv210.h>
>> >>  #include <plat/devs.h>
>> >>  #include <plat/cpu.h>
>> >> +#include <plat/pm.h>
>> >>
>> >>  /* Following are default values for UCON, ULCON and UFCON UART registers */
>> >>  #define S5PV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL |        \
>> >> @@ -86,6 +87,7 @@ static void __init smdkc110_map_io(void)
>> >>
>> >>  static void __init smdkc110_machine_init(void)
>> >>  {
>> >> +     s3c_pm_init();
>>
>> It's common function. Please add it to platform init instead of each board init.
>
> I know Mark Brown would rather this be the case too, but the original intent
> was that each board would declare itself to be capable of PM by calling this
> function to ensure that any boards which had not been validated or where
> simply incapable of suspend/resume did not end up with this enabled.

Just curious!
Which case is possible when enable the PM configuration but don't use
the s3c_pm_init()?

Thank you,
Kyungmin Park

>
>> >>       platform_add_devices(smdkc110_devices, ARRAY_SIZE(smdkc110_devices));
>> >>  }
>> >>
>> >> diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
>> >> index 0d46279..ba30b5d 100644
>> >> --- a/arch/arm/mach-s5pv210/mach-smdkv210.c
>> >> +++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
>> >> @@ -27,6 +27,7 @@
>> >>  #include <plat/cpu.h>
>> >>  #include <plat/adc.h>
>> >>  #include <plat/ts.h>
>> >> +#include <plat/pm.h>
>> >>
>> >>  /* Following are default values for UCON, ULCON and UFCON UART registers */
>> >>  #define S5PV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL |        \
>> >> @@ -96,6 +97,8 @@ static void __init smdkv210_map_io(void)
>> >>
>> >>  static void __init smdkv210_machine_init(void)
>> >>  {
>> >> +     s3c_pm_init();
>> >> +
>> ditto.
>> >>       s3c24xx_ts_set_platdata(&s3c_ts_platform);
>> >>       platform_add_devices(smdkv210_devices, ARRAY_SIZE(smdkv210_devices));
>> >>  }
>>
>> >> diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c
>> >> new file mode 100644
>> >> index 0000000..0690332
>> >> --- /dev/null
>> >> +++ b/arch/arm/mach-s5pv210/pm.c
>> >> @@ -0,0 +1,180 @@
>> >> +/* linux/arch/arm/mach-s5pv210/pm.c
>> >> + *
>> >> + * Copyright (c) 2010 Samsung Electronics Co., Ltd.
>> >> + *           http://www.samsung.com
>> >> + *
>> >> + * S5PV210 - Power Management support
>> >> + *
>> >> + * Based on arch/arm/mach-s3c2410/pm.c
>> >> + * Copyright (c) 2006 Simtec Electronics
>> >> + *   Ben Dooks <ben at simtec.co.uk>
>> >> + *
>> >> + * 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/io.h>
>> >> +
>> >> +#include <plat/cpu.h>
>> >> +#include <plat/pm.h>
>> >> +#include <plat/regs-timer.h>
>> >> +
>> >> +#include <mach/regs-irq.h>
>> >> +#include <mach/regs-clock.h>
>> >> +
>> >> +static struct sleep_save s5pv210_core_save[] = {
>> >> +     /* 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 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)),
>> >> +
>> >> +     /* VIC 2 and 3*/
>> >> +     SAVE_ITEM(VA_VIC2 + VIC_INT_SELECT),
>> >> +     SAVE_ITEM(VA_VIC3 + VIC_INT_SELECT),
>> >> +     SAVE_ITEM(VA_VIC2 + VIC_INT_ENABLE),
>> >> +     SAVE_ITEM(VA_VIC3 + VIC_INT_ENABLE),
>> >> +     SAVE_ITEM(VA_VIC2 + VIC_INT_SOFT),
>> >> +     SAVE_ITEM(VA_VIC3 + VIC_INT_SOFT),
>> >
>> > doesn't the vic driver do this for you? if not, then would be better
>> > to change the vic to fix this.
>> >
>> >> +};
>> >> +
>> >> +void s5pv210_cpu_suspend(void)
>> >> +{
>> >> +     unsigned long tmp;
>> >> +
>> >> +     /* issue the standby signal into the pm unit. Note, we
>> >> +      * issue a write-buffer drain just in case */
>> >> +
>> >> +     tmp = 0;
>> >> +
>> >> +     asm("b 1f\n\t"
>> >> +         ".align 5\n\t"
>> >> +         "1:\n\t"
>> >> +         "mcr p15, 0, %0, c7, c10, 5\n\t"
>> >> +         "mcr p15, 0, %0, c7, c10, 4\n\t"
>> >> +         ".word 0xe320f003" : : "r" (tmp));
>> >
>> > why .word? if there's a compiler problem then make a comment about
>> > what instruction is being synthesised and why.
>> >
>> >> +     /* we should never get past here */
>> >> +     panic("sleep resumed to originator?");
>> >> +}
>> >> +
>> >> +static void s5pv210_pm_prepare(void)
>> >> +{
>> >> +     unsigned int tmp;
>> >> +
>> >> +     /* ensure at least INFORM0 has the resume address */
>> >> +     __raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0);
>> >> +
>> >> +     tmp = __raw_readl(S5P_SLEEP_CFG);
>> >> +     tmp &= ~(S5P_SLEEP_CFG_OSC_EN | S5P_SLEEP_CFG_USBOSC_EN);
>> >> +     __raw_writel(tmp, S5P_SLEEP_CFG);
>> >> +
>> >> +     /* WFI for SLEEP mode configuration by SYSCON */
>> >> +     tmp = __raw_readl(S5P_PWR_CFG);
>> >> +     tmp &= S5P_CFG_WFI_CLEAN;
>>
>> CLEAN? just use the MASK and use common mask operation. tmp &=
>> ~S5P_CFG_WFI_MASK;
>>
>> >> +     tmp |= S5P_CFG_WFI_SLEEP;
>> >> +     __raw_writel(tmp, S5P_PWR_CFG);
>> >> +
>> >> +     /* SYSCON interrupt handling disable */
>> >> +     tmp = __raw_readl(S5P_OTHERS);
>> >> +     tmp |= S5P_OTHER_SYSC_INTOFF;
>> >> +     __raw_writel(tmp, S5P_OTHERS);
>> >> +
>> >> +     __raw_writel(0xffffffff, (VA_VIC0 + VIC_INT_ENABLE_CLEAR));
>> >> +     __raw_writel(0xffffffff, (VA_VIC1 + VIC_INT_ENABLE_CLEAR));
>> >> +     __raw_writel(0xffffffff, (VA_VIC2 + VIC_INT_ENABLE_CLEAR));
>> >> +     __raw_writel(0xffffffff, (VA_VIC3 + VIC_INT_ENABLE_CLEAR));
>> >> +
>> >> +     s3c_pm_do_save(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save));
>> >> +}
>> >> +
>> >> +static int s5pv210_pm_add(struct sys_device *sysdev)
>> >> +{
>> >> +     pm_cpu_prep = s5pv210_pm_prepare;
>> >> +     pm_cpu_sleep = s5pv210_cpu_suspend;
>> >> +
>> >> +     return 0;
>> >> +}
>> >> +
>> >> +static int s5pv210_pm_resume(struct sys_device *dev)
>> >> +{
>> >> +     u32 tmp;
>> >> +
>> >> +     tmp = __raw_readl(S5P_OTHERS);
>> >> +     tmp |= (S5P_OTHERS_RET_IO | S5P_OTHERS_RET_CF | \
>> >> +             S5P_OTHERS_RET_MMC | S5P_OTHERS_RET_UART);
>> >> +     __raw_writel(tmp , S5P_OTHERS);
>> >> +
>> >> +     s3c_pm_do_restore_core(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save));
>> >> +
>> >> +     return 0;
>> >> +}
>> >> +
>> >> +static struct sysdev_driver s5pv210_pm_driver = {
>> >> +     .add            = s5pv210_pm_add,
>> >> +     .resume         = s5pv210_pm_resume,
>> >> +};
>> >> +
>> >> +static __init int s5pv210_pm_drvinit(void)
>> >> +{
>> >> +     return sysdev_driver_register(&s5pv210_sysclass, &s5pv210_pm_driver);
>> >> +}
>> >> +arch_initcall(s5pv210_pm_drvinit);
>> >> diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S
>> >> new file mode 100644
>> >> index 0000000..b7f8272
>> >> --- /dev/null
>> >> +++ b/arch/arm/mach-s5pv210/sleep.S
>> >> @@ -0,0 +1,166 @@
>> >> +/* linux/arch/arm/mach-s5pv210/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 <asm/memory.h>
>> >> +
>> >> +     .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
>> >> +
>> >> +     stmia   r0, { r3 - r13 }
>> >> +
>> >> +     bl      s3c_pm_cb_flushcache
>> >> +
>> >> +     ldr     r0, =pm_cpu_sleep
>> >> +     ldr     r0, [ r0 ]
>> >> +     mov     pc, r0
>> >> +
>> >> +resume_with_mmu:
>> >> +     /* delete added mmu table list */
>> >
>> > hmm, where is this being added?
>> > also, a better description on what it is doing would be better.
>> >
>> >> +     ldr     r9 , =(PAGE_OFFSET - PHYS_OFFSET)
>> >> +     add     r4, r4, r9
>> >> +     str     r12, [r4]
>> >> +
>> >> +     ldmfd   sp!, { r3 - r12, pc }
>> >> +
>> >> +     .ltorg
>> >> +
>> >> +     .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
>> >> +      * s3c_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
>> >> +
>> >> +     mov     r1, #0
>> >> +     mcr     p15, 0, r1, c8, c7, 0           @@ invalidate TLBs
>> >> +     mcr     p15, 0, r1, c7, c5, 0           @@ invalidate I Cache
>> >> +
>> >> +     ldr     r0, s3c_sleep_save_phys         @ address of restore block
>> >> +     ldmia   r0, { r3 - r13 }
>> >> +
>> >> +     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
>> >> +
>> >> +     mcr     p15, 0, r10, c1, c0, 1          @ Auxiliary control register
>> >> +
>> >> +     mov     r0, #0
>> >> +     mcr     p15, 0, r0, c8, c7, 0           @ Invalidate I & D TLB
>> >> +
>> >> +     mov     r0, #0                          @ restore copro access
>> >> +     mcr     p15, 0, r11, c1, c0, 2          @ Co-processor access
>> >> +     mcr     p15, 0, r0, c7, c5, 4
>> >> +
>> >> +     mcr     p15, 0, r12, c10, c2, 0         @ write PRRR
>> >> +     mcr     p15, 0, r3, c10, c2, 1          @ write NMRR
>> >> +
>> >> +     /* Calculate first section address into r8
>> >> +      * In Cotex-A8 case, When MMU turn on, MMU is reseted.
>> >
>> > i'd fix this typo.
>> >
>> >> +      * So, before call resume_with_mmu, backup originally data.
>> >> +     */
>> >> +
>> >> +     mov     r4, r6
>> >> +     mov     r4, r4, LSR #14
>> >> +     mov     r4, r4, LSL #14
>> >> +
>> >> +     /* Load TLB Base address from INFORM0 */
>> >
>> > do you mean mmu page table?
>> >
>> >> +     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
>>
>> r10 is correct register? in the above it used the r9 register.
>>
>> >> +
>> >> +     /* 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
>> >> diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
>> >> index 39c242b..d04ae49 100644
>> >> --- a/arch/arm/plat-s5p/Makefile
>> >> +++ b/arch/arm/plat-s5p/Makefile
>> >> @@ -18,3 +18,5 @@ obj-y                               += clock.o
>> >>  obj-y                                += irq.o
>> >>  obj-$(CONFIG_S5P_EXT_INT)    += irq-eint.o
>> >>
>> >> +obj-$(CONFIG_PM)             += pm.o
>> >> +obj-$(CONFIG_PM)             += irq-pm.o
>> >> diff --git a/arch/arm/plat-s5p/include/plat/irqs.h b/arch/arm/plat-s5p/include/plat/irqs.h
>> >> index 3fb3a3a..9ffdd62 100644
>> >> --- a/arch/arm/plat-s5p/include/plat/irqs.h
>> >> +++ b/arch/arm/plat-s5p/include/plat/irqs.h
>> >> @@ -94,4 +94,6 @@
>> >>                                               ((irq) - S5P_EINT_BASE1) : \
>> >>                                               ((irq) + 16 - S5P_EINT_BASE2))
>> >>
>> >> +#define IRQ_EINT_BIT(x)              EINT_OFFSET(x)
>> >> +
>> >>  #endif /* __ASM_PLAT_S5P_IRQS_H */
>> >> diff --git a/arch/arm/plat-s5p/irq-pm.c b/arch/arm/plat-s5p/irq-pm.c
>> >> new file mode 100644
>> >> index 0000000..03e83a3
>> >> --- /dev/null
>> >> +++ b/arch/arm/plat-s5p/irq-pm.c
>> >> @@ -0,0 +1,108 @@
>> >> +/* linux/arch/arm/plat-s5p/irq-pm.c
>> >> + *
>> >> + * Copyright (c) 2010 Samsung Electronics Co., Ltd.
>> >> + *           http://www.samsung.com
>> >> + *
>> >> + * Based on arch/arm/plat-s3c24xx/irq-pm.c,
>> >> + * Copyright (c) 2003,2004 Simtec Electronics
>> >> + *   Ben Dooks <ben at simtec.co.uk>
>> >> + *   http://armlinux.simtec.co.uk/
>> >> + *
>> >> + * 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/module.h>
>> >> +#include <linux/interrupt.h>
>> >> +#include <linux/sysdev.h>
>> >> +
>> >> +#include <plat/cpu.h>
>> >> +#include <plat/irqs.h>
>> >> +#include <plat/pm.h>
>> >> +#include <mach/map.h>
>> >> +
>> >> +#include <mach/regs-gpio.h>
>> >> +#include <mach/regs-irq.h>
>> >> +
>> >> +/* state for IRQs over sleep */
>> >> +
>> >> +/* default is to allow for EINT0..EINT31, and IRQ_RTC_TIC, IRQ_RTC_ALARM,
>> >> + * as wakeup sources
>> >> + *
>> >> + * set bit to 1 in allow bitfield to enable the wakeup settings on it
>> >> +*/
>> >> +
>> >> +unsigned long s3c_irqwake_intallow   = 0x00000006L;
>> >> +unsigned long s3c_irqwake_eintallow  = 0xffffffffL;
>> >> +
>> >> +int s3c_irq_wake(unsigned int irqno, unsigned int state)
>> >> +{
>> >> +     unsigned long irqbit;
>> >> +
>> >> +     switch (irqno) {
>> >> +     case IRQ_RTC_TIC:
>> >> +     case IRQ_RTC_ALARM:
>> >> +             irqbit = 1 << (irqno + 1 - IRQ_RTC_ALARM);
>> >> +             if (!state)
>> >> +                     s3c_irqwake_intmask |= irqbit;
>> >> +             else
>> >> +                     s3c_irqwake_intmask &= ~irqbit;
>> >> +             break;
>> >> +     default:
>> >> +             return -ENOENT;
>> >> +     }
>> >> +     return 0;
>> >> +}
>> >> +
>> >> +/* this lot should be really saved by the IRQ code */
>> >> +/* VICXADDRESSXX initilaization to be needed */
>> >> +static struct sleep_save irq_save[] = {
>> >> +     SAVE_ITEM(VA_VIC0 + VIC_INT_SELECT),
>> >> +     SAVE_ITEM(VA_VIC1 + VIC_INT_SELECT),
>> >> +
>> >> +     SAVE_ITEM(VA_VIC0 + VIC_INT_ENABLE),
>> >> +     SAVE_ITEM(VA_VIC1 + VIC_INT_ENABLE),
>> >> +
>> >> +     SAVE_ITEM(VA_VIC0 + VIC_INT_SOFT),
>> >> +     SAVE_ITEM(VA_VIC1 + VIC_INT_SOFT),
>> >> +};
>> >> +
>> >> +static struct sleep_save eint_save[] = {
>> >> +     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_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)),
>> >> +};
>> >> +
>> >> +int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
>> >> +{
>> >> +     s3c_pm_do_save(eint_save, ARRAY_SIZE(eint_save));
>> >> +     s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
>> >> +
>> >> +     return 0;
>> >> +}
>> >> +
>> >> +int s3c24xx_irq_resume(struct sys_device *dev)
>> >> +{
>> >> +     s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
>> >> +     s3c_pm_do_restore(eint_save, ARRAY_SIZE(eint_save));
>> >> +
>> >> +     return 0;
>> >> +}
>> >> +
>> >> diff --git a/arch/arm/plat-s5p/pm.c b/arch/arm/plat-s5p/pm.c
>> >> new file mode 100644
>> >> index 0000000..d592b63
>> >> --- /dev/null
>> >> +++ b/arch/arm/plat-s5p/pm.c
>> >> @@ -0,0 +1,52 @@
>> >> +/* linux/arch/arm/plat-s5p/pm.c
>> >> + *
>> >> + * Copyright (c) 2010 Samsung Electronics Co., Ltd.
>> >> + *           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 at simtec.co.uk>
>> >> + *
>> >> + * 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/suspend.h>
>> >> +#include <plat/pm.h>
>> >> +
>> >> +#define PFX "s5p pm: "
>> >> +
>> >> +/* s3c_pm_check_resume_pin
>> >> + *
>> >> + * check to see if the pin is configured correctly for sleep mode, and
>> >> + * make any necessary adjustments if it is not
>> >> +*/
>> >> +
>> >> +static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
>> >> +{
>> >> +     /* nothing here yet */
>> >> +}
>> >> +
>> >> +/* s3c_pm_configure_extint
>> >> + *
>> >> + * configure all external interrupt pins
>> >> +*/
>> >> +
>> >> +void s3c_pm_configure_extint(void)
>> >> +{
>> >> +     /* nothing here yet */
>> >> +}
>> >> +
>> >> +void s3c_pm_restore_core(void)
>> >> +{
>> >> +     /* nothing here yet */
>> >> +}
>> >> +
>> >> +void s3c_pm_save_core(void)
>> >> +{
>> >> +     /* nothing here yet */
>> >> +}
>> >> +
>> >> diff --git a/arch/arm/plat-samsung/pm-gpio.c b/arch/arm/plat-samsung/pm-gpio.c
>> >> index 7df03f8..9652820 100644
>> >> --- a/arch/arm/plat-samsung/pm-gpio.c
>> >> +++ b/arch/arm/plat-samsung/pm-gpio.c
>> >> @@ -192,7 +192,7 @@ struct s3c_gpio_pm s3c_gpio_pm_2bit = {
>> >>       .resume = s3c_gpio_pm_2bit_resume,
>> >>  };
>> >>
>> >> -#ifdef CONFIG_ARCH_S3C64XX
>> >> +#if defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_PLAT_S5P)
>> >>  static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip)
>> >>  {
>> >>       chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON);
>> >> @@ -302,7 +302,7 @@ struct s3c_gpio_pm s3c_gpio_pm_4bit = {
>> >>       .save   = s3c_gpio_pm_4bit_save,
>> >>       .resume = s3c_gpio_pm_4bit_resume,
>> >>  };
>> >> -#endif /* CONFIG_ARCH_S3C64XX */
>> >> +#endif /* CONFIG_ARCH_S3C64XX || CONFIG_PLAT_S5P */
>> >>
>> >>  /**
>> >>   * s3c_pm_save_gpio() - save gpio chip data for suspend
>> >> --
>> >> 1.6.2.5
>> >>
>> >
>> >
>> > --
>> > --
>> > Ben
>> >
>> > Q:      What's a light-year?
>> > A:      One-third less calories than a regular year.
>> >
>> > --
>> > To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
>> > the body of a message to majordomo at vger.kernel.org
>> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> >
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
> --
> --
> Ben
>
> Q:      What's a light-year?
> A:      One-third less calories than a regular year.
>
>



More information about the linux-arm-kernel mailing list