Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 97991657 authored by Magnus Damm's avatar Magnus Damm Committed by Paul Mundt
Browse files

ARM: mach-shmobile: sh7372 Core Standby Suspend-to-RAM



Add sh7372 Core Standby sleep mode support and tie it
in with the shared SH-Mobile ARM suspend code.

The Core Standby mode is the lightest sh7372-specific
sleep mode, cutting power to the ARM core excluding the
L2 cache. Any interrupt source can be used for wakeups.

The low level portion of this code is based on the
TI OMAP sleep code in sleep34xx.S, thanks to them.

Signed-off-by: default avatarMagnus Damm <damm@opensource.se>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent c3dada18
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ obj-$(CONFIG_ARCH_SH73A0) += entry-gic.o

# PM objects
obj-$(CONFIG_SUSPEND)		+= suspend.o
obj-$(CONFIG_ARCH_SH7372)	+= pm-sh7372.o sleep-sh7372.o

# Board objects
obj-$(CONFIG_MACH_G3EVM)	+= board-g3evm.o
+1 −0
Original line number Diff line number Diff line
@@ -1354,6 +1354,7 @@ static void __init ap4evb_init(void)

	hdmi_init_pm_clock();
	fsi_init_pm_clock();
	sh7372_pm_init();
}

static void __init ap4evb_timer_init(void)
+1 −0
Original line number Diff line number Diff line
@@ -1230,6 +1230,7 @@ static void __init mackerel_init(void)
	platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices));

	hdmi_init_pm_clock();
	sh7372_pm_init();
}

static void __init mackerel_timer_init(void)
+3 −0
Original line number Diff line number Diff line
@@ -31,6 +31,9 @@ extern void sh7372_add_early_devices(void);
extern void sh7372_add_standard_devices(void);
extern void sh7372_clock_init(void);
extern void sh7372_pinmux_init(void);
extern void sh7372_pm_init(void);
extern void sh7372_cpu_suspend(void);
extern void sh7372_cpu_resume(void);
extern struct clk sh7372_extal1_clk;
extern struct clk sh7372_extal2_clk;

+79 −0
Original line number Diff line number Diff line
/*
 * sh7372 Power management support
 *
 *  Copyright (C) 2011 Magnus Damm
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */

#include <linux/pm.h>
#include <linux/suspend.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/tlbflush.h>
#include <mach/common.h>

#define SMFRAM 0xe6a70000
#define SYSTBCR 0xe6150024
#define SBAR 0xe6180020
#define APARMBAREA 0xe6f10020

#ifdef CONFIG_SUSPEND
static void sh7372_enter_core_standby(void)
{
	void __iomem *smfram = (void __iomem *)SMFRAM;

	__raw_writel(0, APARMBAREA); /* translate 4k */
	__raw_writel(__pa(sh7372_cpu_resume), SBAR); /* set reset vector */
	__raw_writel(0x10, SYSTBCR); /* enable core standby */

	__raw_writel(0, smfram + 0x3c); /* clear page table address */

	sh7372_cpu_suspend();
	cpu_init();

	/* if page table address is non-NULL then we have been powered down */
	if (__raw_readl(smfram + 0x3c)) {
		__raw_writel(__raw_readl(smfram + 0x40),
			     __va(__raw_readl(smfram + 0x3c)));

		flush_tlb_all();
		set_cr(__raw_readl(smfram + 0x38));
	}

	__raw_writel(0, SYSTBCR); /* disable core standby */
	__raw_writel(0, SBAR); /* disable reset vector translation */
}

static int sh7372_enter_suspend(suspend_state_t suspend_state)
{
	sh7372_enter_core_standby();
	return 0;
}

static void sh7372_suspend_init(void)
{
	shmobile_suspend_ops.enter = sh7372_enter_suspend;
}
#else
static void sh7372_suspend_init(void) {}
#endif

#define DBGREG1 0xe6100020
#define DBGREG9 0xe6100040

void __init sh7372_pm_init(void)
{
	/* enable DBG hardware block to kick SYSC */
	__raw_writel(0x0000a500, DBGREG9);
	__raw_writel(0x0000a501, DBGREG9);
	__raw_writel(0x00000000, DBGREG1);

	sh7372_suspend_init();
}
Loading