diff options
Diffstat (limited to 'drivers/clk/samsung/clk-exynos4.c')
-rw-r--r-- | drivers/clk/samsung/clk-exynos4.c | 226 |
1 files changed, 14 insertions, 212 deletions
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 0421960eb963..59d4d46667ce 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -16,7 +16,6 @@ #include <linux/clk-provider.h> #include <linux/of.h> #include <linux/of_address.h> -#include <linux/syscore_ops.h> #include "clk.h" #include "clk-cpu.h" @@ -123,10 +122,6 @@ #define CLKOUT_CMU_CPU 0x14a00 #define PWR_CTRL1 0x15020 #define E4X12_PWR_CTRL2 0x15024 -#define E4X12_DIV_ISP0 0x18300 -#define E4X12_DIV_ISP1 0x18304 -#define E4X12_GATE_ISP0 0x18800 -#define E4X12_GATE_ISP1 0x18804 /* Below definitions are used for PWR_CTRL settings */ #define PWR_CTRL1_CORE2_DOWN_RATIO(x) (((x) & 0x7) << 28) @@ -158,14 +153,6 @@ static void __iomem *reg_base; static enum exynos4_soc exynos4_soc; /* - * Support for CMU save/restore across system suspends - */ -#ifdef CONFIG_PM_SLEEP -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_pll; - -/* * list of controller registers to be saved and restored during a * suspend/resume cycle. */ @@ -192,7 +179,7 @@ static const unsigned long exynos4x12_clk_save[] __initconst = { E4X12_PWR_CTRL2, }; -static const unsigned long exynos4_clk_pll_regs[] __initconst = { +static const unsigned long exynos4_clk_regs[] __initconst = { EPLL_LOCK, VPLL_LOCK, EPLL_CON0, @@ -201,9 +188,6 @@ static const unsigned long exynos4_clk_pll_regs[] __initconst = { VPLL_CON0, VPLL_CON1, VPLL_CON2, -}; - -static const unsigned long exynos4_clk_regs[] __initconst = { SRC_LEFTBUS, DIV_LEFTBUS, GATE_IP_LEFTBUS, @@ -276,6 +260,8 @@ static const unsigned long exynos4_clk_regs[] __initconst = { }; static const struct samsung_clk_reg_dump src_mask_suspend[] = { + { .offset = VPLL_CON0, .value = 0x80600302, }, + { .offset = EPLL_CON0, .value = 0x806F0302, }, { .offset = SRC_MASK_TOP, .value = 0x00000001, }, { .offset = SRC_MASK_CAM, .value = 0x11111111, }, { .offset = SRC_MASK_TV, .value = 0x00000111, }, @@ -291,123 +277,6 @@ 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_enable_pll(u32 reg) -{ - u32 pll_con = readl(reg_base + reg); - pll_con |= PLL_ENABLED; - writel(pll_con, reg_base + reg); - - while (!(pll_con & PLL_LOCKED)) { - cpu_relax(); - pll_con = readl(reg_base + reg); - } -} - -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) -{ - samsung_clk_save(reg_base, exynos4_save_common, - ARRAY_SIZE(exynos4_clk_regs)); - samsung_clk_save(reg_base, exynos4_save_pll, - ARRAY_SIZE(exynos4_clk_pll_regs)); - - exynos4_clk_enable_pll(EPLL_CON0); - exynos4_clk_enable_pll(VPLL_CON0); - - if (exynos4_soc == EXYNOS4210) { - samsung_clk_save(reg_base, exynos4_save_soc, - ARRAY_SIZE(exynos4210_clk_save)); - samsung_clk_restore(reg_base, src_mask_suspend_e4210, - ARRAY_SIZE(src_mask_suspend_e4210)); - } else { - samsung_clk_save(reg_base, exynos4_save_soc, - ARRAY_SIZE(exynos4x12_clk_save)); - } - - samsung_clk_restore(reg_base, src_mask_suspend, - ARRAY_SIZE(src_mask_suspend)); - - return 0; -} - -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, - ARRAY_SIZE(exynos4_clk_regs)); - - if (exynos4_soc == EXYNOS4210) - samsung_clk_restore(reg_base, exynos4_save_soc, - ARRAY_SIZE(exynos4210_clk_save)); - else - samsung_clk_restore(reg_base, exynos4_save_soc, - ARRAY_SIZE(exynos4x12_clk_save)); -} - -static struct syscore_ops exynos4_clk_syscore_ops = { - .suspend = exynos4_clk_suspend, - .resume = exynos4_clk_resume, -}; - -static void __init exynos4_clk_sleep_init(void) -{ - exynos4_save_common = samsung_clk_alloc_reg_dump(exynos4_clk_regs, - ARRAY_SIZE(exynos4_clk_regs)); - if (!exynos4_save_common) - goto err_warn; - - if (exynos4_soc == EXYNOS4210) - exynos4_save_soc = samsung_clk_alloc_reg_dump( - exynos4210_clk_save, - ARRAY_SIZE(exynos4210_clk_save)); - else - exynos4_save_soc = samsung_clk_alloc_reg_dump( - exynos4x12_clk_save, - ARRAY_SIZE(exynos4x12_clk_save)); - if (!exynos4_save_soc) - 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); - return; - -err_soc: - kfree(exynos4_save_soc); -err_common: - kfree(exynos4_save_common); -err_warn: - pr_warn("%s: failed to allocate sleep save data, no sleep support!\n", - __func__); -} -#else -static void __init exynos4_clk_sleep_init(void) {} -#endif - /* list of all parent clock list */ PNAME(mout_apll_p) = { "fin_pll", "fout_apll", }; PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", }; @@ -841,18 +710,6 @@ static const struct samsung_div_clock exynos4x12_div_clks[] __initconst = { DIV(0, "div_c2c_aclk", "div_c2c", DIV_DMC1, 12, 3), }; -static struct samsung_div_clock exynos4x12_isp_div_clks[] = { - DIV_F(CLK_DIV_ISP0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3, - CLK_GET_RATE_NOCACHE, 0), - DIV_F(CLK_DIV_ISP1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3, - CLK_GET_RATE_NOCACHE, 0), - DIV(0, "div_mpwm", "div_isp1", E4X12_DIV_ISP1, 0, 3), - DIV_F(CLK_DIV_MCUISP0, "div_mcuisp0", "aclk400_mcuisp", E4X12_DIV_ISP1, - 4, 3, CLK_GET_RATE_NOCACHE, 0), - DIV_F(CLK_DIV_MCUISP1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1, - 8, 3, CLK_GET_RATE_NOCACHE, 0), -}; - /* list of gate clocks supported in all exynos4 soc's */ static const struct samsung_gate_clock exynos4_gate_clks[] __initconst = { GATE(CLK_PPMULEFT, "ppmuleft", "aclk200", GATE_IP_LEFTBUS, 1, 0, 0), @@ -1150,61 +1007,6 @@ static const struct samsung_gate_clock exynos4x12_gate_clks[] __initconst = { 0), }; -static struct samsung_gate_clock exynos4x12_isp_gate_clks[] = { - GATE(CLK_FIMC_ISP, "isp", "aclk200", E4X12_GATE_ISP0, 0, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_FIMC_DRC, "drc", "aclk200", E4X12_GATE_ISP0, 1, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_FIMC_FD, "fd", "aclk200", E4X12_GATE_ISP0, 2, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_FIMC_LITE0, "lite0", "aclk200", E4X12_GATE_ISP0, 3, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_FIMC_LITE1, "lite1", "aclk200", E4X12_GATE_ISP0, 4, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_MCUISP, "mcuisp", "aclk200", E4X12_GATE_ISP0, 5, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_GICISP, "gicisp", "aclk200", E4X12_GATE_ISP0, 7, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_SMMU_ISP, "smmu_isp", "aclk200", E4X12_GATE_ISP0, 8, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_SMMU_DRC, "smmu_drc", "aclk200", E4X12_GATE_ISP0, 9, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_SMMU_FD, "smmu_fd", "aclk200", E4X12_GATE_ISP0, 10, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_SMMU_LITE0, "smmu_lite0", "aclk200", E4X12_GATE_ISP0, 11, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_SMMU_LITE1, "smmu_lite1", "aclk200", E4X12_GATE_ISP0, 12, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_PPMUISPMX, "ppmuispmx", "aclk200", E4X12_GATE_ISP0, 20, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_PPMUISPX, "ppmuispx", "aclk200", E4X12_GATE_ISP0, 21, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_MCUCTL_ISP, "mcuctl_isp", "aclk200", E4X12_GATE_ISP0, 23, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_MPWM_ISP, "mpwm_isp", "aclk200", E4X12_GATE_ISP0, 24, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_I2C0_ISP, "i2c0_isp", "aclk200", E4X12_GATE_ISP0, 25, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_I2C1_ISP, "i2c1_isp", "aclk200", E4X12_GATE_ISP0, 26, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_MTCADC_ISP, "mtcadc_isp", "aclk200", E4X12_GATE_ISP0, 27, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_PWM_ISP, "pwm_isp", "aclk200", E4X12_GATE_ISP0, 28, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_WDT_ISP, "wdt_isp", "aclk200", E4X12_GATE_ISP0, 30, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_UART_ISP, "uart_isp", "aclk200", E4X12_GATE_ISP0, 31, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_ASYNCAXIM, "asyncaxim", "aclk200", E4X12_GATE_ISP1, 0, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_SMMU_ISPCX, "smmu_ispcx", "aclk200", E4X12_GATE_ISP1, 4, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_SPI0_ISP, "spi0_isp", "aclk200", E4X12_GATE_ISP1, 12, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_SPI1_ISP, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), -}; - /* * The parent of the fin_pll clock is selected by the XOM[0] bit. This bit * resides in chipid register space, outside of the clock controller memory @@ -1504,8 +1306,6 @@ static void __init exynos4_clk_init(struct device_node *np, e4210_armclk_d, ARRAY_SIZE(e4210_armclk_d), CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1); } else { - struct resource res; - samsung_clk_register_mux(ctx, exynos4x12_mux_clks, ARRAY_SIZE(exynos4x12_mux_clks)); samsung_clk_register_div(ctx, exynos4x12_div_clks, @@ -1516,14 +1316,6 @@ static void __init exynos4_clk_init(struct device_node *np, exynos4x12_fixed_factor_clks, ARRAY_SIZE(exynos4x12_fixed_factor_clks)); - of_address_to_resource(np, 0, &res); - if (resource_size(&res) > 0x18000) { - samsung_clk_register_div(ctx, exynos4x12_isp_div_clks, - ARRAY_SIZE(exynos4x12_isp_div_clks)); - samsung_clk_register_gate(ctx, exynos4x12_isp_gate_clks, - ARRAY_SIZE(exynos4x12_isp_gate_clks)); - } - exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk", mout_core_p4x12[0], mout_core_p4x12[1], 0x14200, e4412_armclk_d, ARRAY_SIZE(e4412_armclk_d), @@ -1532,7 +1324,17 @@ static void __init exynos4_clk_init(struct device_node *np, if (soc == EXYNOS4X12) exynos4x12_core_down_clock(); - exynos4_clk_sleep_init(); + + samsung_clk_extended_sleep_init(reg_base, + exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs), + src_mask_suspend, ARRAY_SIZE(src_mask_suspend)); + if (exynos4_soc == EXYNOS4210) + samsung_clk_extended_sleep_init(reg_base, + exynos4210_clk_save, ARRAY_SIZE(exynos4210_clk_save), + src_mask_suspend_e4210, ARRAY_SIZE(src_mask_suspend_e4210)); + else + samsung_clk_sleep_init(reg_base, exynos4x12_clk_save, + ARRAY_SIZE(exynos4x12_clk_save)); samsung_clk_of_add_provider(np, ctx); |