From c4b48f2fe3c15e63de453e9fa06096f29650db70 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Tue, 20 Aug 2013 11:30:19 -0400 Subject: ENGR00275821-1 ARM: imx: rename pm-imx6q.c To support all i.MX6 SOCs' suspend/resume, need to rename pm-imx6q.c to pm-imx6.c and move common code of ccm setting from platform specific clk file to pm-imx6.c to avoid duplicated code. Signed-off-by: Anson Huang --- arch/arm/mach-imx/Makefile | 4 +- arch/arm/mach-imx/clk-imx6q.c | 187 +-------------------- arch/arm/mach-imx/common.h | 10 +- arch/arm/mach-imx/cpuidle-imx6q.c | 6 +- arch/arm/mach-imx/mach-imx6q.c | 2 +- arch/arm/mach-imx/pm-imx6.c | 333 ++++++++++++++++++++++++++++++++++++++ arch/arm/mach-imx/pm-imx6q.c | 152 ----------------- 7 files changed, 346 insertions(+), 348 deletions(-) create mode 100644 arch/arm/mach-imx/pm-imx6.c delete mode 100644 arch/arm/mach-imx/pm-imx6q.c diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 1a76d593e713..64aacbe49e61 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -102,9 +102,7 @@ obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a -ifeq ($(CONFIG_PM),y) -obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o suspend-imx6.o -endif +obj-$(CONFIG_PM) += pm-imx6.o headsmp.o suspend-imx6.o # i.MX5 based machines obj-$(CONFIG_MACH_MX51_BABBAGE) += mach-mx51_babbage.o diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 549568df147c..77d17eca0d9b 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -25,188 +24,6 @@ #include "common.h" #include "hardware.h" -#define CCR 0x0 -#define BM_CCR_WB_COUNT (0x7 << 16) -#define BM_CCR_RBC_BYPASS_COUNT (0x3f << 21) -#define BM_CCR_RBC_EN (0x1 << 27) - -#define CCGR0 0x68 -#define CCGR1 0x6c -#define CCGR2 0x70 -#define CCGR3 0x74 -#define CCGR4 0x78 -#define CCGR5 0x7c -#define CCGR6 0x80 -#define CCGR7 0x84 - -#define CLPCR 0x54 -#define BP_CLPCR_LPM 0 -#define BM_CLPCR_LPM (0x3 << 0) -#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2) -#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5) -#define BM_CLPCR_SBYOS (0x1 << 6) -#define BM_CLPCR_DIS_REF_OSC (0x1 << 7) -#define BM_CLPCR_VSTBY (0x1 << 8) -#define BP_CLPCR_STBY_COUNT 9 -#define BM_CLPCR_STBY_COUNT (0x3 << 9) -#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11) -#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16) -#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17) -#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19) -#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21) -#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22) -#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23) -#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24) -#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25) -#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26) -#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27) - -#define CGPR 0x64 -#define BM_CGPR_INT_MEM_CLK_LPM (0x1 << 17) - -#define MX6Q_INT_IOMUXC 32 - -static void __iomem *ccm_base; - -void imx6q_set_cache_lpm_in_wait(bool enable) -{ - if ((cpu_is_imx6q() && imx_get_soc_revision() > - IMX_CHIP_REVISION_1_1) || - (cpu_is_imx6dl() && imx_get_soc_revision() > - IMX_CHIP_REVISION_1_0)) { - u32 val; - - val = readl_relaxed(ccm_base + CGPR); - if (enable) - val |= BM_CGPR_INT_MEM_CLK_LPM; - else - val &= ~BM_CGPR_INT_MEM_CLK_LPM; - writel_relaxed(val, ccm_base + CGPR); - } -} - -static void imx6q_enable_rbc(bool enable) -{ - u32 val; - static bool last_rbc_mode; - - if (last_rbc_mode == enable) - return; - /* - * need to mask all interrupts in GPC before - * operating RBC configurations - */ - imx_gpc_mask_all(); - - /* configure RBC enable bit */ - val = readl_relaxed(ccm_base + CCR); - val &= ~BM_CCR_RBC_EN; - val |= enable ? BM_CCR_RBC_EN : 0; - writel_relaxed(val, ccm_base + CCR); - - /* configure RBC count */ - val = readl_relaxed(ccm_base + CCR); - val &= ~BM_CCR_RBC_BYPASS_COUNT; - val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0; - writel(val, ccm_base + CCR); - - /* - * need to delay at least 2 cycles of CKIL(32K) - * due to hardware design requirement, which is - * ~61us, here we use 65us for safe - */ - udelay(65); - - /* restore GPC interrupt mask settings */ - imx_gpc_restore_all(); - - last_rbc_mode = enable; -} - -static void imx6q_enable_wb(bool enable) -{ - u32 val; - static bool last_wb_mode; - - if (last_wb_mode == enable) - return; - - /* configure well bias enable bit */ - val = readl_relaxed(ccm_base + CLPCR); - val &= ~BM_CLPCR_WB_PER_AT_LPM; - val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0; - writel_relaxed(val, ccm_base + CLPCR); - - /* configure well bias count */ - val = readl_relaxed(ccm_base + CCR); - val &= ~BM_CCR_WB_COUNT; - val |= enable ? BM_CCR_WB_COUNT : 0; - writel_relaxed(val, ccm_base + CCR); - - last_wb_mode = enable; -} - -int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) -{ - u32 val = readl_relaxed(ccm_base + CLPCR); - struct irq_desc *desc = irq_to_desc(MX6Q_INT_IOMUXC); - - /* - * CCM state machine has restriction, before enabling - * LPM mode, need to make sure last LPM mode is waked up - * by dsm_wakeup_signal, which means the wakeup source - * must be seen by GPC, then CCM will clean its state machine - * and re-sample necessary signal to decide whether it can - * enter LPM mode. We force irq #32 to be always pending, - * unmask it before we enable LPM mode and mask it after LPM - * is enabled, this flow will make sure CCM state machine in - * reliable status before entering LPM mode. Otherwise, CCM - * may enter LPM mode by mistake which will cause system bus - * locked by CPU access not finished, as when CCM enter - * LPM mode, CPU will stop running. - */ - imx_gpc_irq_unmask(&desc->irq_data); - - val &= ~BM_CLPCR_LPM; - switch (mode) { - case WAIT_CLOCKED: - imx6q_enable_wb(false); - imx6q_enable_rbc(false); - break; - case WAIT_UNCLOCKED: - val |= 0x1 << BP_CLPCR_LPM; - val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM; - break; - case STOP_POWER_ON: - val |= 0x2 << BP_CLPCR_LPM; - val &= ~BM_CLPCR_VSTBY; - val &= ~BM_CLPCR_SBYOS; - val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS; - break; - case WAIT_UNCLOCKED_POWER_OFF: - val |= 0x1 << BP_CLPCR_LPM; - val &= ~BM_CLPCR_VSTBY; - val &= ~BM_CLPCR_SBYOS; - break; - case STOP_POWER_OFF: - val |= 0x2 << BP_CLPCR_LPM; - val |= 0x3 << BP_CLPCR_STBY_COUNT; - val |= BM_CLPCR_VSTBY; - val |= BM_CLPCR_SBYOS; - val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS; - imx6q_enable_wb(true); - break; - default: - imx_gpc_irq_mask(&desc->irq_data); - return -EINVAL; - } - - writel_relaxed(val, ccm_base + CLPCR); - imx_gpc_irq_mask(&desc->irq_data); - - return 0; -} - static const char *step_sels[] = { "osc", "pll2_pfd2_396m", }; static const char *pll1_sw_sels[] = { "pll1_sys", "step", }; static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", }; @@ -400,7 +217,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) np = ccm_node; base = of_iomap(np, 0); WARN_ON(!base); - ccm_base = base; + imx6_pm_set_ccm_base(base); /* name reg shift width parent_names num_parents */ clk[step] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); @@ -667,7 +484,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) pr_warn("failed to set up CLKO: %d\n", ret); /* Set initial power mode */ - imx6q_set_lpm(WAIT_CLOCKED); + imx6_set_lpm(WAIT_CLOCKED); np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt"); base = of_iomap(np, 0); diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 310867dbca88..ab19a1f839f6 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -143,18 +143,20 @@ extern void imx_gpc_restore_all(void); extern void imx_anatop_init(void); extern void imx_anatop_pre_suspend(void); extern void imx_anatop_post_resume(void); -extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); -extern void imx6q_set_cache_lpm_in_wait(bool enable); +extern int imx6_set_lpm(enum mxc_cpu_pwr_mode mode); +extern void imx6_set_cache_lpm_in_wait(bool enable); extern void imx_cpu_die(unsigned int cpu); extern int imx_cpu_kill(unsigned int cpu); #ifdef CONFIG_PM -extern void imx6q_pm_init(void); +extern void imx6_pm_init(void); +extern void imx6_pm_set_ccm_base(void __iomem *base); extern void imx51_pm_init(void); extern void imx53_pm_init(void); #else -static inline void imx6q_pm_init(void) {} +static inline void imx6_pm_init(void) {} +static inline void imx6_pm_set_ccm_base(void __iomem *base) {} static inline void imx51_pm_init(void) {} static inline void imx53_pm_init(void) {} #endif diff --git a/arch/arm/mach-imx/cpuidle-imx6q.c b/arch/arm/mach-imx/cpuidle-imx6q.c index 8065e185daed..d74d0ce794ab 100644 --- a/arch/arm/mach-imx/cpuidle-imx6q.c +++ b/arch/arm/mach-imx/cpuidle-imx6q.c @@ -27,9 +27,9 @@ static int imx6q_enter_wait(struct cpuidle_device *dev, */ if (!spin_trylock(&master_lock)) goto idle; - imx6q_set_lpm(WAIT_UNCLOCKED); + imx6_set_lpm(WAIT_UNCLOCKED); cpu_do_idle(); - imx6q_set_lpm(WAIT_CLOCKED); + imx6_set_lpm(WAIT_CLOCKED); spin_unlock(&master_lock); goto done; } @@ -69,7 +69,7 @@ int __init imx6q_cpuidle_init(void) imx_scu_standby_enable(); /* Set cache lpm bit for reliable WAIT mode support */ - imx6q_set_cache_lpm_in_wait(true); + imx6_set_cache_lpm_in_wait(true); return cpuidle_register(&imx6q_cpuidle_driver, NULL); } diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index e1e334380534..cfa93827c9ad 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -213,7 +213,7 @@ static void __init imx6q_init_machine(void) of_platform_populate(NULL, of_default_bus_match_table, NULL, parent); imx_anatop_init(); - imx6q_pm_init(); + imx6_pm_init(); imx6q_1588_init(); imx6q_lvds_cabc_init(); } diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c new file mode 100644 index 000000000000..e1c5eb5e03a1 --- /dev/null +++ b/arch/arm/mach-imx/pm-imx6.c @@ -0,0 +1,333 @@ +/* + * Copyright 2011-2013 Freescale Semiconductor, Inc. + * Copyright 2011 Linaro Ltd. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "hardware.h" + +#define CCR 0x0 +#define BM_CCR_WB_COUNT (0x7 << 16) +#define BM_CCR_RBC_BYPASS_COUNT (0x3f << 21) +#define BM_CCR_RBC_EN (0x1 << 27) + +#define CLPCR 0x54 +#define BP_CLPCR_LPM 0 +#define BM_CLPCR_LPM (0x3 << 0) +#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2) +#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5) +#define BM_CLPCR_SBYOS (0x1 << 6) +#define BM_CLPCR_DIS_REF_OSC (0x1 << 7) +#define BM_CLPCR_VSTBY (0x1 << 8) +#define BP_CLPCR_STBY_COUNT 9 +#define BM_CLPCR_STBY_COUNT (0x3 << 9) +#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11) +#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16) +#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17) +#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19) +#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21) +#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22) +#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23) +#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24) +#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25) +#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26) +#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27) + +#define CGPR 0x64 +#define BM_CGPR_INT_MEM_CLK_LPM (0x1 << 17) + +#define MX6_INT_IOMUXC 32 + +static struct gen_pool *iram_pool; +static void *suspend_iram_base; +static unsigned long iram_size, iram_paddr; +static int (*suspend_in_iram_fn)(void *iram_vbase, + unsigned long iram_pbase, unsigned int cpu_type); +static unsigned int cpu_type; +static void __iomem *ccm_base; + +void imx6_set_cache_lpm_in_wait(bool enable) +{ + if ((cpu_is_imx6q() && imx_get_soc_revision() > + IMX_CHIP_REVISION_1_1) || + (cpu_is_imx6dl() && imx_get_soc_revision() > + IMX_CHIP_REVISION_1_0)) { + u32 val; + + val = readl_relaxed(ccm_base + CGPR); + if (enable) + val |= BM_CGPR_INT_MEM_CLK_LPM; + else + val &= ~BM_CGPR_INT_MEM_CLK_LPM; + writel_relaxed(val, ccm_base + CGPR); + } +} + +static void imx6_enable_rbc(bool enable) +{ + u32 val; + static bool last_rbc_mode; + + if (last_rbc_mode == enable) + return; + /* + * need to mask all interrupts in GPC before + * operating RBC configurations + */ + imx_gpc_mask_all(); + + /* configure RBC enable bit */ + val = readl_relaxed(ccm_base + CCR); + val &= ~BM_CCR_RBC_EN; + val |= enable ? BM_CCR_RBC_EN : 0; + writel_relaxed(val, ccm_base + CCR); + + /* configure RBC count */ + val = readl_relaxed(ccm_base + CCR); + val &= ~BM_CCR_RBC_BYPASS_COUNT; + val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0; + writel(val, ccm_base + CCR); + + /* + * need to delay at least 2 cycles of CKIL(32K) + * due to hardware design requirement, which is + * ~61us, here we use 65us for safe + */ + udelay(65); + + /* restore GPC interrupt mask settings */ + imx_gpc_restore_all(); + + last_rbc_mode = enable; +} + +static void imx6_enable_wb(bool enable) +{ + u32 val; + static bool last_wb_mode; + + if (last_wb_mode == enable) + return; + + /* configure well bias enable bit */ + val = readl_relaxed(ccm_base + CLPCR); + val &= ~BM_CLPCR_WB_PER_AT_LPM; + val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0; + writel_relaxed(val, ccm_base + CLPCR); + + /* configure well bias count */ + val = readl_relaxed(ccm_base + CCR); + val &= ~BM_CCR_WB_COUNT; + val |= enable ? BM_CCR_WB_COUNT : 0; + writel_relaxed(val, ccm_base + CCR); + + last_wb_mode = enable; +} + +int imx6_set_lpm(enum mxc_cpu_pwr_mode mode) +{ + u32 val = readl_relaxed(ccm_base + CLPCR); + struct irq_desc *desc = irq_to_desc(MX6_INT_IOMUXC); + + /* + * CCM state machine has restriction, before enabling + * LPM mode, need to make sure last LPM mode is waked up + * by dsm_wakeup_signal, which means the wakeup source + * must be seen by GPC, then CCM will clean its state machine + * and re-sample necessary signal to decide whether it can + * enter LPM mode. We force irq #32 to be always pending, + * unmask it before we enable LPM mode and mask it after LPM + * is enabled, this flow will make sure CCM state machine in + * reliable status before entering LPM mode. Otherwise, CCM + * may enter LPM mode by mistake which will cause system bus + * locked by CPU access not finished, as when CCM enter + * LPM mode, CPU will stop running. + */ + imx_gpc_irq_unmask(&desc->irq_data); + + val &= ~BM_CLPCR_LPM; + switch (mode) { + case WAIT_CLOCKED: + imx6_enable_wb(false); + imx6_enable_rbc(false); + break; + case WAIT_UNCLOCKED: + val |= 0x1 << BP_CLPCR_LPM; + val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM; + break; + case STOP_POWER_ON: + val |= 0x2 << BP_CLPCR_LPM; + val &= ~BM_CLPCR_VSTBY; + val &= ~BM_CLPCR_SBYOS; + val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS; + break; + case WAIT_UNCLOCKED_POWER_OFF: + val |= 0x1 << BP_CLPCR_LPM; + val &= ~BM_CLPCR_VSTBY; + val &= ~BM_CLPCR_SBYOS; + break; + case STOP_POWER_OFF: + val |= 0x2 << BP_CLPCR_LPM; + val |= 0x3 << BP_CLPCR_STBY_COUNT; + val |= BM_CLPCR_VSTBY; + val |= BM_CLPCR_SBYOS; + val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS; + imx6_enable_wb(true); + break; + default: + imx_gpc_irq_mask(&desc->irq_data); + return -EINVAL; + } + + writel_relaxed(val, ccm_base + CLPCR); + imx_gpc_irq_mask(&desc->irq_data); + + return 0; +} + +static int imx6_suspend_finish(unsigned long val) +{ + /* + * call low level suspend function in iram, + * as we need to float DDR IO. + */ + suspend_in_iram_fn(suspend_iram_base, iram_paddr, cpu_type); + return 0; +} + +static int imx6_pm_enter(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_STANDBY: + imx6_set_lpm(STOP_POWER_ON); + imx6_set_cache_lpm_in_wait(true); + imx_gpc_pre_suspend(false); + /* Zzz ... */ + cpu_do_idle(); + imx_gpc_post_resume(); + imx6_set_lpm(WAIT_CLOCKED); + break; + case PM_SUSPEND_MEM: + imx6_set_cache_lpm_in_wait(false); + imx6_set_lpm(STOP_POWER_OFF); + imx_gpc_pre_suspend(true); + imx_anatop_pre_suspend(); + imx_set_cpu_jump(0, v7_cpu_resume); + /* Zzz ... */ + cpu_suspend(0, imx6_suspend_finish); + imx_smp_prepare(); + imx_anatop_post_resume(); + imx_gpc_post_resume(); + imx6_set_cache_lpm_in_wait(true); + imx6_set_lpm(WAIT_CLOCKED); + break; + default: + return -EINVAL; + } + + return 0; +} + +static struct map_desc imx6_pm_io_desc[] __initdata = { + imx_map_entry(MX6Q, MMDC_P0, MT_DEVICE), + imx_map_entry(MX6Q, MMDC_P1, MT_DEVICE), + imx_map_entry(MX6Q, SRC, MT_DEVICE), + imx_map_entry(MX6Q, IOMUXC, MT_DEVICE), + imx_map_entry(MX6Q, CCM, MT_DEVICE), + imx_map_entry(MX6Q, ANATOP, MT_DEVICE), + imx_map_entry(MX6Q, GPC, MT_DEVICE), + imx_map_entry(MX6Q, L2, MT_DEVICE), +}; + +void __init imx6_pm_map_io(void) +{ + iotable_init(imx6_pm_io_desc, ARRAY_SIZE(imx6_pm_io_desc)); +} + +static int imx6_pm_valid(suspend_state_t state) +{ + return (state == PM_SUSPEND_STANDBY || state == PM_SUSPEND_MEM); +} + +static const struct platform_suspend_ops imx6_pm_ops = { + .enter = imx6_pm_enter, + .valid = imx6_pm_valid, +}; + +void imx6_pm_set_ccm_base(void __iomem *base) +{ + if (!base) + pr_warn("ccm base is NULL!\n"); + ccm_base = base; +} + +void __init imx6_pm_init(void) +{ + struct device_node *node; + unsigned long iram_base; + struct platform_device *pdev; + + node = of_find_compatible_node(NULL, NULL, "mmio-sram"); + if (!node) { + pr_err("failed to find ocram node!\n"); + return; + } + + pdev = of_find_device_by_node(node); + if (!pdev) { + pr_err("failed to find ocram device!\n"); + return; + } + + iram_pool = dev_get_gen_pool(&pdev->dev); + if (!iram_pool) { + pr_err("iram pool unavailable!\n"); + return; + } + + iram_size = MX6_SUSPEND_IRAM_SIZE; + + iram_base = gen_pool_alloc(iram_pool, iram_size); + if (!iram_base) { + pr_err("unable to alloc iram!\n"); + return; + } + + iram_paddr = gen_pool_virt_to_phys(iram_pool, iram_base); + + suspend_iram_base = __arm_ioremap(iram_paddr, iram_size, + MT_MEMORY_NONCACHED); + + suspend_in_iram_fn = (void *)fncpy(suspend_iram_base, + &imx6_suspend, iram_size); + + suspend_set_ops(&imx6_pm_ops); + + /* Set cpu_type for DSM */ + if (cpu_is_imx6q()) + cpu_type = MXC_CPU_IMX6Q; + else if (cpu_is_imx6dl()) + cpu_type = MXC_CPU_IMX6DL; +} diff --git a/arch/arm/mach-imx/pm-imx6q.c b/arch/arm/mach-imx/pm-imx6q.c deleted file mode 100644 index 637653b81db9..000000000000 --- a/arch/arm/mach-imx/pm-imx6q.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright 2011-2013 Freescale Semiconductor, Inc. - * Copyright 2011 Linaro Ltd. - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "common.h" -#include "hardware.h" - -static struct gen_pool *iram_pool; -static void *suspend_iram_base; -static unsigned long iram_size, iram_paddr; -static int (*suspend_in_iram_fn)(void *iram_vbase, - unsigned long iram_pbase, unsigned int cpu_type); -static unsigned int cpu_type; - -static int imx6q_suspend_finish(unsigned long val) -{ - /* - * call low level suspend function in iram, - * as we need to float DDR IO. - */ - suspend_in_iram_fn(suspend_iram_base, iram_paddr, cpu_type); - return 0; -} - -static int imx6q_pm_enter(suspend_state_t state) -{ - switch (state) { - case PM_SUSPEND_STANDBY: - imx6q_set_lpm(STOP_POWER_ON); - imx6q_set_cache_lpm_in_wait(true); - imx_gpc_pre_suspend(false); - /* Zzz ... */ - cpu_do_idle(); - imx_gpc_post_resume(); - imx6q_set_lpm(WAIT_CLOCKED); - break; - case PM_SUSPEND_MEM: - imx6q_set_cache_lpm_in_wait(false); - imx6q_set_lpm(STOP_POWER_OFF); - imx_gpc_pre_suspend(true); - imx_anatop_pre_suspend(); - imx_set_cpu_jump(0, v7_cpu_resume); - /* Zzz ... */ - cpu_suspend(0, imx6q_suspend_finish); - imx_smp_prepare(); - imx_anatop_post_resume(); - imx_gpc_post_resume(); - imx6q_set_cache_lpm_in_wait(true); - imx6q_set_lpm(WAIT_CLOCKED); - break; - default: - return -EINVAL; - } - - return 0; -} - -static struct map_desc imx6_pm_io_desc[] __initdata = { - imx_map_entry(MX6Q, MMDC_P0, MT_DEVICE), - imx_map_entry(MX6Q, MMDC_P1, MT_DEVICE), - imx_map_entry(MX6Q, SRC, MT_DEVICE), - imx_map_entry(MX6Q, IOMUXC, MT_DEVICE), - imx_map_entry(MX6Q, CCM, MT_DEVICE), - imx_map_entry(MX6Q, ANATOP, MT_DEVICE), - imx_map_entry(MX6Q, GPC, MT_DEVICE), - imx_map_entry(MX6Q, L2, MT_DEVICE), -}; - -void __init imx6_pm_map_io(void) -{ - iotable_init(imx6_pm_io_desc, ARRAY_SIZE(imx6_pm_io_desc)); -} - -static int imx6q_pm_valid(suspend_state_t state) -{ - return (state == PM_SUSPEND_STANDBY || state == PM_SUSPEND_MEM); -} - -static const struct platform_suspend_ops imx6q_pm_ops = { - .enter = imx6q_pm_enter, - .valid = imx6q_pm_valid, -}; - -void __init imx6q_pm_init(void) -{ - struct device_node *node; - unsigned long iram_base; - struct platform_device *pdev; - - node = of_find_compatible_node(NULL, NULL, "mmio-sram"); - if (!node) { - pr_err("failed to find ocram node!\n"); - return; - } - - pdev = of_find_device_by_node(node); - if (!pdev) { - pr_err("failed to find ocram device!\n"); - return; - } - - iram_pool = dev_get_gen_pool(&pdev->dev); - if (!iram_pool) { - pr_err("iram pool unavailable!\n"); - return; - } - - iram_size = MX6_SUSPEND_IRAM_SIZE; - - iram_base = gen_pool_alloc(iram_pool, iram_size); - if (!iram_base) { - pr_err("unable to alloc iram!\n"); - return; - } - - iram_paddr = gen_pool_virt_to_phys(iram_pool, iram_base); - - suspend_iram_base = __arm_ioremap(iram_paddr, iram_size, - MT_MEMORY_NONCACHED); - - suspend_in_iram_fn = (void *)fncpy(suspend_iram_base, - &imx6_suspend, iram_size); - - suspend_set_ops(&imx6q_pm_ops); - - /* Set cpu_type for DSM */ - if (cpu_is_imx6q()) - cpu_type = MXC_CPU_IMX6Q; - else if (cpu_is_imx6dl()) - cpu_type = MXC_CPU_IMX6DL; -} -- cgit v1.2.2