* [PATCH] stm: pm: Rework the suspend SOC code
@ 2009-05-18 13:18 Francesco VIRLINZI
2009-05-18 13:19 ` Francesco VIRLINZI
0 siblings, 1 reply; 2+ messages in thread
From: Francesco VIRLINZI @ 2009-05-18 13:18 UTC (permalink / raw)
To: linux-sh
Changed the suspend SOC code based on the registration mechanism
Signed-off-by: Francesco Virlinzi <francesco.virlinzi@st.com>
---
arch/sh/kernel/cpu/sh4/clock-stx7200.c | 5 +-
arch/sh/kernel/cpu/sh4/soc-stb7100.h | 7 ++
arch/sh/kernel/cpu/sh4/soc-stx5197.h | 17 ++--
arch/sh/kernel/cpu/sh4/soc-stx7141.h | 2 +-
arch/sh/kernel/cpu/sh4/soc-stx7200.h | 34 +++++----
arch/sh/kernel/cpu/sh4/suspend-stb7100.c | 102 ++++++++++----------------
arch/sh/kernel/cpu/sh4/suspend-stx5197.c | 119 ++++++++++++-----------------
arch/sh/kernel/cpu/sh4/suspend-stx7105.c | 112 +++++++++++-----------------
arch/sh/kernel/cpu/sh4/suspend-stx7111.c | 98 ++++++++++--------------
arch/sh/kernel/cpu/sh4/suspend-stx7141.c | 102 +++++++++++---------------
arch/sh/kernel/cpu/sh4/suspend-stx7200.c | 94 ++++++++++--------------
11 files changed, 294 insertions(+), 398 deletions(-)
diff --git a/arch/sh/kernel/cpu/sh4/clock-stx7200.c b/arch/sh/kernel/cpu/sh4/clock-stx7200.c
index cf03964..ce6a92d 100644
--- a/arch/sh/kernel/cpu/sh4/clock-stx7200.c
+++ b/arch/sh/kernel/cpu/sh4/clock-stx7200.c
@@ -620,8 +620,9 @@ int clk_pm_state(pm_message_t state)
tmp = readl(CLOCKGENB_BASE_ADDR + CLKB_PWR_CFG);
writel(tmp & ~CLKB_PLL0_OFF,
CLOCKGENB_BASE_ADDR + CLKB_PWR_CFG);
-
- mdelay(10); /* wait for stable signal */
+ /* Wait PllB lock */
+ while ((readl(CLOCKGENB_BASE_ADDR + CLKB_PLL0_CFG)
+ & CLKB_PLL0_LOCK) != 0);
tmp = readl(CLOCKGENB_BASE_ADDR + CLKB_PLL0_CFG);
writel(tmp & ~CLKB_PLL0_BYPASS,
CLOCKGENB_BASE_ADDR + CLKB_PLL0_CFG);
diff --git a/arch/sh/kernel/cpu/sh4/soc-stb7100.h b/arch/sh/kernel/cpu/sh4/soc-stb7100.h
index 8f75fd8..20fa102 100644
--- a/arch/sh/kernel/cpu/sh4/soc-stb7100.h
+++ b/arch/sh/kernel/cpu/sh4/soc-stb7100.h
@@ -22,6 +22,10 @@
#define CLKA_PLL0_ENABLE (1 << 19)
#define CLKA_PLL0_SUSPEND ((5 << 16) | (100 << 8) | \
(CONFIG_SH_EXTERNAL_CLOCK / 1000000))
+
+#define CLKA_PLL0_LOCK 0x10
+ #define CLKA_PLL0_LOCK_LOCKED 0x01
+
#define CLKA_ST40 0x14
#define CLKA_ST40_IC 0x18
#define CLKA_ST40_PER 0x1c
@@ -30,6 +34,9 @@
#define CLKA_PLL1_ENABLE (1 << 19)
#define CLKA_PLL1_SUSPEND ((5 << 16) | (100 << 8) | \
(CONFIG_SH_EXTERNAL_CLOCK / 1000000))
+#define CLKA_PLL1_LOCK 0x2C
+ #define CLKA_PLL1_LOCK_LOCKED 0x01
+
#define CLKA_CLK_DIV 0x30
#define CLKA_CLK_EN 0x34
#define CLKA_CLK_EN_ST231_AUD (1 << 0)
diff --git a/arch/sh/kernel/cpu/sh4/soc-stx5197.h b/arch/sh/kernel/cpu/sh4/soc-stx5197.h
index 4009a76..54092e0 100644
--- a/arch/sh/kernel/cpu/sh4/soc-stx5197.h
+++ b/arch/sh/kernel/cpu/sh4/soc-stx5197.h
@@ -40,7 +40,8 @@ enum clocks_ID {
#define CLK_PLL_CONFIG0(x) ((x*8)+0x0)
#define CLK_PLL_CONFIG1(x) ((x*8)+0x4)
- #define CLK_PLL_CONFIG1_POFF (1<<13)
+#define CLK_PLL_CONFIG1_POFF (1<<13)
+#define CLK_PLL_CONFIG1_LOCK (1<<15)
#define CLKDIV0_CONFIG0 0x90
#define CLKDIV1_4_CONFIG0(n) (0x0a0 + ((n-1)*0xc))
@@ -54,20 +55,20 @@ enum clocks_ID {
#define CLK_MODE_CTRL 0x110
- #define CLK_MODE_CTRL_NULL 0x0
- #define CLK_MODE_CTRL_X1 0x1
- #define CLK_MODE_CTRL_PROG 0x2
- #define CLK_MODE_CTRL_STDB 0x3
+#define CLK_MODE_CTRL_NULL 0x0
+#define CLK_MODE_CTRL_X1 0x1
+#define CLK_MODE_CTRL_PROG 0x2
+#define CLK_MODE_CTRL_STDB 0x3
/*
* The REDUCED_PM is used in CLK_MODE_CTRL_PROG...
*/
#define CLK_REDUCED_PM_CTRL 0x114
- #define CLK_REDUCED_ON_XTAL_MEMSTDBY (1<<11)
- #define CLK_REDUCED_ON_XTAL_STDBY (~(0x22))
+#define CLK_REDUCED_ON_XTAL_MEMSTDBY (1<<11)
+#define CLK_REDUCED_ON_XTAL_STDBY (~(0x22))
#define CLK_LP_MODE_DIS0 0x118
- #define CLK_LP_MODE_DIS0_VALUE ((0x3 << 11) | (0x7ff & ~(1<<9)))
+#define CLK_LP_MODE_DIS0_VALUE (0x3 << 11)
#define CLK_LP_MODE_DIS2 0x11C
diff --git a/arch/sh/kernel/cpu/sh4/soc-stx7141.h b/arch/sh/kernel/cpu/sh4/soc-stx7141.h
index d98b506..5048610 100644
--- a/arch/sh/kernel/cpu/sh4/soc-stx7141.h
+++ b/arch/sh/kernel/cpu/sh4/soc-stx7141.h
@@ -21,7 +21,7 @@
#define CLOCKGENA_BASE_ADDR 0xfe213000 /* Clockgen A */
#define CLOCKGENB_BASE_ADDR 0xfe000000 /* Clockgen B */
-#define ckga_pll0_cfg 0x000
+#define CKGA_PLL0_CFG 0x000
#define CKGA_PLL0_CFG_DIVRES (1 << 20)
#define CKGA_PLL0_CFG_BYPASS CKGA_PLL0_CFG_DIVRES
#define CKGA_PLL0_CFG_LOCK (1 << 31)
diff --git a/arch/sh/kernel/cpu/sh4/soc-stx7200.h b/arch/sh/kernel/cpu/sh4/soc-stx7200.h
index 9045b16..5933506 100644
--- a/arch/sh/kernel/cpu/sh4/soc-stx7200.h
+++ b/arch/sh/kernel/cpu/sh4/soc-stx7200.h
@@ -24,38 +24,42 @@
#define CLOCKGENC_BASE_ADDR 0xfd601000 /* Clockgen C */
#define CLKA_PLL0 0x00
- #define CLKA_PLL0_BYPASS (1 << 20)
- #define CLKA_PLL0_ENABLE_STATUS (1 << 19)
- #define CLKA_PLL0_SUSPEND ((5 << 16) | (100 << 8) | \
+#define CLKA_PLL0_BYPASS (1 << 20)
+#define CLKA_PLL0_ENABLE_STATUS (1 << 19)
+#define CLKA_PLL0_LOCK (1 << 31)
+#define CLKA_PLL0_SUSPEND ((5 << 16) | (100 << 8) | \
(SYSACLKIN / 1000000))
#define CLKA_PLL1 0x04
- #define CLKA_PLL1_BYPASS (1 << 20)
- #define CLKA_PLL1_ENABLE_STATUS (1 << 19)
- #define CLKA_PLL1_SUSPEND ((100 << 8) | (SYSACLKIN / 1000000))
+#define CLKA_PLL1_BYPASS (1 << 20)
+#define CLKA_PLL1_ENABLE_STATUS (1 << 19)
+#define CLKA_PLL1_LOCK (1 << 31)
+#define CLKA_PLL1_SUSPEND ((100 << 8) | (SYSACLKIN / 1000000))
#define CLKA_PLL2 0x08
- #define CLKA_PLL2_BYPASS (1 << 20)
- #define CLKA_PLL2_ENABLE_STATUS (1 << 19)
- #define CLKA_PLL2_SUSPEND ((5 << 16) | (100 << 8) | \
+#define CLKA_PLL2_BYPASS (1 << 20)
+#define CLKA_PLL2_ENABLE_STATUS (1 << 19)
+#define CLKA_PLL2_LOCK (1 << 31)
+#define CLKA_PLL2_SUSPEND ((5 << 16) | (100 << 8) | \
(SYSACLKIN / 1000000))
#define CKGA_CLKOUT_SEL 0x18
#define CLKA_PWR_CFG 0x1C
- #define PWR_CFG_PLL0_OFF 0x1
- #define PWR_CFG_PLL1_OFF 0x2
- #define PWR_CFG_PLL2_OFF 0x4
+#define PWR_CFG_PLL0_OFF 0x1
+#define PWR_CFG_PLL1_OFF 0x2
+#define PWR_CFG_PLL2_OFF 0x4
#define CLKA_DIV_CFG 0x10
#define CLKB_PLL0_CFG 0x3C
- #define CLKB_PLL0_BYPASS (1 << 20)
- #define CLKB_PLL0_SUSPEND ((5 << 16) | (100 << 8) | \
+#define CLKB_PLL0_LOCK (1 << 31)
+#define CLKB_PLL0_BYPASS (1 << 20)
+#define CLKB_PLL0_SUSPEND ((5 << 16) | (100 << 8) | \
(SYSACLKIN / 1000000))
#define CLKB_PWR_CFG 0x58
- #define CLKB_PLL0_OFF (1 << 15)
+#define CLKB_PLL0_OFF (1 << 15)
#endif
diff --git a/arch/sh/kernel/cpu/sh4/suspend-stb7100.c b/arch/sh/kernel/cpu/sh4/suspend-stb7100.c
index e5134ec..79eab1f 100644
--- a/arch/sh/kernel/cpu/sh4/suspend-stb7100.c
+++ b/arch/sh/kernel/cpu/sh4/suspend-stb7100.c
@@ -32,11 +32,13 @@
#define _SYS_CFG11 (6)
#define _SYS_CFG11_MASK (7)
+extern void __iomem *clkgena_base;
+
/* *************************
* STANDBY INSTRUCTION TABLE
* *************************
*/
-
+#ifdef CONFIG_PM_DEBUG
static unsigned long stb7100_standby_table[] __cacheline_aligned = {
/* 1. PLL0 at the minimum frequency */
/* Unlock the clocks */
@@ -51,6 +53,8 @@ CLK_AND_LONG(CLKA_PLL0, ~(0x7ffff)),
CLK_OR_LONG(CLKA_PLL0, CLKA_PLL0_SUSPEND),
/* enables the pll0 */
CLK_OR_LONG(CLKA_PLL0, CLKA_PLL0_ENABLE),
+ /* Wait PLL0 lock */
+CLK_WHILE_NEQ(CLKA_PLL0_LOCK, CLKA_PLL0_LOCK_LOCKED, CLKA_PLL0_LOCK_LOCKED),
/* removes the bypass */
CLK_AND_LONG(CLKA_PLL0, ~(CLKA_PLL0_BYPASS)),
/* 0 4 5 - 1:4 1:6 1:8 */
@@ -79,6 +83,8 @@ _OR(),
CLK_STORE(CLKA_PLL0),
/* enables the pll0 */
CLK_OR_LONG(CLKA_PLL0, CLKA_PLL0_ENABLE),
+ /* Wait PLL0 lock */
+CLK_WHILE_NEQ(CLKA_PLL0_LOCK, CLKA_PLL0_LOCK_LOCKED, CLKA_PLL0_LOCK_LOCKED),
/* removes the bypass */
CLK_AND_LONG(CLKA_PLL0, ~(CLKA_PLL0_BYPASS)),
/* Lock the clocks */
@@ -86,7 +92,7 @@ CLK_POKE(CLKA_LOCK, 0x0),
/* END. */
_END()
};
-
+#endif
/* *********************
* MEM INSTRUCTION TABLE
* *********************
@@ -112,6 +118,8 @@ CLK_AND_LONG(CLKA_PLL0, ~(0x7ffff)),
CLK_OR_LONG(CLKA_PLL0, CLKA_PLL0_SUSPEND),
/* enables the pll0 */
CLK_OR_LONG(CLKA_PLL0, CLKA_PLL0_ENABLE),
+ /* Wait PLL0 lock */
+CLK_WHILE_NEQ(CLKA_PLL0_LOCK, CLKA_PLL0_LOCK_LOCKED, CLKA_PLL0_LOCK_LOCKED),
/* removes the bypass */
CLK_AND_LONG(CLKA_PLL0, ~(CLKA_PLL0_BYPASS)),
@@ -126,6 +134,8 @@ CLK_AND_LONG(CLKA_PLL1, ~(0x7ffff)),
CLK_OR_LONG(CLKA_PLL1, CLKA_PLL1_SUSPEND),
/* enables the pll1 */
CLK_OR_LONG(CLKA_PLL1, CLKA_PLL1_ENABLE),
+ /* Wait PLL1 lock */
+CLK_WHILE_NEQ(CLKA_PLL1_LOCK, CLKA_PLL1_LOCK_LOCKED, CLKA_PLL1_LOCK_LOCKED),
CLK_AND_LONG(CLKA_PLL1_BYPASS, ~(2)), /* removes the bypass */
/* 4. Turn-off the LMI clocks and the ST231 clocks */
@@ -150,6 +160,8 @@ CLK_AND_LONG(CLKA_PLL1, ~(CLKA_PLL1_ENABLE)), /* disable the pll1 */
DATA_LOAD(0x1),
CLK_STORE(CLKA_PLL1),
CLK_OR_LONG(CLKA_PLL1, CLKA_PLL1_ENABLE), /* enables the pll1 */
+ /* Wait PLL1 lock */
+CLK_WHILE_NEQ(CLKA_PLL1_LOCK, CLKA_PLL1_LOCK_LOCKED, CLKA_PLL1_LOCK_LOCKED),
CLK_AND_LONG(CLKA_PLL1_BYPASS, ~(2)), /* removes the bypass */
/* 4. Disables the DDR self refresh mode */
@@ -167,6 +179,8 @@ IMMEDIATE_SRC0(CLKA_PLL0_BYPASS),
_OR(),
CLK_STORE(CLKA_PLL0), /* save the r2 in PLL0 */
CLK_OR_LONG(CLKA_PLL0, CLKA_PLL0_ENABLE), /* enables the pll0 */
+ /* Wait PLL0 lock */
+CLK_WHILE_NEQ(CLKA_PLL0_LOCK, CLKA_PLL0_LOCK_LOCKED, CLKA_PLL0_LOCK_LOCKED),
CLK_AND_LONG(CLKA_PLL0, ~(CLKA_PLL0_BYPASS)), /* removes the bypass */
CLK_POKE(CLKA_LOCK, 0x0),
@@ -182,46 +196,8 @@ static unsigned long stb7100_wrt_table[8] __cacheline_aligned;
static int stb7100_suspend_prepare(suspend_state_t state)
{
- int ret = -EINVAL;
- pm_message_t pms = {.event = PM_EVENT_SUSPEND, };
- emi_pm_state(pms);
-/* clk_pm_state(pms);*/
- sysconf_pm_state(pms);
- switch (state) {
- case PM_SUSPEND_STANDBY:
- stb7100_wrt_table[0] = readl(clkgena_base + CLKA_PLL0) & 0x7ffff;
- ret = 0;
- break;
- case PM_SUSPEND_MEM:
- stb7100_wrt_table[0] = readl(clkgena_base + CLKA_PLL0) & 0x7ffff;
- stb7100_wrt_table[1] = readl(clkgena_base + CLKA_PLL1) & 0x7ffff;
- ret = 0;
- break;
- }
- return ret;
-}
-
-static int stb7100_suspend_valid(suspend_state_t state)
-{
- switch (state) {
- case PM_SUSPEND_STANDBY:
- case PM_SUSPEND_MEM:
- return 1;
- };
- return 0;
-}
-
-/*
- * The xxxx_finish function is called after the resume
- * sysdev devices (i.e.: timer, cpufreq)
- * But it isn't a big issue in our platform
- */
-static int stb7100_suspend_finish(suspend_state_t state)
-{
- pm_message_t pms = {.event = PM_EVENT_ON, };
- sysconf_pm_state(pms);
-/* clk_pm_state(pms);*/
- emi_pm_state(pms);
+ stb7100_wrt_table[0] = readl(clkgena_base + CLKA_PLL0) & 0x7ffff;
+ stb7100_wrt_table[1] = readl(clkgena_base + CLKA_PLL1) & 0x7ffff;
return 0;
}
@@ -234,31 +210,29 @@ static unsigned long stb7100_iomem[2] __cacheline_aligned = {
stb7100_wrt_table,
};
-int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
+static struct sh4_suspend_t st40data __cacheline_aligned = {
+ .iobase = stb7100_iomem,
+ .ops.prepare = stb7100_suspend_prepare,
+ .evt_to_irq = stb7100_evttoirq,
+#ifdef CONFIG_PM_DEBUG
+ .stby_tbl = (unsigned long)stb7100_standby_table,
+ .stby_size = DIV_ROUND_UP(ARRAY_SIZE(stb7100_standby_table) *
+ sizeof(long), L1_CACHE_BYTES),
+#endif
+ .mem_tbl = (unsigned long)stb7100_mem_table,
+ .mem_size = DIV_ROUND_UP(ARRAY_SIZE(stb7100_mem_table) * sizeof(long),
+ L1_CACHE_BYTES),
+ .wrt_tbl = (unsigned long)stb7100_wrt_table,
+ .wrt_size = DIV_ROUND_UP(ARRAY_SIZE(stb7100_wrt_table) * sizeof(long),
+ L1_CACHE_BYTES),
+};
+
+static int __init suspend_platform_setup()
{
struct sysconf_field* sc;
stb7100_iomem[1] = (unsigned long) clkgena_base;
- st40data->iobase = stb7100_iomem;
- st40data->ops.valid = stb7100_suspend_valid;
- st40data->ops.finish = stb7100_suspend_finish;
- st40data->ops.prepare = stb7100_suspend_prepare;
-
- st40data->evt_to_irq = stb7100_evttoirq;
-
- st40data->stby_tbl = (unsigned long)stb7100_standby_table;
- st40data->stby_size = DIV_ROUND_UP(
- ARRAY_SIZE(stb7100_standby_table)*sizeof(long), L1_CACHE_BYTES);;
-
- st40data->mem_tbl = (unsigned long)stb7100_mem_table;
- st40data->mem_size = DIV_ROUND_UP(
- ARRAY_SIZE(stb7100_mem_table)*sizeof(long), L1_CACHE_BYTES);
-
- st40data->wrt_tbl = (unsigned long)stb7100_wrt_table;
- st40data->wrt_size = DIV_ROUND_UP(
- ARRAY_SIZE(stb7100_wrt_table)*sizeof(long), L1_CACHE_BYTES);
-
sc = sysconf_claim(SYS_STA, 12, 28, 28, "pm");
stb7100_wrt_table[_SYS_STA12] = (unsigned long)sysconf_address(sc);
stb7100_wrt_table[_SYS_STA12_MASK] = sysconf_mask(sc);
@@ -273,5 +247,7 @@ int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
sc = sysconf_claim(SYS_CFG, 11, 30, 30, "pm");
stb7100_wrt_table[_SYS_CFG11_MASK] |= sysconf_mask(sc);
- return 0;
+ return sh4_suspend_register(&st40data);
}
+
+late_initcall(suspend_platform_setup);
diff --git a/arch/sh/kernel/cpu/sh4/suspend-stx5197.c b/arch/sh/kernel/cpu/sh4/suspend-stx5197.c
index 69aa3f3..ee793ad 100644
--- a/arch/sh/kernel/cpu/sh4/suspend-stx5197.c
+++ b/arch/sh/kernel/cpu/sh4/suspend-stx5197.c
@@ -31,10 +31,25 @@
#define _SYS_CFG_H (2)
#define _SYS_CFG_H_MASK (3)
+
+
+/*
+ * System Service Finite State Machine
+ * +-------+ +------+ +------+
+ * | reset |-->| X1 |<-->| Prog |
+ * +-------+ +------+ +------+
+ * /\ |
+ * | \/
+ * wakeup | +-------+
+ * event +-------|Standby|
+ * +-------+
+ */
+
/* *************************
* STANDBY INSTRUCTION TABLE
* *************************
*/
+#ifdef CONFIG_PM_DEBUG
static unsigned long stx5197_standby_table[] __cacheline_aligned = {
CLK_POKE(CLK_LOCK_CFG, 0xf0),
CLK_POKE(CLK_LOCK_CFG, 0x0f), /* UnLock the clocks */
@@ -54,6 +69,7 @@ CLK_POKE(CLK_LOCK_CFG, 0x0f), /* UnLock the clocks */
CLK_POKE(CLK_MODE_CTRL, CLK_MODE_CTRL_X1),
CLK_AND_LONG(CLK_REDUCED_PM_CTRL, ~CLK_REDUCED_ON_XTAL_STDBY),
CLK_AND_LONG(CLK_PLL_CONFIG1(0), ~CLK_PLL_CONFIG1_POFF),
+CLK_WHILE_NEQ(CLK_PLL_CONFIG1(0), CLK_PLL_CONFIG1_LOCK, CLK_PLL_CONFIG1_LOCK),
CLK_POKE(CLK_MODE_CTRL, CLK_MODE_CTRL_PROG),
CLK_POKE(CLK_LOCK_CFG, 0x100), /* Lock the clocks */
_DELAY(),
@@ -61,6 +77,7 @@ _DELAY(),
_DELAY(),
_END()
};
+#endif
/* *********************
* MEM INSTRUCTION TABLE
@@ -73,22 +90,19 @@ DATA_WHILE_NEQ(_SYS_MON_J, _SYS_MON_J_MASK, _SYS_MON_J_MASK),
CLK_POKE(CLK_LOCK_CFG, 0xf0),
CLK_POKE(CLK_LOCK_CFG, 0x0f), /* UnLock the clocks */
-CLK_POKE(CLK_MODE_CTRL, CLK_MODE_CTRL_X1),
-/* on exetrnal Xtal */
-CLK_OR_LONG(CLK_REDUCED_PM_CTRL, CLK_REDUCED_ON_XTAL_MEMSTDBY),
-CLK_OR_LONG(CLK_PLL_CONFIG1(0), CLK_PLL_CONFIG1_POFF),
-CLK_OR_LONG(CLK_PLL_CONFIG1(1), CLK_PLL_CONFIG1_POFF),
-CLK_POKE(CLK_MODE_CTRL, CLK_MODE_CTRL_PROG),
-CLK_POKE(CLK_LOCK_CFG, 0x100), /* Lock the clocks */
+/* disable PLLs in standby */
+CLK_OR_LONG(CLK_LP_MODE_DIS0, CLK_LP_MODE_DIS0_VALUE),
+CLK_POKE(CLK_MODE_CTRL, CLK_MODE_CTRL_STDB), /* IN STANDBY */
-_END(),
-
-CLK_POKE(CLK_LOCK_CFG, 0xf0),
-CLK_POKE(CLK_LOCK_CFG, 0x0f), /* UnLock the clocks */
-CLK_POKE(CLK_MODE_CTRL, CLK_MODE_CTRL_X1),
+_END_NO_SLEEP(),
+/*
+ * On a wakeup Event the System Service goes directly in X1 mode */
CLK_AND_LONG(CLK_PLL_CONFIG1(0), ~CLK_PLL_CONFIG1_POFF),
CLK_AND_LONG(CLK_PLL_CONFIG1(1), ~CLK_PLL_CONFIG1_POFF),
-CLK_AND_LONG(CLK_REDUCED_PM_CTRL, ~CLK_REDUCED_ON_XTAL_MEMSTDBY), /* on PLLs */
+/* Wait PLLs lock */
+CLK_WHILE_NEQ(CLK_PLL_CONFIG1(0), CLK_PLL_CONFIG1_LOCK, CLK_PLL_CONFIG1_LOCK),
+CLK_WHILE_NEQ(CLK_PLL_CONFIG1(1), CLK_PLL_CONFIG1_LOCK, CLK_PLL_CONFIG1_LOCK),
+
CLK_POKE(CLK_MODE_CTRL, CLK_MODE_CTRL_PROG),
CLK_POKE(CLK_LOCK_CFG, 0x100), /* Lock the clocks */
@@ -109,42 +123,6 @@ static unsigned long stx5197_wrt_table[8] __cacheline_aligned;
static int stx5197_suspend_prepare(suspend_state_t state)
{
- int ret = -EINVAL;
- pm_message_t pms = {.event = PM_EVENT_SUSPEND, };
- emi_pm_state(pms);
-/* clk_pm_state(pms);*/
- sysconf_pm_state(pms);
-
- switch (state) {
- case PM_SUSPEND_STANDBY:
- case PM_SUSPEND_MEM:
- ret = 0;
- break;
- }
- return ret;
-}
-
-static int stx5197_suspend_valid(suspend_state_t state)
-{
- switch (state) {
- case PM_SUSPEND_STANDBY:
- case PM_SUSPEND_MEM:
- return 1;
- };
- return 0;
-}
-
-/*
- * The xxxx_finish function is called after the resume
- * sysdev devices (i.e.: timer, cpufreq)
- * But it isn't a big issue in our platform
- */
-static int stx5197_suspend_finish(suspend_state_t state)
-{
- pm_message_t pms = {.event = PM_EVENT_ON, };
- sysconf_pm_state(pms);
-/* clk_pm_state(pms);*/
- emi_pm_state(pms);
return 0;
}
@@ -154,31 +132,30 @@ static unsigned long stx5197_iomem[2] __cacheline_aligned = {
static int stx5197_evt_to_irq(unsigned long evt)
{
- return ilc2irq(evt);
+ return ((evt < 0x400) ? ilc2irq(evt) : evt2irq(evt));
}
-int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
+static struct sh4_suspend_t st40data __cacheline_aligned = {
+ .iobase = stx5197_iomem,
+ .ops.prepare = stx5197_suspend_prepare,
+ .evt_to_irq = stx5197_evt_to_irq,
+#ifdef CONFIG_PM_DEBUG
+ .stby_tbl = (unsigned long)stx5197_standby_table,
+ .stby_size = DIV_ROUND_UP(ARRAY_SIZE(stx5197_standby_table) *
+ sizeof(long), L1_CACHE_BYTES),
+#endif
+ .mem_tbl = (unsigned long)stx5197_mem_table,
+ .mem_size = DIV_ROUND_UP(ARRAY_SIZE(stx5197_mem_table) * sizeof(long),
+ L1_CACHE_BYTES),
+ .wrt_tbl = (unsigned long)stx5197_wrt_table,
+ .wrt_size = DIV_ROUND_UP(ARRAY_SIZE(stx5197_wrt_table) * sizeof(long),
+ L1_CACHE_BYTES),
+};
+
+static int __init suspend_platform_setup(void)
{
struct sysconf_field* sc;
- st40data->iobase = stx5197_iomem;
- st40data->ops.valid = stx5197_suspend_valid;
- st40data->ops.finish = stx5197_suspend_finish;
- st40data->ops.prepare = stx5197_suspend_prepare;
-
- st40data->evt_to_irq = stx5197_evt_to_irq;
-
- st40data->stby_tbl = (unsigned long)stx5197_standby_table;
- st40data->stby_size = DIV_ROUND_UP(
- ARRAY_SIZE(stx5197_standby_table) * sizeof(long), L1_CACHE_BYTES);
-
- st40data->mem_tbl = (unsigned long)stx5197_mem_table;
- st40data->mem_size = DIV_ROUND_UP(
- ARRAY_SIZE(stx5197_mem_table) * sizeof(long), L1_CACHE_BYTES);
-
- st40data->wrt_tbl = (unsigned long)stx5197_wrt_table;
- st40data->wrt_size = DIV_ROUND_UP(
- ARRAY_SIZE(stx5197_wrt_table) * sizeof(long), L1_CACHE_BYTES);
sc = sysconf_claim(SYS_DEV, CFG_MONITOR_J, 24, 24, "LMI pwd ack");
stx5197_wrt_table[_SYS_MON_J] = (unsigned long)sysconf_address(sc);
@@ -188,5 +165,7 @@ int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
stx5197_wrt_table[_SYS_CFG_H] = (unsigned long)sysconf_address(sc);
stx5197_wrt_table[_SYS_CFG_H_MASK] = sysconf_mask(sc);
- return 0;
+ return sh4_suspend_register(&st40data);
}
+
+late_initcall(suspend_platform_setup);
diff --git a/arch/sh/kernel/cpu/sh4/suspend-stx7105.c b/arch/sh/kernel/cpu/sh4/suspend-stx7105.c
index b9b88a2..e5e0329 100644
--- a/arch/sh/kernel/cpu/sh4/suspend-stx7105.c
+++ b/arch/sh/kernel/cpu/sh4/suspend-stx7105.c
@@ -27,6 +27,10 @@
#define _SYS_STA4 (7)
#define _SYS_STA4_MASK (8)
+#define _SYS_STA3 (11)
+#define _SYS_STA3_MASK (12)
+#define _SYS_STA3_VALUE (13)
+
#define _SYS_CFG11 (9)
#define _SYS_CFG11_MASK (10)
#define _SYS_CFG38 (5)
@@ -35,6 +39,7 @@
* STANDBY INSTRUCTION TABLE
* *************************
*/
+#ifdef CONFIG_PM_DEBUG
static unsigned long stx7105_standby_table[] __cacheline_aligned = {
/* 1. Move all the clock on OSC */
CLK_POKE(CKGA_CLKOPSRC_SWITCH_CFG(0x0), 0x0),
@@ -57,7 +62,7 @@ CLK_STORE(CKGA_OSC_DIV_CFG(5)),
/* END. */
_END()
};
-
+#endif
/* *********************
* MEM INSTRUCTION TABLE
* *********************
@@ -91,8 +96,15 @@ _END(),
/* Turn-on the PLLs */
CLK_AND_LONG(CKGA_POWER_CFG, ~3),
+/* Wait PLLS lock */
+CLK_WHILE_NEQ(CKGA_PLL0_CFG, CKGA_PLL0_CFG_LOCK, CKGA_PLL0_CFG_LOCK),
+CLK_WHILE_NEQ(CKGA_PLL1_CFG, CKGA_PLL1_CFG_LOCK, CKGA_PLL1_CFG_LOCK),
+
/* 1. Turn-on the LMI ClocksGenD */
DATA_AND_NOT_LONG(_SYS_CFG11, _SYS_CFG11_MASK),
+/* Wait LMI ClocksGenD lock */
+DATA_WHILE_NEQ(_SYS_STA3, _SYS_STA3_MASK, _SYS_STA3_VALUE),
+
/* 2. Disables the DDR self refresh mode */
DATA_AND_NOT_LONG(_SYS_CFG38, _SYS_CFG38_MASK),
/* waits until the ack bit is zero */
@@ -100,6 +112,7 @@ DATA_WHILE_EQ(_SYS_STA4, _SYS_STA4_MASK, _SYS_STA4_MASK),
IMMEDIATE_DEST(0x10000),
CLK_STORE(CKGA_PLL0LS_DIV_CFG(4)),
+
/* 3. Restore the previous clocks setting */
DATA_LOAD(0x0),
CLK_STORE(CKGA_CLKOPSRC_SWITCH_CFG(0x0)),
@@ -111,6 +124,7 @@ DATA_LOAD(0x2),
CLK_STORE(CKGA_OSC_DIV_CFG(0x0)),
DATA_LOAD(0x4),
CLK_STORE(CKGA_OSC_DIV_CFG(17)),
+
_DELAY(),
_DELAY(),
_DELAY(),
@@ -121,23 +135,17 @@ static unsigned long stx7105_wrt_table[16] __cacheline_aligned;
static int stx7105_suspend_prepare(suspend_state_t state)
{
- int ret = -EINVAL;
- pm_message_t pms = {.event = PM_EVENT_SUSPEND, };
- emi_pm_state(pms);
- clk_pm_state(pms);
- sysconf_pm_state(pms);
-
- switch (state) {
- case PM_SUSPEND_STANDBY:
+#ifdef CONFIG_PM_DEBUG
+ if (state = PM_SUSPEND_STANDBY) {
stx7105_wrt_table[0] = /* swith config */
ioread32(CLOCKGENA_BASE_ADDR + CKGA_CLKOPSRC_SWITCH_CFG(0));
stx7105_wrt_table[1] = /* clk_STNoc */
ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(0));
stx7105_wrt_table[2] = /* clk_ic_if_100 */
ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(5));
- ret = 0;
- break;
- case PM_SUSPEND_MEM:
+ } else
+#endif
+ {
stx7105_wrt_table[0] = /* swith config */
ioread32(CLOCKGENA_BASE_ADDR + CKGA_CLKOPSRC_SWITCH_CFG(0));
stx7105_wrt_table[1] = /* swith config 1 */
@@ -148,33 +156,7 @@ static int stx7105_suspend_prepare(suspend_state_t state)
ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(5));
stx7105_wrt_table[4] = /* clk_ic_if_200 */
ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(17));
- ret = 0;
- break;
}
- return ret;
-}
-
-static int stx7105_suspend_valid(suspend_state_t state)
-{
- switch (state) {
- case PM_SUSPEND_STANDBY:
- case PM_SUSPEND_MEM:
- return 1;
- };
- return 0;
-}
-
-/*
- * The xxxx_finish function is called after the resume
- * sysdev devices (i.e.: timer, cpufreq)
- * But it isn't a big issue in our platform
- */
-static int stx7105_suspend_finish(suspend_state_t state)
-{
- pm_message_t pms = {.event = PM_EVENT_ON, };
- sysconf_pm_state(pms);
- clk_pm_state(pms);
- emi_pm_state(pms);
return 0;
}
@@ -187,41 +169,27 @@ static int stx7105_evt_to_irq(unsigned long evt)
return evt2irq(evt);
}
-#if 0
-#define GPLMI_BASEADDRESS 0xfe901000
-#define GPLMI_SCR_APPD 0x14
-static void stx7105_sleep_on_idle(void)
-{
- iowrite32(0x10 << 16 | 0x10, GPLMI_BASEADDRESS + GPLMI_SCR_APPD);
- asm volatile ("sleep \n":::"memory");
- iowrite32(0x0, GPLMI_BASEADDRESS + GPLMI_SCR_APPD);
-}
+static struct sh4_suspend_t st40data __cacheline_aligned = {
+ .iobase = stx7105_iomem,
+ .ops.prepare = stx7105_suspend_prepare,
+ .evt_to_irq = stx7105_evt_to_irq,
+#ifdef CONFIG_PM_DEBUG
+ .stby_tbl = (unsigned long)stx7105_standby_table,
+ .stby_size = DIV_ROUND_UP(ARRAY_SIZE(stx7105_standby_table) *
+ sizeof(long), L1_CACHE_BYTES),
#endif
+ .mem_tbl = (unsigned long)stx7105_mem_table,
+ .mem_size = DIV_ROUND_UP(ARRAY_SIZE(stx7105_mem_table) * sizeof(long),
+ L1_CACHE_BYTES),
+ .wrt_tbl = (unsigned long)stx7105_wrt_table,
+ .wrt_size = DIV_ROUND_UP(ARRAY_SIZE(stx7105_wrt_table) * sizeof(long),
+ L1_CACHE_BYTES),
+};
-int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
+static int __init suspend_platform_setup(void)
{
struct sysconf_field* sc;
- st40data->iobase = stx7105_iomem;
- st40data->ops.valid = stx7105_suspend_valid;
- st40data->ops.finish = stx7105_suspend_finish;
- st40data->ops.prepare = stx7105_suspend_prepare;
-
- st40data->evt_to_irq = stx7105_evt_to_irq;
-
- st40data->stby_tbl = (unsigned long)stx7105_standby_table;
- st40data->stby_size = DIV_ROUND_UP(
- ARRAY_SIZE(stx7105_standby_table) * sizeof(long), L1_CACHE_BYTES);
-
- st40data->mem_tbl = (unsigned long)stx7105_mem_table;
- st40data->mem_size = DIV_ROUND_UP(
- ARRAY_SIZE(stx7105_mem_table) * sizeof(long), L1_CACHE_BYTES);
-
- st40data->wrt_tbl = (unsigned long)stx7105_wrt_table;
- st40data->wrt_size = DIV_ROUND_UP(
- ARRAY_SIZE(stx7105_wrt_table) * sizeof(long), L1_CACHE_BYTES);
-
-/* pm_idle = stx7105_sleep_on_idle; */
sc = sysconf_claim(SYS_CFG, 38, 20, 20, "pm");
stx7105_wrt_table[_SYS_CFG38] = (unsigned long)sysconf_address(sc);
stx7105_wrt_table[_SYS_CFG38_MASK] = sysconf_mask(sc);
@@ -234,5 +202,11 @@ int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
stx7105_wrt_table[_SYS_STA4] = (unsigned long)sysconf_address(sc);
stx7105_wrt_table[_SYS_STA4_MASK] = sysconf_mask(sc);
- return 0;
+ sc = sysconf_claim(SYS_STA, 3, 0, 0, "pm");
+ stx7105_wrt_table[_SYS_STA3] = (unsigned long)sysconf_address(sc);
+ stx7105_wrt_table[_SYS_STA3_MASK] = sysconf_mask(sc);
+ stx7105_wrt_table[_SYS_STA3_VALUE] = 0;
+ return sh4_suspend_register(&st40data);
}
+
+late_initcall(suspend_platform_setup);
diff --git a/arch/sh/kernel/cpu/sh4/suspend-stx7111.c b/arch/sh/kernel/cpu/sh4/suspend-stx7111.c
index a0b2104..8203184 100644
--- a/arch/sh/kernel/cpu/sh4/suspend-stx7111.c
+++ b/arch/sh/kernel/cpu/sh4/suspend-stx7111.c
@@ -27,6 +27,9 @@
#define _SYS_STA4 (5)
#define _SYS_STA4_MASK (6)
+#define _SYS_STA3 (11)
+#define _SYS_STA3_MASK (12)
+#define _SYS_STA3_VALUE (13)
#define _SYS_CFG11 (7)
#define _SYS_CFG11_MASK (8)
@@ -38,6 +41,7 @@
* STANDBY INSTRUCTION TABLE
* *************************
*/
+#ifdef CONFIG_PM_DEBUG
static unsigned long stx7111_standby_table[] __cacheline_aligned = {
/* 1. Move all the clock on OSC */
CLK_POKE(CKGA_CLKOPSRC_SWITCH_CFG(0x0), 0x0),
@@ -64,6 +68,7 @@ CLK_STORE(CKGA_OSC_DIV_CFG(5)),
/* END. */
_END()
};
+#endif
/* *********************
* MEM INSTRUCTION TABLE
@@ -96,9 +101,15 @@ _END(),
/* Turn-on the PLLs */
CLK_AND_LONG(CKGA_POWER_CFG, ~3),
+/* Wait PLLs lock */
+CLK_WHILE_NEQ(CKGA_PLL0_CFG, CKGA_PLL0_CFG_LOCK, CKGA_PLL0_CFG_LOCK),
+CLK_WHILE_NEQ(CKGA_PLL1_CFG, CKGA_PLL1_CFG_LOCK, CKGA_PLL1_CFG_LOCK),
/* 1. Turn-on the LMI ClocksGenD */
DATA_AND_NOT_LONG(_SYS_CFG11, _SYS_CFG11_MASK),
+/* Wait LMI ClocksGenD lock */
+DATA_WHILE_NEQ(_SYS_STA3, _SYS_STA3_MASK, _SYS_STA3_VALUE),
+
/* 2. Disables the DDR self refresh mode */
DATA_AND_NOT_LONG(_SYS_CFG38, _SYS_CFG38_MASK),
/* waits until the ack bit is zero */
@@ -129,23 +140,17 @@ static unsigned long stx7111_wrt_table[16] __cacheline_aligned;
static int stx7111_suspend_prepare(suspend_state_t state)
{
- int ret = -EINVAL;
- pm_message_t pms = {.event = PM_EVENT_SUSPEND, };
- emi_pm_state(pms);
- clk_pm_state(pms);
- sysconf_pm_state(pms);
-
- switch (state) {
- case PM_SUSPEND_STANDBY:
+#ifdef CONFIG_PM_DEBUG
+ if (state = PM_SUSPEND_STANDBY) {
stx7111_wrt_table[0] = /* swith config */
ioread32(CLOCKGENA_BASE_ADDR + CKGA_CLKOPSRC_SWITCH_CFG(0));
stx7111_wrt_table[1] = /* clk_STNoc_ic */
ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(0));
stx7111_wrt_table[2] = /* clk_ic_if_100 */
ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(5));
- ret = 0;
- break;
- case PM_SUSPEND_MEM:
+ } else
+#endif
+ {
stx7111_wrt_table[0] = /* swith config */
ioread32(CLOCKGENA_BASE_ADDR + CKGA_CLKOPSRC_SWITCH_CFG(0));
stx7111_wrt_table[1] = /* swith config 1 */
@@ -156,33 +161,7 @@ static int stx7111_suspend_prepare(suspend_state_t state)
ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(5));
stx7111_wrt_table[4] = /* clk_ic_if_200 */
ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(17));
- ret = 0;
- break;
}
- return ret;
-}
-
-static int stx7111_suspend_valid(suspend_state_t state)
-{
- switch (state) {
- case PM_SUSPEND_STANDBY:
- case PM_SUSPEND_MEM:
- return 1;
- };
- return 0;
-}
-
-/*
- * The xxxx_finish function is called after the resume
- * sysdev devices (i.e.: timer, cpufreq)
- * But it isn't a big issue in our platform
- */
-static int stx7111_suspend_finish(suspend_state_t state)
-{
- pm_message_t pms = {.event = PM_EVENT_ON, };
- sysconf_pm_state(pms);
- clk_pm_state(pms);
- emi_pm_state(pms);
return 0;
}
@@ -195,31 +174,30 @@ static int stx7111_evttoirq(unsigned long evt)
return evt2irq(evt);
}
-int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
+static struct sh4_suspend_t st40data __cacheline_aligned = {
+ .iobase = stx7111_iomem,
+ .ops.prepare = stx7111_suspend_prepare,
+ .evt_to_irq = stx7111_evttoirq,
+#ifdef CONFIG_PM_DEBUG
+ .stby_tbl = (unsigned long)stx7111_standby_table,
+ .stby_size = DIV_ROUND_UP(ARRAY_SIZE(stx7111_standby_table) *
+ sizeof(long), L1_CACHE_BYTES),
+#endif
+ .mem_tbl = (unsigned long)stx7111_mem_table,
+ .mem_size = DIV_ROUND_UP(ARRAY_SIZE(stx7111_mem_table) * sizeof(long),
+ L1_CACHE_BYTES),
+ .wrt_tbl = (unsigned long)stx7111_wrt_table,
+ .wrt_size = DIV_ROUND_UP(ARRAY_SIZE(stx7111_wrt_table) * sizeof(long),
+ L1_CACHE_BYTES),
+};
+
+static int __init suspend_platform_setup()
{
struct sysconf_field* sc;
#ifdef CONFIG_PM_DEBUG
/* route the sh4/2 clock frequenfy */
iowrite32(0xc, CLOCKGENA_BASE_ADDR + CKGA_CLKOBS_MUX1_CFG);
#endif
- st40data->iobase = stx7111_iomem;
- st40data->ops.valid = stx7111_suspend_valid;
- st40data->ops.finish = stx7111_suspend_finish;
- st40data->ops.prepare = stx7111_suspend_prepare;
-
- st40data->evt_to_irq = stx7111_evttoirq;
-
- st40data->stby_tbl = (unsigned long)stx7111_standby_table;
- st40data->stby_size = DIV_ROUND_UP(
- ARRAY_SIZE(stx7111_standby_table)*sizeof(long), L1_CACHE_BYTES);
-
- st40data->mem_tbl = (unsigned long)stx7111_mem_table;
- st40data->mem_size = DIV_ROUND_UP(
- ARRAY_SIZE(stx7111_mem_table)*sizeof(long), L1_CACHE_BYTES);
-
- st40data->wrt_tbl = (unsigned long)stx7111_wrt_table;
- st40data->wrt_size = DIV_ROUND_UP(
- ARRAY_SIZE(stx7111_wrt_table)*sizeof(long), L1_CACHE_BYTES);
sc = sysconf_claim(SYS_CFG, 38, 20, 20, "pm");
stx7111_wrt_table[_SYS_CFG38] = (unsigned long)sysconf_address(sc);
@@ -233,5 +211,11 @@ int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
stx7111_wrt_table[_SYS_STA4] = (unsigned long)sysconf_address(sc);
stx7111_wrt_table[_SYS_STA4_MASK] = sysconf_mask(sc);
- return 0;
+ sc = sysconf_claim(SYS_STA, 3, 0, 0, "pm");
+ stx7111_wrt_table[_SYS_STA3] = (unsigned long)sysconf_address(sc);
+ stx7111_wrt_table[_SYS_STA3_MASK] = sysconf_mask(sc);
+ stx7111_wrt_table[_SYS_STA3_VALUE] = 0;
+ return sh4_suspend_register(&st40data);
}
+
+late_initcall(suspend_platform_setup);
diff --git a/arch/sh/kernel/cpu/sh4/suspend-stx7141.c b/arch/sh/kernel/cpu/sh4/suspend-stx7141.c
index f2d131c..3dffc3a 100644
--- a/arch/sh/kernel/cpu/sh4/suspend-stx7141.c
+++ b/arch/sh/kernel/cpu/sh4/suspend-stx7141.c
@@ -31,6 +31,10 @@
#define _SYS_STA4 (7)
#define _SYS_STA4_MASK (8)
+#define _SYS_STA3 (11)
+#define _SYS_STA3_MASK (12)
+#define _SYS_STA3_VALUE (13)
+
#define _SYS_CFG11 (9)
#define _SYS_CFG11_MASK (10)
#define _SYS_CFG38 (5)
@@ -40,6 +44,7 @@
* STANDBY INSTRUCTION TABLE
* *************************
*/
+#ifdef CONFIG_PM_DEBUG
static unsigned long stx7141_standby_table[] __cacheline_aligned = {
IMMEDIATE_DEST(0x1f),
/* reduces the st40 frequency */
@@ -63,6 +68,7 @@ CLK_STORE(CKGA_OSC_DIV_CFG(10)),
/* END. */
_END()
};
+#endif
/* *********************
* MEM INSTRUCTION TABLE
@@ -96,8 +102,15 @@ _END(),
/* Turn-on the PLLs */
CLK_AND_LONG(CKGA_POWER_CFG, ~3),
+/* Wait PLLs lock */
+CLK_WHILE_NEQ(CKGA_PLL0_CFG, CKGA_PLL0_CFG_LOCK, CKGA_PLL0_CFG_LOCK),
+CLK_WHILE_NEQ(CKGA_PLL1_CFG, CKGA_PLL1_CFG_LOCK, CKGA_PLL1_CFG_LOCK),
+
/* 1. Turn-on the LMI ClocksGenD */
DATA_AND_NOT_LONG(_SYS_CFG11, _SYS_CFG11_MASK),
+/* Wait LMI ClocksGenD lock */
+DATA_WHILE_NEQ(_SYS_STA3, _SYS_STA3_MASK, _SYS_STA3_VALUE),
+
/* 2. Disables the DDR self refresh mode */
DATA_AND_NOT_LONG(_SYS_CFG38, _SYS_CFG38_MASK),
/* waits until the ack bit is zero */
@@ -126,23 +139,17 @@ static unsigned long stx7141_wrt_table[16] __cacheline_aligned;
static int stx7141_suspend_prepare(suspend_state_t state)
{
- int ret = -EINVAL;
- pm_message_t pms = {.event = PM_EVENT_SUSPEND, };
- emi_pm_state(pms);
- clk_pm_state(pms);
- sysconf_pm_state(pms);
-
- switch (state) {
- case PM_SUSPEND_STANDBY:
+#ifdef CONFIG_PM_DEBUG
+ if (state = PM_SUSPEND_STANDBY) {
stx7141_wrt_table[0] = /* swith config */
ioread32(CLOCKGENA_BASE_ADDR + CKGA_CLKOPSRC_SWITCH_CFG(0));
stx7141_wrt_table[1] = /* clk_ic */
ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(0));
stx7141_wrt_table[2] = /* clk_ic_if_100 */
ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(10));
- ret = 0;
- break;
- case PM_SUSPEND_MEM:
+ } else
+#endif
+ {
stx7141_wrt_table[0] = /* swith config */
ioread32(CLOCKGENA_BASE_ADDR + CKGA_CLKOPSRC_SWITCH_CFG(0));
stx7141_wrt_table[1] = /* swith config */
@@ -153,33 +160,7 @@ static int stx7141_suspend_prepare(suspend_state_t state)
ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(10));
stx7141_wrt_table[4] = /* clk_ic_if_200 */
ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(17));
- ret = 0;
- break;
}
- return ret;
-}
-
-static int stx7141_suspend_valid(suspend_state_t state)
-{
- switch (state) {
- case PM_SUSPEND_STANDBY:
- case PM_SUSPEND_MEM:
- return 1;
- };
- return 0;
-}
-
-/*
- * The xxxx_finish function is called after the resume
- * sysdev devices (i.e.: timer, cpufreq)
- * But it isn't a big issue in our platform
- */
-static int stx7141_suspend_finish(suspend_state_t state)
-{
- pm_message_t pms = {.event = PM_EVENT_ON, };
- sysconf_pm_state(pms);
- clk_pm_state(pms);
- emi_pm_state(pms);
return 0;
}
@@ -189,10 +170,27 @@ static unsigned long stx7141_iomem[2] __cacheline_aligned = {
static int stx7141_evttoirq(unsigned long evt)
{
- return ilc2irq(evt);
+ return ((evt < 0x400) ? ilc2irq(evt) : evt2irq(evt));
}
-int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
+static struct sh4_suspend_t st40data __cacheline_aligned = {
+ .iobase = stx7141_iomem,
+ .ops.prepare = stx7141_suspend_prepare,
+ .evt_to_irq = stx7141_evttoirq,
+#ifdef CONFIG_PM_DEBUG
+ .stby_tbl = (unsigned long)stx7141_standby_table,
+ .stby_size = DIV_ROUND_UP(ARRAY_SIZE(stx7141_standby_table) *
+ sizeof(long), L1_CACHE_BYTES),
+#endif
+ .mem_tbl = (unsigned long)stx7141_mem_table,
+ .mem_size = DIV_ROUND_UP(ARRAY_SIZE(stx7141_mem_table) * sizeof(long),
+ L1_CACHE_BYTES),
+ .wrt_tbl = (unsigned long)stx7141_wrt_table,
+ .wrt_size = DIV_ROUND_UP(ARRAY_SIZE(stx7141_wrt_table) * sizeof(long),
+ L1_CACHE_BYTES),
+};
+
+static int __init suspend_platform_setup()
{
struct sysconf_field *sc;
#ifdef CONFIG_PM_DEBUG
@@ -202,24 +200,6 @@ int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
sc = sysconf_claim(SYS_CFG, 19, 22, 23, "clkA dbg");
sysconf_write(sc, 11);
#endif
- st40data->iobase = stx7141_iomem;
- st40data->ops.valid = stx7141_suspend_valid;
- st40data->ops.finish = stx7141_suspend_finish;
- st40data->ops.prepare = stx7141_suspend_prepare;
-
- st40data->evt_to_irq = stx7141_evttoirq;
-
- st40data->stby_tbl = (unsigned long)stx7141_standby_table;
- st40data->stby_size = DIV_ROUND_UP(
- ARRAY_SIZE(stx7141_standby_table)*sizeof(long), L1_CACHE_BYTES);
-
- st40data->mem_tbl = (unsigned long)stx7141_mem_table;
- st40data->mem_size = DIV_ROUND_UP(
- ARRAY_SIZE(stx7141_mem_table)*sizeof(long), L1_CACHE_BYTES);
-
- st40data->wrt_tbl = (unsigned long)stx7141_wrt_table;
- st40data->wrt_size = DIV_ROUND_UP(
- ARRAY_SIZE(stx7141_wrt_table) * sizeof(long), L1_CACHE_BYTES);
sc = sysconf_claim(SYS_CFG, 38, 20, 20, "pm");
stx7141_wrt_table[_SYS_CFG38] = (unsigned long)sysconf_address(sc);
@@ -233,5 +213,11 @@ int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
stx7141_wrt_table[_SYS_STA4] = (unsigned long)sysconf_address(sc);
stx7141_wrt_table[_SYS_STA4_MASK] = sysconf_mask(sc);
- return 0;
+ sc = sysconf_claim(SYS_STA, 3, 0, 0, "pm");
+ stx7141_wrt_table[_SYS_STA3] = (unsigned long)sysconf_address(sc);
+ stx7141_wrt_table[_SYS_STA3_MASK] = sysconf_mask(sc);
+ stx7141_wrt_table[_SYS_STA3_VALUE] = 0;
+ return sh4_suspend_register(&st40data);
}
+
+late_initcall(suspend_platform_setup);
diff --git a/arch/sh/kernel/cpu/sh4/suspend-stx7200.c b/arch/sh/kernel/cpu/sh4/suspend-stx7200.c
index 320b660..23201b1 100644
--- a/arch/sh/kernel/cpu/sh4/suspend-stx7200.c
+++ b/arch/sh/kernel/cpu/sh4/suspend-stx7200.c
@@ -40,6 +40,7 @@
* STANDBY INSTRUCTION TABLE
* *************************
*/
+#ifdef CONFIG_PM_DEBUG
static unsigned long stx7200_standby_table[] __cacheline_aligned = {
/* Down scale the GenA.Pll0 and GenA.Pll2*/
CLK_OR_LONG(CLKA_PLL0, CLKA_PLL0_BYPASS),
@@ -79,6 +80,8 @@ _OR(),
CLK_STORE(CLKA_PLL2),
#endif
CLK_AND_LONG(CLKA_PWR_CFG, ~(PWR_CFG_PLL0_OFF | PWR_CFG_PLL2_OFF)),
+CLK_WHILE_NEQ(CLKA_PLL0, CLKA_PLL0_LOCK, CLKA_PLL0_LOCK),
+CLK_WHILE_NEQ(CLKA_PLL2, CLKA_PLL2_LOCK, CLKA_PLL2_LOCK),
CLK_AND_LONG(CLKA_PLL0, ~(CLKA_PLL0_BYPASS)),
CLK_AND_LONG(CLKA_PLL2, ~(CLKA_PLL2_BYPASS)),
@@ -86,6 +89,7 @@ _DELAY(),
/* END. */
_END()
};
+#endif
/* *********************
* MEM INSTRUCTION TABLE
@@ -118,6 +122,10 @@ CLK_OR_LONG(CLKA_PLL2, CLKA_PLL2_SUSPEND),
CLK_AND_LONG(CLKA_PWR_CFG, ~(PWR_CFG_PLL0_OFF | PWR_CFG_PLL1_OFF | PWR_CFG_PLL2_OFF)),
+CLK_WHILE_NEQ(CLKA_PLL0, CLKA_PLL0_LOCK, CLKA_PLL0_LOCK),
+CLK_WHILE_NEQ(CLKA_PLL1, CLKA_PLL1_LOCK, CLKA_PLL1_LOCK),
+CLK_WHILE_NEQ(CLKA_PLL2, CLKA_PLL2_LOCK, CLKA_PLL2_LOCK),
+
CLK_AND_LONG(CLKA_PLL0, ~(CLKA_PLL0_BYPASS)),
CLK_AND_LONG(CLKA_PLL1, ~(CLKA_PLL1_BYPASS)),
CLK_AND_LONG(CLKA_PLL2, ~(CLKA_PLL2_BYPASS)),
@@ -149,6 +157,10 @@ _OR(),
CLK_STORE(CLKA_PLL2),
#endif
CLK_AND_LONG(CLKA_PWR_CFG, ~(PWR_CFG_PLL0_OFF | PWR_CFG_PLL1_OFF | PWR_CFG_PLL2_OFF)),
+/* Wait PLLs lock */
+CLK_WHILE_NEQ(CLKA_PLL0, CLKA_PLL0_LOCK, CLKA_PLL0_LOCK),
+CLK_WHILE_NEQ(CLKA_PLL1, CLKA_PLL1_LOCK, CLKA_PLL1_LOCK),
+CLK_WHILE_NEQ(CLKA_PLL2, CLKA_PLL2_LOCK, CLKA_PLL2_LOCK),
CLK_AND_LONG(CLKA_PLL0, ~(CLKA_PLL0_BYPASS)),
CLK_AND_LONG(CLKA_PLL1, ~(CLKA_PLL1_BYPASS)),
@@ -172,53 +184,25 @@ static unsigned long stx7200_wrt_table[16] __cacheline_aligned;
static int stx7200_suspend_prepare(suspend_state_t state)
{
- pm_message_t pm = {.event = PM_EVENT_SUSPEND, };
- emi_pm_state(pm);
- clk_pm_state(pm);
- sysconf_pm_state(pm);
-
- switch (state) {
- case PM_SUSPEND_STANDBY:
+#ifdef CONFIG_PM_DEBUG
+ if (state = PM_SUSPEND_STANDBY) {
stx7200_wrt_table[0] readl(CLOCKGEN_BASE_ADDR + CLKA_PLL0) & 0x7ffff;
stx7200_wrt_table[1] readl(CLOCKGEN_BASE_ADDR + CLKA_PLL2) & 0x7ffff;
- return 0;
- case PM_SUSPEND_MEM:
+ } else
+#endif
+ {
stx7200_wrt_table[0] readl(CLOCKGEN_BASE_ADDR + CLKA_PLL0) & 0x7ffff;
stx7200_wrt_table[1] readl(CLOCKGEN_BASE_ADDR + CLKA_PLL1) & 0x7ffff;
stx7200_wrt_table[2] readl(CLOCKGEN_BASE_ADDR + CLKA_PLL2) & 0x7ffff;
- return 0;
}
- return -EINVAL;
-}
-
-static int stx7200_suspend_valid(suspend_state_t state)
-{
- switch (state) {
- case PM_SUSPEND_STANDBY:
- case PM_SUSPEND_MEM:
- return 1;
- };
return 0;
}
-/*
- * The xxxx_finish function is called after the resume
- * sysdev devices (i.e.: timer, cpufreq)
- * But it isn't a big issue in our platform
- */
-static int stx7200_suspend_finish(suspend_state_t state)
-{
- pm_message_t pm = {.event = PM_EVENT_ON, };
- sysconf_pm_state(pm);
- clk_pm_state(pm);
- emi_pm_state(pm);
- return 0;
-}
static unsigned long stx7200_iomem[2] __cacheline_aligned = {
stx7200_wrt_table, /* To access Sysconf */
@@ -226,32 +210,30 @@ static unsigned long stx7200_iomem[2] __cacheline_aligned = {
static int stx7200_evttoirq(unsigned long evt)
{
- return ilc2irq(evt);
+ return ((evt < 0x400) ? ilc2irq(evt) : evt2irq(evt));
}
-int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
+static struct sh4_suspend_t st40data __cacheline_aligned = {
+ .iobase = stx7200_iomem,
+ .ops.prepare = stx7200_suspend_prepare,
+ .evt_to_irq = stx7200_evttoirq,
+#ifdef CONFIG_PM_DEBUG
+ .stby_tbl = (unsigned long)stx7200_standby_table,
+ .stby_size = DIV_ROUND_UP(ARRAY_SIZE(stx7200_standby_table) *
+ sizeof(long), L1_CACHE_BYTES),
+#endif
+ .mem_tbl = (unsigned long)stx7200_mem_table,
+ .mem_size = DIV_ROUND_UP(ARRAY_SIZE(stx7200_mem_table) * sizeof(long),
+ L1_CACHE_BYTES),
+ .wrt_tbl = (unsigned long)stx7200_wrt_table,
+ .wrt_size = DIV_ROUND_UP(ARRAY_SIZE(stx7200_wrt_table) * sizeof(long),
+ L1_CACHE_BYTES),
+};
+
+static int __init suspend_platform_setup()
{
struct sysconf_field* sc;
- st40data->iobase = stx7200_iomem;
- st40data->ops.valid = stx7200_suspend_valid;
- st40data->ops.finish = stx7200_suspend_finish;
- st40data->ops.prepare = stx7200_suspend_prepare;
-
- st40data->evt_to_irq = stx7200_evttoirq;
-
- st40data->stby_tbl = (unsigned long)stx7200_standby_table;
- st40data->stby_size = DIV_ROUND_UP(
- ARRAY_SIZE(stx7200_standby_table)*sizeof(long), L1_CACHE_BYTES);
-
- st40data->mem_tbl = (unsigned long)stx7200_mem_table;
- st40data->mem_size = DIV_ROUND_UP(
- ARRAY_SIZE(stx7200_mem_table)*sizeof(long), L1_CACHE_BYTES);
-
- st40data->wrt_tbl = (unsigned long)stx7200_wrt_table;
- st40data->wrt_size = DIV_ROUND_UP(
- ARRAY_SIZE(stx7200_wrt_table) * sizeof(long), L1_CACHE_BYTES);
-
sc = sysconf_claim(SYS_STA, 4, 0, 0, "pm");
stx7200_wrt_table[_SYS_STA4] = (unsigned long)sysconf_address(sc);
stx7200_wrt_table[_SYS_STA4_MASK] = sysconf_mask(sc);
@@ -272,5 +254,7 @@ int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
ctrl_outl(0xc, CKGA_CLKOUT_SEL +
CLOCKGEN_BASE_ADDR); /* sh4:2 routed on SYSCLK_OUT */
#endif
- return 0;
+ return sh4_suspend_register(&st40data);
}
+
+late_initcall(suspend_platform_setup);
--
1.6.0.6
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] stm: pm: Rework the suspend SOC code
2009-05-18 13:18 [PATCH] stm: pm: Rework the suspend SOC code Francesco VIRLINZI
@ 2009-05-18 13:19 ` Francesco VIRLINZI
0 siblings, 0 replies; 2+ messages in thread
From: Francesco VIRLINZI @ 2009-05-18 13:19 UTC (permalink / raw)
To: linux-sh
Sorry!
I sent the patch on the wrong mail-list
Regards
Francesco
Francesco VIRLINZI ha scritto:
> Changed the suspend SOC code based on the registration mechanism
>
> Signed-off-by: Francesco Virlinzi <francesco.virlinzi@st.com>
> ---
> arch/sh/kernel/cpu/sh4/clock-stx7200.c | 5 +-
> arch/sh/kernel/cpu/sh4/soc-stb7100.h | 7 ++
> arch/sh/kernel/cpu/sh4/soc-stx5197.h | 17 ++--
> arch/sh/kernel/cpu/sh4/soc-stx7141.h | 2 +-
> arch/sh/kernel/cpu/sh4/soc-stx7200.h | 34 +++++----
> arch/sh/kernel/cpu/sh4/suspend-stb7100.c | 102 ++++++++++----------------
> arch/sh/kernel/cpu/sh4/suspend-stx5197.c | 119 ++++++++++++-----------------
> arch/sh/kernel/cpu/sh4/suspend-stx7105.c | 112 +++++++++++-----------------
> arch/sh/kernel/cpu/sh4/suspend-stx7111.c | 98 ++++++++++--------------
> arch/sh/kernel/cpu/sh4/suspend-stx7141.c | 102 +++++++++++---------------
> arch/sh/kernel/cpu/sh4/suspend-stx7200.c | 94 ++++++++++--------------
> 11 files changed, 294 insertions(+), 398 deletions(-)
>
> diff --git a/arch/sh/kernel/cpu/sh4/clock-stx7200.c b/arch/sh/kernel/cpu/sh4/clock-stx7200.c
> index cf03964..ce6a92d 100644
> --- a/arch/sh/kernel/cpu/sh4/clock-stx7200.c
> +++ b/arch/sh/kernel/cpu/sh4/clock-stx7200.c
> @@ -620,8 +620,9 @@ int clk_pm_state(pm_message_t state)
> tmp = readl(CLOCKGENB_BASE_ADDR + CLKB_PWR_CFG);
> writel(tmp & ~CLKB_PLL0_OFF,
> CLOCKGENB_BASE_ADDR + CLKB_PWR_CFG);
> -
> - mdelay(10); /* wait for stable signal */
> + /* Wait PllB lock */
> + while ((readl(CLOCKGENB_BASE_ADDR + CLKB_PLL0_CFG)
> + & CLKB_PLL0_LOCK) != 0);
> tmp = readl(CLOCKGENB_BASE_ADDR + CLKB_PLL0_CFG);
> writel(tmp & ~CLKB_PLL0_BYPASS,
> CLOCKGENB_BASE_ADDR + CLKB_PLL0_CFG);
> diff --git a/arch/sh/kernel/cpu/sh4/soc-stb7100.h b/arch/sh/kernel/cpu/sh4/soc-stb7100.h
> index 8f75fd8..20fa102 100644
> --- a/arch/sh/kernel/cpu/sh4/soc-stb7100.h
> +++ b/arch/sh/kernel/cpu/sh4/soc-stb7100.h
> @@ -22,6 +22,10 @@
> #define CLKA_PLL0_ENABLE (1 << 19)
> #define CLKA_PLL0_SUSPEND ((5 << 16) | (100 << 8) | \
> (CONFIG_SH_EXTERNAL_CLOCK / 1000000))
> +
> +#define CLKA_PLL0_LOCK 0x10
> + #define CLKA_PLL0_LOCK_LOCKED 0x01
> +
> #define CLKA_ST40 0x14
> #define CLKA_ST40_IC 0x18
> #define CLKA_ST40_PER 0x1c
> @@ -30,6 +34,9 @@
> #define CLKA_PLL1_ENABLE (1 << 19)
> #define CLKA_PLL1_SUSPEND ((5 << 16) | (100 << 8) | \
> (CONFIG_SH_EXTERNAL_CLOCK / 1000000))
> +#define CLKA_PLL1_LOCK 0x2C
> + #define CLKA_PLL1_LOCK_LOCKED 0x01
> +
> #define CLKA_CLK_DIV 0x30
> #define CLKA_CLK_EN 0x34
> #define CLKA_CLK_EN_ST231_AUD (1 << 0)
> diff --git a/arch/sh/kernel/cpu/sh4/soc-stx5197.h b/arch/sh/kernel/cpu/sh4/soc-stx5197.h
> index 4009a76..54092e0 100644
> --- a/arch/sh/kernel/cpu/sh4/soc-stx5197.h
> +++ b/arch/sh/kernel/cpu/sh4/soc-stx5197.h
> @@ -40,7 +40,8 @@ enum clocks_ID {
>
> #define CLK_PLL_CONFIG0(x) ((x*8)+0x0)
> #define CLK_PLL_CONFIG1(x) ((x*8)+0x4)
> - #define CLK_PLL_CONFIG1_POFF (1<<13)
> +#define CLK_PLL_CONFIG1_POFF (1<<13)
> +#define CLK_PLL_CONFIG1_LOCK (1<<15)
>
> #define CLKDIV0_CONFIG0 0x90
> #define CLKDIV1_4_CONFIG0(n) (0x0a0 + ((n-1)*0xc))
> @@ -54,20 +55,20 @@ enum clocks_ID {
>
>
> #define CLK_MODE_CTRL 0x110
> - #define CLK_MODE_CTRL_NULL 0x0
> - #define CLK_MODE_CTRL_X1 0x1
> - #define CLK_MODE_CTRL_PROG 0x2
> - #define CLK_MODE_CTRL_STDB 0x3
> +#define CLK_MODE_CTRL_NULL 0x0
> +#define CLK_MODE_CTRL_X1 0x1
> +#define CLK_MODE_CTRL_PROG 0x2
> +#define CLK_MODE_CTRL_STDB 0x3
>
> /*
> * The REDUCED_PM is used in CLK_MODE_CTRL_PROG...
> */
> #define CLK_REDUCED_PM_CTRL 0x114
> - #define CLK_REDUCED_ON_XTAL_MEMSTDBY (1<<11)
> - #define CLK_REDUCED_ON_XTAL_STDBY (~(0x22))
> +#define CLK_REDUCED_ON_XTAL_MEMSTDBY (1<<11)
> +#define CLK_REDUCED_ON_XTAL_STDBY (~(0x22))
>
> #define CLK_LP_MODE_DIS0 0x118
> - #define CLK_LP_MODE_DIS0_VALUE ((0x3 << 11) | (0x7ff & ~(1<<9)))
> +#define CLK_LP_MODE_DIS0_VALUE (0x3 << 11)
>
> #define CLK_LP_MODE_DIS2 0x11C
>
> diff --git a/arch/sh/kernel/cpu/sh4/soc-stx7141.h b/arch/sh/kernel/cpu/sh4/soc-stx7141.h
> index d98b506..5048610 100644
> --- a/arch/sh/kernel/cpu/sh4/soc-stx7141.h
> +++ b/arch/sh/kernel/cpu/sh4/soc-stx7141.h
> @@ -21,7 +21,7 @@
> #define CLOCKGENA_BASE_ADDR 0xfe213000 /* Clockgen A */
> #define CLOCKGENB_BASE_ADDR 0xfe000000 /* Clockgen B */
>
> -#define ckga_pll0_cfg 0x000
> +#define CKGA_PLL0_CFG 0x000
> #define CKGA_PLL0_CFG_DIVRES (1 << 20)
> #define CKGA_PLL0_CFG_BYPASS CKGA_PLL0_CFG_DIVRES
> #define CKGA_PLL0_CFG_LOCK (1 << 31)
> diff --git a/arch/sh/kernel/cpu/sh4/soc-stx7200.h b/arch/sh/kernel/cpu/sh4/soc-stx7200.h
> index 9045b16..5933506 100644
> --- a/arch/sh/kernel/cpu/sh4/soc-stx7200.h
> +++ b/arch/sh/kernel/cpu/sh4/soc-stx7200.h
> @@ -24,38 +24,42 @@
> #define CLOCKGENC_BASE_ADDR 0xfd601000 /* Clockgen C */
>
> #define CLKA_PLL0 0x00
> - #define CLKA_PLL0_BYPASS (1 << 20)
> - #define CLKA_PLL0_ENABLE_STATUS (1 << 19)
> - #define CLKA_PLL0_SUSPEND ((5 << 16) | (100 << 8) | \
> +#define CLKA_PLL0_BYPASS (1 << 20)
> +#define CLKA_PLL0_ENABLE_STATUS (1 << 19)
> +#define CLKA_PLL0_LOCK (1 << 31)
> +#define CLKA_PLL0_SUSPEND ((5 << 16) | (100 << 8) | \
> (SYSACLKIN / 1000000))
>
> #define CLKA_PLL1 0x04
> - #define CLKA_PLL1_BYPASS (1 << 20)
> - #define CLKA_PLL1_ENABLE_STATUS (1 << 19)
> - #define CLKA_PLL1_SUSPEND ((100 << 8) | (SYSACLKIN / 1000000))
> +#define CLKA_PLL1_BYPASS (1 << 20)
> +#define CLKA_PLL1_ENABLE_STATUS (1 << 19)
> +#define CLKA_PLL1_LOCK (1 << 31)
> +#define CLKA_PLL1_SUSPEND ((100 << 8) | (SYSACLKIN / 1000000))
>
> #define CLKA_PLL2 0x08
> - #define CLKA_PLL2_BYPASS (1 << 20)
> - #define CLKA_PLL2_ENABLE_STATUS (1 << 19)
> - #define CLKA_PLL2_SUSPEND ((5 << 16) | (100 << 8) | \
> +#define CLKA_PLL2_BYPASS (1 << 20)
> +#define CLKA_PLL2_ENABLE_STATUS (1 << 19)
> +#define CLKA_PLL2_LOCK (1 << 31)
> +#define CLKA_PLL2_SUSPEND ((5 << 16) | (100 << 8) | \
> (SYSACLKIN / 1000000))
>
> #define CKGA_CLKOUT_SEL 0x18
>
> #define CLKA_PWR_CFG 0x1C
> - #define PWR_CFG_PLL0_OFF 0x1
> - #define PWR_CFG_PLL1_OFF 0x2
> - #define PWR_CFG_PLL2_OFF 0x4
> +#define PWR_CFG_PLL0_OFF 0x1
> +#define PWR_CFG_PLL1_OFF 0x2
> +#define PWR_CFG_PLL2_OFF 0x4
>
> #define CLKA_DIV_CFG 0x10
>
>
> #define CLKB_PLL0_CFG 0x3C
> - #define CLKB_PLL0_BYPASS (1 << 20)
> - #define CLKB_PLL0_SUSPEND ((5 << 16) | (100 << 8) | \
> +#define CLKB_PLL0_LOCK (1 << 31)
> +#define CLKB_PLL0_BYPASS (1 << 20)
> +#define CLKB_PLL0_SUSPEND ((5 << 16) | (100 << 8) | \
> (SYSACLKIN / 1000000))
>
> #define CLKB_PWR_CFG 0x58
> - #define CLKB_PLL0_OFF (1 << 15)
> +#define CLKB_PLL0_OFF (1 << 15)
>
> #endif
> diff --git a/arch/sh/kernel/cpu/sh4/suspend-stb7100.c b/arch/sh/kernel/cpu/sh4/suspend-stb7100.c
> index e5134ec..79eab1f 100644
> --- a/arch/sh/kernel/cpu/sh4/suspend-stb7100.c
> +++ b/arch/sh/kernel/cpu/sh4/suspend-stb7100.c
> @@ -32,11 +32,13 @@
> #define _SYS_CFG11 (6)
> #define _SYS_CFG11_MASK (7)
>
> +extern void __iomem *clkgena_base;
> +
> /* *************************
> * STANDBY INSTRUCTION TABLE
> * *************************
> */
> -
> +#ifdef CONFIG_PM_DEBUG
> static unsigned long stb7100_standby_table[] __cacheline_aligned = {
> /* 1. PLL0 at the minimum frequency */
> /* Unlock the clocks */
> @@ -51,6 +53,8 @@ CLK_AND_LONG(CLKA_PLL0, ~(0x7ffff)),
> CLK_OR_LONG(CLKA_PLL0, CLKA_PLL0_SUSPEND),
> /* enables the pll0 */
> CLK_OR_LONG(CLKA_PLL0, CLKA_PLL0_ENABLE),
> + /* Wait PLL0 lock */
> +CLK_WHILE_NEQ(CLKA_PLL0_LOCK, CLKA_PLL0_LOCK_LOCKED, CLKA_PLL0_LOCK_LOCKED),
> /* removes the bypass */
> CLK_AND_LONG(CLKA_PLL0, ~(CLKA_PLL0_BYPASS)),
> /* 0 4 5 - 1:4 1:6 1:8 */
> @@ -79,6 +83,8 @@ _OR(),
> CLK_STORE(CLKA_PLL0),
> /* enables the pll0 */
> CLK_OR_LONG(CLKA_PLL0, CLKA_PLL0_ENABLE),
> + /* Wait PLL0 lock */
> +CLK_WHILE_NEQ(CLKA_PLL0_LOCK, CLKA_PLL0_LOCK_LOCKED, CLKA_PLL0_LOCK_LOCKED),
> /* removes the bypass */
> CLK_AND_LONG(CLKA_PLL0, ~(CLKA_PLL0_BYPASS)),
> /* Lock the clocks */
> @@ -86,7 +92,7 @@ CLK_POKE(CLKA_LOCK, 0x0),
> /* END. */
> _END()
> };
> -
> +#endif
> /* *********************
> * MEM INSTRUCTION TABLE
> * *********************
> @@ -112,6 +118,8 @@ CLK_AND_LONG(CLKA_PLL0, ~(0x7ffff)),
> CLK_OR_LONG(CLKA_PLL0, CLKA_PLL0_SUSPEND),
> /* enables the pll0 */
> CLK_OR_LONG(CLKA_PLL0, CLKA_PLL0_ENABLE),
> + /* Wait PLL0 lock */
> +CLK_WHILE_NEQ(CLKA_PLL0_LOCK, CLKA_PLL0_LOCK_LOCKED, CLKA_PLL0_LOCK_LOCKED),
> /* removes the bypass */
> CLK_AND_LONG(CLKA_PLL0, ~(CLKA_PLL0_BYPASS)),
>
> @@ -126,6 +134,8 @@ CLK_AND_LONG(CLKA_PLL1, ~(0x7ffff)),
> CLK_OR_LONG(CLKA_PLL1, CLKA_PLL1_SUSPEND),
> /* enables the pll1 */
> CLK_OR_LONG(CLKA_PLL1, CLKA_PLL1_ENABLE),
> + /* Wait PLL1 lock */
> +CLK_WHILE_NEQ(CLKA_PLL1_LOCK, CLKA_PLL1_LOCK_LOCKED, CLKA_PLL1_LOCK_LOCKED),
> CLK_AND_LONG(CLKA_PLL1_BYPASS, ~(2)), /* removes the bypass */
>
> /* 4. Turn-off the LMI clocks and the ST231 clocks */
> @@ -150,6 +160,8 @@ CLK_AND_LONG(CLKA_PLL1, ~(CLKA_PLL1_ENABLE)), /* disable the pll1 */
> DATA_LOAD(0x1),
> CLK_STORE(CLKA_PLL1),
> CLK_OR_LONG(CLKA_PLL1, CLKA_PLL1_ENABLE), /* enables the pll1 */
> + /* Wait PLL1 lock */
> +CLK_WHILE_NEQ(CLKA_PLL1_LOCK, CLKA_PLL1_LOCK_LOCKED, CLKA_PLL1_LOCK_LOCKED),
> CLK_AND_LONG(CLKA_PLL1_BYPASS, ~(2)), /* removes the bypass */
>
> /* 4. Disables the DDR self refresh mode */
> @@ -167,6 +179,8 @@ IMMEDIATE_SRC0(CLKA_PLL0_BYPASS),
> _OR(),
> CLK_STORE(CLKA_PLL0), /* save the r2 in PLL0 */
> CLK_OR_LONG(CLKA_PLL0, CLKA_PLL0_ENABLE), /* enables the pll0 */
> + /* Wait PLL0 lock */
> +CLK_WHILE_NEQ(CLKA_PLL0_LOCK, CLKA_PLL0_LOCK_LOCKED, CLKA_PLL0_LOCK_LOCKED),
> CLK_AND_LONG(CLKA_PLL0, ~(CLKA_PLL0_BYPASS)), /* removes the bypass */
> CLK_POKE(CLKA_LOCK, 0x0),
>
> @@ -182,46 +196,8 @@ static unsigned long stb7100_wrt_table[8] __cacheline_aligned;
>
> static int stb7100_suspend_prepare(suspend_state_t state)
> {
> - int ret = -EINVAL;
> - pm_message_t pms = {.event = PM_EVENT_SUSPEND, };
> - emi_pm_state(pms);
> -/* clk_pm_state(pms);*/
> - sysconf_pm_state(pms);
> - switch (state) {
> - case PM_SUSPEND_STANDBY:
> - stb7100_wrt_table[0] = readl(clkgena_base + CLKA_PLL0) & 0x7ffff;
> - ret = 0;
> - break;
> - case PM_SUSPEND_MEM:
> - stb7100_wrt_table[0] = readl(clkgena_base + CLKA_PLL0) & 0x7ffff;
> - stb7100_wrt_table[1] = readl(clkgena_base + CLKA_PLL1) & 0x7ffff;
> - ret = 0;
> - break;
> - }
> - return ret;
> -}
> -
> -static int stb7100_suspend_valid(suspend_state_t state)
> -{
> - switch (state) {
> - case PM_SUSPEND_STANDBY:
> - case PM_SUSPEND_MEM:
> - return 1;
> - };
> - return 0;
> -}
> -
> -/*
> - * The xxxx_finish function is called after the resume
> - * sysdev devices (i.e.: timer, cpufreq)
> - * But it isn't a big issue in our platform
> - */
> -static int stb7100_suspend_finish(suspend_state_t state)
> -{
> - pm_message_t pms = {.event = PM_EVENT_ON, };
> - sysconf_pm_state(pms);
> -/* clk_pm_state(pms);*/
> - emi_pm_state(pms);
> + stb7100_wrt_table[0] = readl(clkgena_base + CLKA_PLL0) & 0x7ffff;
> + stb7100_wrt_table[1] = readl(clkgena_base + CLKA_PLL1) & 0x7ffff;
> return 0;
> }
>
> @@ -234,31 +210,29 @@ static unsigned long stb7100_iomem[2] __cacheline_aligned = {
> stb7100_wrt_table,
> };
>
> -int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
> +static struct sh4_suspend_t st40data __cacheline_aligned = {
> + .iobase = stb7100_iomem,
> + .ops.prepare = stb7100_suspend_prepare,
> + .evt_to_irq = stb7100_evttoirq,
> +#ifdef CONFIG_PM_DEBUG
> + .stby_tbl = (unsigned long)stb7100_standby_table,
> + .stby_size = DIV_ROUND_UP(ARRAY_SIZE(stb7100_standby_table) *
> + sizeof(long), L1_CACHE_BYTES),
> +#endif
> + .mem_tbl = (unsigned long)stb7100_mem_table,
> + .mem_size = DIV_ROUND_UP(ARRAY_SIZE(stb7100_mem_table) * sizeof(long),
> + L1_CACHE_BYTES),
> + .wrt_tbl = (unsigned long)stb7100_wrt_table,
> + .wrt_size = DIV_ROUND_UP(ARRAY_SIZE(stb7100_wrt_table) * sizeof(long),
> + L1_CACHE_BYTES),
> +};
> +
> +static int __init suspend_platform_setup()
> {
> struct sysconf_field* sc;
>
> stb7100_iomem[1] = (unsigned long) clkgena_base;
>
> - st40data->iobase = stb7100_iomem;
> - st40data->ops.valid = stb7100_suspend_valid;
> - st40data->ops.finish = stb7100_suspend_finish;
> - st40data->ops.prepare = stb7100_suspend_prepare;
> -
> - st40data->evt_to_irq = stb7100_evttoirq;
> -
> - st40data->stby_tbl = (unsigned long)stb7100_standby_table;
> - st40data->stby_size = DIV_ROUND_UP(
> - ARRAY_SIZE(stb7100_standby_table)*sizeof(long), L1_CACHE_BYTES);;
> -
> - st40data->mem_tbl = (unsigned long)stb7100_mem_table;
> - st40data->mem_size = DIV_ROUND_UP(
> - ARRAY_SIZE(stb7100_mem_table)*sizeof(long), L1_CACHE_BYTES);
> -
> - st40data->wrt_tbl = (unsigned long)stb7100_wrt_table;
> - st40data->wrt_size = DIV_ROUND_UP(
> - ARRAY_SIZE(stb7100_wrt_table)*sizeof(long), L1_CACHE_BYTES);
> -
> sc = sysconf_claim(SYS_STA, 12, 28, 28, "pm");
> stb7100_wrt_table[_SYS_STA12] = (unsigned long)sysconf_address(sc);
> stb7100_wrt_table[_SYS_STA12_MASK] = sysconf_mask(sc);
> @@ -273,5 +247,7 @@ int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
> sc = sysconf_claim(SYS_CFG, 11, 30, 30, "pm");
> stb7100_wrt_table[_SYS_CFG11_MASK] |= sysconf_mask(sc);
>
> - return 0;
> + return sh4_suspend_register(&st40data);
> }
> +
> +late_initcall(suspend_platform_setup);
> diff --git a/arch/sh/kernel/cpu/sh4/suspend-stx5197.c b/arch/sh/kernel/cpu/sh4/suspend-stx5197.c
> index 69aa3f3..ee793ad 100644
> --- a/arch/sh/kernel/cpu/sh4/suspend-stx5197.c
> +++ b/arch/sh/kernel/cpu/sh4/suspend-stx5197.c
> @@ -31,10 +31,25 @@
> #define _SYS_CFG_H (2)
> #define _SYS_CFG_H_MASK (3)
>
> +
> +
> +/*
> + * System Service Finite State Machine
> + * +-------+ +------+ +------+
> + * | reset |-->| X1 |<-->| Prog |
> + * +-------+ +------+ +------+
> + * /\ |
> + * | \/
> + * wakeup | +-------+
> + * event +-------|Standby|
> + * +-------+
> + */
> +
> /* *************************
> * STANDBY INSTRUCTION TABLE
> * *************************
> */
> +#ifdef CONFIG_PM_DEBUG
> static unsigned long stx5197_standby_table[] __cacheline_aligned = {
> CLK_POKE(CLK_LOCK_CFG, 0xf0),
> CLK_POKE(CLK_LOCK_CFG, 0x0f), /* UnLock the clocks */
> @@ -54,6 +69,7 @@ CLK_POKE(CLK_LOCK_CFG, 0x0f), /* UnLock the clocks */
> CLK_POKE(CLK_MODE_CTRL, CLK_MODE_CTRL_X1),
> CLK_AND_LONG(CLK_REDUCED_PM_CTRL, ~CLK_REDUCED_ON_XTAL_STDBY),
> CLK_AND_LONG(CLK_PLL_CONFIG1(0), ~CLK_PLL_CONFIG1_POFF),
> +CLK_WHILE_NEQ(CLK_PLL_CONFIG1(0), CLK_PLL_CONFIG1_LOCK, CLK_PLL_CONFIG1_LOCK),
> CLK_POKE(CLK_MODE_CTRL, CLK_MODE_CTRL_PROG),
> CLK_POKE(CLK_LOCK_CFG, 0x100), /* Lock the clocks */
> _DELAY(),
> @@ -61,6 +77,7 @@ _DELAY(),
> _DELAY(),
> _END()
> };
> +#endif
>
> /* *********************
> * MEM INSTRUCTION TABLE
> @@ -73,22 +90,19 @@ DATA_WHILE_NEQ(_SYS_MON_J, _SYS_MON_J_MASK, _SYS_MON_J_MASK),
> CLK_POKE(CLK_LOCK_CFG, 0xf0),
> CLK_POKE(CLK_LOCK_CFG, 0x0f), /* UnLock the clocks */
>
> -CLK_POKE(CLK_MODE_CTRL, CLK_MODE_CTRL_X1),
> -/* on exetrnal Xtal */
> -CLK_OR_LONG(CLK_REDUCED_PM_CTRL, CLK_REDUCED_ON_XTAL_MEMSTDBY),
> -CLK_OR_LONG(CLK_PLL_CONFIG1(0), CLK_PLL_CONFIG1_POFF),
> -CLK_OR_LONG(CLK_PLL_CONFIG1(1), CLK_PLL_CONFIG1_POFF),
> -CLK_POKE(CLK_MODE_CTRL, CLK_MODE_CTRL_PROG),
> -CLK_POKE(CLK_LOCK_CFG, 0x100), /* Lock the clocks */
> +/* disable PLLs in standby */
> +CLK_OR_LONG(CLK_LP_MODE_DIS0, CLK_LP_MODE_DIS0_VALUE),
> +CLK_POKE(CLK_MODE_CTRL, CLK_MODE_CTRL_STDB), /* IN STANDBY */
>
> -_END(),
> -
> -CLK_POKE(CLK_LOCK_CFG, 0xf0),
> -CLK_POKE(CLK_LOCK_CFG, 0x0f), /* UnLock the clocks */
> -CLK_POKE(CLK_MODE_CTRL, CLK_MODE_CTRL_X1),
> +_END_NO_SLEEP(),
> +/*
> + * On a wakeup Event the System Service goes directly in X1 mode */
> CLK_AND_LONG(CLK_PLL_CONFIG1(0), ~CLK_PLL_CONFIG1_POFF),
> CLK_AND_LONG(CLK_PLL_CONFIG1(1), ~CLK_PLL_CONFIG1_POFF),
> -CLK_AND_LONG(CLK_REDUCED_PM_CTRL, ~CLK_REDUCED_ON_XTAL_MEMSTDBY), /* on PLLs */
> +/* Wait PLLs lock */
> +CLK_WHILE_NEQ(CLK_PLL_CONFIG1(0), CLK_PLL_CONFIG1_LOCK, CLK_PLL_CONFIG1_LOCK),
> +CLK_WHILE_NEQ(CLK_PLL_CONFIG1(1), CLK_PLL_CONFIG1_LOCK, CLK_PLL_CONFIG1_LOCK),
> +
> CLK_POKE(CLK_MODE_CTRL, CLK_MODE_CTRL_PROG),
> CLK_POKE(CLK_LOCK_CFG, 0x100), /* Lock the clocks */
>
> @@ -109,42 +123,6 @@ static unsigned long stx5197_wrt_table[8] __cacheline_aligned;
>
> static int stx5197_suspend_prepare(suspend_state_t state)
> {
> - int ret = -EINVAL;
> - pm_message_t pms = {.event = PM_EVENT_SUSPEND, };
> - emi_pm_state(pms);
> -/* clk_pm_state(pms);*/
> - sysconf_pm_state(pms);
> -
> - switch (state) {
> - case PM_SUSPEND_STANDBY:
> - case PM_SUSPEND_MEM:
> - ret = 0;
> - break;
> - }
> - return ret;
> -}
> -
> -static int stx5197_suspend_valid(suspend_state_t state)
> -{
> - switch (state) {
> - case PM_SUSPEND_STANDBY:
> - case PM_SUSPEND_MEM:
> - return 1;
> - };
> - return 0;
> -}
> -
> -/*
> - * The xxxx_finish function is called after the resume
> - * sysdev devices (i.e.: timer, cpufreq)
> - * But it isn't a big issue in our platform
> - */
> -static int stx5197_suspend_finish(suspend_state_t state)
> -{
> - pm_message_t pms = {.event = PM_EVENT_ON, };
> - sysconf_pm_state(pms);
> -/* clk_pm_state(pms);*/
> - emi_pm_state(pms);
> return 0;
> }
>
> @@ -154,31 +132,30 @@ static unsigned long stx5197_iomem[2] __cacheline_aligned = {
>
> static int stx5197_evt_to_irq(unsigned long evt)
> {
> - return ilc2irq(evt);
> + return ((evt < 0x400) ? ilc2irq(evt) : evt2irq(evt));
> }
>
> -int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
> +static struct sh4_suspend_t st40data __cacheline_aligned = {
> + .iobase = stx5197_iomem,
> + .ops.prepare = stx5197_suspend_prepare,
> + .evt_to_irq = stx5197_evt_to_irq,
> +#ifdef CONFIG_PM_DEBUG
> + .stby_tbl = (unsigned long)stx5197_standby_table,
> + .stby_size = DIV_ROUND_UP(ARRAY_SIZE(stx5197_standby_table) *
> + sizeof(long), L1_CACHE_BYTES),
> +#endif
> + .mem_tbl = (unsigned long)stx5197_mem_table,
> + .mem_size = DIV_ROUND_UP(ARRAY_SIZE(stx5197_mem_table) * sizeof(long),
> + L1_CACHE_BYTES),
> + .wrt_tbl = (unsigned long)stx5197_wrt_table,
> + .wrt_size = DIV_ROUND_UP(ARRAY_SIZE(stx5197_wrt_table) * sizeof(long),
> + L1_CACHE_BYTES),
> +};
> +
> +static int __init suspend_platform_setup(void)
> {
>
> struct sysconf_field* sc;
> - st40data->iobase = stx5197_iomem;
> - st40data->ops.valid = stx5197_suspend_valid;
> - st40data->ops.finish = stx5197_suspend_finish;
> - st40data->ops.prepare = stx5197_suspend_prepare;
> -
> - st40data->evt_to_irq = stx5197_evt_to_irq;
> -
> - st40data->stby_tbl = (unsigned long)stx5197_standby_table;
> - st40data->stby_size = DIV_ROUND_UP(
> - ARRAY_SIZE(stx5197_standby_table) * sizeof(long), L1_CACHE_BYTES);
> -
> - st40data->mem_tbl = (unsigned long)stx5197_mem_table;
> - st40data->mem_size = DIV_ROUND_UP(
> - ARRAY_SIZE(stx5197_mem_table) * sizeof(long), L1_CACHE_BYTES);
> -
> - st40data->wrt_tbl = (unsigned long)stx5197_wrt_table;
> - st40data->wrt_size = DIV_ROUND_UP(
> - ARRAY_SIZE(stx5197_wrt_table) * sizeof(long), L1_CACHE_BYTES);
>
> sc = sysconf_claim(SYS_DEV, CFG_MONITOR_J, 24, 24, "LMI pwd ack");
> stx5197_wrt_table[_SYS_MON_J] = (unsigned long)sysconf_address(sc);
> @@ -188,5 +165,7 @@ int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
> stx5197_wrt_table[_SYS_CFG_H] = (unsigned long)sysconf_address(sc);
> stx5197_wrt_table[_SYS_CFG_H_MASK] = sysconf_mask(sc);
>
> - return 0;
> + return sh4_suspend_register(&st40data);
> }
> +
> +late_initcall(suspend_platform_setup);
> diff --git a/arch/sh/kernel/cpu/sh4/suspend-stx7105.c b/arch/sh/kernel/cpu/sh4/suspend-stx7105.c
> index b9b88a2..e5e0329 100644
> --- a/arch/sh/kernel/cpu/sh4/suspend-stx7105.c
> +++ b/arch/sh/kernel/cpu/sh4/suspend-stx7105.c
> @@ -27,6 +27,10 @@
>
> #define _SYS_STA4 (7)
> #define _SYS_STA4_MASK (8)
> +#define _SYS_STA3 (11)
> +#define _SYS_STA3_MASK (12)
> +#define _SYS_STA3_VALUE (13)
> +
> #define _SYS_CFG11 (9)
> #define _SYS_CFG11_MASK (10)
> #define _SYS_CFG38 (5)
> @@ -35,6 +39,7 @@
> * STANDBY INSTRUCTION TABLE
> * *************************
> */
> +#ifdef CONFIG_PM_DEBUG
> static unsigned long stx7105_standby_table[] __cacheline_aligned = {
> /* 1. Move all the clock on OSC */
> CLK_POKE(CKGA_CLKOPSRC_SWITCH_CFG(0x0), 0x0),
> @@ -57,7 +62,7 @@ CLK_STORE(CKGA_OSC_DIV_CFG(5)),
> /* END. */
> _END()
> };
> -
> +#endif
> /* *********************
> * MEM INSTRUCTION TABLE
> * *********************
> @@ -91,8 +96,15 @@ _END(),
>
> /* Turn-on the PLLs */
> CLK_AND_LONG(CKGA_POWER_CFG, ~3),
> +/* Wait PLLS lock */
> +CLK_WHILE_NEQ(CKGA_PLL0_CFG, CKGA_PLL0_CFG_LOCK, CKGA_PLL0_CFG_LOCK),
> +CLK_WHILE_NEQ(CKGA_PLL1_CFG, CKGA_PLL1_CFG_LOCK, CKGA_PLL1_CFG_LOCK),
> +
> /* 1. Turn-on the LMI ClocksGenD */
> DATA_AND_NOT_LONG(_SYS_CFG11, _SYS_CFG11_MASK),
> +/* Wait LMI ClocksGenD lock */
> +DATA_WHILE_NEQ(_SYS_STA3, _SYS_STA3_MASK, _SYS_STA3_VALUE),
> +
> /* 2. Disables the DDR self refresh mode */
> DATA_AND_NOT_LONG(_SYS_CFG38, _SYS_CFG38_MASK),
> /* waits until the ack bit is zero */
> @@ -100,6 +112,7 @@ DATA_WHILE_EQ(_SYS_STA4, _SYS_STA4_MASK, _SYS_STA4_MASK),
>
> IMMEDIATE_DEST(0x10000),
> CLK_STORE(CKGA_PLL0LS_DIV_CFG(4)),
> +
> /* 3. Restore the previous clocks setting */
> DATA_LOAD(0x0),
> CLK_STORE(CKGA_CLKOPSRC_SWITCH_CFG(0x0)),
> @@ -111,6 +124,7 @@ DATA_LOAD(0x2),
> CLK_STORE(CKGA_OSC_DIV_CFG(0x0)),
> DATA_LOAD(0x4),
> CLK_STORE(CKGA_OSC_DIV_CFG(17)),
> +
> _DELAY(),
> _DELAY(),
> _DELAY(),
> @@ -121,23 +135,17 @@ static unsigned long stx7105_wrt_table[16] __cacheline_aligned;
>
> static int stx7105_suspend_prepare(suspend_state_t state)
> {
> - int ret = -EINVAL;
> - pm_message_t pms = {.event = PM_EVENT_SUSPEND, };
> - emi_pm_state(pms);
> - clk_pm_state(pms);
> - sysconf_pm_state(pms);
> -
> - switch (state) {
> - case PM_SUSPEND_STANDBY:
> +#ifdef CONFIG_PM_DEBUG
> + if (state = PM_SUSPEND_STANDBY) {
> stx7105_wrt_table[0] = /* swith config */
> ioread32(CLOCKGENA_BASE_ADDR + CKGA_CLKOPSRC_SWITCH_CFG(0));
> stx7105_wrt_table[1] = /* clk_STNoc */
> ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(0));
> stx7105_wrt_table[2] = /* clk_ic_if_100 */
> ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(5));
> - ret = 0;
> - break;
> - case PM_SUSPEND_MEM:
> + } else
> +#endif
> + {
> stx7105_wrt_table[0] = /* swith config */
> ioread32(CLOCKGENA_BASE_ADDR + CKGA_CLKOPSRC_SWITCH_CFG(0));
> stx7105_wrt_table[1] = /* swith config 1 */
> @@ -148,33 +156,7 @@ static int stx7105_suspend_prepare(suspend_state_t state)
> ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(5));
> stx7105_wrt_table[4] = /* clk_ic_if_200 */
> ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(17));
> - ret = 0;
> - break;
> }
> - return ret;
> -}
> -
> -static int stx7105_suspend_valid(suspend_state_t state)
> -{
> - switch (state) {
> - case PM_SUSPEND_STANDBY:
> - case PM_SUSPEND_MEM:
> - return 1;
> - };
> - return 0;
> -}
> -
> -/*
> - * The xxxx_finish function is called after the resume
> - * sysdev devices (i.e.: timer, cpufreq)
> - * But it isn't a big issue in our platform
> - */
> -static int stx7105_suspend_finish(suspend_state_t state)
> -{
> - pm_message_t pms = {.event = PM_EVENT_ON, };
> - sysconf_pm_state(pms);
> - clk_pm_state(pms);
> - emi_pm_state(pms);
> return 0;
> }
>
> @@ -187,41 +169,27 @@ static int stx7105_evt_to_irq(unsigned long evt)
> return evt2irq(evt);
> }
>
> -#if 0
> -#define GPLMI_BASEADDRESS 0xfe901000
> -#define GPLMI_SCR_APPD 0x14
> -static void stx7105_sleep_on_idle(void)
> -{
> - iowrite32(0x10 << 16 | 0x10, GPLMI_BASEADDRESS + GPLMI_SCR_APPD);
> - asm volatile ("sleep \n":::"memory");
> - iowrite32(0x0, GPLMI_BASEADDRESS + GPLMI_SCR_APPD);
> -}
> +static struct sh4_suspend_t st40data __cacheline_aligned = {
> + .iobase = stx7105_iomem,
> + .ops.prepare = stx7105_suspend_prepare,
> + .evt_to_irq = stx7105_evt_to_irq,
> +#ifdef CONFIG_PM_DEBUG
> + .stby_tbl = (unsigned long)stx7105_standby_table,
> + .stby_size = DIV_ROUND_UP(ARRAY_SIZE(stx7105_standby_table) *
> + sizeof(long), L1_CACHE_BYTES),
> #endif
> + .mem_tbl = (unsigned long)stx7105_mem_table,
> + .mem_size = DIV_ROUND_UP(ARRAY_SIZE(stx7105_mem_table) * sizeof(long),
> + L1_CACHE_BYTES),
> + .wrt_tbl = (unsigned long)stx7105_wrt_table,
> + .wrt_size = DIV_ROUND_UP(ARRAY_SIZE(stx7105_wrt_table) * sizeof(long),
> + L1_CACHE_BYTES),
> +};
>
> -int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
> +static int __init suspend_platform_setup(void)
> {
>
> struct sysconf_field* sc;
> - st40data->iobase = stx7105_iomem;
> - st40data->ops.valid = stx7105_suspend_valid;
> - st40data->ops.finish = stx7105_suspend_finish;
> - st40data->ops.prepare = stx7105_suspend_prepare;
> -
> - st40data->evt_to_irq = stx7105_evt_to_irq;
> -
> - st40data->stby_tbl = (unsigned long)stx7105_standby_table;
> - st40data->stby_size = DIV_ROUND_UP(
> - ARRAY_SIZE(stx7105_standby_table) * sizeof(long), L1_CACHE_BYTES);
> -
> - st40data->mem_tbl = (unsigned long)stx7105_mem_table;
> - st40data->mem_size = DIV_ROUND_UP(
> - ARRAY_SIZE(stx7105_mem_table) * sizeof(long), L1_CACHE_BYTES);
> -
> - st40data->wrt_tbl = (unsigned long)stx7105_wrt_table;
> - st40data->wrt_size = DIV_ROUND_UP(
> - ARRAY_SIZE(stx7105_wrt_table) * sizeof(long), L1_CACHE_BYTES);
> -
> -/* pm_idle = stx7105_sleep_on_idle; */
> sc = sysconf_claim(SYS_CFG, 38, 20, 20, "pm");
> stx7105_wrt_table[_SYS_CFG38] = (unsigned long)sysconf_address(sc);
> stx7105_wrt_table[_SYS_CFG38_MASK] = sysconf_mask(sc);
> @@ -234,5 +202,11 @@ int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
> stx7105_wrt_table[_SYS_STA4] = (unsigned long)sysconf_address(sc);
> stx7105_wrt_table[_SYS_STA4_MASK] = sysconf_mask(sc);
>
> - return 0;
> + sc = sysconf_claim(SYS_STA, 3, 0, 0, "pm");
> + stx7105_wrt_table[_SYS_STA3] = (unsigned long)sysconf_address(sc);
> + stx7105_wrt_table[_SYS_STA3_MASK] = sysconf_mask(sc);
> + stx7105_wrt_table[_SYS_STA3_VALUE] = 0;
> + return sh4_suspend_register(&st40data);
> }
> +
> +late_initcall(suspend_platform_setup);
> diff --git a/arch/sh/kernel/cpu/sh4/suspend-stx7111.c b/arch/sh/kernel/cpu/sh4/suspend-stx7111.c
> index a0b2104..8203184 100644
> --- a/arch/sh/kernel/cpu/sh4/suspend-stx7111.c
> +++ b/arch/sh/kernel/cpu/sh4/suspend-stx7111.c
> @@ -27,6 +27,9 @@
>
> #define _SYS_STA4 (5)
> #define _SYS_STA4_MASK (6)
> +#define _SYS_STA3 (11)
> +#define _SYS_STA3_MASK (12)
> +#define _SYS_STA3_VALUE (13)
>
> #define _SYS_CFG11 (7)
> #define _SYS_CFG11_MASK (8)
> @@ -38,6 +41,7 @@
> * STANDBY INSTRUCTION TABLE
> * *************************
> */
> +#ifdef CONFIG_PM_DEBUG
> static unsigned long stx7111_standby_table[] __cacheline_aligned = {
> /* 1. Move all the clock on OSC */
> CLK_POKE(CKGA_CLKOPSRC_SWITCH_CFG(0x0), 0x0),
> @@ -64,6 +68,7 @@ CLK_STORE(CKGA_OSC_DIV_CFG(5)),
> /* END. */
> _END()
> };
> +#endif
>
> /* *********************
> * MEM INSTRUCTION TABLE
> @@ -96,9 +101,15 @@ _END(),
>
> /* Turn-on the PLLs */
> CLK_AND_LONG(CKGA_POWER_CFG, ~3),
> +/* Wait PLLs lock */
> +CLK_WHILE_NEQ(CKGA_PLL0_CFG, CKGA_PLL0_CFG_LOCK, CKGA_PLL0_CFG_LOCK),
> +CLK_WHILE_NEQ(CKGA_PLL1_CFG, CKGA_PLL1_CFG_LOCK, CKGA_PLL1_CFG_LOCK),
>
> /* 1. Turn-on the LMI ClocksGenD */
> DATA_AND_NOT_LONG(_SYS_CFG11, _SYS_CFG11_MASK),
> +/* Wait LMI ClocksGenD lock */
> +DATA_WHILE_NEQ(_SYS_STA3, _SYS_STA3_MASK, _SYS_STA3_VALUE),
> +
> /* 2. Disables the DDR self refresh mode */
> DATA_AND_NOT_LONG(_SYS_CFG38, _SYS_CFG38_MASK),
> /* waits until the ack bit is zero */
> @@ -129,23 +140,17 @@ static unsigned long stx7111_wrt_table[16] __cacheline_aligned;
>
> static int stx7111_suspend_prepare(suspend_state_t state)
> {
> - int ret = -EINVAL;
> - pm_message_t pms = {.event = PM_EVENT_SUSPEND, };
> - emi_pm_state(pms);
> - clk_pm_state(pms);
> - sysconf_pm_state(pms);
> -
> - switch (state) {
> - case PM_SUSPEND_STANDBY:
> +#ifdef CONFIG_PM_DEBUG
> + if (state = PM_SUSPEND_STANDBY) {
> stx7111_wrt_table[0] = /* swith config */
> ioread32(CLOCKGENA_BASE_ADDR + CKGA_CLKOPSRC_SWITCH_CFG(0));
> stx7111_wrt_table[1] = /* clk_STNoc_ic */
> ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(0));
> stx7111_wrt_table[2] = /* clk_ic_if_100 */
> ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(5));
> - ret = 0;
> - break;
> - case PM_SUSPEND_MEM:
> + } else
> +#endif
> + {
> stx7111_wrt_table[0] = /* swith config */
> ioread32(CLOCKGENA_BASE_ADDR + CKGA_CLKOPSRC_SWITCH_CFG(0));
> stx7111_wrt_table[1] = /* swith config 1 */
> @@ -156,33 +161,7 @@ static int stx7111_suspend_prepare(suspend_state_t state)
> ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(5));
> stx7111_wrt_table[4] = /* clk_ic_if_200 */
> ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(17));
> - ret = 0;
> - break;
> }
> - return ret;
> -}
> -
> -static int stx7111_suspend_valid(suspend_state_t state)
> -{
> - switch (state) {
> - case PM_SUSPEND_STANDBY:
> - case PM_SUSPEND_MEM:
> - return 1;
> - };
> - return 0;
> -}
> -
> -/*
> - * The xxxx_finish function is called after the resume
> - * sysdev devices (i.e.: timer, cpufreq)
> - * But it isn't a big issue in our platform
> - */
> -static int stx7111_suspend_finish(suspend_state_t state)
> -{
> - pm_message_t pms = {.event = PM_EVENT_ON, };
> - sysconf_pm_state(pms);
> - clk_pm_state(pms);
> - emi_pm_state(pms);
> return 0;
> }
>
> @@ -195,31 +174,30 @@ static int stx7111_evttoirq(unsigned long evt)
> return evt2irq(evt);
> }
>
> -int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
> +static struct sh4_suspend_t st40data __cacheline_aligned = {
> + .iobase = stx7111_iomem,
> + .ops.prepare = stx7111_suspend_prepare,
> + .evt_to_irq = stx7111_evttoirq,
> +#ifdef CONFIG_PM_DEBUG
> + .stby_tbl = (unsigned long)stx7111_standby_table,
> + .stby_size = DIV_ROUND_UP(ARRAY_SIZE(stx7111_standby_table) *
> + sizeof(long), L1_CACHE_BYTES),
> +#endif
> + .mem_tbl = (unsigned long)stx7111_mem_table,
> + .mem_size = DIV_ROUND_UP(ARRAY_SIZE(stx7111_mem_table) * sizeof(long),
> + L1_CACHE_BYTES),
> + .wrt_tbl = (unsigned long)stx7111_wrt_table,
> + .wrt_size = DIV_ROUND_UP(ARRAY_SIZE(stx7111_wrt_table) * sizeof(long),
> + L1_CACHE_BYTES),
> +};
> +
> +static int __init suspend_platform_setup()
> {
> struct sysconf_field* sc;
> #ifdef CONFIG_PM_DEBUG
> /* route the sh4/2 clock frequenfy */
> iowrite32(0xc, CLOCKGENA_BASE_ADDR + CKGA_CLKOBS_MUX1_CFG);
> #endif
> - st40data->iobase = stx7111_iomem;
> - st40data->ops.valid = stx7111_suspend_valid;
> - st40data->ops.finish = stx7111_suspend_finish;
> - st40data->ops.prepare = stx7111_suspend_prepare;
> -
> - st40data->evt_to_irq = stx7111_evttoirq;
> -
> - st40data->stby_tbl = (unsigned long)stx7111_standby_table;
> - st40data->stby_size = DIV_ROUND_UP(
> - ARRAY_SIZE(stx7111_standby_table)*sizeof(long), L1_CACHE_BYTES);
> -
> - st40data->mem_tbl = (unsigned long)stx7111_mem_table;
> - st40data->mem_size = DIV_ROUND_UP(
> - ARRAY_SIZE(stx7111_mem_table)*sizeof(long), L1_CACHE_BYTES);
> -
> - st40data->wrt_tbl = (unsigned long)stx7111_wrt_table;
> - st40data->wrt_size = DIV_ROUND_UP(
> - ARRAY_SIZE(stx7111_wrt_table)*sizeof(long), L1_CACHE_BYTES);
>
> sc = sysconf_claim(SYS_CFG, 38, 20, 20, "pm");
> stx7111_wrt_table[_SYS_CFG38] = (unsigned long)sysconf_address(sc);
> @@ -233,5 +211,11 @@ int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
> stx7111_wrt_table[_SYS_STA4] = (unsigned long)sysconf_address(sc);
> stx7111_wrt_table[_SYS_STA4_MASK] = sysconf_mask(sc);
>
> - return 0;
> + sc = sysconf_claim(SYS_STA, 3, 0, 0, "pm");
> + stx7111_wrt_table[_SYS_STA3] = (unsigned long)sysconf_address(sc);
> + stx7111_wrt_table[_SYS_STA3_MASK] = sysconf_mask(sc);
> + stx7111_wrt_table[_SYS_STA3_VALUE] = 0;
> + return sh4_suspend_register(&st40data);
> }
> +
> +late_initcall(suspend_platform_setup);
> diff --git a/arch/sh/kernel/cpu/sh4/suspend-stx7141.c b/arch/sh/kernel/cpu/sh4/suspend-stx7141.c
> index f2d131c..3dffc3a 100644
> --- a/arch/sh/kernel/cpu/sh4/suspend-stx7141.c
> +++ b/arch/sh/kernel/cpu/sh4/suspend-stx7141.c
> @@ -31,6 +31,10 @@
>
> #define _SYS_STA4 (7)
> #define _SYS_STA4_MASK (8)
> +#define _SYS_STA3 (11)
> +#define _SYS_STA3_MASK (12)
> +#define _SYS_STA3_VALUE (13)
> +
> #define _SYS_CFG11 (9)
> #define _SYS_CFG11_MASK (10)
> #define _SYS_CFG38 (5)
> @@ -40,6 +44,7 @@
> * STANDBY INSTRUCTION TABLE
> * *************************
> */
> +#ifdef CONFIG_PM_DEBUG
> static unsigned long stx7141_standby_table[] __cacheline_aligned = {
> IMMEDIATE_DEST(0x1f),
> /* reduces the st40 frequency */
> @@ -63,6 +68,7 @@ CLK_STORE(CKGA_OSC_DIV_CFG(10)),
> /* END. */
> _END()
> };
> +#endif
>
> /* *********************
> * MEM INSTRUCTION TABLE
> @@ -96,8 +102,15 @@ _END(),
>
> /* Turn-on the PLLs */
> CLK_AND_LONG(CKGA_POWER_CFG, ~3),
> +/* Wait PLLs lock */
> +CLK_WHILE_NEQ(CKGA_PLL0_CFG, CKGA_PLL0_CFG_LOCK, CKGA_PLL0_CFG_LOCK),
> +CLK_WHILE_NEQ(CKGA_PLL1_CFG, CKGA_PLL1_CFG_LOCK, CKGA_PLL1_CFG_LOCK),
> +
> /* 1. Turn-on the LMI ClocksGenD */
> DATA_AND_NOT_LONG(_SYS_CFG11, _SYS_CFG11_MASK),
> +/* Wait LMI ClocksGenD lock */
> +DATA_WHILE_NEQ(_SYS_STA3, _SYS_STA3_MASK, _SYS_STA3_VALUE),
> +
> /* 2. Disables the DDR self refresh mode */
> DATA_AND_NOT_LONG(_SYS_CFG38, _SYS_CFG38_MASK),
> /* waits until the ack bit is zero */
> @@ -126,23 +139,17 @@ static unsigned long stx7141_wrt_table[16] __cacheline_aligned;
>
> static int stx7141_suspend_prepare(suspend_state_t state)
> {
> - int ret = -EINVAL;
> - pm_message_t pms = {.event = PM_EVENT_SUSPEND, };
> - emi_pm_state(pms);
> - clk_pm_state(pms);
> - sysconf_pm_state(pms);
> -
> - switch (state) {
> - case PM_SUSPEND_STANDBY:
> +#ifdef CONFIG_PM_DEBUG
> + if (state = PM_SUSPEND_STANDBY) {
> stx7141_wrt_table[0] = /* swith config */
> ioread32(CLOCKGENA_BASE_ADDR + CKGA_CLKOPSRC_SWITCH_CFG(0));
> stx7141_wrt_table[1] = /* clk_ic */
> ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(0));
> stx7141_wrt_table[2] = /* clk_ic_if_100 */
> ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(10));
> - ret = 0;
> - break;
> - case PM_SUSPEND_MEM:
> + } else
> +#endif
> + {
> stx7141_wrt_table[0] = /* swith config */
> ioread32(CLOCKGENA_BASE_ADDR + CKGA_CLKOPSRC_SWITCH_CFG(0));
> stx7141_wrt_table[1] = /* swith config */
> @@ -153,33 +160,7 @@ static int stx7141_suspend_prepare(suspend_state_t state)
> ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(10));
> stx7141_wrt_table[4] = /* clk_ic_if_200 */
> ioread32(CLOCKGENA_BASE_ADDR + CKGA_OSC_DIV_CFG(17));
> - ret = 0;
> - break;
> }
> - return ret;
> -}
> -
> -static int stx7141_suspend_valid(suspend_state_t state)
> -{
> - switch (state) {
> - case PM_SUSPEND_STANDBY:
> - case PM_SUSPEND_MEM:
> - return 1;
> - };
> - return 0;
> -}
> -
> -/*
> - * The xxxx_finish function is called after the resume
> - * sysdev devices (i.e.: timer, cpufreq)
> - * But it isn't a big issue in our platform
> - */
> -static int stx7141_suspend_finish(suspend_state_t state)
> -{
> - pm_message_t pms = {.event = PM_EVENT_ON, };
> - sysconf_pm_state(pms);
> - clk_pm_state(pms);
> - emi_pm_state(pms);
> return 0;
> }
>
> @@ -189,10 +170,27 @@ static unsigned long stx7141_iomem[2] __cacheline_aligned = {
>
> static int stx7141_evttoirq(unsigned long evt)
> {
> - return ilc2irq(evt);
> + return ((evt < 0x400) ? ilc2irq(evt) : evt2irq(evt));
> }
>
> -int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
> +static struct sh4_suspend_t st40data __cacheline_aligned = {
> + .iobase = stx7141_iomem,
> + .ops.prepare = stx7141_suspend_prepare,
> + .evt_to_irq = stx7141_evttoirq,
> +#ifdef CONFIG_PM_DEBUG
> + .stby_tbl = (unsigned long)stx7141_standby_table,
> + .stby_size = DIV_ROUND_UP(ARRAY_SIZE(stx7141_standby_table) *
> + sizeof(long), L1_CACHE_BYTES),
> +#endif
> + .mem_tbl = (unsigned long)stx7141_mem_table,
> + .mem_size = DIV_ROUND_UP(ARRAY_SIZE(stx7141_mem_table) * sizeof(long),
> + L1_CACHE_BYTES),
> + .wrt_tbl = (unsigned long)stx7141_wrt_table,
> + .wrt_size = DIV_ROUND_UP(ARRAY_SIZE(stx7141_wrt_table) * sizeof(long),
> + L1_CACHE_BYTES),
> +};
> +
> +static int __init suspend_platform_setup()
> {
> struct sysconf_field *sc;
> #ifdef CONFIG_PM_DEBUG
> @@ -202,24 +200,6 @@ int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
> sc = sysconf_claim(SYS_CFG, 19, 22, 23, "clkA dbg");
> sysconf_write(sc, 11);
> #endif
> - st40data->iobase = stx7141_iomem;
> - st40data->ops.valid = stx7141_suspend_valid;
> - st40data->ops.finish = stx7141_suspend_finish;
> - st40data->ops.prepare = stx7141_suspend_prepare;
> -
> - st40data->evt_to_irq = stx7141_evttoirq;
> -
> - st40data->stby_tbl = (unsigned long)stx7141_standby_table;
> - st40data->stby_size = DIV_ROUND_UP(
> - ARRAY_SIZE(stx7141_standby_table)*sizeof(long), L1_CACHE_BYTES);
> -
> - st40data->mem_tbl = (unsigned long)stx7141_mem_table;
> - st40data->mem_size = DIV_ROUND_UP(
> - ARRAY_SIZE(stx7141_mem_table)*sizeof(long), L1_CACHE_BYTES);
> -
> - st40data->wrt_tbl = (unsigned long)stx7141_wrt_table;
> - st40data->wrt_size = DIV_ROUND_UP(
> - ARRAY_SIZE(stx7141_wrt_table) * sizeof(long), L1_CACHE_BYTES);
>
> sc = sysconf_claim(SYS_CFG, 38, 20, 20, "pm");
> stx7141_wrt_table[_SYS_CFG38] = (unsigned long)sysconf_address(sc);
> @@ -233,5 +213,11 @@ int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
> stx7141_wrt_table[_SYS_STA4] = (unsigned long)sysconf_address(sc);
> stx7141_wrt_table[_SYS_STA4_MASK] = sysconf_mask(sc);
>
> - return 0;
> + sc = sysconf_claim(SYS_STA, 3, 0, 0, "pm");
> + stx7141_wrt_table[_SYS_STA3] = (unsigned long)sysconf_address(sc);
> + stx7141_wrt_table[_SYS_STA3_MASK] = sysconf_mask(sc);
> + stx7141_wrt_table[_SYS_STA3_VALUE] = 0;
> + return sh4_suspend_register(&st40data);
> }
> +
> +late_initcall(suspend_platform_setup);
> diff --git a/arch/sh/kernel/cpu/sh4/suspend-stx7200.c b/arch/sh/kernel/cpu/sh4/suspend-stx7200.c
> index 320b660..23201b1 100644
> --- a/arch/sh/kernel/cpu/sh4/suspend-stx7200.c
> +++ b/arch/sh/kernel/cpu/sh4/suspend-stx7200.c
> @@ -40,6 +40,7 @@
> * STANDBY INSTRUCTION TABLE
> * *************************
> */
> +#ifdef CONFIG_PM_DEBUG
> static unsigned long stx7200_standby_table[] __cacheline_aligned = {
> /* Down scale the GenA.Pll0 and GenA.Pll2*/
> CLK_OR_LONG(CLKA_PLL0, CLKA_PLL0_BYPASS),
> @@ -79,6 +80,8 @@ _OR(),
> CLK_STORE(CLKA_PLL2),
> #endif
> CLK_AND_LONG(CLKA_PWR_CFG, ~(PWR_CFG_PLL0_OFF | PWR_CFG_PLL2_OFF)),
> +CLK_WHILE_NEQ(CLKA_PLL0, CLKA_PLL0_LOCK, CLKA_PLL0_LOCK),
> +CLK_WHILE_NEQ(CLKA_PLL2, CLKA_PLL2_LOCK, CLKA_PLL2_LOCK),
> CLK_AND_LONG(CLKA_PLL0, ~(CLKA_PLL0_BYPASS)),
> CLK_AND_LONG(CLKA_PLL2, ~(CLKA_PLL2_BYPASS)),
>
> @@ -86,6 +89,7 @@ _DELAY(),
> /* END. */
> _END()
> };
> +#endif
>
> /* *********************
> * MEM INSTRUCTION TABLE
> @@ -118,6 +122,10 @@ CLK_OR_LONG(CLKA_PLL2, CLKA_PLL2_SUSPEND),
>
> CLK_AND_LONG(CLKA_PWR_CFG, ~(PWR_CFG_PLL0_OFF | PWR_CFG_PLL1_OFF | PWR_CFG_PLL2_OFF)),
>
> +CLK_WHILE_NEQ(CLKA_PLL0, CLKA_PLL0_LOCK, CLKA_PLL0_LOCK),
> +CLK_WHILE_NEQ(CLKA_PLL1, CLKA_PLL1_LOCK, CLKA_PLL1_LOCK),
> +CLK_WHILE_NEQ(CLKA_PLL2, CLKA_PLL2_LOCK, CLKA_PLL2_LOCK),
> +
> CLK_AND_LONG(CLKA_PLL0, ~(CLKA_PLL0_BYPASS)),
> CLK_AND_LONG(CLKA_PLL1, ~(CLKA_PLL1_BYPASS)),
> CLK_AND_LONG(CLKA_PLL2, ~(CLKA_PLL2_BYPASS)),
> @@ -149,6 +157,10 @@ _OR(),
> CLK_STORE(CLKA_PLL2),
> #endif
> CLK_AND_LONG(CLKA_PWR_CFG, ~(PWR_CFG_PLL0_OFF | PWR_CFG_PLL1_OFF | PWR_CFG_PLL2_OFF)),
> +/* Wait PLLs lock */
> +CLK_WHILE_NEQ(CLKA_PLL0, CLKA_PLL0_LOCK, CLKA_PLL0_LOCK),
> +CLK_WHILE_NEQ(CLKA_PLL1, CLKA_PLL1_LOCK, CLKA_PLL1_LOCK),
> +CLK_WHILE_NEQ(CLKA_PLL2, CLKA_PLL2_LOCK, CLKA_PLL2_LOCK),
>
> CLK_AND_LONG(CLKA_PLL0, ~(CLKA_PLL0_BYPASS)),
> CLK_AND_LONG(CLKA_PLL1, ~(CLKA_PLL1_BYPASS)),
> @@ -172,53 +184,25 @@ static unsigned long stx7200_wrt_table[16] __cacheline_aligned;
>
> static int stx7200_suspend_prepare(suspend_state_t state)
> {
> - pm_message_t pm = {.event = PM_EVENT_SUSPEND, };
> - emi_pm_state(pm);
> - clk_pm_state(pm);
> - sysconf_pm_state(pm);
> -
> - switch (state) {
> - case PM_SUSPEND_STANDBY:
> +#ifdef CONFIG_PM_DEBUG
> + if (state = PM_SUSPEND_STANDBY) {
> stx7200_wrt_table[0] > readl(CLOCKGEN_BASE_ADDR + CLKA_PLL0) & 0x7ffff;
> stx7200_wrt_table[1] > readl(CLOCKGEN_BASE_ADDR + CLKA_PLL2) & 0x7ffff;
> - return 0;
> - case PM_SUSPEND_MEM:
> + } else
> +#endif
> + {
> stx7200_wrt_table[0] > readl(CLOCKGEN_BASE_ADDR + CLKA_PLL0) & 0x7ffff;
> stx7200_wrt_table[1] > readl(CLOCKGEN_BASE_ADDR + CLKA_PLL1) & 0x7ffff;
> stx7200_wrt_table[2] > readl(CLOCKGEN_BASE_ADDR + CLKA_PLL2) & 0x7ffff;
> - return 0;
> }
> - return -EINVAL;
> -}
> -
> -static int stx7200_suspend_valid(suspend_state_t state)
> -{
> - switch (state) {
> - case PM_SUSPEND_STANDBY:
> - case PM_SUSPEND_MEM:
> - return 1;
> - };
> return 0;
> }
>
> -/*
> - * The xxxx_finish function is called after the resume
> - * sysdev devices (i.e.: timer, cpufreq)
> - * But it isn't a big issue in our platform
> - */
> -static int stx7200_suspend_finish(suspend_state_t state)
> -{
> - pm_message_t pm = {.event = PM_EVENT_ON, };
> - sysconf_pm_state(pm);
> - clk_pm_state(pm);
> - emi_pm_state(pm);
> - return 0;
> -}
>
> static unsigned long stx7200_iomem[2] __cacheline_aligned = {
> stx7200_wrt_table, /* To access Sysconf */
> @@ -226,32 +210,30 @@ static unsigned long stx7200_iomem[2] __cacheline_aligned = {
>
> static int stx7200_evttoirq(unsigned long evt)
> {
> - return ilc2irq(evt);
> + return ((evt < 0x400) ? ilc2irq(evt) : evt2irq(evt));
> }
>
> -int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
> +static struct sh4_suspend_t st40data __cacheline_aligned = {
> + .iobase = stx7200_iomem,
> + .ops.prepare = stx7200_suspend_prepare,
> + .evt_to_irq = stx7200_evttoirq,
> +#ifdef CONFIG_PM_DEBUG
> + .stby_tbl = (unsigned long)stx7200_standby_table,
> + .stby_size = DIV_ROUND_UP(ARRAY_SIZE(stx7200_standby_table) *
> + sizeof(long), L1_CACHE_BYTES),
> +#endif
> + .mem_tbl = (unsigned long)stx7200_mem_table,
> + .mem_size = DIV_ROUND_UP(ARRAY_SIZE(stx7200_mem_table) * sizeof(long),
> + L1_CACHE_BYTES),
> + .wrt_tbl = (unsigned long)stx7200_wrt_table,
> + .wrt_size = DIV_ROUND_UP(ARRAY_SIZE(stx7200_wrt_table) * sizeof(long),
> + L1_CACHE_BYTES),
> +};
> +
> +static int __init suspend_platform_setup()
> {
> struct sysconf_field* sc;
>
> - st40data->iobase = stx7200_iomem;
> - st40data->ops.valid = stx7200_suspend_valid;
> - st40data->ops.finish = stx7200_suspend_finish;
> - st40data->ops.prepare = stx7200_suspend_prepare;
> -
> - st40data->evt_to_irq = stx7200_evttoirq;
> -
> - st40data->stby_tbl = (unsigned long)stx7200_standby_table;
> - st40data->stby_size = DIV_ROUND_UP(
> - ARRAY_SIZE(stx7200_standby_table)*sizeof(long), L1_CACHE_BYTES);
> -
> - st40data->mem_tbl = (unsigned long)stx7200_mem_table;
> - st40data->mem_size = DIV_ROUND_UP(
> - ARRAY_SIZE(stx7200_mem_table)*sizeof(long), L1_CACHE_BYTES);
> -
> - st40data->wrt_tbl = (unsigned long)stx7200_wrt_table;
> - st40data->wrt_size = DIV_ROUND_UP(
> - ARRAY_SIZE(stx7200_wrt_table) * sizeof(long), L1_CACHE_BYTES);
> -
> sc = sysconf_claim(SYS_STA, 4, 0, 0, "pm");
> stx7200_wrt_table[_SYS_STA4] = (unsigned long)sysconf_address(sc);
> stx7200_wrt_table[_SYS_STA4_MASK] = sysconf_mask(sc);
> @@ -272,5 +254,7 @@ int __init suspend_platform_setup(struct sh4_suspend_t *st40data)
> ctrl_outl(0xc, CKGA_CLKOUT_SEL +
> CLOCKGEN_BASE_ADDR); /* sh4:2 routed on SYSCLK_OUT */
> #endif
> - return 0;
> + return sh4_suspend_register(&st40data);
> }
> +
> +late_initcall(suspend_platform_setup);
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2009-05-18 13:19 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-05-18 13:18 [PATCH] stm: pm: Rework the suspend SOC code Francesco VIRLINZI
2009-05-18 13:19 ` Francesco VIRLINZI
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox