Skip to content

Commit

Permalink
[ARM] S3C64XX: Initial support for PM (suspend to RAM)
Browse files Browse the repository at this point in the history
Add the initial support for the S3C64XX based systems to use
suspend-to-RAM to sleep.

Includes basic debugging for use with the SMDK6410 usign the
LEDs on the baseboard.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>
  • Loading branch information
Ben Dooks committed May 7, 2009
1 parent 4b637dc commit bd117bd
Show file tree
Hide file tree
Showing 11 changed files with 479 additions and 2 deletions.
16 changes: 16 additions & 0 deletions arch/arm/mach-s3c6400/include/mach/regs-clock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* linux/arch/arm/mach-s3c6400/include/mach/regs-clock.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
* S3C64XX - clock register compatibility with s3c24xx
*
* 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 <plat/regs-clock.h>

9 changes: 9 additions & 0 deletions arch/arm/plat-s3c/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ config S3C2410_PM_DEBUG
Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
for more information.

config S3C_PM_DEBUG_LED_SMDK
bool "SMDK LED suspend/resume debugging"
depends on PM && (MACH_SMDK6410)
help
Say Y here to enable the use of the SMDK LEDs on the baseboard
for debugging of the state of the suspend and resume process.

Note, this currently only works for S3C64XX based SMDK boards.

config S3C2410_PM_CHECK
bool "S3C2410 PM Suspend Memory CRC"
depends on PM && CRC32
Expand Down
12 changes: 12 additions & 0 deletions arch/arm/plat-s3c/include/plat/pm.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,18 @@ extern void s3c_pm_dbg(const char *msg, ...);
#define S3C_PMDBG(fmt...) printk(KERN_DEBUG 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
Expand Down
6 changes: 4 additions & 2 deletions arch/arm/plat-s3c/pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@

#include <asm/cacheflush.h>
#include <mach/hardware.h>
#include <mach/map.h>

#include <plat/regs-serial.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
#include <mach/regs-mem.h>
#include <mach/regs-irq.h>
#include <asm/irq.h>

Expand Down Expand Up @@ -326,6 +325,9 @@ static int s3c_pm_enter(suspend_state_t state)

S3C_PMDBG("%s: post sleep, preparing to return\n", __func__);

/* LEDs should now be 1110 */
s3c_pm_debug_smdkled(1 << 1, 0);

s3c_pm_check_restore();

/* ok, let's return from sleep */
Expand Down
5 changes: 5 additions & 0 deletions arch/arm/plat-s3c64xx/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ obj-y += gpiolib.o
obj-$(CONFIG_CPU_S3C6400_INIT) += s3c6400-init.o
obj-$(CONFIG_CPU_S3C6400_CLOCK) += s3c6400-clock.o

# PM support

obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_PM) += sleep.o

# Device setup

obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o
Expand Down
1 change: 1 addition & 0 deletions arch/arm/plat-s3c64xx/include/plat/irqs.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@

#define S3C_EINT(x) ((x) + S3C_IRQ_EINT_BASE)
#define IRQ_EINT(x) S3C_EINT(x)
#define IRQ_EINT_BIT(x) ((x) - S3C_EINT(0))

/* Next the external interrupt groups. These are similar to the IRQ_EINT(x)
* that they are sourced from the GPIO pins but with a different scheme for
Expand Down
98 changes: 98 additions & 0 deletions arch/arm/plat-s3c64xx/include/plat/pm-core.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/* linux/arch/arm/plat-s3c64xx/include/plat/pm-core.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX - PM core support for arch/arm/plat-s3c/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 <plat/regs-gpio.h>

static inline void s3c_pm_debug_init_uart(void)
{
u32 tmp = __raw_readl(S3C_PCLK_GATE);

/* As a note, since the S3C64XX UARTs generally have multiple
* clock sources, we simply enable PCLK at the moment and hope
* that the resume settings for the UART are suitable for the
* use with PCLK.
*/

