From: Daniel Lezcano <daniel.lezcano@linaro.org>
To: Lina Iyer <lina.iyer@linaro.org>,
khilman@linaro.org, amit.kucheria@linaro.org,
sboyd@codeaurora.org, davidb@codeaurora.org,
galak@codeaurora.org, linux-arm-msm@vger.kernel.org
Cc: msivasub@codeaurora.org,
Venkat Devarasetty <vdevaras@codeaurora.org>,
Nicolas Pitre <nicolas.pitre@linaro.org>
Subject: Re: [PATCH v2 07/10] qcom: msm-pm: Add cpu low power mode functions
Date: Wed, 13 Aug 2014 13:18:01 +0200 [thread overview]
Message-ID: <53EB4969.3030204@linaro.org> (raw)
In-Reply-To: <1407872640-6732-8-git-send-email-lina.iyer@linaro.org>
On 08/12/2014 09:43 PM, Lina Iyer wrote:
> Add interface layer to abstract and handle hardware specific
> functionality for executing various cpu low power modes in QCOM
> chipsets.
>
> Signed-off-by: Venkat Devarasetty <vdevaras@codeaurora.org>
> Signed-off-by: Mahesh Sivasubramanian <msivasub@codeaurora.org>
> Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
> ---
> drivers/soc/qcom/Makefile | 2 +-
> drivers/soc/qcom/msm-pm.c | 219 ++++++++++++++++++++++++++++++++++++++++++++++
> include/soc/qcom/pm.h | 39 +++++++++
> 3 files changed, 259 insertions(+), 1 deletion(-)
> create mode 100644 drivers/soc/qcom/msm-pm.c
> create mode 100644 include/soc/qcom/pm.h
>
> diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
> index d7ae93b..7925f83 100644
> --- a/drivers/soc/qcom/Makefile
> +++ b/drivers/soc/qcom/Makefile
> @@ -1,5 +1,5 @@
> obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o
> -obj-$(CONFIG_QCOM_PM) += spm-devices.o spm.o
> +obj-$(CONFIG_QCOM_PM) += spm-devices.o spm.o msm-pm.o
>
> CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
> obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o
> diff --git a/drivers/soc/qcom/msm-pm.c b/drivers/soc/qcom/msm-pm.c
> new file mode 100644
> index 0000000..f2f15b8
> --- /dev/null
> +++ b/drivers/soc/qcom/msm-pm.c
> @@ -0,0 +1,219 @@
> +/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/smp.h>
> +#include <linux/tick.h>
> +#include <linux/platform_device.h>
> +#include <linux/cpu_pm.h>
> +#include <linux/uaccess.h>
> +
> +#include <soc/qcom/spm.h>
> +#include <soc/qcom/pm.h>
> +#include <soc/qcom/scm.h>
> +#include <soc/qcom/scm-boot.h>
> +
> +#include <asm/suspend.h>
> +#include <asm/cacheflush.h>
> +#include <asm/cputype.h>
> +#include <asm/system_misc.h>
> +
> +#define SCM_CMD_TERMINATE_PC (0x2)
> +#define SCM_CMD_CORE_HOTPLUGGED (0x10)
> +#define SCM_FLUSH_FLAG_MASK (0x3)
> +
> +static bool msm_pm_is_L1_writeback(void)
> +{
> + u32 cache_id = 0;
> +
> +#if defined(CONFIG_CPU_V7)
> + u32 sel = 0;
> +
> + asm volatile ("mcr p15, 2, %[ccselr], c0, c0, 0\n\t"
> + "isb\n\t"
> + "mrc p15, 1, %[ccsidr], c0, c0, 0\n\t"
> + :[ccsidr]"=r" (cache_id)
> + :[ccselr]"r" (sel)
> + );
> + return cache_id & BIT(30);
> +#elif defined(CONFIG_ARM64)
> + u32 sel = 0;
> + asm volatile("msr csselr_el1, %[ccselr]\n\t"
> + "isb\n\t"
> + "mrs %[ccsidr],ccsidr_el1\n\t"
> + :[ccsidr]"=r" (cache_id)
> + :[ccselr]"r" (sel)
> + );
> + return cache_id & BIT(30);
> +#else
> +#error No valid CPU arch selected
> +#endif
> +}
> +
> +static inline void msm_arch_idle(void)
> +{
> + /* Flush and clock-gate */
> + mb();
Why is needed this memory barrier ?
> + wfi();
> +}
> +
> +static bool msm_pm_swfi(bool from_idle)
> +{
> + msm_arch_idle();
> + return true;
> +}
> +
> +static bool msm_pm_retention(bool from_idle)
> +{
> + int ret = 0;
> +
> + ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_RETENTION, false);
> + WARN_ON(ret);
> +
> + msm_arch_idle();
> +
> + ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING, false);
> + WARN_ON(ret);
Why do you need to set the clock gating mode each time you exit the
retention mode ?
> + return true;
> +}
> +
> +static int msm_pm_collapse(unsigned long from_idle)
> +{
> + enum msm_pm_l2_scm_flag flag = MSM_SCM_L2_ON;
> +
> + /**
> + * Single core processors need to have L2
> + * flushed when powering down the core.
> + * Notify SCM to flush secure L2 lines.
> + */
> + if (num_possible_cpus() == 1)
> + flag = MSM_SCM_L2_OFF;
I am wondering if this shouldn't be handle by a mcpm driver.
Cc nico.
> + if (flag == MSM_SCM_L2_OFF)
> + flush_cache_all();
> + else if (msm_pm_is_L1_writeback())
> + flush_cache_louis();
> +
> + flag &= SCM_FLUSH_FLAG_MASK;
> + if (!from_idle)
> + flag |= SCM_CMD_CORE_HOTPLUGGED;
> +
> + scm_call_atomic1(SCM_SVC_BOOT, SCM_CMD_TERMINATE_PC, flag);
> +
> + return 0;
> +}
> +
> +static void set_up_boot_address(void *entry, int cpu)
> +{
> + static int flags[NR_CPUS] = {
> + SCM_FLAG_WARMBOOT_CPU0,
> + SCM_FLAG_WARMBOOT_CPU1,
> + SCM_FLAG_WARMBOOT_CPU2,
> + SCM_FLAG_WARMBOOT_CPU3,
> + };
> + static DEFINE_PER_CPU(void *, last_known_entry);
> +
> + if (entry == per_cpu(last_known_entry, cpu))
> + return;
> +
> + per_cpu(last_known_entry, cpu) = entry;
> + scm_set_boot_addr(virt_to_phys(entry), flags[cpu]);
> +}
> +
> +static bool __ref msm_pm_spm_power_collapse(unsigned int cpu, bool from_idle)
> +{
> + void *entry;
> + bool collapsed = 0;
> + int ret;
> + bool save_cpu_regs = (cpu_online(cpu) || from_idle);
> +
> + if (from_idle)
> + cpu_pm_enter();
> +
> + ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_POWER_COLLAPSE, false);
> + WARN_ON(ret);
> +
> + entry = save_cpu_regs ? cpu_resume : secondary_startup;
> + set_up_boot_address(entry, cpu);
> +
> +#ifdef CONFIG_CPU_V7
> + collapsed = !cpu_suspend(from_idle, msm_pm_collapse);
> +#else
> + collapsed = !cpu_suspend(0);
> +#endif
> +
> + if (collapsed)
> + local_fiq_enable();
> +
> + if (from_idle)
> + cpu_pm_exit();
> +
> + ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING, false);
> + WARN_ON(ret);
> +
> + return collapsed;
> +}
> +
> +static bool msm_pm_power_collapse_standalone(bool from_idle)
> +{
> + unsigned int cpu = smp_processor_id();
> + bool collapsed;
> +
> + collapsed = msm_pm_spm_power_collapse(cpu, from_idle);
> +
> + return collapsed;
> +}
> +
> +static bool msm_pm_power_collapse(bool from_idle)
> +{
> + unsigned int cpu = smp_processor_id();
> + bool collapsed;
> +
> + collapsed = msm_pm_spm_power_collapse(cpu, from_idle);
> +
> + return collapsed;
> +}
> +
> +static bool (*execute[MSM_PM_SLEEP_MODE_NR])(bool idle) = {
> + [MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT] = msm_pm_swfi,
> + [MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE] =
> + msm_pm_power_collapse_standalone,
> + [MSM_PM_SLEEP_MODE_RETENTION] = msm_pm_retention,
> + [MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = msm_pm_power_collapse,
> +};
> +
> +/**
> + * msm_cpu_pm_enter_sleep(): Enter a low power mode on current cpu
> + *
> + * @mode - sleep mode to enter
> + * @from_idle - bool to indicate that the mode is exercised during idle/suspend
> + *
> + * The code should be with interrupts disabled and on the core on which the
> + * low power is to be executed.
> + *
> + */
> +bool msm_cpu_pm_enter_sleep(enum msm_pm_sleep_mode mode, bool from_idle)
> +{
> + bool exit_stat = false;
> +
> + if (execute[mode])
> + exit_stat = execute[mode](from_idle);
> +
> + local_irq_enable();
> + return exit_stat;
> +}
> +EXPORT_SYMBOL(msm_cpu_pm_enter_sleep);
> diff --git a/include/soc/qcom/pm.h b/include/soc/qcom/pm.h
> new file mode 100644
> index 0000000..01872ad
> --- /dev/null
> +++ b/include/soc/qcom/pm.h
> @@ -0,0 +1,39 @@
> +/*
> + * Copyright (c) 2009-2014, The Linux Foundation. All rights reserved.
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#ifndef __QCOM_PM_H
> +#define __QCOM_PM_H
> +
> +enum msm_pm_sleep_mode {
> + MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT,
> + MSM_PM_SLEEP_MODE_RETENTION,
> + MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE,
> + MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
> + MSM_PM_SLEEP_MODE_NR,
> +};
> +
> +enum msm_pm_l2_scm_flag {
> + MSM_SCM_L2_ON = 0,
> + MSM_SCM_L2_OFF = 1,
> +};
> +
> +#ifdef CONFIG_QCOM_PM
> +bool msm_cpu_pm_enter_sleep(enum msm_pm_sleep_mode mode, bool from_idle);
> +#else
> +static inline bool msm_cpu_pm_enter_sleep(enum msm_pm_sleep_mode mode,
> + bool from_idle)
> +{ return true; }
> +#endif
> +
> +#endif /* __QCOM_PM_H */
>
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
next prev parent reply other threads:[~2014-08-13 11:18 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-12 19:43 [PATCH v2 00/10] QCOM 8074 cpuidle driver Lina Iyer
2014-08-12 19:43 ` [PATCH v2 01/10] msm: scm: Move scm-boot files to drivers/soc and include/soc Lina Iyer
2014-08-12 19:43 ` [PATCH v2 02/10] msm: scm: Add SCM warmboot flags for quad core targets Lina Iyer
2014-08-14 10:20 ` Pramod Gurav
2014-08-12 19:43 ` [PATCH v2 03/10] qcom: spm: Add Subsystem Power Manager (SPM) driver for QCOM chipsets Lina Iyer
2014-08-13 10:49 ` Daniel Lezcano
2014-08-13 14:00 ` Lina Iyer
2014-08-14 13:01 ` Pramod Gurav
2014-08-14 15:18 ` Lina Iyer
2014-08-14 15:16 ` Kumar Gala
2014-08-14 15:27 ` Lina Iyer
2014-08-14 15:33 ` Kumar Gala
2014-08-14 16:09 ` Kumar Gala
2014-08-14 16:18 ` Lina Iyer
2014-08-14 16:41 ` Kumar Gala
2014-08-15 4:18 ` Lina Iyer
2014-08-15 13:42 ` Kumar Gala
2014-08-16 3:41 ` Lina Iyer
2014-08-12 19:43 ` [PATCH v2 04/10] soc: qcom: Add QCOM Power management config Lina Iyer
2014-08-13 9:36 ` Daniel Lezcano
2014-08-12 19:43 ` [PATCH v2 05/10] arm: qcom-msm8974: Add CPU phandles to CPU definitions Lina Iyer
2014-08-12 21:09 ` Kumar Gala
2014-08-14 10:04 ` Pramod Gurav
2014-08-12 19:43 ` [PATCH v2 06/10] arm: dts: qcom: Add SPM device bindings for 8974 Lina Iyer
2014-08-12 21:10 ` Kumar Gala
2014-08-12 21:32 ` Lina Iyer
2014-08-13 7:39 ` Ivan T. Ivanov
2014-08-12 19:43 ` [PATCH v2 07/10] qcom: msm-pm: Add cpu low power mode functions Lina Iyer
2014-08-13 11:18 ` Daniel Lezcano [this message]
2014-08-13 14:16 ` Lina Iyer
2014-08-14 14:24 ` Daniel Lezcano
2014-08-14 14:53 ` Lina Iyer
2014-08-14 16:11 ` Daniel Lezcano
2014-08-14 19:22 ` Lina Iyer
2014-08-15 0:01 ` Daniel Lezcano
2014-08-15 1:02 ` Lina Iyer
2014-08-14 13:38 ` Pramod Gurav
2014-08-14 14:43 ` Lina Iyer
2014-08-12 19:43 ` [PATCH v2 08/10] qcom: cpuidle: Add cpuidle driver for QCOM cpus Lina Iyer
2014-08-13 11:22 ` Daniel Lezcano
2014-08-13 14:03 ` Lina Iyer
2014-08-12 19:43 ` [PATCH v2 09/10] qcom: cpuidle: Config option to enable QCOM cpuidle driver Lina Iyer
2014-08-13 11:18 ` Daniel Lezcano
2014-08-12 19:44 ` [PATCH v2 10/10] qcom: cpuidle: Add cpuidle device nodes for 8974 chipset Lina Iyer
2014-08-13 1:52 ` [PATCH v2 00/10] QCOM 8074 cpuidle driver Stephen Boyd
2014-08-13 2:17 ` Lina Iyer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=53EB4969.3030204@linaro.org \
--to=daniel.lezcano@linaro.org \
--cc=amit.kucheria@linaro.org \
--cc=davidb@codeaurora.org \
--cc=galak@codeaurora.org \
--cc=khilman@linaro.org \
--cc=lina.iyer@linaro.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=msivasub@codeaurora.org \
--cc=nicolas.pitre@linaro.org \
--cc=sboyd@codeaurora.org \
--cc=vdevaras@codeaurora.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).