summaryrefslogtreecommitdiff
path: root/arch/arm/mach-imx
diff options
context:
space:
mode:
authorBai Ping <ping.bai@nxp.com>2017-12-05 10:00:54 +0800
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:29:38 +0800
commitd9bf1eef6a6353c31e61e58c8e7f517ac34c95f8 (patch)
treea1407e59263ab157d246963850ea4eaf435ddbfb /arch/arm/mach-imx
parentd21616b0f52e79b700dbe01a8bc9c478084f202a (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.c23
-rw-r--r--arch/arm/mach-imx/cpuidle-imx6sll.c15
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;
}