Commit 4fcf47e2 authored by Tomasz Figa's avatar Tomasz Figa Committed by Kukjin Kim

clk: samsung: exynos4: Add remaining suspend/resume handling

As of now, part of Exynos4 clock suspend/resume handling is located
in mach-exynos/pm.c, which is not where code accessing CMU registers
should reside.

This patch implements all the necessary suspend/resume handling code
in Exynos4 clock driver to allow dropping that old code.
Signed-off-by: default avatarTomasz Figa <t.figa@samsung.com>
Acked-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Reviewed-by: default avatarThomas Abraham <thomas.ab@samsung.com>
Reviewed-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: default avatarKukjin Kim <kgene.kim@samsung.com>
parent 3efb2511
...@@ -140,6 +140,7 @@ static enum exynos4_soc exynos4_soc; ...@@ -140,6 +140,7 @@ static enum exynos4_soc exynos4_soc;
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static struct samsung_clk_reg_dump *exynos4_save_common; static struct samsung_clk_reg_dump *exynos4_save_common;
static struct samsung_clk_reg_dump *exynos4_save_soc; static struct samsung_clk_reg_dump *exynos4_save_soc;
static struct samsung_clk_reg_dump *exynos4_save_pll;
/* /*
* list of controller registers to be saved and restored during a * list of controller registers to be saved and restored during a
...@@ -165,6 +166,17 @@ static unsigned long exynos4x12_clk_save[] __initdata = { ...@@ -165,6 +166,17 @@ static unsigned long exynos4x12_clk_save[] __initdata = {
E4X12_MPLL_CON0, E4X12_MPLL_CON0,
}; };
static unsigned long exynos4_clk_pll_regs[] __initdata = {
EPLL_LOCK,
VPLL_LOCK,
EPLL_CON0,
EPLL_CON1,
EPLL_CON2,
VPLL_CON0,
VPLL_CON1,
VPLL_CON2,
};
static unsigned long exynos4_clk_regs[] __initdata = { static unsigned long exynos4_clk_regs[] __initdata = {
SRC_LEFTBUS, SRC_LEFTBUS,
DIV_LEFTBUS, DIV_LEFTBUS,
...@@ -172,12 +184,6 @@ static unsigned long exynos4_clk_regs[] __initdata = { ...@@ -172,12 +184,6 @@ static unsigned long exynos4_clk_regs[] __initdata = {
SRC_RIGHTBUS, SRC_RIGHTBUS,
DIV_RIGHTBUS, DIV_RIGHTBUS,
GATE_IP_RIGHTBUS, GATE_IP_RIGHTBUS,
EPLL_CON0,
EPLL_CON1,
EPLL_CON2,
VPLL_CON0,
VPLL_CON1,
VPLL_CON2,
SRC_TOP0, SRC_TOP0,
SRC_TOP1, SRC_TOP1,
SRC_CAM, SRC_CAM,
...@@ -238,23 +244,70 @@ static unsigned long exynos4_clk_regs[] __initdata = { ...@@ -238,23 +244,70 @@ static unsigned long exynos4_clk_regs[] __initdata = {
GATE_IP_CPU, GATE_IP_CPU,
}; };
static const struct samsung_clk_reg_dump src_mask_suspend[] = {
{ .offset = SRC_MASK_TOP, .value = 0x00000001, },
{ .offset = SRC_MASK_CAM, .value = 0x11111111, },
{ .offset = SRC_MASK_TV, .value = 0x00000111, },
{ .offset = SRC_MASK_LCD0, .value = 0x00001111, },
{ .offset = SRC_MASK_MAUDIO, .value = 0x00000001, },
{ .offset = SRC_MASK_FSYS, .value = 0x01011111, },
{ .offset = SRC_MASK_PERIL0, .value = 0x01111111, },
{ .offset = SRC_MASK_PERIL1, .value = 0x01110111, },
{ .offset = SRC_MASK_DMC, .value = 0x00010000, },
};
static const struct samsung_clk_reg_dump src_mask_suspend_e4210[] = {
{ .offset = E4210_SRC_MASK_LCD1, .value = 0x00001111, },
};
#define PLL_ENABLED (1 << 31)
#define PLL_LOCKED (1 << 29)
static void exynos4_clk_wait_for_pll(u32 reg)
{
u32 pll_con;
pll_con = readl(reg_base + reg);
if (!(pll_con & PLL_ENABLED))
return;
while (!(pll_con & PLL_LOCKED)) {
cpu_relax();
pll_con = readl(reg_base + reg);
}
}
static int exynos4_clk_suspend(void) static int exynos4_clk_suspend(void)
{ {
samsung_clk_save(reg_base, exynos4_save_common, samsung_clk_save(reg_base, exynos4_save_common,
ARRAY_SIZE(exynos4_clk_regs)); ARRAY_SIZE(exynos4_clk_regs));
samsung_clk_save(reg_base, exynos4_save_pll,
ARRAY_SIZE(exynos4_clk_pll_regs));
if (exynos4_soc == EXYNOS4210) if (exynos4_soc == EXYNOS4210) {
samsung_clk_save(reg_base, exynos4_save_soc, samsung_clk_save(reg_base, exynos4_save_soc,
ARRAY_SIZE(exynos4210_clk_save)); ARRAY_SIZE(exynos4210_clk_save));
else samsung_clk_restore(reg_base, src_mask_suspend_e4210,
ARRAY_SIZE(src_mask_suspend_e4210));
} else {
samsung_clk_save(reg_base, exynos4_save_soc, samsung_clk_save(reg_base, exynos4_save_soc,
ARRAY_SIZE(exynos4x12_clk_save)); ARRAY_SIZE(exynos4x12_clk_save));
}
samsung_clk_restore(reg_base, src_mask_suspend,
ARRAY_SIZE(src_mask_suspend));
return 0; return 0;
} }
static void exynos4_clk_resume(void) static void exynos4_clk_resume(void)
{ {
samsung_clk_restore(reg_base, exynos4_save_pll,
ARRAY_SIZE(exynos4_clk_pll_regs));
exynos4_clk_wait_for_pll(EPLL_CON0);
exynos4_clk_wait_for_pll(VPLL_CON0);
samsung_clk_restore(reg_base, exynos4_save_common, samsung_clk_restore(reg_base, exynos4_save_common,
ARRAY_SIZE(exynos4_clk_regs)); ARRAY_SIZE(exynos4_clk_regs));
...@@ -289,9 +342,16 @@ static void exynos4_clk_sleep_init(void) ...@@ -289,9 +342,16 @@ static void exynos4_clk_sleep_init(void)
if (!exynos4_save_soc) if (!exynos4_save_soc)
goto err_common; goto err_common;
exynos4_save_pll = samsung_clk_alloc_reg_dump(exynos4_clk_pll_regs,
ARRAY_SIZE(exynos4_clk_pll_regs));
if (!exynos4_save_pll)
goto err_soc;
register_syscore_ops(&exynos4_clk_syscore_ops); register_syscore_ops(&exynos4_clk_syscore_ops);
return; return;
err_soc:
kfree(exynos4_save_soc);
err_common: err_common:
kfree(exynos4_save_common); kfree(exynos4_save_common);
err_warn: err_warn:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment