From: Francesco VIRLINZI <francesco.virlinzi@st.com>
To: linux-sh@vger.kernel.org
Subject: Re: [PATCH] stm: pm: Rework the suspend SOC code
Date: Mon, 18 May 2009 13:19:26 +0000 [thread overview]
Message-ID: <4A11605E.50004@st.com> (raw)
In-Reply-To: <1242652698-12170-1-git-send-email-francesco.virlinzi@st.com>
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);
>
prev parent reply other threads:[~2009-05-18 13:19 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-05-18 13:18 [PATCH] stm: pm: Rework the suspend SOC code Francesco VIRLINZI
2009-05-18 13:19 ` Francesco VIRLINZI [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4A11605E.50004@st.com \
--to=francesco.virlinzi@st.com \
--cc=linux-sh@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox