diff options
author | Bai Ping <ping.bai@nxp.com> | 2017-12-05 10:00:54 +0800 |
---|---|---|
committer | Jason Liu <jason.hui.liu@nxp.com> | 2019-02-12 10:29:38 +0800 |
commit | d9bf1eef6a6353c31e61e58c8e7f517ac34c95f8 (patch) | |
tree | a1407e59263ab157d246963850ea4eaf435ddbfb /arch/arm/mach-imx | |
parent | d21616b0f52e79b700dbe01a8bc9c478084f202a (diff) |
MLK-17082-01 ARM: imx: Add psci support in cpuidle for imx6sl/sll
Using PSCI to handle low power idle when linux is running in
no secure world. If the kernel is running in secure world, keep
using the method we used before.
Signed-off-by: Bai Ping <ping.bai@nxp.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Diffstat (limited to 'arch/arm/mach-imx')
-rw-r--r-- | arch/arm/mach-imx/cpuidle-imx6sl.c | 23 | ||||
-rw-r--r-- | arch/arm/mach-imx/cpuidle-imx6sll.c | 15 |
2 files changed, 35 insertions, 3 deletions
diff --git a/arch/arm/mach-imx/cpuidle-imx6sl.c b/arch/arm/mach-imx/cpuidle-imx6sl.c index 21ecebf699aa..ed7cb52bc99b 100644 --- a/arch/arm/mach-imx/cpuidle-imx6sl.c +++ b/arch/arm/mach-imx/cpuidle-imx6sl.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2014-2015 Freescale Semiconductor, Inc. + * Copyright 2017 NXP. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -10,6 +11,7 @@ #include <linux/cpuidle.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/psci.h> #include <linux/regulator/consumer.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> @@ -17,6 +19,8 @@ #include <asm/fncpy.h> #include <asm/proc-fns.h> +#include <uapi/linux/psci.h> + #include "common.h" #include "cpuidle.h" #include "hardware.h" @@ -63,15 +67,30 @@ static int ldo2p5_dummy_enable; static void (*imx6sl_wfi_in_iram_fn)(void __iomem *iram_vbase, int audio_mode, bool vbus_ldo); +#define MX6SL_POWERDWN_IDLE_PARAM \ + ((1 << PSCI_0_2_POWER_STATE_ID_SHIFT) | \ + (1 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) | \ + (PSCI_POWER_STATE_TYPE_POWER_DOWN << PSCI_0_2_POWER_STATE_TYPE_SHIFT)) + static int imx6sl_enter_wait(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { int mode = get_bus_freq_mode(); imx6_set_lpm(WAIT_UNCLOCKED); + if ((mode == BUS_FREQ_AUDIO) || (mode == BUS_FREQ_ULTRA_LOW)) { - imx6sl_wfi_in_iram_fn(wfi_iram_base, (mode == BUS_FREQ_AUDIO) ? 1 : 0 , - ldo2p5_dummy_enable); + /* + * bit 1 used for low power mode; + * bit 2 used for the ldo2p5_dummmy enable + */ + if (psci_ops.cpu_suspend) { + psci_ops.cpu_suspend((MX6SL_POWERDWN_IDLE_PARAM | ((BUS_FREQ_AUDIO ? 1 : 0) << 2) | + (ldo2p5_dummy_enable ? 1 : 0) << 1), __pa(cpu_resume)); + } else { + imx6sl_wfi_in_iram_fn(wfi_iram_base, (mode == BUS_FREQ_AUDIO) ? 1 : 0, + ldo2p5_dummy_enable); + } } else { /* * Software workaround for ERR005311, see function diff --git a/arch/arm/mach-imx/cpuidle-imx6sll.c b/arch/arm/mach-imx/cpuidle-imx6sll.c index 65d82e5855e2..bb8678ff56f0 100644 --- a/arch/arm/mach-imx/cpuidle-imx6sll.c +++ b/arch/arm/mach-imx/cpuidle-imx6sll.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -12,6 +13,7 @@ #include <linux/delay.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/psci.h> #include <linux/regulator/consumer.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> @@ -20,6 +22,8 @@ #include <asm/proc-fns.h> #include <asm/suspend.h> +#include <uapi/linux/psci.h> + #include "common.h" #include "cpuidle.h" #include "hardware.h" @@ -83,9 +87,18 @@ static const u32 imx6sll_mmdc_io_offset[] __initconst = { static void (*imx6sll_wfi_in_iram_fn)(void __iomem *iram_vbase); +#define MX6SLL_POWERDWN_IDLE_PARAM \ + ((1 << PSCI_0_2_POWER_STATE_ID_SHIFT) | \ + (1 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) | \ + (PSCI_POWER_STATE_TYPE_POWER_DOWN << PSCI_0_2_POWER_STATE_TYPE_SHIFT)) + static int imx6sll_idle_finish(unsigned long val) { - imx6sll_wfi_in_iram_fn(wfi_iram_base); + if (psci_ops.cpu_suspend) + psci_ops.cpu_suspend(MX6SLL_POWERDWN_IDLE_PARAM, + __pa(cpu_resume)); + else + imx6sll_wfi_in_iram_fn(wfi_iram_base); return 0; } |