tmp |= S3C_CLKCON_PCLK_UART0;
tmp |= S3C_CLKCON_PCLK_UART1;
tmp |= S3C_CLKCON_PCLK_UART2;
tmp |= S3C_CLKCON_PCLK_UART3;

__raw_writel(tmp, S3C_PCLK_GATE);
udelay(10);
}

static inline void s3c_pm_arch_prepare_irqs(void)
{
/* VIC should have already been taken care of */

/* clear any pending EINT0 interrupts */
__raw_writel(__raw_readl(S3C64XX_EINT0PEND), S3C64XX_EINT0PEND);
}

static inline void s3c_pm_arch_stop_clocks(void)
{
}

static inline void s3c_pm_arch_show_resume_irqs(void)
{
}

/* make these defines, we currently do not have any need to change
* the IRQ wake controls depending on the CPU we are running on */

#define s3c_irqwake_eintallow ((1 << 28) - 1)
#define s3c_irqwake_intallow (0)

static inline void s3c_pm_arch_update_uart(void __iomem *regs,
struct pm_uart_save *save)
{
u32 ucon = __raw_readl(regs + S3C2410_UCON);
u32 ucon_clk = ucon & S3C6400_UCON_CLKMASK;
u32 save_clk = save->ucon & S3C6400_UCON_CLKMASK;
u32 new_ucon;
u32 delta;

/* S3C64XX UART blocks only support level interrupts, so ensure that
* when we restore unused UART blocks we force the level interrupt
* settigs. */
save->ucon |= S3C2410_UCON_TXILEVEL | S3C2410_UCON_RXILEVEL;

/* We have a constraint on changing the clock type of the UART
* between UCLKx and PCLK, so ensure that when we restore UCON
* that the CLK field is correctly modified if the bootloader
* has changed anything.
*/
if (ucon_clk != save_clk) {
new_ucon = save->ucon;
delta = ucon_clk ^ save_clk;

/* change from UCLKx => wrong PCLK,
* either UCLK can be tested for by a bit-test
* with UCLK0 */
if (ucon_clk & S3C6400_UCON_UCLK0 &&
!(save_clk & S3C6400_UCON_UCLK0) &&
delta & S3C6400_UCON_PCLK2) {
new_ucon &= ~S3C6400_UCON_UCLK0;
} else if (delta == S3C6400_UCON_PCLK2) {
/* as an precaution, don't change from
* PCLK2 => PCLK or vice-versa */
new_ucon ^= S3C6400_UCON_PCLK2;
}

S3C_PMDBG("ucon change %04x => %04x (save=%04x)\n",
ucon, new_ucon, save->ucon);
save->ucon = new_ucon;
}
}
1 change: 1 addition & 0 deletions arch/arm/plat-s3c64xx/include/plat/regs-clock.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#define S3C_HCLK_GATE S3C_CLKREG(0x30)
#define S3C_PCLK_GATE S3C_CLKREG(0x34)
#define S3C_SCLK_GATE S3C_CLKREG(0x38)
#define S3C_MEM0_GATE S3C_CLKREG(0x3C)

/* CLKDIV0 */
#define S3C6400_CLKDIV0_MFC_MASK (0xf << 28)
Expand Down
3 changes: 3 additions & 0 deletions arch/arm/plat-s3c64xx/irq-eint.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/sysdev.h>
#include <linux/gpio.h>
#include <linux/irq.h>
#include <linux/io.h>
Expand All @@ -26,6 +27,7 @@

#include <mach/map.h>
#include <plat/cpu.h>
#include <plat/pm.h>

#define eint_offset(irq) ((irq) - IRQ_EINT(0))
#define eint_irq_to_bit(irq) (1 << eint_offset(irq))
Expand Down Expand Up @@ -134,6 +136,7 @@ static struct irq_chip s3c_irq_eint = {
.mask_ack = s3c_irq_eint_maskack,
.ack = s3c_irq_eint_ack,
.set_type = s3c_irq_eint_set_type,
.set_wake = s3c_irqext_wake,
};

/* s3c_irq_demux_eint
Expand Down
Loading

0 comments on commit bd117bd

Please sign in to comment.