All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/8] QCOM 8074 cpuidle driver
@ 2014-08-18 22:23 Lina Iyer
  2014-08-18 22:23 ` [PATCH v3 1/8] msm: scm: Move scm-boot files to drivers/soc and include/soc Lina Iyer
                   ` (8 more replies)
  0 siblings, 9 replies; 21+ messages in thread
From: Lina Iyer @ 2014-08-18 22:23 UTC (permalink / raw
  To: daniel.lezcano, khilman, sboyd, davidb, galak, linux-arm-msm,
	lorenzo.pieralisi
  Cc: msivasub, Lina Iyer

Changes since v2:
[ https://www.mail-archive.com/linux-arm-msm@vger.kernel.org/msg10148.html ]
- Prune all the drivers to support basic WFI and power down cpuidle
  functionality. Remove debug code.
- Integrate KConfig changes into the drivers' patches.
- Use Lorenzo's ARM idle-states patches as the basis for reading cpuidle
  c-states from DT.
- Incorporate review comments
- Rebase on top of 3.16

Changes since v1/RFC:
[ https://www.mail-archive.com/linux-arm-msm@vger.kernel.org/msg10065.html ]
- Remove hotplug from the patch series. Will submit it seprately.
- Fix SPM drivers per the review comments
- Modify patch sequence to compile SPM drivers independent of msm-pm, so as to
  allow wfi() calls to use SPM even without SoC interface driver.

8074 like any ARM SoC can do architectural clock gating, that helps save on
power, but not enough of leakage power.  Leakage power of the SoC can be
further reduced by turning off power to the core. To aid this, every core (cpu
and L2) is accompanied by a Sub-system Power Manager (SPM), that can be
configured to indicate the low power mode, the core would be put into and the
SPM programs the peripheral h/w accordingly to enter low power and turn off the
power rail to the core.

The idle invocation hierarchy - 

	CPUIDLE
	|
	cpuidle-qcom.c [CPUIdle driver]
	|
	------>	msm-pm.c [SoC Interface layer for QCOM chipsets]
		|
		------> spm-devices.c [SPM devices manager]
		|	|
		|	------>	spm.c [SPM h/w driver]
		|
		------> scm-boot.c [SCM interface layer]		
			|
------------------------|--------------------------
(EL)			Secure Monitor Code
			|
			|
			wfi(); 
------------------------|--------------------------
(HW)			[CPU] {clock gate}
			|
			-----> [SPM] {statemachine}
			

The patchsets do the following -

- Move scm-boot files from arm/mach-qcom to drivers/soc, following convention.
They are based on Stephen Boyd's series of patches
[http://www.spinics.net/lists/linux-arm-msm/msg10482.html]

- Add new Secure Monitor flags to support warmboot of a quad core system.

- Introduce the SPM driver to control power to the core. The SPM h/w IP works
in conjunction with the Krait CPU/L2. When the core executes WFI instruction,
the core is clockgated and the SPM state machine takes over and powers the core
down. An interrupt from GIC, resumes the SPM state machine which brings the cpu
out of the low power mode.

- Add a SPM device manager to configure multiple SPM devices.

- Add the device tree configuration for each of the SPM nodes. There is one for
each cpu. There is one for each cpu.

- Introduce the SoC driver interface layer to configure SPM per the core's idle
 state. To power down the cpu core, the SPM h/w needs to be set up correctly
to power down the core, when the core executes WFI. Linux is expected to call
into Secure Monitor to power down the core. At reset, the core will start in
seure mode and will be returned back to Linux. 

- Add CPUIDLE driver for QCOM cpus. The cpuidle driver uses the SoC interface
layer to configure the SPM to allow Krait to be powered down. The cpuidle driver
is based on ARM idle-state framework for cpuidle drivers.

- Provide device configuration for 8074 SoC. Current support is for WFI and
standalone power collapse, which powers only the core independent of the
other cores and caches.

Thanks,
Lina


Lina Iyer (8):
  msm: scm: Move scm-boot files to drivers/soc and include/soc
  msm: scm: Add SCM warmboot flags for quad core targets.
  qcom: spm: Add Subsystem Power Manager driver (SAW2)
  qcom: spm-devices: Add SPM device manager for the SoC
  arm: dts: qcom: Add SPM device bindings for 8974
  qcom: msm-pm: Add cpu low power mode functions
  qcom: cpuidle: Add cpuidle driver for QCOM cpus
  arm: dts: qcom: Add idle states device nodes for 8974

 Documentation/devicetree/bindings/arm/msm/spm.txt  |  47 ++++
 arch/arm/boot/dts/qcom-msm8974-pm.dtsi             |  69 ++++++
 arch/arm/boot/dts/qcom-msm8974.dtsi                |  24 +-
 arch/arm/mach-qcom/Makefile                        |   1 -
 arch/arm/mach-qcom/platsmp.c                       |   2 +-
 drivers/cpuidle/Kconfig.arm                        |   7 +
 drivers/cpuidle/Makefile                           |   1 +
 drivers/cpuidle/cpuidle-qcom.c                     | 119 ++++++++++
 drivers/soc/qcom/Kconfig                           |   8 +
 drivers/soc/qcom/Makefile                          |   3 +-
 drivers/soc/qcom/msm-pm.c                          | 117 ++++++++++
 .../arm/mach-qcom => drivers/soc/qcom}/scm-boot.c  |   4 +-
 drivers/soc/qcom/spm-devices.c                     | 242 +++++++++++++++++++++
 drivers/soc/qcom/spm.c                             | 176 +++++++++++++++
 drivers/soc/qcom/spm_driver.h                      |  85 ++++++++
 include/soc/qcom/pm.h                              |  38 ++++
 .../arm/mach-qcom => include/soc/qcom}/scm-boot.h  |   2 +
 include/soc/qcom/spm.h                             |  34 +++
 18 files changed, 970 insertions(+), 9 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/msm/spm.txt
 create mode 100644 arch/arm/boot/dts/qcom-msm8974-pm.dtsi
 create mode 100644 drivers/cpuidle/cpuidle-qcom.c
 create mode 100644 drivers/soc/qcom/msm-pm.c
 rename {arch/arm/mach-qcom => drivers/soc/qcom}/scm-boot.c (97%)
 create mode 100644 drivers/soc/qcom/spm-devices.c
 create mode 100644 drivers/soc/qcom/spm.c
 create mode 100644 drivers/soc/qcom/spm_driver.h
 create mode 100644 include/soc/qcom/pm.h
 rename {arch/arm/mach-qcom => include/soc/qcom}/scm-boot.h (92%)
 create mode 100644 include/soc/qcom/spm.h

-- 
1.9.1

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH v3 1/8] msm: scm: Move scm-boot files to drivers/soc and include/soc
  2014-08-18 22:23 [PATCH v3 0/8] QCOM 8074 cpuidle driver Lina Iyer
@ 2014-08-18 22:23 ` Lina Iyer
  2014-08-27 17:18   ` Kevin Hilman
  2014-08-18 22:23 ` [PATCH v3 2/8] msm: scm: Add SCM warmboot flags for quad core targets Lina Iyer
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Lina Iyer @ 2014-08-18 22:23 UTC (permalink / raw
  To: daniel.lezcano, khilman, sboyd, davidb, galak, linux-arm-msm,
	lorenzo.pieralisi
  Cc: msivasub, Lina Iyer

Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
---
 arch/arm/mach-qcom/Makefile                         | 1 -
 arch/arm/mach-qcom/platsmp.c                        | 2 +-
 drivers/soc/qcom/Makefile                           | 2 +-
 {arch/arm/mach-qcom => drivers/soc/qcom}/scm-boot.c | 4 ++--
 {arch/arm/mach-qcom => include/soc/qcom}/scm-boot.h | 0
 5 files changed, 4 insertions(+), 5 deletions(-)
 rename {arch/arm/mach-qcom => drivers/soc/qcom}/scm-boot.c (97%)
 rename {arch/arm/mach-qcom => include/soc/qcom}/scm-boot.h (100%)

diff --git a/arch/arm/mach-qcom/Makefile b/arch/arm/mach-qcom/Makefile
index db41e8c..e324375 100644
--- a/arch/arm/mach-qcom/Makefile
+++ b/arch/arm/mach-qcom/Makefile
@@ -1,3 +1,2 @@
 obj-y			:= board.o
 obj-$(CONFIG_SMP)	+= platsmp.o
-obj-$(CONFIG_QCOM_SCM)	+= scm-boot.o
diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c
index d690856..a692bcb 100644
--- a/arch/arm/mach-qcom/platsmp.c
+++ b/arch/arm/mach-qcom/platsmp.c
@@ -20,7 +20,7 @@
 
 #include <asm/smp_plat.h>
 
-#include "scm-boot.h"
+#include <soc/qcom/scm-boot.h>
 
 #define VDD_SC1_ARRAY_CLAMP_GFS_CTL	0x35a0
 #define SCSS_CPU1CORE_RESET		0x2d80
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index a39446d..70d52ed 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -1,3 +1,3 @@
 obj-$(CONFIG_QCOM_GSBI)	+=	qcom_gsbi.o
 CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
-obj-$(CONFIG_QCOM_SCM) += scm.o
+obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o
diff --git a/arch/arm/mach-qcom/scm-boot.c b/drivers/soc/qcom/scm-boot.c
similarity index 97%
rename from arch/arm/mach-qcom/scm-boot.c
rename to drivers/soc/qcom/scm-boot.c
index 5add20e..60ff7b4 100644
--- a/arch/arm/mach-qcom/scm-boot.c
+++ b/drivers/soc/qcom/scm-boot.c
@@ -17,9 +17,9 @@
 
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <soc/qcom/scm.h>
 
-#include "scm-boot.h"
+#include <soc/qcom/scm.h>
+#include <soc/qcom/scm-boot.h>
 
 /*
  * Set the cold/warm boot address for one of the CPU cores.
diff --git a/arch/arm/mach-qcom/scm-boot.h b/include/soc/qcom/scm-boot.h
similarity index 100%
rename from arch/arm/mach-qcom/scm-boot.h
rename to include/soc/qcom/scm-boot.h
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v3 2/8] msm: scm: Add SCM warmboot flags for quad core targets.
  2014-08-18 22:23 [PATCH v3 0/8] QCOM 8074 cpuidle driver Lina Iyer
  2014-08-18 22:23 ` [PATCH v3 1/8] msm: scm: Move scm-boot files to drivers/soc and include/soc Lina Iyer
@ 2014-08-18 22:23 ` Lina Iyer
  2014-08-18 22:23 ` [PATCH v3 3/8] qcom: spm: Add Subsystem Power Manager driver (SAW2) Lina Iyer
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Lina Iyer @ 2014-08-18 22:23 UTC (permalink / raw
  To: daniel.lezcano, khilman, sboyd, davidb, galak, linux-arm-msm,
	lorenzo.pieralisi
  Cc: msivasub, Lina Iyer

Quad core targets like APQ8074, APQ8064, APQ8084 need SCM support set up
warm boot addresses in the Secure Monitor. Extend the SCM flags to
support warmboot addresses for seconday cores.

Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
---
 include/soc/qcom/scm-boot.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/soc/qcom/scm-boot.h b/include/soc/qcom/scm-boot.h
index 6aabb24..02b445c 100644
--- a/include/soc/qcom/scm-boot.h
+++ b/include/soc/qcom/scm-boot.h
@@ -18,6 +18,8 @@
 #define SCM_FLAG_COLDBOOT_CPU3		0x20
 #define SCM_FLAG_WARMBOOT_CPU0		0x04
 #define SCM_FLAG_WARMBOOT_CPU1		0x02
+#define SCM_FLAG_WARMBOOT_CPU2		0x10
+#define SCM_FLAG_WARMBOOT_CPU3		0x40
 
 int scm_set_boot_addr(phys_addr_t addr, int flags);
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v3 3/8] qcom: spm: Add Subsystem Power Manager driver (SAW2)
  2014-08-18 22:23 [PATCH v3 0/8] QCOM 8074 cpuidle driver Lina Iyer
  2014-08-18 22:23 ` [PATCH v3 1/8] msm: scm: Move scm-boot files to drivers/soc and include/soc Lina Iyer
  2014-08-18 22:23 ` [PATCH v3 2/8] msm: scm: Add SCM warmboot flags for quad core targets Lina Iyer
@ 2014-08-18 22:23 ` Lina Iyer
  2014-08-19 14:07   ` Kumar Gala
  2014-08-18 22:23 ` [PATCH v3 4/8] qcom: spm-devices: Add SPM device manager for the SoC Lina Iyer
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Lina Iyer @ 2014-08-18 22:23 UTC (permalink / raw
  To: daniel.lezcano, khilman, sboyd, davidb, galak, linux-arm-msm,
	lorenzo.pieralisi
  Cc: msivasub, Lina Iyer, Praveen Chidambaram

SPM is a hardware block that controls the peripheral logic surrounding
the application cores (cpu/l$). When the core executes WFI instruction,
the SPM takes over the putting the core in low power state as
configured. The wake up for the SPM is an interrupt at the GIC, which
then completes the rest of low power mode sequence and brings the core
out of low power mode.

Allow drivers to configure the idle mode for the cores in the SPM start
address register.

Signed-off-by: Praveen Chidambaram <pchidamb@codeaurora.org>
Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
---
 drivers/soc/qcom/Makefile     |   1 +
 drivers/soc/qcom/spm.c        | 176 ++++++++++++++++++++++++++++++++++++++++++
 drivers/soc/qcom/spm_driver.h |  85 ++++++++++++++++++++
 3 files changed, 262 insertions(+)
 create mode 100644 drivers/soc/qcom/spm.c
 create mode 100644 drivers/soc/qcom/spm_driver.h

diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index 70d52ed..20b329f 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_QCOM_GSBI)	+=	qcom_gsbi.o
+obj-$(CONFIG_QCOM_PM)	+=	spm.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/spm.c b/drivers/soc/qcom/spm.c
new file mode 100644
index 0000000..3e1de43
--- /dev/null
+++ b/drivers/soc/qcom/spm.c
@@ -0,0 +1,176 @@
+/* Copyright (c) 2011-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/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include "spm_driver.h"
+
+#define NUM_SPM_ENTRY 32
+
+static uint32_t msm_spm_reg_offsets_saw2_v2_1[MSM_SPM_REG_NR] = {
+	[MSM_SPM_REG_SAW2_SECURE]		= 0x00,
+	[MSM_SPM_REG_SAW2_ID]			= 0x04,
+	[MSM_SPM_REG_SAW2_CFG]			= 0x08,
+	[MSM_SPM_REG_SAW2_SPM_STS]		= 0x0C,
+	[MSM_SPM_REG_SAW2_AVS_STS]		= 0x10,
+	[MSM_SPM_REG_SAW2_PMIC_STS]		= 0x14,
+	[MSM_SPM_REG_SAW2_RST]			= 0x18,
+	[MSM_SPM_REG_SAW2_VCTL]			= 0x1C,
+	[MSM_SPM_REG_SAW2_AVS_CTL]		= 0x20,
+	[MSM_SPM_REG_SAW2_AVS_LIMIT]		= 0x24,
+	[MSM_SPM_REG_SAW2_AVS_DLY]		= 0x28,
+	[MSM_SPM_REG_SAW2_AVS_HYSTERESIS]	= 0x2C,
+	[MSM_SPM_REG_SAW2_SPM_CTL]		= 0x30,
+	[MSM_SPM_REG_SAW2_SPM_DLY]		= 0x34,
+	[MSM_SPM_REG_SAW2_PMIC_DATA_0]		= 0x40,
+	[MSM_SPM_REG_SAW2_PMIC_DATA_1]		= 0x44,
+	[MSM_SPM_REG_SAW2_PMIC_DATA_2]		= 0x48,
+	[MSM_SPM_REG_SAW2_PMIC_DATA_3]		= 0x4C,
+	[MSM_SPM_REG_SAW2_PMIC_DATA_4]		= 0x50,
+	[MSM_SPM_REG_SAW2_PMIC_DATA_5]		= 0x54,
+	[MSM_SPM_REG_SAW2_PMIC_DATA_6]		= 0x58,
+	[MSM_SPM_REG_SAW2_PMIC_DATA_7]		= 0x5C,
+	[MSM_SPM_REG_SAW2_SEQ_ENTRY]		= 0x80,
+	[MSM_SPM_REG_SAW2_VERSION]		= 0xFD0,
+};
+
+static void msm_spm_drv_flush_shadow(struct msm_spm_driver_data *dev,
+		unsigned int reg_index)
+{
+	__raw_writel(dev->reg_shadow[reg_index],
+			dev->reg_base_addr + dev->reg_offsets[reg_index]);
+}
+
+static void msm_spm_drv_load_shadow(struct msm_spm_driver_data *dev,
+		unsigned int reg_index)
+{
+	dev->reg_shadow[reg_index] = __raw_readl(dev->reg_base_addr +
+						dev->reg_offsets[reg_index]);
+}
+
+static inline void msm_spm_drv_set_start_addr(
+		struct msm_spm_driver_data *dev, uint32_t addr)
+{
+	addr &= 0x7F;
+	addr <<= 4;
+	dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] &= 0xFFFFF80F;
+	dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] |= addr;
+}
+
+inline int msm_spm_drv_set_spm_enable(
+		struct msm_spm_driver_data *dev, bool enable)
+{
+	uint32_t value = enable ? 0x01 : 0x00;
+
+	if ((dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] & 0x01) ^ value) {
+		dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] &= ~0x1;
+		dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] |= value;
+		msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_SPM_CTL);
+		wmb();
+	}
+
+	return 0;
+}
+
+void msm_spm_drv_flush_seq_entry(struct msm_spm_driver_data *dev)
+{
+	int i;
+
+	for (i = 0; i < NUM_SPM_ENTRY; i++) {
+		__raw_writel(dev->reg_seq_entry_shadow[i],
+			dev->reg_base_addr
+			+ dev->reg_offsets[MSM_SPM_REG_SAW2_SEQ_ENTRY]
+			+ 4 * i);
+	}
+	mb();
+}
+
+/**
+ * msm_spm_drv_write_seq_data - Load the SPM register with sequences
+ *
+ * @dev - The SPM device whose sequences to be programmed
+ * @cmd - The byte array
+ * @offset - The last written byte position, to continue from.
+ */
+int msm_spm_drv_write_seq_data(struct msm_spm_driver_data *dev,
+		uint8_t *cmd, uint32_t *offset)
+{
+	uint32_t cmd_w;
+	uint32_t offset_w = *offset / 4;
+	uint8_t last_cmd;
+
+	while (1) {
+		int i;
+
+		cmd_w = 0;
+		last_cmd = 0;
+		cmd_w = dev->reg_seq_entry_shadow[offset_w];
+
+		for (i = (*offset % 4); i < 4; i++) {
+			last_cmd = *(cmd++);
+			cmd_w |=  last_cmd << (i * 8);
+			(*offset)++;
+			if (last_cmd == 0x0f)
+				break;
+		}
+
+		dev->reg_seq_entry_shadow[offset_w++] = cmd_w;
+		if (last_cmd == 0x0f)
+			break;
+	}
+
+	return 0;
+}
+
+int msm_spm_drv_set_low_power_mode(struct msm_spm_driver_data *dev,
+		uint32_t addr)
+{
+
+	msm_spm_drv_set_start_addr(dev, addr);
+	msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_SPM_CTL);
+	wmb();
+	msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_SPM_STS);
+
+	return 0;
+}
+
+void msm_spm_drv_reinit(struct msm_spm_driver_data *dev)
+{
+	int i;
+
+	msm_spm_drv_flush_seq_entry(dev);
+
+	for (i = MSM_SPM_REG_NR_INITIALIZE + 1; i < MSM_SPM_REG_NR; i++)
+		msm_spm_drv_load_shadow(dev, i);
+}
+
+int msm_spm_drv_init(struct msm_spm_driver_data *dev,
+		struct msm_spm_platform_data *data)
+{
+	dev->reg_base_addr = data->reg_base_addr;
+	memcpy(dev->reg_shadow, data->reg_init_values,
+			sizeof(data->reg_init_values));
+	dev->reg_offsets = msm_spm_reg_offsets_saw2_v2_1;
+	dev->reg_seq_entry_shadow = kcalloc(NUM_SPM_ENTRY,
+					sizeof(*dev->reg_seq_entry_shadow),
+					GFP_KERNEL);
+	if (!dev->reg_seq_entry_shadow)
+		return -ENOMEM;
+
+	return 0;
+}
diff --git a/drivers/soc/qcom/spm_driver.h b/drivers/soc/qcom/spm_driver.h
new file mode 100644
index 0000000..6ff69bb
--- /dev/null
+++ b/drivers/soc/qcom/spm_driver.h
@@ -0,0 +1,85 @@
+/* Copyright (c) 2011-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.
+ */
+#ifndef __QCOM_SPM_DRIVER_H
+#define __QCOM_SPM_DRIVER_H
+
+enum {
+	MSM_SPM_REG_SAW2_CFG,
+	MSM_SPM_REG_SAW2_AVS_CTL,
+	MSM_SPM_REG_SAW2_AVS_HYSTERESIS,
+	MSM_SPM_REG_SAW2_SPM_CTL,
+	MSM_SPM_REG_SAW2_PMIC_DLY,
+	MSM_SPM_REG_SAW2_AVS_LIMIT,
+	MSM_SPM_REG_SAW2_AVS_DLY,
+	MSM_SPM_REG_SAW2_SPM_DLY,
+	MSM_SPM_REG_SAW2_PMIC_DATA_0,
+	MSM_SPM_REG_SAW2_PMIC_DATA_1,
+	MSM_SPM_REG_SAW2_PMIC_DATA_2,
+	MSM_SPM_REG_SAW2_PMIC_DATA_3,
+	MSM_SPM_REG_SAW2_PMIC_DATA_4,
+	MSM_SPM_REG_SAW2_PMIC_DATA_5,
+	MSM_SPM_REG_SAW2_PMIC_DATA_6,
+	MSM_SPM_REG_SAW2_PMIC_DATA_7,
+	MSM_SPM_REG_SAW2_RST,
+
+	MSM_SPM_REG_NR_INITIALIZE = MSM_SPM_REG_SAW2_RST,
+
+	MSM_SPM_REG_SAW2_ID,
+	MSM_SPM_REG_SAW2_SECURE,
+	MSM_SPM_REG_SAW2_STS0,
+	MSM_SPM_REG_SAW2_STS1,
+	MSM_SPM_REG_SAW2_STS2,
+	MSM_SPM_REG_SAW2_VCTL,
+	MSM_SPM_REG_SAW2_SEQ_ENTRY,
+	MSM_SPM_REG_SAW2_SPM_STS,
+	MSM_SPM_REG_SAW2_AVS_STS,
+	MSM_SPM_REG_SAW2_PMIC_STS,
+	MSM_SPM_REG_SAW2_VERSION,
+
+	MSM_SPM_REG_NR,
+};
+
+struct msm_spm_seq_entry {
+	uint32_t mode;
+	uint8_t *cmd;
+};
+
+struct msm_spm_platform_data {
+	void __iomem *reg_base_addr;
+	uint32_t reg_init_values[MSM_SPM_REG_NR_INITIALIZE];
+
+	uint32_t num_modes;
+	struct msm_spm_seq_entry *modes;
+};
+
+struct msm_spm_driver_data {
+	void __iomem *reg_base_addr;
+	uint32_t reg_shadow[MSM_SPM_REG_NR];
+	uint32_t *reg_seq_entry_shadow;
+	uint32_t *reg_offsets;
+	uint32_t num_spm_entry;
+};
+
+int msm_spm_drv_init(struct msm_spm_driver_data *dev,
+		struct msm_spm_platform_data *data);
+void msm_spm_drv_reinit(struct msm_spm_driver_data *dev);
+int msm_spm_drv_set_low_power_mode(struct msm_spm_driver_data *dev,
+		uint32_t addr);
+int msm_spm_drv_write_seq_data(struct msm_spm_driver_data *dev,
+		uint8_t *cmd, uint32_t *offset);
+void msm_spm_drv_flush_seq_entry(struct msm_spm_driver_data *dev);
+int msm_spm_drv_set_spm_enable(struct msm_spm_driver_data *dev,
+		bool enable);
+void msm_spm_reinit(void);
+int msm_spm_init(struct msm_spm_platform_data *data, int nr_devs);
+
+#endif /* __QCOM_SPM_DRIVER_H */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v3 4/8] qcom: spm-devices: Add SPM device manager for the SoC
  2014-08-18 22:23 [PATCH v3 0/8] QCOM 8074 cpuidle driver Lina Iyer
                   ` (2 preceding siblings ...)
  2014-08-18 22:23 ` [PATCH v3 3/8] qcom: spm: Add Subsystem Power Manager driver (SAW2) Lina Iyer
@ 2014-08-18 22:23 ` Lina Iyer
  2014-08-19  9:29   ` Pramod Gurav
  2014-08-18 22:23 ` [PATCH v3 5/8] arm: dts: qcom: Add SPM device bindings for 8974 Lina Iyer
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Lina Iyer @ 2014-08-18 22:23 UTC (permalink / raw
  To: daniel.lezcano, khilman, sboyd, davidb, galak, linux-arm-msm,
	lorenzo.pieralisi
  Cc: msivasub, Lina Iyer, Praveen Chidamabram, Murali Nalajala

Each cpu or an L2$ has an SPM device. They are identical instances of
the same SPM block. This allows for multiple instances be grouped and
managed collectively. spm-devices.c is the SPM device manager managing
multiple SPM devices on top of the driver layer.

Device configuration of each SPM is picked up from the DTS. The hardware
configuration of each of the SPM is handled by the spm.c driver.

Signed-off-by: Praveen Chidamabram <pchidamb@codeaurora.org>
Signed-off-by: Murali Nalajala <mnalajal@codeaurora.org>
Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
---
 Documentation/devicetree/bindings/arm/msm/spm.txt |  47 +++++
 drivers/soc/qcom/Kconfig                          |   8 +
 drivers/soc/qcom/Makefile                         |   2 +-
 drivers/soc/qcom/spm-devices.c                    | 242 ++++++++++++++++++++++
 include/soc/qcom/spm.h                            |  34 +++
 5 files changed, 332 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/arm/msm/spm.txt
 create mode 100644 drivers/soc/qcom/spm-devices.c
 create mode 100644 include/soc/qcom/spm.h

diff --git a/Documentation/devicetree/bindings/arm/msm/spm.txt b/Documentation/devicetree/bindings/arm/msm/spm.txt
new file mode 100644
index 0000000..318e024
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/spm.txt
@@ -0,0 +1,47 @@
+* Subsystem Power Manager (SAW2)
+
+S4 generation of MSMs have SPM hardware blocks to control the Application
+Processor Sub-System power. These SPM blocks run individual state machine
+to determine what the core (L2 or Krait/Scorpion) would do when the WFI
+instruction is executed by the core.
+
+The devicetree representation of the SPM block should be:
+
+Required properties
+
+- compatible: Could be one of -
+		"qcom,spm-v2.1"
+		"qcom,spm-v3.0"
+- reg: The physical address and the size of the SPM's memory mapped registers
+- qcom,cpu: phandle for the CPU that the SPM block is attached to.
+	This field is required on only for SPMs that control the CPU.
+- qcom,saw2-cfg: SAW2 configuration register
+- qcom,saw2-spm-dly: Provides the values for the SPM delay command in the SPM
+	sequence
+- qcom,saw2-spm-ctl: The SPM control register
+
+Optional properties
+
+- qcom,saw2-spm-cmd-wfi: The WFI command sequence
+- qcom,saw2-spm-cmd-ret: The Retention command sequence
+- qcom,saw2-spm-cmd-spc: The Standalone PC command sequence
+- qcom,saw2-spm-cmd-pc: The Power Collapse command sequence. This sequence may
+	turn off other SoC components.
+- qcom,saw2-spm-cmd-gdhs: GDHS (Globally Distributed Head Switch) command
+	sequence. This sequence will retain the memory but turn off the logic.
+-
+Example:
+	spm@f9089000 {
+		compatible = "qcom,spm-v2.1";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0xf9089000 0x1000>;
+		qcom,cpu = <&CPU0>;
+		qcom,saw2-cfg = <0x1>;
+		qcom,saw2-spm-dly= <0x20000400>;
+		qcom,saw2-spm-ctl = <0x1>;
+		qcom,saw2-spm-cmd-wfi = [03 0b 0f];
+		qcom,saw2-spm-cmd-spc = [00 20 50 80 60 70 10 92
+				a0 b0 03 68 70 3b 92 a0 b0
+				82 2b 50 10 30 02 22 30 0f];
+	};
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 7dcd554..1569410 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -11,3 +11,11 @@ config QCOM_GSBI
 
 config QCOM_SCM
 	bool
+
+config QCOM_PM
+	tristate "Qualcomm Power Management"
+	depends on PM && ARCH_QCOM && OF
+	help
+	  QCOM Platform specific power driver to manage cores and L2 low power
+	  modes. It interface with various system drivers to put the cores in
+	  low power modes.
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index 20b329f..9457b2a 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -1,4 +1,4 @@
 obj-$(CONFIG_QCOM_GSBI)	+=	qcom_gsbi.o
-obj-$(CONFIG_QCOM_PM)	+=	spm.o
+obj-$(CONFIG_QCOM_PM)	+=	spm.o spm-devices.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/spm-devices.c b/drivers/soc/qcom/spm-devices.c
new file mode 100644
index 0000000..4f725f8
--- /dev/null
+++ b/drivers/soc/qcom/spm-devices.c
@@ -0,0 +1,242 @@
+/* Copyright (c) 2011-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/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+
+#include <soc/qcom/spm.h>
+
+#include "spm_driver.h"
+
+
+struct msm_spm_power_modes {
+	uint32_t mode;
+	uint32_t start_addr;
+};
+
+struct msm_spm_device {
+	bool initialized;
+	struct msm_spm_driver_data reg_data;
+	struct msm_spm_power_modes *modes;
+	uint32_t num_modes;
+};
+
+static DEFINE_PER_CPU_SHARED_ALIGNED(struct msm_spm_device, msm_cpu_spm_device);
+
+/**
+ * msm_spm_set_low_power_mode() - Configure SPM start address for low power mode
+ * @mode: SPM LPM mode to enter
+ */
+int msm_spm_set_low_power_mode(unsigned int mode)
+{
+	struct msm_spm_device *dev = &__get_cpu_var(msm_cpu_spm_device);
+	uint32_t i;
+	uint32_t start_addr = 0;
+	int ret = -EINVAL;
+
+	if (!dev->initialized)
+		return -ENXIO;
+
+	if (mode == MSM_SPM_MODE_DISABLED) {
+		ret = msm_spm_drv_set_spm_enable(&dev->reg_data, false);
+	} else if (!msm_spm_drv_set_spm_enable(&dev->reg_data, true)) {
+		for (i = 0; i < dev->num_modes; i++) {
+			if (dev->modes[i].mode == mode) {
+				start_addr = dev->modes[i].start_addr;
+				break;
+			}
+		}
+		ret = msm_spm_drv_set_low_power_mode(&dev->reg_data,
+					start_addr);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(msm_spm_set_low_power_mode);
+
+static int get_cpu_id(struct device_node *node)
+{
+	struct device_node *cpu_node;
+	u32 cpu;
+	int ret = -EINVAL;
+	char *key = "qcom,cpu";
+
+	cpu_node = of_parse_phandle(node, key, 0);
+	if (cpu_node) {
+		for_each_possible_cpu(cpu) {
+			if (of_get_cpu_node(cpu, NULL) == cpu_node)
+				return cpu;
+		}
+	}
+	return ret;
+}
+
+static struct msm_spm_device *msm_spm_get_device(struct platform_device *pdev)
+{
+	struct msm_spm_device *dev = NULL;
+	int cpu = get_cpu_id(pdev->dev.of_node);
+
+	if ((cpu >= 0) && cpu < num_possible_cpus())
+		dev = &per_cpu(msm_cpu_spm_device, cpu);
+
+	return dev;
+}
+
+static int msm_spm_dev_init(struct msm_spm_device *dev,
+		struct msm_spm_platform_data *data)
+{
+	int i;
+	int ret = -ENOMEM;
+	uint32_t offset = 0;
+
+	dev->num_modes = data->num_modes;
+	dev->modes = kcalloc(dev->num_modes,
+				sizeof(struct msm_spm_power_modes),
+				GFP_KERNEL);
+	if (!dev->modes)
+		return ret;
+
+	ret = msm_spm_drv_init(&dev->reg_data, data);
+	if (ret) {
+		kfree(dev->modes);
+		return ret;
+	}
+
+	for (i = 0; i < dev->num_modes; i++) {
+		dev->modes[i].start_addr = offset;
+		dev->modes[i].mode = data->modes[i].mode;
+		msm_spm_drv_write_seq_data(&dev->reg_data, data->modes[i].cmd,
+						&offset);
+	}
+
+	msm_spm_drv_reinit(&dev->reg_data);
+	dev->initialized = true;
+
+	return 0;
+}
+
+static int msm_spm_dev_probe(struct platform_device *pdev)
+{
+	int ret;
+	int i;
+	struct device_node *node = pdev->dev.of_node;
+	struct msm_spm_platform_data spm_data;
+	char *key;
+	uint32_t val;
+	struct msm_spm_seq_entry modes[MSM_SPM_MODE_NR];
+	struct msm_spm_device *dev;
+	struct resource *res;
+	uint32_t mode_count = 0;
+
+	struct spm_of {
+		char *key;
+		uint32_t id;
+	};
+
+	/* SPM Configuration registers */
+	struct spm_of spm_of_data[] = {
+		{"qcom,saw2-clk-div", MSM_SPM_REG_SAW2_CFG},
+		{"qcom,saw2-enable", MSM_SPM_REG_SAW2_SPM_CTL},
+		{"qcom,saw2-delays", MSM_SPM_REG_SAW2_SPM_DLY},
+	};
+
+	/* SPM sleep sequences */
+	struct spm_of mode_of_data[] = {
+		{"qcom,saw2-spm-cmd-wfi", MSM_SPM_MODE_CLOCK_GATING},
+		{"qcom,saw2-spm-cmd-spc", MSM_SPM_MODE_POWER_COLLAPSE},
+		{"qcom,saw2-spm-cmd-ret", MSM_SPM_MODE_RETENTION},
+	};
+
+	 /* Get the right SPM device */
+	dev = msm_spm_get_device(pdev);
+	if (IS_ERR_OR_NULL(dev))
+		return -EINVAL;
+
+	memset(&spm_data, 0, sizeof(struct msm_spm_platform_data));
+	memset(&modes, 0,
+		(MSM_SPM_MODE_NR - 2) * sizeof(struct msm_spm_seq_entry));
+
+	/* Get the SAW start address */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -EINVAL;
+		goto fail;
+	}
+	spm_data.reg_base_addr = devm_ioremap(&pdev->dev, res->start,
+					resource_size(res));
+	if (!spm_data.reg_base_addr) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	/* Read the SPM configuration register values */
+	for (i = 0; i < ARRAY_SIZE(spm_of_data); i++) {
+		ret = of_property_read_u32(node, spm_of_data[i].key, &val);
+		if (ret)
+			continue;
+		spm_data.reg_init_values[spm_of_data[i].id] = val;
+	}
+
+	/* Read the byte arrays for the SPM sleep sequences */
+	for (i = 0; i < ARRAY_SIZE(mode_of_data); i++) {
+		key = mode_of_data[i].key;
+		modes[mode_count].cmd =
+			(uint8_t *)of_get_property(node, key, &val);
+		if (!modes[mode_count].cmd)
+			continue;
+		modes[mode_count].mode = mode_of_data[i].id;
+		mode_count++;
+	}
+	spm_data.modes = modes;
+	spm_data.num_modes = mode_count;
+
+	/* Initialize the hardware */
+	ret = msm_spm_dev_init(dev, &spm_data);
+	if (ret)
+		goto fail;
+
+	platform_set_drvdata(pdev, dev);
+	return ret;
+
+fail:
+	dev_err(&pdev->dev, "SPM device probe failed: %d\n", ret);
+	return ret;
+}
+
+static struct of_device_id msm_spm_match_table[] = {
+	{.compatible = "qcom,spm-v2.1"},
+	{},
+};
+
+static struct platform_driver msm_spm_device_driver = {
+	.probe = msm_spm_dev_probe,
+	.driver = {
+		.name = "spm-v2",
+		.owner = THIS_MODULE,
+		.of_match_table = msm_spm_match_table,
+	},
+};
+
+static int __init msm_spm_device_init(void)
+{
+	return platform_driver_register(&msm_spm_device_driver);
+}
+device_initcall(msm_spm_device_init);
diff --git a/include/soc/qcom/spm.h b/include/soc/qcom/spm.h
new file mode 100644
index 0000000..99a1d12
--- /dev/null
+++ b/include/soc/qcom/spm.h
@@ -0,0 +1,34 @@
+/* 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.
+ */
+
+#ifndef __QCOM_SPM_H
+#define __QCOM_SPM_H
+
+enum {
+	MSM_SPM_MODE_DISABLED,
+	MSM_SPM_MODE_CLOCK_GATING,
+	MSM_SPM_MODE_RETENTION,
+	MSM_SPM_MODE_GDHS,
+	MSM_SPM_MODE_POWER_COLLAPSE,
+	MSM_SPM_MODE_NR
+};
+
+struct msm_spm_device;
+
+#if defined(CONFIG_QCOM_PM)
+int msm_spm_set_low_power_mode(unsigned int mode);
+#else /* defined(CONFIG_QCOM_PM) */
+static inline int msm_spm_set_low_power_mode(unsigned int mode)
+{ return -ENOSYS; }
+#endif  /* defined (CONFIG_QCOM_PM) */
+
+#endif  /* __QCOM_SPM_H */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v3 5/8] arm: dts: qcom: Add SPM device bindings for 8974
  2014-08-18 22:23 [PATCH v3 0/8] QCOM 8074 cpuidle driver Lina Iyer
                   ` (3 preceding siblings ...)
  2014-08-18 22:23 ` [PATCH v3 4/8] qcom: spm-devices: Add SPM device manager for the SoC Lina Iyer
@ 2014-08-18 22:23 ` Lina Iyer
  2014-08-18 22:23 ` [PATCH v3 6/8] qcom: msm-pm: Add cpu low power mode functions Lina Iyer
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Lina Iyer @ 2014-08-18 22:23 UTC (permalink / raw
  To: daniel.lezcano, khilman, sboyd, davidb, galak, linux-arm-msm,
	lorenzo.pieralisi
  Cc: msivasub, Lina Iyer, Praveen Chidambaram

Add SPM device bindings for QCOM 8974 based cpus. SPM is the sub-system
power manager and controls the logic around the cores (cpu and L2).

Each core has an instance of SPM and controls only that core. Each cpu
SPM is configured to support WFI and SPC (standalone-power collapse) and
L2 can do retention (clock-gating).

Signed-off-by: Praveen Chidambaram <pchidamb@codeaurora.org>
Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
---
 arch/arm/boot/dts/qcom-msm8974-pm.dtsi | 69 ++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/qcom-msm8974.dtsi    | 10 +++--
 2 files changed, 75 insertions(+), 4 deletions(-)
 create mode 100644 arch/arm/boot/dts/qcom-msm8974-pm.dtsi

diff --git a/arch/arm/boot/dts/qcom-msm8974-pm.dtsi b/arch/arm/boot/dts/qcom-msm8974-pm.dtsi
new file mode 100644
index 0000000..bbfb1d5
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-msm8974-pm.dtsi
@@ -0,0 +1,69 @@
+/* Copyright (c) 2013-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.
+ */
+
+&soc {
+	spm@f9089000 {
+		compatible = "qcom,spm-v2.1";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0xf9089000 0x1000>;
+		qcom,cpu = <&CPU0>;
+		qcom,saw2-clk-div = <0x01>;
+		qcom,saw2-delays = <0x3C102800>;
+		qcom,saw2-enable = <0x01>;
+		qcom,saw2-spm-cmd-wfi = [03 0b 0f];
+		qcom,saw2-spm-cmd-spc = [00 20 80 10 E8 5B 03 3B E8 5B 82 10 0B
+			30 06 26 30 0F];
+	};
+
+	spm@f9099000 {
+		compatible = "qcom,spm-v2.1";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0xf9099000 0x1000>;
+		qcom,cpu = <&CPU1>;
+		qcom,saw2-clk-div = <0x01>;
+		qcom,saw2-delays = <0x3C102800>;
+		qcom,saw2-enable = <0x01>;
+		qcom,saw2-spm-cmd-wfi = [03 0b 0f];
+		qcom,saw2-spm-cmd-spc = [00 20 80 10 E8 5B 03 3B E8 5B 82 10 0B
+			30 06 26 30 0F];
+	};
+
+	spm@f90a9000 {
+		compatible = "qcom,spm-v2.1";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0xf90a9000 0x1000>;
+		qcom,cpu = <&CPU2>;
+		qcom,saw2-clk-div = <0x01>;
+		qcom,saw2-delays = <0x3C102800>;
+		qcom,saw2-enable = <0x01>;
+		qcom,saw2-spm-cmd-wfi = [03 0b 0f];
+		qcom,saw2-spm-cmd-spc = [00 20 80 10 E8 5B 03 3B E8 5B 82 10 0B
+			30 06 26 30 0F];
+	};
+
+	spm@f90b9000 {
+		compatible = "qcom,spm-v2.1";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0xf90b9000 0x1000>;
+		qcom,cpu = <&CPU3>;
+		qcom,saw2-clk-div = <0x01>;
+		qcom,saw2-delays = <0x3C102800>;
+		qcom,saw2-enable = <0x01>;
+		qcom,saw2-spm-cmd-wfi = [03 0b 0f];
+		qcom,saw2-spm-cmd-spc = [00 20 80 10 E8 5B 03 3B E8 5B 82 10 0B
+			30 06 26 30 0F];
+	};
+};
diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 69dca2a..0580bc2 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -14,7 +14,7 @@
 		#size-cells = <0>;
 		interrupts = <1 9 0xf04>;
 
-		cpu@0 {
+		CPU0: cpu@0 {
 			compatible = "qcom,krait";
 			enable-method = "qcom,kpss-acc-v2";
 			device_type = "cpu";
@@ -23,7 +23,7 @@
 			qcom,acc = <&acc0>;
 		};
 
-		cpu@1 {
+		CPU1: cpu@1 {
 			compatible = "qcom,krait";
 			enable-method = "qcom,kpss-acc-v2";
 			device_type = "cpu";
@@ -32,7 +32,7 @@
 			qcom,acc = <&acc1>;
 		};
 
-		cpu@2 {
+		CPU2: cpu@2 {
 			compatible = "qcom,krait";
 			enable-method = "qcom,kpss-acc-v2";
 			device_type = "cpu";
@@ -41,7 +41,7 @@
 			qcom,acc = <&acc2>;
 		};
 
-		cpu@3 {
+		CPU3: cpu@3 {
 			compatible = "qcom,krait";
 			enable-method = "qcom,kpss-acc-v2";
 			device_type = "cpu";
@@ -238,3 +238,5 @@
 		};
 	};
 };
+
+#include "qcom-msm8974-pm.dtsi"
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v3 6/8] qcom: msm-pm: Add cpu low power mode functions
  2014-08-18 22:23 [PATCH v3 0/8] QCOM 8074 cpuidle driver Lina Iyer
                   ` (4 preceding siblings ...)
  2014-08-18 22:23 ` [PATCH v3 5/8] arm: dts: qcom: Add SPM device bindings for 8974 Lina Iyer
@ 2014-08-18 22:23 ` Lina Iyer
  2014-08-18 22:23 ` [PATCH v3 7/8] qcom: cpuidle: Add cpuidle driver for QCOM cpus Lina Iyer
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Lina Iyer @ 2014-08-18 22:23 UTC (permalink / raw
  To: daniel.lezcano, khilman, sboyd, davidb, galak, linux-arm-msm,
	lorenzo.pieralisi
  Cc: msivasub, Lina Iyer, Venkat Devarasetty, Mahesh Sivasubramanian

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 | 117 ++++++++++++++++++++++++++++++++++++++++++++++
 include/soc/qcom/pm.h     |  38 +++++++++++++++
 3 files changed, 156 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 9457b2a..acdd6fa 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -1,4 +1,4 @@
 obj-$(CONFIG_QCOM_GSBI)	+=	qcom_gsbi.o
-obj-$(CONFIG_QCOM_PM)	+=	spm.o spm-devices.o
+obj-$(CONFIG_QCOM_PM)	+=	spm.o spm-devices.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..5a984e3
--- /dev/null
+++ b/drivers/soc/qcom/msm-pm.c
@@ -0,0 +1,117 @@
+/* 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/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_FLUSH_FLAG_MASK	(0x3)
+
+static int msm_pm_collapse(unsigned long unused)
+{
+	enum msm_pm_l2_scm_flag flag;
+
+	flag = MSM_SCM_L2_ON & SCM_FLUSH_FLAG_MASK;
+	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 int do_power_down(void)
+{
+	int ret;
+
+	cpu_pm_enter();
+
+	msm_spm_set_low_power_mode(MSM_SPM_MODE_POWER_COLLAPSE);
+	set_up_boot_address(cpu_resume, raw_smp_processor_id());
+	ret = cpu_suspend(0, msm_pm_collapse);
+
+	cpu_pm_exit();
+
+	return ret;
+}
+
+static inline int do_idle(void)
+{
+	msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING);
+
+	/* Flush and clock-gate */
+	mb();
+	wfi();
+
+	return 0;
+}
+
+/**
+ * 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.
+ *
+ */
+int msm_cpu_pm_enter_sleep(enum msm_pm_sleep_mode mode, bool from_idle)
+{
+	int ret;
+
+	switch (mode) {
+	case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE:
+		ret = do_power_down();
+		break;
+	default:
+	case MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT:
+		ret = do_idle();
+		break;
+	}
+
+	local_irq_enable();
+
+	return ret;
+}
+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..7563e09
--- /dev/null
+++ b/include/soc/qcom/pm.h
@@ -0,0 +1,38 @@
+/*
+ * 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_POWER_COLLAPSE_STANDALONE,
+	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
+int msm_cpu_pm_enter_sleep(enum msm_pm_sleep_mode mode, bool from_idle);
+#else
+static inline int msm_cpu_pm_enter_sleep(enum msm_pm_sleep_mode mode,
+						bool from_idle)
+{ return -ENODEV; }
+#endif
+
+#endif  /* __QCOM_PM_H */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v3 7/8] qcom: cpuidle: Add cpuidle driver for QCOM cpus
  2014-08-18 22:23 [PATCH v3 0/8] QCOM 8074 cpuidle driver Lina Iyer
                   ` (5 preceding siblings ...)
  2014-08-18 22:23 ` [PATCH v3 6/8] qcom: msm-pm: Add cpu low power mode functions Lina Iyer
@ 2014-08-18 22:23 ` Lina Iyer
  2014-08-19  7:41   ` Pramod Gurav
  2014-08-18 22:23 ` [PATCH v3 8/8] arm: dts: qcom: Add idle states device nodes for 8974 Lina Iyer
  2014-08-19 15:30 ` [PATCH v3 0/8] QCOM 8074 cpuidle driver Lina Iyer
  8 siblings, 1 reply; 21+ messages in thread
From: Lina Iyer @ 2014-08-18 22:23 UTC (permalink / raw
  To: daniel.lezcano, khilman, sboyd, davidb, galak, linux-arm-msm,
	lorenzo.pieralisi
  Cc: msivasub, Lina Iyer

Add cpuidle driver interface to allow cpus to go into C-States.
Use the cpuidle DT interfacecommon across ARM architectures to provide
the C-State information to the cpuidle framework.

Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
---
 drivers/cpuidle/Kconfig.arm    |   7 +++
 drivers/cpuidle/Makefile       |   1 +
 drivers/cpuidle/cpuidle-qcom.c | 119 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 127 insertions(+)
 create mode 100644 drivers/cpuidle/cpuidle-qcom.c

diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index e339c7f..26e31bd 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -63,3 +63,10 @@ config ARM_MVEBU_V7_CPUIDLE
 	depends on ARCH_MVEBU
 	help
 	  Select this to enable cpuidle on Armada 370, 38x and XP processors.
+
+config ARM_QCOM_CPUIDLE
+	bool "CPU Idle drivers for Qualcomm processors"
+	depends on QCOM_PM
+	select DT_IDLE_STATES
+	help
+	  Select this to enable cpuidle for QCOM processors
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 4d177b9..6c222d5 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_ARM_ZYNQ_CPUIDLE)		+= cpuidle-zynq.o
 obj-$(CONFIG_ARM_U8500_CPUIDLE)         += cpuidle-ux500.o
 obj-$(CONFIG_ARM_AT91_CPUIDLE)          += cpuidle-at91.o
 obj-$(CONFIG_ARM_EXYNOS_CPUIDLE)        += cpuidle-exynos.o
+obj-$(CONFIG_ARM_QCOM_CPUIDLE)		+= cpuidle-qcom.o
 
 ###############################################################################
 # MIPS drivers
diff --git a/drivers/cpuidle/cpuidle-qcom.c b/drivers/cpuidle/cpuidle-qcom.c
new file mode 100644
index 0000000..4aae672
--- /dev/null
+++ b/drivers/cpuidle/cpuidle-qcom.c
@@ -0,0 +1,119 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, Linaro Limited.
+ *
+ * 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/platform_device.h>
+#include <linux/of.h>
+#include <linux/cpuidle.h>
+#include <linux/cpumask.h>
+#include <linux/slab.h>
+#include <linux/of_device.h>
+
+#include <soc/qcom/pm.h>
+#include "dt_idle_states.h"
+
+static enum msm_pm_sleep_mode modes[CPUIDLE_STATE_MAX];
+
+static int qcom_lpm_enter(struct cpuidle_device *dev,
+				struct cpuidle_driver *drv, int index)
+{
+	return msm_cpu_pm_enter_sleep(modes[index], true);
+}
+
+static struct cpuidle_driver qcom_cpuidle_driver = {
+	.name	= "qcom_cpuidle",
+	.owner	= THIS_MODULE,
+};
+
+static void parse_state_translations(struct cpuidle_driver *drv)
+{
+	struct device_node *state_node, *cpu_node;
+	const char *mode_name;
+	int i, j;
+
+	struct name_map {
+		enum msm_pm_sleep_mode mode;
+		char *name;
+	};
+	static struct name_map c_states[] = {
+		{ MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE,
+						"standalone-pc" },
+		{ MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT, "wfi" },
+	};
+
+	cpu_node = of_cpu_device_node_get(cpumask_first(drv->cpumask));
+	if (!cpu_node)
+		return;
+
+	/**
+	 * Get the state description from idle-state node entry-method
+	 * First state is always WFI, per spec.
+	 */
+	modes[0] = MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT;
+	for (i = 1; i < drv->state_count; i++) {
+		mode_name = NULL;
+		state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
+		of_property_read_string(state_node, "entry-method",
+						&mode_name);
+		for (j = 0; mode_name && (j < ARRAY_SIZE(c_states)); j++) {
+			if (!strcmp(mode_name, c_states[j].name)) {
+				modes[i] = c_states[j].mode;
+				break;
+			}
+		}
+	}
+}
+
+static int qcom_cpuidle_init(void)
+{
+	struct cpuidle_driver *drv = &qcom_cpuidle_driver;
+	int ret;
+	int i;
+
+	drv->cpumask = kzalloc(cpumask_size(), GFP_KERNEL);
+	if (!drv->cpumask)
+		return -ENOMEM;
+	cpumask_copy(drv->cpumask, cpu_possible_mask);
+
+	/**
+	 * Default to standard for WFI (index = 0)
+	 * Probe only for other states
+	 */
+	ret = dt_init_idle_driver(drv, 1);
+	if (ret < 0) {
+		pr_err("%s: failed to initialize idle states\n", __func__);
+		goto failed;
+	}
+
+	/* Parse the idle states for C-States on this cpu */
+	parse_state_translations(drv);
+
+	/* Register entry point for all low states */
+	for (i = 0; i < drv->state_count; i++)
+		drv->states[i].enter = qcom_lpm_enter;
+	drv->safe_state_index = 0;
+
+	ret = cpuidle_register(drv, NULL);
+	if (ret) {
+		pr_err("%s: failed to register cpuidle driver\n", __func__);
+		goto failed;
+	}
+
+	return 0;
+
+failed:
+	kfree(drv->cpumask);
+	return ret;
+}
+module_init(qcom_cpuidle_init);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v3 8/8] arm: dts: qcom: Add idle states device nodes for 8974
  2014-08-18 22:23 [PATCH v3 0/8] QCOM 8074 cpuidle driver Lina Iyer
                   ` (6 preceding siblings ...)
  2014-08-18 22:23 ` [PATCH v3 7/8] qcom: cpuidle: Add cpuidle driver for QCOM cpus Lina Iyer
@ 2014-08-18 22:23 ` Lina Iyer
  2014-08-19 15:30 ` [PATCH v3 0/8] QCOM 8074 cpuidle driver Lina Iyer
  8 siblings, 0 replies; 21+ messages in thread
From: Lina Iyer @ 2014-08-18 22:23 UTC (permalink / raw
  To: daniel.lezcano, khilman, sboyd, davidb, galak, linux-arm-msm,
	lorenzo.pieralisi
  Cc: msivasub, Lina Iyer

Add allowable C-States for each cpu using the cpu-idle-states node.
ARM spec dictates WFI as the default idle state at 0. Support standalone
power collapse (power down that does not affect any SoC idle states) for
each cpu.

Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
---
 arch/arm/boot/dts/qcom-msm8974.dtsi | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 0580bc2..fd66afb 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -21,6 +21,7 @@
 			reg = <0>;
 			next-level-cache = <&L2>;
 			qcom,acc = <&acc0>;
+			cpu-idle-states = <&CPU_SPC>;
 		};
 
 		CPU1: cpu@1 {
@@ -30,6 +31,7 @@
 			reg = <1>;
 			next-level-cache = <&L2>;
 			qcom,acc = <&acc1>;
+			cpu-idle-states = <&CPU_SPC>;
 		};
 
 		CPU2: cpu@2 {
@@ -39,6 +41,7 @@
 			reg = <2>;
 			next-level-cache = <&L2>;
 			qcom,acc = <&acc2>;
+			cpu-idle-states = <&CPU_SPC>;
 		};
 
 		CPU3: cpu@3 {
@@ -48,6 +51,7 @@
 			reg = <3>;
 			next-level-cache = <&L2>;
 			qcom,acc = <&acc3>;
+			cpu-idle-states = <&CPU_SPC>;
 		};
 
 		L2: l2-cache {
@@ -55,6 +59,16 @@
 			cache-level = <2>;
 			qcom,saw = <&saw_l2>;
 		};
+
+		idle-states {
+			CPU_SPC: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				entry-latency-us = <150>;
+				exit-latency-us = <200>;
+				min-residency-us = <2000>;
+				entry-method = "standalone-pc";
+			};
+		};
 	};
 
 	cpu-pmu {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 7/8] qcom: cpuidle: Add cpuidle driver for QCOM cpus
  2014-08-18 22:23 ` [PATCH v3 7/8] qcom: cpuidle: Add cpuidle driver for QCOM cpus Lina Iyer
@ 2014-08-19  7:41   ` Pramod Gurav
  2014-08-19 14:54     ` Lina Iyer
  0 siblings, 1 reply; 21+ messages in thread
From: Pramod Gurav @ 2014-08-19  7:41 UTC (permalink / raw
  To: Lina Iyer
  Cc: daniel.lezcano, khilman, sboyd, davidb, galak, linux-arm-msm,
	lorenzo.pieralisi, msivasub

Hi Lina,

Compilation breaks while I try to compile these driver. Find below the
comments.

On Tuesday 19 August 2014 03:53 AM, Lina Iyer wrote:
> Add cpuidle driver interface to allow cpus to go into C-States.
> Use the cpuidle DT interfacecommon across ARM architectures to provide
> the C-State information to the cpuidle framework.
> 
> Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
> ---
>  drivers/cpuidle/Kconfig.arm    |   7 +++
>  drivers/cpuidle/Makefile       |   1 +
>  drivers/cpuidle/cpuidle-qcom.c | 119 +++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 127 insertions(+)
>  create mode 100644 drivers/cpuidle/cpuidle-qcom.c
> 
> diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
> index e339c7f..26e31bd 100644
> --- a/drivers/cpuidle/Kconfig.arm
> +++ b/drivers/cpuidle/Kconfig.arm
> @@ -63,3 +63,10 @@ config ARM_MVEBU_V7_CPUIDLE
>  	depends on ARCH_MVEBU
>  	help
>  	  Select this to enable cpuidle on Armada 370, 38x and XP processors.
> +
> +config ARM_QCOM_CPUIDLE
> +	bool "CPU Idle drivers for Qualcomm processors"
> +	depends on QCOM_PM
> +	select DT_IDLE_STATES
I see no reference to this in any patch? Moreover it was not there in
v2. Anything new that you missed to add?
> +	help
> +	  Select this to enable cpuidle for QCOM processors
> diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
> index 4d177b9..6c222d5 100644
> --- a/drivers/cpuidle/Makefile
> +++ b/drivers/cpuidle/Makefile
> @@ -17,6 +17,7 @@ obj-$(CONFIG_ARM_ZYNQ_CPUIDLE)		+= cpuidle-zynq.o
>  obj-$(CONFIG_ARM_U8500_CPUIDLE)         += cpuidle-ux500.o
>  obj-$(CONFIG_ARM_AT91_CPUIDLE)          += cpuidle-at91.o
>  obj-$(CONFIG_ARM_EXYNOS_CPUIDLE)        += cpuidle-exynos.o
> +obj-$(CONFIG_ARM_QCOM_CPUIDLE)		+= cpuidle-qcom.o
>  
>  ###############################################################################
>  # MIPS drivers
> diff --git a/drivers/cpuidle/cpuidle-qcom.c b/drivers/cpuidle/cpuidle-qcom.c
> new file mode 100644
> index 0000000..4aae672
> --- /dev/null
> +++ b/drivers/cpuidle/cpuidle-qcom.c
> @@ -0,0 +1,119 @@
> +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
> + * Copyright (c) 2014, Linaro Limited.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU G./8.patch:226:+eneral 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/platform_device.h>
> +#include <linux/of.h>
> +#include <linux/cpuidle.h>
> +#include <linux/cpumask.h>
> +#include <linux/slab.h>
> +#include <linux/of_device.h>
> +
> +#include <soc/qcom/pm.h>
> +#include "dt_idle_states.h"
Did you miss to commit this file? Compilation fails as this file is nowhere.

> +
> +static enum msm_pm_sleep_mode modes[CPUIDLE_STATE_MAX];
> +
> +static int qcom_lpm_enter(struct cpuidle_device *dev,
> +				struct cpuidle_driver *drv, int index)
> +{
> +	return msm_cpu_pm_enter_sleep(modes[index], true);
> +}
> +
> +static struct cpuidle_driver qcom_cpuidle_driver = {
> +	.name	= "qcom_cpuidle",
> +	.owner	= THIS_MODULE,
> +};
> +
> +static void parse_state_translations(struct cpuidle_driver *drv)
> +{
> +	struct device_node *state_node, *cpu_node;
> +	const char *mode_name;
> +	int i, j;
> +
> +	struct name_map {
> +		enum msm_pm_sleep_mode mode;
> +		char *name;
> +	};
> +	static struct name_map c_states[] = {
> +		{ MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE,
> +						"standalone-pc" },
> +		{ MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT, "wfi" },
> +	};
> +
> +	cpu_node = of_cpu_device_node_get(cpumask_first(drv->cpumask));
> +	if (!cpu_node)
> +		return;
> +
> +	/**
> +	 * Get the state description from idle-state node entry-method
> +	 * First state is always WFI, per spec.
> +	 */
> +	modes[0] = MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT;
> +	for (i = 1; i < drv->state_count; i++) {
> +		mode_name = NULL;
> +		state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
> +		of_property_read_string(state_node, "entry-method",
> +						&mode_name);
> +		for (j = 0; mode_name && (j < ARRAY_SIZE(c_states)); j++) {
> +			if (!strcmp(mode_name, c_states[j].name)) {
> +				modes[i] = c_states[j].mode;
> +				break;
> +			}
> +		}
> +	}
> +}
> +
> +static int qcom_cpuidle_init(void)
> +{
> +	struct cpuidle_driver *drv = &qcom_cpuidle_driver;
> +	int ret;
> +	int i;
> +
> +	drv->cpumask = kzalloc(cpumask_size(), GFP_KERNEL);
> +	if (!drv->cpumask)
> +		return -ENOMEM;
> +	cpumask_copy(drv->cpumask, cpu_possible_mask);
> +
> +	/**
> +	 * Default to standard for WFI (index = 0)
> +	 * Probe only for other states
> +	 */
> +	ret = dt_init_idle_driver(drv, 1);
There is no reference to this function as well.
> +	if (ret < 0) {
> +		pr_err("%s: failed to initialize idle states\n", __func__);
> +		goto failed;
> +	}
> +
> +	/* Parse the idle states for C-States on this cpu */
> +	parse_state_translations(drv);
> +
> +	/* Register entry point for all low states */
> +	for (i = 0; i < drv->state_count; i++)
> +		drv->states[i].enter = qcom_lpm_enter;
> +	drv->safe_state_index = 0;
> +
> +	ret = cpuidle_register(drv, NULL);
> +	if (ret) {
> +		pr_err("%s: failed to register cpuidle driver\n", __func__);
> +		goto failed;
> +	}
> +
> +	return 0;
> +
> +failed:
> +	kfree(drv->cpumask);
> +	return ret;
> +}
> +module_init(qcom_cpuidle_init);
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 4/8] qcom: spm-devices: Add SPM device manager for the SoC
  2014-08-18 22:23 ` [PATCH v3 4/8] qcom: spm-devices: Add SPM device manager for the SoC Lina Iyer
@ 2014-08-19  9:29   ` Pramod Gurav
  2014-08-19 14:51     ` Lina Iyer
  0 siblings, 1 reply; 21+ messages in thread
From: Pramod Gurav @ 2014-08-19  9:29 UTC (permalink / raw
  To: Lina Iyer
  Cc: daniel.lezcano, khilman, sboyd, davidb, galak, linux-arm-msm,
	lorenzo.pieralisi, msivasub, Praveen Chidamabram, Murali Nalajala

Hi Lina,

On Tuesday 19 August 2014 03:53 AM, Lina Iyer wrote:
> +
> +config QCOM_PM
> +	tristate "Qualcomm Power Management"
This does not compile as a module. making CONFIG_QCOM_PM=m causing
redefinition of function 'msm_spm_set_low_power_mode' in header.

drivers/soc/qcom/spm-devices.c:48:5: error: redefinition of
‘msm_spm_set_low_power_mode’
In file included from drivers/soc/qcom/spm-devices.c:25:0:
include/soc/qcom/spm.h:30:19: note: previous definition of
‘msm_spm_set_low_power_mode’ was here


> +	depends on PM && ARCH_QCOM && OF
> +	help
> +	  QCOM Platform specific power driver to manage cores and L2 low power
> +	  modes. It interface with various system drivers to put the cores in
> +	  low power modes.
> diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
> index 20b329f..9457b2a 100644
> --- a/drivers/soc/qcom/Makefile
> +++ b/drivers/soc/qcom/Makefile
> @@ -1,4 +1,4 @@
>  obj-$(CONFIG_QCOM_GSBI)	+=	qcom_gsbi.o
> -obj-$(CONFIG_QCOM_PM)	+=	spm.o
> +obj-$(CONFIG_QCOM_PM)	+=	spm.o spm-devices.o
>  CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
>  obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 3/8] qcom: spm: Add Subsystem Power Manager driver (SAW2)
  2014-08-18 22:23 ` [PATCH v3 3/8] qcom: spm: Add Subsystem Power Manager driver (SAW2) Lina Iyer
@ 2014-08-19 14:07   ` Kumar Gala
  2014-08-19 15:28     ` Lina Iyer
  0 siblings, 1 reply; 21+ messages in thread
From: Kumar Gala @ 2014-08-19 14:07 UTC (permalink / raw
  To: Lina Iyer
  Cc: daniel.lezcano, khilman, sboyd, davidb, linux-arm-msm,
	lorenzo.pieralisi, msivasub, Praveen Chidambaram


On Aug 18, 2014, at 5:23 PM, Lina Iyer <lina.iyer@linaro.org> wrote:

> SPM is a hardware block that controls the peripheral logic surrounding
> the application cores (cpu/l$). When the core executes WFI instruction,
> the SPM takes over the putting the core in low power state as
> configured. The wake up for the SPM is an interrupt at the GIC, which
> then completes the rest of low power mode sequence and brings the core
> out of low power mode.
> 
> Allow drivers to configure the idle mode for the cores in the SPM start
> address register.

What is the ‘start address’?

Can we add anything about ‘start address’ and the sequences in the commit message?

> 
> Signed-off-by: Praveen Chidambaram <pchidamb@codeaurora.org>
> Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
> ---
> drivers/soc/qcom/Makefile     |   1 +
> drivers/soc/qcom/spm.c        | 176 ++++++++++++++++++++++++++++++++++++++++++
> drivers/soc/qcom/spm_driver.h |  85 ++++++++++++++++++++
> 3 files changed, 262 insertions(+)
> create mode 100644 drivers/soc/qcom/spm.c
> create mode 100644 drivers/soc/qcom/spm_driver.h
> 
> diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
> index 70d52ed..20b329f 100644
> --- a/drivers/soc/qcom/Makefile
> +++ b/drivers/soc/qcom/Makefile
> @@ -1,3 +1,4 @@
> obj-$(CONFIG_QCOM_GSBI)	+=	qcom_gsbi.o
> +obj-$(CONFIG_QCOM_PM)	+=	spm.o
> CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
> obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o

We should have the Kconfig that adds QCOM_PM as part of this patch so it actual is buildable.

> diff --git a/drivers/soc/qcom/spm.c b/drivers/soc/qcom/spm.c
> new file mode 100644
> index 0000000..3e1de43
> --- /dev/null
> +++ b/drivers/soc/qcom/spm.c
> @@ -0,0 +1,176 @@
> +/* Copyright (c) 2011-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/delay.h>
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/slab.h>
> +
> +#include "spm_driver.h"
> +
> +#define NUM_SPM_ENTRY 32
> +
> +static uint32_t msm_spm_reg_offsets_saw2_v2_1[MSM_SPM_REG_NR] = {
> +	[MSM_SPM_REG_SAW2_SECURE]		= 0x00,
> +	[MSM_SPM_REG_SAW2_ID]			= 0x04,
> +	[MSM_SPM_REG_SAW2_CFG]			= 0x08,
> +	[MSM_SPM_REG_SAW2_SPM_STS]		= 0x0C,
> +	[MSM_SPM_REG_SAW2_AVS_STS]		= 0x10,
> +	[MSM_SPM_REG_SAW2_PMIC_STS]		= 0x14,
> +	[MSM_SPM_REG_SAW2_RST]			= 0x18,
> +	[MSM_SPM_REG_SAW2_VCTL]			= 0x1C,
> +	[MSM_SPM_REG_SAW2_AVS_CTL]		= 0x20,
> +	[MSM_SPM_REG_SAW2_AVS_LIMIT]		= 0x24,
> +	[MSM_SPM_REG_SAW2_AVS_DLY]		= 0x28,
> +	[MSM_SPM_REG_SAW2_AVS_HYSTERESIS]	= 0x2C,
> +	[MSM_SPM_REG_SAW2_SPM_CTL]		= 0x30,
> +	[MSM_SPM_REG_SAW2_SPM_DLY]		= 0x34,
> +	[MSM_SPM_REG_SAW2_PMIC_DATA_0]		= 0x40,
> +	[MSM_SPM_REG_SAW2_PMIC_DATA_1]		= 0x44,
> +	[MSM_SPM_REG_SAW2_PMIC_DATA_2]		= 0x48,
> +	[MSM_SPM_REG_SAW2_PMIC_DATA_3]		= 0x4C,
> +	[MSM_SPM_REG_SAW2_PMIC_DATA_4]		= 0x50,
> +	[MSM_SPM_REG_SAW2_PMIC_DATA_5]		= 0x54,
> +	[MSM_SPM_REG_SAW2_PMIC_DATA_6]		= 0x58,
> +	[MSM_SPM_REG_SAW2_PMIC_DATA_7]		= 0x5C,
> +	[MSM_SPM_REG_SAW2_SEQ_ENTRY]		= 0x80,
> +	[MSM_SPM_REG_SAW2_VERSION]		= 0xFD0,
> +};

Why do we need an array for these offsets, can’t they just be #defines?

> +
> +static void msm_spm_drv_flush_shadow(struct msm_spm_driver_data *dev,
> +		unsigned int reg_index)
> +{
> +	__raw_writel(dev->reg_shadow[reg_index],
> +			dev->reg_base_addr + dev->reg_offsets[reg_index]);
> +}
> +
> +static void msm_spm_drv_load_shadow(struct msm_spm_driver_data *dev,
> +		unsigned int reg_index)
> +{
> +	dev->reg_shadow[reg_index] = __raw_readl(dev->reg_base_addr +
> +						dev->reg_offsets[reg_index]);
> +}
> +
> +static inline void msm_spm_drv_set_start_addr(
> +		struct msm_spm_driver_data *dev, uint32_t addr)
> +{
> +	addr &= 0x7F;
> +	addr <<= 4;

possibly worth a comment why we are shifting addr

> +	dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] &= 0xFFFFF80F;
> +	dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] |= addr;
> +}
> +
> +inline int msm_spm_drv_set_spm_enable(
> +		struct msm_spm_driver_data *dev, bool enable)
> +{
> +	uint32_t value = enable ? 0x01 : 0x00;
> +
> +	if ((dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] & 0x01) ^ value) {
> +		dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] &= ~0x1;
> +		dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] |= value;
> +		msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_SPM_CTL);
> +		wmb();

typically barriers should have comments about why they are needed.

> +	}
> +
> +	return 0;
> +}
> +
> +void msm_spm_drv_flush_seq_entry(struct msm_spm_driver_data *dev)

Can this be static?

> +{
> +	int i;
> +
> +	for (i = 0; i < NUM_SPM_ENTRY; i++) {
> +		__raw_writel(dev->reg_seq_entry_shadow[i],
> +			dev->reg_base_addr
> +			+ dev->reg_offsets[MSM_SPM_REG_SAW2_SEQ_ENTRY]
> +			+ 4 * i);
> +	}
> +	mb();

again, comment about barrier usage.

> +}
> +
> +/**
> + * msm_spm_drv_write_seq_data - Load the SPM register with sequences
> + *
> + * @dev - The SPM device whose sequences to be programmed
> + * @cmd - The byte array
> + * @offset - The last written byte position, to continue from.
> + */
> +int msm_spm_drv_write_seq_data(struct msm_spm_driver_data *dev,
> +		uint8_t *cmd, uint32_t *offset)
> +{
> +	uint32_t cmd_w;
> +	uint32_t offset_w = *offset / 4;
> +	uint8_t last_cmd;
> +
> +	while (1) {
> +		int i;
> +
> +		cmd_w = 0;
> +		last_cmd = 0;
> +		cmd_w = dev->reg_seq_entry_shadow[offset_w];
> +
> +		for (i = (*offset % 4); i < 4; i++) {
> +			last_cmd = *(cmd++);
> +			cmd_w |=  last_cmd << (i * 8);
> +			(*offset)++;
> +			if (last_cmd == 0x0f)
> +				break;
> +		}
> +
> +		dev->reg_seq_entry_shadow[offset_w++] = cmd_w;
> +		if (last_cmd == 0x0f)
> +			break;
> +	}
> +
> +	return 0;
> +}
> +
> +int msm_spm_drv_set_low_power_mode(struct msm_spm_driver_data *dev,
> +		uint32_t addr)
> +{
> +
> +	msm_spm_drv_set_start_addr(dev, addr);
> +	msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_SPM_CTL);
> +	wmb();

comment on barrier

> +	msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_SPM_STS);
> +
> +	return 0;
> +}
> +

We should add a comment about what reinit is for.

> +void msm_spm_drv_reinit(struct msm_spm_driver_data *dev)
> +{
> +	int i;
> +
> +	msm_spm_drv_flush_seq_entry(dev);
> +
> +	for (i = MSM_SPM_REG_NR_INITIALIZE + 1; i < MSM_SPM_REG_NR; i++)
> +		msm_spm_drv_load_shadow(dev, i);
> +}
> +

can we have the caller either use msm_spm_driver_data or just pass in reg_base_addr & reg_init_values as args to the function?
> 
> +int msm_spm_drv_init(struct msm_spm_driver_data *dev,
> +		struct msm_spm_platform_data *data)
> +{
> +	dev->reg_base_addr = data->reg_base_addr;
> +	memcpy(dev->reg_shadow, data->reg_init_values,
> +			sizeof(data->reg_init_values));
> +	dev->reg_offsets = msm_spm_reg_offsets_saw2_v2_1;
> +	dev->reg_seq_entry_shadow = kcalloc(NUM_SPM_ENTRY,
> +					sizeof(*dev->reg_seq_entry_shadow),
> +					GFP_KERNEL);
> +	if (!dev->reg_seq_entry_shadow)
> +		return -ENOMEM;
> +
> +	return 0;
> +}
> diff --git a/drivers/soc/qcom/spm_driver.h b/drivers/soc/qcom/spm_driver.h
> new file mode 100644
> index 0000000..6ff69bb
> --- /dev/null
> +++ b/drivers/soc/qcom/spm_driver.h
> @@ -0,0 +1,85 @@
> +/* Copyright (c) 2011-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.
> + */
> +#ifndef __QCOM_SPM_DRIVER_H
> +#define __QCOM_SPM_DRIVER_H
> +
> +enum {
> +	MSM_SPM_REG_SAW2_CFG,
> +	MSM_SPM_REG_SAW2_AVS_CTL,
> +	MSM_SPM_REG_SAW2_AVS_HYSTERESIS,
> +	MSM_SPM_REG_SAW2_SPM_CTL,
> +	MSM_SPM_REG_SAW2_PMIC_DLY,
> +	MSM_SPM_REG_SAW2_AVS_LIMIT,
> +	MSM_SPM_REG_SAW2_AVS_DLY,
> +	MSM_SPM_REG_SAW2_SPM_DLY,
> +	MSM_SPM_REG_SAW2_PMIC_DATA_0,
> +	MSM_SPM_REG_SAW2_PMIC_DATA_1,
> +	MSM_SPM_REG_SAW2_PMIC_DATA_2,
> +	MSM_SPM_REG_SAW2_PMIC_DATA_3,
> +	MSM_SPM_REG_SAW2_PMIC_DATA_4,
> +	MSM_SPM_REG_SAW2_PMIC_DATA_5,
> +	MSM_SPM_REG_SAW2_PMIC_DATA_6,
> +	MSM_SPM_REG_SAW2_PMIC_DATA_7,
> +	MSM_SPM_REG_SAW2_RST,
> +
> +	MSM_SPM_REG_NR_INITIALIZE = MSM_SPM_REG_SAW2_RST,
> +
> +	MSM_SPM_REG_SAW2_ID,
> +	MSM_SPM_REG_SAW2_SECURE,
> +	MSM_SPM_REG_SAW2_STS0,
> +	MSM_SPM_REG_SAW2_STS1,
> +	MSM_SPM_REG_SAW2_STS2,
> +	MSM_SPM_REG_SAW2_VCTL,
> +	MSM_SPM_REG_SAW2_SEQ_ENTRY,
> +	MSM_SPM_REG_SAW2_SPM_STS,
> +	MSM_SPM_REG_SAW2_AVS_STS,
> +	MSM_SPM_REG_SAW2_PMIC_STS,
> +	MSM_SPM_REG_SAW2_VERSION,
> +
> +	MSM_SPM_REG_NR,
> +};
> +
> +struct msm_spm_seq_entry {
> +	uint32_t mode;
> +	uint8_t *cmd;
> +};
> +
> +struct msm_spm_platform_data {
> +	void __iomem *reg_base_addr;
> +	uint32_t reg_init_values[MSM_SPM_REG_NR_INITIALIZE];
> +
> +	uint32_t num_modes;
> +	struct msm_spm_seq_entry *modes;

Are modes used?  is msm_spm_seq_entry used anywhere?

> +};
> +
> +struct msm_spm_driver_data {
> +	void __iomem *reg_base_addr;
> +	uint32_t reg_shadow[MSM_SPM_REG_NR];
> +	uint32_t *reg_seq_entry_shadow;
> +	uint32_t *reg_offsets;
> +	uint32_t num_spm_entry;
> +};

Is there a reason we need both platform_dta & driver_data ?

> +
> +int msm_spm_drv_init(struct msm_spm_driver_data *dev,
> +		struct msm_spm_platform_data *data);
> +void msm_spm_drv_reinit(struct msm_spm_driver_data *dev);
> +int msm_spm_drv_set_low_power_mode(struct msm_spm_driver_data *dev,
> +		uint32_t addr);
> +int msm_spm_drv_write_seq_data(struct msm_spm_driver_data *dev,
> +		uint8_t *cmd, uint32_t *offset);
> +void msm_spm_drv_flush_seq_entry(struct msm_spm_driver_data *dev);

does flush need to be exposed?

> +int msm_spm_drv_set_spm_enable(struct msm_spm_driver_data *dev,
> +		bool enable);
> +void msm_spm_reinit(void);
> +int msm_spm_init(struct msm_spm_platform_data *data, int nr_devs);
> +
> +#endif /* __QCOM_SPM_DRIVER_H */
> -- 
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 4/8] qcom: spm-devices: Add SPM device manager for the SoC
  2014-08-19  9:29   ` Pramod Gurav
@ 2014-08-19 14:51     ` Lina Iyer
  0 siblings, 0 replies; 21+ messages in thread
From: Lina Iyer @ 2014-08-19 14:51 UTC (permalink / raw
  To: Pramod Gurav
  Cc: daniel.lezcano, khilman, sboyd, davidb, galak, linux-arm-msm,
	lorenzo.pieralisi, msivasub, Praveen Chidamabram, Murali Nalajala

On Tue, Aug 19, 2014 at 02:59:56PM +0530, Pramod Gurav wrote:
>Hi Lina,
>
>On Tuesday 19 August 2014 03:53 AM, Lina Iyer wrote:
>> +
>> +config QCOM_PM
>> +	tristate "Qualcomm Power Management"
>This does not compile as a module. making CONFIG_QCOM_PM=m causing
>redefinition of function 'msm_spm_set_low_power_mode' in header.
Good point. Let me make it a bool. I dont see a need for this to be a
loadable module.
>
>drivers/soc/qcom/spm-devices.c:48:5: error: redefinition of
>‘msm_spm_set_low_power_mode’
>In file included from drivers/soc/qcom/spm-devices.c:25:0:
>include/soc/qcom/spm.h:30:19: note: previous definition of
>‘msm_spm_set_low_power_mode’ was here
>
>
>> +	depends on PM && ARCH_QCOM && OF
>> +	help
>> +	  QCOM Platform specific power driver to manage cores and L2 low power
>> +	  modes. It interface with various system drivers to put the cores in
>> +	  low power modes.
>> diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
>> index 20b329f..9457b2a 100644
>> --- a/drivers/soc/qcom/Makefile
>> +++ b/drivers/soc/qcom/Makefile
>> @@ -1,4 +1,4 @@
>>  obj-$(CONFIG_QCOM_GSBI)	+=	qcom_gsbi.o
>> -obj-$(CONFIG_QCOM_PM)	+=	spm.o
>> +obj-$(CONFIG_QCOM_PM)	+=	spm.o spm-devices.o
>>  CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
>>  obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o
>
>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 7/8] qcom: cpuidle: Add cpuidle driver for QCOM cpus
  2014-08-19  7:41   ` Pramod Gurav
@ 2014-08-19 14:54     ` Lina Iyer
  2014-08-19 15:01       ` Pramod Gurav
  0 siblings, 1 reply; 21+ messages in thread
From: Lina Iyer @ 2014-08-19 14:54 UTC (permalink / raw
  To: Pramod Gurav
  Cc: daniel.lezcano, khilman, sboyd, davidb, galak, linux-arm-msm,
	lorenzo.pieralisi, msivasub

On Tue, Aug 19, 2014 at 01:11:43PM +0530, Pramod Gurav wrote:
>Hi Lina,
>
>Compilation breaks while I try to compile these driver. Find below the
>comments.
>
>On Tuesday 19 August 2014 03:53 AM, Lina Iyer wrote:
>> Add cpuidle driver interface to allow cpus to go into C-States.
>> Use the cpuidle DT interfacecommon across ARM architectures to provide
>> the C-State information to the cpuidle framework.
>>
>> Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
>> ---
>>  drivers/cpuidle/Kconfig.arm    |   7 +++
>>  drivers/cpuidle/Makefile       |   1 +
>>  drivers/cpuidle/cpuidle-qcom.c | 119 +++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 127 insertions(+)
>>  create mode 100644 drivers/cpuidle/cpuidle-qcom.c
>>
>> diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
>> index e339c7f..26e31bd 100644
>> --- a/drivers/cpuidle/Kconfig.arm
>> +++ b/drivers/cpuidle/Kconfig.arm
>> @@ -63,3 +63,10 @@ config ARM_MVEBU_V7_CPUIDLE
>>  	depends on ARCH_MVEBU
>>  	help
>>  	  Select this to enable cpuidle on Armada 370, 38x and XP processors.
>> +
>> +config ARM_QCOM_CPUIDLE
>> +	bool "CPU Idle drivers for Qualcomm processors"
>> +	depends on QCOM_PM
>> +	select DT_IDLE_STATES
>I see no reference to this in any patch? Moreover it was not there in
>v2. Anything new that you missed to add?
Nope. You need to build this patchset on top of Lorenzo's patches
http://marc.info/?l=linux-pm&m=140794514812383&w=2


>> +	help
>> +	  Select this to enable cpuidle for QCOM processors
>> diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
>> index 4d177b9..6c222d5 100644
>> --- a/drivers/cpuidle/Makefile
>> +++ b/drivers/cpuidle/Makefile
>> @@ -17,6 +17,7 @@ obj-$(CONFIG_ARM_ZYNQ_CPUIDLE)		+= cpuidle-zynq.o
>>  obj-$(CONFIG_ARM_U8500_CPUIDLE)         += cpuidle-ux500.o
>>  obj-$(CONFIG_ARM_AT91_CPUIDLE)          += cpuidle-at91.o
>>  obj-$(CONFIG_ARM_EXYNOS_CPUIDLE)        += cpuidle-exynos.o
>> +obj-$(CONFIG_ARM_QCOM_CPUIDLE)		+= cpuidle-qcom.o
>>
>>  ###############################################################################
>>  # MIPS drivers
>> diff --git a/drivers/cpuidle/cpuidle-qcom.c b/drivers/cpuidle/cpuidle-qcom.c
>> new file mode 100644
>> index 0000000..4aae672
>> --- /dev/null
>> +++ b/drivers/cpuidle/cpuidle-qcom.c
>> @@ -0,0 +1,119 @@
>> +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
>> + * Copyright (c) 2014, Linaro Limited.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU G./8.patch:226:+eneral 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/platform_device.h>
>> +#include <linux/of.h>
>> +#include <linux/cpuidle.h>
>> +#include <linux/cpumask.h>
>> +#include <linux/slab.h>
>> +#include <linux/of_device.h>
>> +
>> +#include <soc/qcom/pm.h>
>> +#include "dt_idle_states.h"
>Did you miss to commit this file? Compilation fails as this file is nowhere.
>
See link.
>> +
>> +static enum msm_pm_sleep_mode modes[CPUIDLE_STATE_MAX];
>> +
>> +static int qcom_lpm_enter(struct cpuidle_device *dev,
>> +				struct cpuidle_driver *drv, int index)
>> +{
>> +	return msm_cpu_pm_enter_sleep(modes[index], true);
>> +}
>> +
>> +static struct cpuidle_driver qcom_cpuidle_driver = {
>> +	.name	= "qcom_cpuidle",
>> +	.owner	= THIS_MODULE,
>> +};
>> +
>> +static void parse_state_translations(struct cpuidle_driver *drv)
>> +{
>> +	struct device_node *state_node, *cpu_node;
>> +	const char *mode_name;
>> +	int i, j;
>> +
>> +	struct name_map {
>> +		enum msm_pm_sleep_mode mode;
>> +		char *name;
>> +	};
>> +	static struct name_map c_states[] = {
>> +		{ MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE,
>> +						"standalone-pc" },
>> +		{ MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT, "wfi" },
>> +	};
>> +
>> +	cpu_node = of_cpu_device_node_get(cpumask_first(drv->cpumask));
>> +	if (!cpu_node)
>> +		return;
>> +
>> +	/**
>> +	 * Get the state description from idle-state node entry-method
>> +	 * First state is always WFI, per spec.
>> +	 */
>> +	modes[0] = MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT;
>> +	for (i = 1; i < drv->state_count; i++) {
>> +		mode_name = NULL;
>> +		state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
>> +		of_property_read_string(state_node, "entry-method",
>> +						&mode_name);
>> +		for (j = 0; mode_name && (j < ARRAY_SIZE(c_states)); j++) {
>> +			if (!strcmp(mode_name, c_states[j].name)) {
>> +				modes[i] = c_states[j].mode;
>> +				break;
>> +			}
>> +		}
>> +	}
>> +}
>> +
>> +static int qcom_cpuidle_init(void)
>> +{
>> +	struct cpuidle_driver *drv = &qcom_cpuidle_driver;
>> +	int ret;
>> +	int i;
>> +
>> +	drv->cpumask = kzalloc(cpumask_size(), GFP_KERNEL);
>> +	if (!drv->cpumask)
>> +		return -ENOMEM;
>> +	cpumask_copy(drv->cpumask, cpu_possible_mask);
>> +
>> +	/**
>> +	 * Default to standard for WFI (index = 0)
>> +	 * Probe only for other states
>> +	 */
>> +	ret = dt_init_idle_driver(drv, 1);
>There is no reference to this function as well.
Same here.
>> +	if (ret < 0) {
>> +		pr_err("%s: failed to initialize idle states\n", __func__);
>> +		goto failed;
>> +	}
>> +
>> +	/* Parse the idle states for C-States on this cpu */
>> +	parse_state_translations(drv);
>> +
>> +	/* Register entry point for all low states */
>> +	for (i = 0; i < drv->state_count; i++)
>> +		drv->states[i].enter = qcom_lpm_enter;
>> +	drv->safe_state_index = 0;
>> +
>> +	ret = cpuidle_register(drv, NULL);
>> +	if (ret) {
>> +		pr_err("%s: failed to register cpuidle driver\n", __func__);
>> +		goto failed;
>> +	}
>> +
>> +	return 0;
>> +
>> +failed:
>> +	kfree(drv->cpumask);
>> +	return ret;
>> +}
>> +module_init(qcom_cpuidle_init);
>>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 7/8] qcom: cpuidle: Add cpuidle driver for QCOM cpus
  2014-08-19 14:54     ` Lina Iyer
@ 2014-08-19 15:01       ` Pramod Gurav
  0 siblings, 0 replies; 21+ messages in thread
From: Pramod Gurav @ 2014-08-19 15:01 UTC (permalink / raw
  To: Lina Iyer
  Cc: daniel.lezcano, khilman, sboyd, davidb, galak, linux-arm-msm,
	lorenzo.pieralisi, msivasub


On Tuesday 19 August 2014 08:24 PM, Lina Iyer wrote:
>>> +config ARM_QCOM_CPUIDLE
>>> >> +	bool "CPU Idle drivers for Qualcomm processors"
>>> >> +	depends on QCOM_PM
>>> >> +	select DT_IDLE_STATES
>> >I see no reference to this in any patch? Moreover it was not there in
>> >v2. Anything new that you missed to add?
> Nope. You need to build this patchset on top of Lorenzo's patches
> http://marc.info/?l=linux-pm&m=140794514812383&w=2

Ohh. Sure. Shall take them and test yours.


> 
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 3/8] qcom: spm: Add Subsystem Power Manager driver (SAW2)
  2014-08-19 14:07   ` Kumar Gala
@ 2014-08-19 15:28     ` Lina Iyer
  0 siblings, 0 replies; 21+ messages in thread
From: Lina Iyer @ 2014-08-19 15:28 UTC (permalink / raw
  To: Kumar Gala
  Cc: daniel.lezcano, khilman, sboyd, davidb, linux-arm-msm,
	lorenzo.pieralisi, msivasub, Praveen Chidambaram

On Tue, Aug 19, 2014 at 09:07:51AM -0500, Kumar Gala wrote:
>
>On Aug 18, 2014, at 5:23 PM, Lina Iyer <lina.iyer@linaro.org> wrote:
>
>> SPM is a hardware block that controls the peripheral logic surrounding
>> the application cores (cpu/l$). When the core executes WFI instruction,
>> the SPM takes over the putting the core in low power state as
>> configured. The wake up for the SPM is an interrupt at the GIC, which
>> then completes the rest of low power mode sequence and brings the core
>> out of low power mode.
>>
>> Allow drivers to configure the idle mode for the cores in the SPM start
>> address register.
>
>What is the ‘start address’?
>
>Can we add anything about ‘start address’ and the sequences in the commit message?
>
Commit message? The start address is just the register's physical
address.
I can definitely add information about the sequences.

>>
>> Signed-off-by: Praveen Chidambaram <pchidamb@codeaurora.org>
>> Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
>> ---
>> drivers/soc/qcom/Makefile     |   1 +
>> drivers/soc/qcom/spm.c        | 176 ++++++++++++++++++++++++++++++++++++++++++
>> drivers/soc/qcom/spm_driver.h |  85 ++++++++++++++++++++
>> 3 files changed, 262 insertions(+)
>> create mode 100644 drivers/soc/qcom/spm.c
>> create mode 100644 drivers/soc/qcom/spm_driver.h
>>
>> diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
>> index 70d52ed..20b329f 100644
>> --- a/drivers/soc/qcom/Makefile
>> +++ b/drivers/soc/qcom/Makefile
>> @@ -1,3 +1,4 @@
>> obj-$(CONFIG_QCOM_GSBI)	+=	qcom_gsbi.o
>> +obj-$(CONFIG_QCOM_PM)	+=	spm.o
>> CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
>> obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o
>
>We should have the Kconfig that adds QCOM_PM as part of this patch so it actual is buildable.
This patch is not useful at all without the spm-devices.c patch. Hence,
the separate patches. 
>
>> diff --git a/drivers/soc/qcom/spm.c b/drivers/soc/qcom/spm.c
>> new file mode 100644
>> index 0000000..3e1de43
>> --- /dev/null
>> +++ b/drivers/soc/qcom/spm.c
>> @@ -0,0 +1,176 @@
>> +/* Copyright (c) 2011-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/delay.h>
>> +#include <linux/init.h>
>> +#include <linux/io.h>
>> +#include <linux/slab.h>
>> +
>> +#include "spm_driver.h"
>> +d
>> +#define NUM_SPM_ENTRY 32
>> +
>> +static uint32_t msm_spm_reg_offsets_saw2_v2_1[MSM_SPM_REG_NR] = {
>> +	[MSM_SPM_REG_SAW2_SECURE]		= 0x00,
>> +	[MSM_SPM_REG_SAW2_ID]			= 0x04,
>> +	[MSM_SPM_REG_SAW2_CFG]			= 0x08,
>> +	[MSM_SPM_REG_SAW2_SPM_STS]		= 0x0C,
>> +	[MSM_SPM_REG_SAW2_AVS_STS]		= 0x10,
>> +	[MSM_SPM_REG_SAW2_PMIC_STS]		= 0x14,
>> +	[MSM_SPM_REG_SAW2_RST]			= 0x18,
>> +	[MSM_SPM_REG_SAW2_VCTL]			= 0x1C,
>> +	[MSM_SPM_REG_SAW2_AVS_CTL]		= 0x20,
>> +	[MSM_SPM_REG_SAW2_AVS_LIMIT]		= 0x24,
>> +	[MSM_SPM_REG_SAW2_AVS_DLY]		= 0x28,
>> +	[MSM_SPM_REG_SAW2_AVS_HYSTERESIS]	= 0x2C,
>> +	[MSM_SPM_REG_SAW2_SPM_CTL]		= 0x30,
>> +	[MSM_SPM_REG_SAW2_SPM_DLY]		= 0x34,
>> +	[MSM_SPM_REG_SAW2_PMIC_DATA_0]		= 0x40,
>> +	[MSM_SPM_REG_SAW2_PMIC_DATA_1]		= 0x44,
>> +	[MSM_SPM_REG_SAW2_PMIC_DATA_2]		= 0x48,
>> +	[MSM_SPM_REG_SAW2_PMIC_DATA_3]		= 0x4C,
>> +	[MSM_SPM_REG_SAW2_PMIC_DATA_4]		= 0x50,
>> +	[MSM_SPM_REG_SAW2_PMIC_DATA_5]		= 0x54,
>> +	[MSM_SPM_REG_SAW2_PMIC_DATA_6]		= 0x58,
>> +	[MSM_SPM_REG_SAW2_PMIC_DATA_7]		= 0x5C,
>> +	[MSM_SPM_REG_SAW2_SEQ_ENTRY]		= 0x80,
>> +	[MSM_SPM_REG_SAW2_VERSION]		= 0xFD0,
>> +};
>
>Why do we need an array for these offsets, can’t they just be #defines?
They could be, but they could change with each rev of hardware. Any
advantage to the #define other than the memory.
>
>> +
>> +static void msm_spm_drv_flush_shadow(struct msm_spm_driver_data *dev,
>> +		unsigned int reg_index)
>> +{
>> +	__raw_writel(dev->reg_shadow[reg_index],
>> +			dev->reg_base_addr + dev->reg_offsets[reg_index]);
>> +}
>> +
>> +static void msm_spm_drv_load_shadow(struct msm_spm_driver_data *dev,
>> +		unsigned int reg_index)
>> +{
>> +	dev->reg_shadow[reg_index] = __raw_readl(dev->reg_base_addr +
>> +						dev->reg_offsets[reg_index]);
>> +}
>> +
>> +static inline void msm_spm_drv_set_start_addr(
>> +		struct msm_spm_driver_data *dev, uint32_t addr)
>> +{
>> +	addr &= 0x7F;
>> +	addr <<= 4;
>
>possibly worth a comment why we are shifting addr
>
OK. Its just the building of the address to the position in the
register.
>> +	dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] &= 0xFFFFF80F;
>> +	dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] |= addr;
>> +}
>> +
>> +inline int msm_spm_drv_set_spm_enable(
>> +		struct msm_spm_driver_data *dev, bool enable)
>> +{
>> +	uint32_t value = enable ? 0x01 : 0x00;
>> +
>> +	if ((dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] & 0x01) ^ value) {
>> +		dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] &= ~0x1;
>> +		dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] |= value;
>> +		msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_SPM_CTL);
>> +		wmb();
>
>typically barriers should have comments about why they are needed.
>
:) Well this file is full of barriers. Barriers + __raw_writel instead
of writel helps club writes togethers and prevents unnecessary flush,
until we need to.
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +void msm_spm_drv_flush_seq_entry(struct msm_spm_driver_data *dev)
>
>Can this be static?
>
Need this externally in spm-devices.c.
More comment below.

>> +{
>> +	int i;
>> +
>> +	for (i = 0; i < NUM_SPM_ENTRY; i++) {
>> +		__raw_writel(dev->reg_seq_entry_shadow[i],
>> +			dev->reg_base_addr
>> +			+ dev->reg_offsets[MSM_SPM_REG_SAW2_SEQ_ENTRY]
>> +			+ 4 * i);
>> +	}
>> +	mb();
>
>again, comment about barrier usage.
>
>> +}
>> +
>> +/**
>> + * msm_spm_drv_write_seq_data - Load the SPM register with sequences
>> + *
>> + * @dev - The SPM device whose sequences to be programmed
>> + * @cmd - The byte array
>> + * @offset - The last written byte position, to continue from.
>> + */
>> +int msm_spm_drv_write_seq_data(struct msm_spm_driver_data *dev,
>> +		uint8_t *cmd, uint32_t *offset)
>> +{
>> +	uint32_t cmd_w;
>> +	uint32_t offset_w = *offset / 4;
>> +	uint8_t last_cmd;
>> +
>> +	while (1) {
>> +		int i;
>> +
>> +		cmd_w = 0;
>> +		last_cmd = 0;
>> +		cmd_w = dev->reg_seq_entry_shadow[offset_w];
>> +
>> +		for (i = (*offset % 4); i < 4; i++) {
>> +			last_cmd = *(cmd++);
>> +			cmd_w |=  last_cmd << (i * 8);
>> +			(*offset)++;
>> +			if (last_cmd == 0x0f)
>> +				break;
>> +		}
>> +
>> +		dev->reg_seq_entry_shadow[offset_w++] = cmd_w;
>> +		if (last_cmd == 0x0f)
>> +			break;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +int msm_spm_drv_set_low_power_mode(struct msm_spm_driver_data *dev,
>> +		uint32_t addr)
>> +{
>> +
>> +	msm_spm_drv_set_start_addr(dev, addr);
>> +	msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_SPM_CTL);
>> +	wmb();
>
>comment on barrier
>
>> +	msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_SPM_STS);
>> +
>> +	return 0;
>> +}
>> +
>
>We should add a comment about what reinit is for.
>
OK.
>> +void msm_spm_drv_reinit(struct msm_spm_driver_data *dev)
>> +{
>> +	int i;
>> +
>> +	msm_spm_drv_flush_seq_entry(dev);
>> +
>> +	for (i = MSM_SPM_REG_NR_INITIALIZE + 1; i < MSM_SPM_REG_NR; i++)
>> +		msm_spm_drv_load_shadow(dev, i);
>> +}
>> +
>
>can we have the caller either use msm_spm_driver_data or just pass in reg_base_addr & reg_init_values as args to the function?

I presume, you are talking about the msm_spm_drv_load_shadow() here.
Yes, we could do that. This just seemed cleaner, since we already have a
nice SPM packet around, with all the relevant data. Any advantages, that
I am failing to see?

>>
>> +int msm_spm_drv_init(struct msm_spm_driver_data *dev,
>> +		struct msm_spm_platform_data *data)
>> +{
>> +	dev->reg_base_addr = data->reg_base_addr;
>> +	memcpy(dev->reg_shadow, data->reg_init_values,
>> +			sizeof(data->reg_init_values));
>> +	dev->reg_offsets = msm_spm_reg_offsets_saw2_v2_1;
>> +	dev->reg_seq_entry_shadow = kcalloc(NUM_SPM_ENTRY,
>> +					sizeof(*dev->reg_seq_entry_shadow),
>> +					GFP_KERNEL);
>> +	if (!dev->reg_seq_entry_shadow)
>> +		return -ENOMEM;
>> +
>> +	return 0;
>> +}
>> diff --git a/drivers/soc/qcom/spm_driver.h b/drivers/soc/qcom/spm_driver.h
>> new file mode 100644
>> index 0000000..6ff69bb
>> --- /dev/null
>> +++ b/drivers/soc/qcom/spm_driver.h
>> @@ -0,0 +1,85 @@
>> +/* Copyright (c) 2011-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.
>> + */
>> +#ifndef __QCOM_SPM_DRIVER_H
>> +#define __QCOM_SPM_DRIVER_H
>> +
>> +enum {
>> +	MSM_SPM_REG_SAW2_CFG,
>> +	MSM_SPM_REG_SAW2_AVS_CTL,
>> +	MSM_SPM_REG_SAW2_AVS_HYSTERESIS,
>> +	MSM_SPM_REG_SAW2_SPM_CTL,
>> +	MSM_SPM_REG_SAW2_PMIC_DLY,
>> +	MSM_SPM_REG_SAW2_AVS_LIMIT,
>> +	MSM_SPM_REG_SAW2_AVS_DLY,
>> +	MSM_SPM_REG_SAW2_SPM_DLY,
>> +	MSM_SPM_REG_SAW2_PMIC_DATA_0,
>> +	MSM_SPM_REG_SAW2_PMIC_DATA_1,
>> +	MSM_SPM_REG_SAW2_PMIC_DATA_2,
>> +	MSM_SPM_REG_SAW2_PMIC_DATA_3,
>> +	MSM_SPM_REG_SAW2_PMIC_DATA_4,
>> +	MSM_SPM_REG_SAW2_PMIC_DATA_5,
>> +	MSM_SPM_REG_SAW2_PMIC_DATA_6,
>> +	MSM_SPM_REG_SAW2_PMIC_DATA_7,
>> +	MSM_SPM_REG_SAW2_RST,
>> +
>> +	MSM_SPM_REG_NR_INITIALIZE = MSM_SPM_REG_SAW2_RST,
>> +
>> +	MSM_SPM_REG_SAW2_ID,
>> +	MSM_SPM_REG_SAW2_SECURE,
>> +	MSM_SPM_REG_SAW2_STS0,
>> +	MSM_SPM_REG_SAW2_STS1,
>> +	MSM_SPM_REG_SAW2_STS2,
>> +	MSM_SPM_REG_SAW2_VCTL,
>> +	MSM_SPM_REG_SAW2_SEQ_ENTRY,
>> +	MSM_SPM_REG_SAW2_SPM_STS,
>> +	MSM_SPM_REG_SAW2_AVS_STS,
>> +	MSM_SPM_REG_SAW2_PMIC_STS,
>> +	MSM_SPM_REG_SAW2_VERSION,
>> +
>> +	MSM_SPM_REG_NR,
>> +};
>> +
>> +struct msm_spm_seq_entry {
>> +	uint32_t mode;
>> +	uint8_t *cmd;
>> +};
>> +
>> +struct msm_spm_platform_data {
>> +	void __iomem *reg_base_addr;
>> +	uint32_t reg_init_values[MSM_SPM_REG_NR_INITIALIZE];
>> +
>> +	uint32_t num_modes;
>> +	struct msm_spm_seq_entry *modes;
>
>Are modes used?  is msm_spm_seq_entry used anywhere?
>
Its used to populate the SPM sequences by spm-devices.c

>> +};
>> +
>> +struct msm_spm_driver_data {
>> +	void __iomem *reg_base_addr;
>> +	uint32_t reg_shadow[MSM_SPM_REG_NR];
>> +	uint32_t *reg_seq_entry_shadow;
>> +	uint32_t *reg_offsets;
>> +	uint32_t num_spm_entry;
>> +};
>
>Is there a reason we need both platform_dta & driver_data ?
>
Yes. SAW is SPM - AVS Wrapper. The other part of SAW is currently not
implemented, the platform data would hold both and the driver-data would
hold only the SPM aspect of it.
I do agree, the justification doesnt hold water much. I will try and see
if I can use the same structure.

>> +
>> +int msm_spm_drv_init(struct msm_spm_driver_data *dev,
>> +		struct msm_spm_platform_data *data);
>> +void msm_spm_drv_reinit(struct msm_spm_driver_data *dev);
>> +int msm_spm_drv_set_low_power_mode(struct msm_spm_driver_data *dev,
>> +		uint32_t addr);
>> +int msm_spm_drv_write_seq_data(struct msm_spm_driver_data *dev,
>> +		uint8_t *cmd, uint32_t *offset);
>> +void msm_spm_drv_flush_seq_entry(struct msm_spm_driver_data *dev);
>
>does flush need to be exposed?
>
SPM devices may need to flush the sequences in some cpus separately
before setting up the control register.

>> +int msm_spm_drv_set_spm_enable(struct msm_spm_driver_data *dev,
>> +		bool enable);
>> +void msm_spm_reinit(void);
>> +int msm_spm_init(struct msm_spm_platform_data *data, int nr_devs);
>> +
>> +#endif /* __QCOM_SPM_DRIVER_H */
>> --
>> 1.9.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>-- 
>Employee of Qualcomm Innovation Center, Inc.
>Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 0/8] QCOM 8074 cpuidle driver
  2014-08-18 22:23 [PATCH v3 0/8] QCOM 8074 cpuidle driver Lina Iyer
                   ` (7 preceding siblings ...)
  2014-08-18 22:23 ` [PATCH v3 8/8] arm: dts: qcom: Add idle states device nodes for 8974 Lina Iyer
@ 2014-08-19 15:30 ` Lina Iyer
  8 siblings, 0 replies; 21+ messages in thread
From: Lina Iyer @ 2014-08-19 15:30 UTC (permalink / raw
  To: daniel.lezcano, khilman, sboyd, davidb, galak, linux-arm-msm,
	lorenzo.pieralisi
  Cc: msivasub

On Mon, Aug 18, 2014 at 04:23:26PM -0600, Lina Iyer wrote:
>Changes since v2:
>[ https://www.mail-archive.com/linux-arm-msm@vger.kernel.org/msg10148.html ]
>- Prune all the drivers to support basic WFI and power down cpuidle
>  functionality. Remove debug code.
>- Integrate KConfig changes into the drivers' patches.
>- Use Lorenzo's ARM idle-states patches as the basis for reading cpuidle
>  c-states from DT.

Ref: http://marc.info/?l=linux-pm&m=140794514812383&w=2

>- Incorporate review comments
>- Rebase on top of 3.16
>
>Changes since v1/RFC:
>[ https://www.mail-archive.com/linux-arm-msm@vger.kernel.org/msg10065.html ]
>- Remove hotplug from the patch series. Will submit it seprately.
>- Fix SPM drivers per the review comments
>- Modify patch sequence to compile SPM drivers independent of msm-pm, so as to
>  allow wfi() calls to use SPM even without SoC interface driver.
>
>8074 like any ARM SoC can do architectural clock gating, that helps save on
>power, but not enough of leakage power.  Leakage power of the SoC can be
>further reduced by turning off power to the core. To aid this, every core (cpu
>and L2) is accompanied by a Sub-system Power Manager (SPM), that can be
>configured to indicate the low power mode, the core would be put into and the
>SPM programs the peripheral h/w accordingly to enter low power and turn off the
>power rail to the core.
>
>The idle invocation hierarchy -
>
>	CPUIDLE
>	|
>	cpuidle-qcom.c [CPUIdle driver]
>	|
>	------>	msm-pm.c [SoC Interface layer for QCOM chipsets]
>		|
>		------> spm-devices.c [SPM devices manager]
>		|	|
>		|	------>	spm.c [SPM h/w driver]
>		|
>		------> scm-boot.c [SCM interface layer]		
>			|
>------------------------|--------------------------
>(EL)			Secure Monitor Code
>			|
>			|
>			wfi();
>------------------------|--------------------------
>(HW)			[CPU] {clock gate}
>			|
>			-----> [SPM] {statemachine}
>			
>
>The patchsets do the following -
>
>- Move scm-boot files from arm/mach-qcom to drivers/soc, following convention.
>They are based on Stephen Boyd's series of patches
>[http://www.spinics.net/lists/linux-arm-msm/msg10482.html]
>
>- Add new Secure Monitor flags to support warmboot of a quad core system.
>
>- Introduce the SPM driver to control power to the core. The SPM h/w IP works
>in conjunction with the Krait CPU/L2. When the core executes WFI instruction,
>the core is clockgated and the SPM state machine takes over and powers the core
>down. An interrupt from GIC, resumes the SPM state machine which brings the cpu
>out of the low power mode.
>
>- Add a SPM device manager to configure multiple SPM devices.
>
>- Add the device tree configuration for each of the SPM nodes. There is one for
>each cpu. There is one for each cpu.
>
>- Introduce the SoC driver interface layer to configure SPM per the core's idle
> state. To power down the cpu core, the SPM h/w needs to be set up correctly
>to power down the core, when the core executes WFI. Linux is expected to call
>into Secure Monitor to power down the core. At reset, the core will start in
>seure mode and will be returned back to Linux.
>
>- Add CPUIDLE driver for QCOM cpus. The cpuidle driver uses the SoC interface
>layer to configure the SPM to allow Krait to be powered down. The cpuidle driver
>is based on ARM idle-state framework for cpuidle drivers.
>
>- Provide device configuration for 8074 SoC. Current support is for WFI and
>standalone power collapse, which powers only the core independent of the
>other cores and caches.
>
>Thanks,
>Lina
>
>
>Lina Iyer (8):
>  msm: scm: Move scm-boot files to drivers/soc and include/soc
>  msm: scm: Add SCM warmboot flags for quad core targets.
>  qcom: spm: Add Subsystem Power Manager driver (SAW2)
>  qcom: spm-devices: Add SPM device manager for the SoC
>  arm: dts: qcom: Add SPM device bindings for 8974
>  qcom: msm-pm: Add cpu low power mode functions
>  qcom: cpuidle: Add cpuidle driver for QCOM cpus
>  arm: dts: qcom: Add idle states device nodes for 8974
>
> Documentation/devicetree/bindings/arm/msm/spm.txt  |  47 ++++
> arch/arm/boot/dts/qcom-msm8974-pm.dtsi             |  69 ++++++
> arch/arm/boot/dts/qcom-msm8974.dtsi                |  24 +-
> arch/arm/mach-qcom/Makefile                        |   1 -
> arch/arm/mach-qcom/platsmp.c                       |   2 +-
> drivers/cpuidle/Kconfig.arm                        |   7 +
> drivers/cpuidle/Makefile                           |   1 +
> drivers/cpuidle/cpuidle-qcom.c                     | 119 ++++++++++
> drivers/soc/qcom/Kconfig                           |   8 +
> drivers/soc/qcom/Makefile                          |   3 +-
> drivers/soc/qcom/msm-pm.c                          | 117 ++++++++++
> .../arm/mach-qcom => drivers/soc/qcom}/scm-boot.c  |   4 +-
> drivers/soc/qcom/spm-devices.c                     | 242 +++++++++++++++++++++
> drivers/soc/qcom/spm.c                             | 176 +++++++++++++++
> drivers/soc/qcom/spm_driver.h                      |  85 ++++++++
> include/soc/qcom/pm.h                              |  38 ++++
> .../arm/mach-qcom => include/soc/qcom}/scm-boot.h  |   2 +
> include/soc/qcom/spm.h                             |  34 +++
> 18 files changed, 970 insertions(+), 9 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/arm/msm/spm.txt
> create mode 100644 arch/arm/boot/dts/qcom-msm8974-pm.dtsi
> create mode 100644 drivers/cpuidle/cpuidle-qcom.c
> create mode 100644 drivers/soc/qcom/msm-pm.c
> rename {arch/arm/mach-qcom => drivers/soc/qcom}/scm-boot.c (97%)
> create mode 100644 drivers/soc/qcom/spm-devices.c
> create mode 100644 drivers/soc/qcom/spm.c
> create mode 100644 drivers/soc/qcom/spm_driver.h
> create mode 100644 include/soc/qcom/pm.h
> rename {arch/arm/mach-qcom => include/soc/qcom}/scm-boot.h (92%)
> create mode 100644 include/soc/qcom/spm.h
>
>-- 
>1.9.1
>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 1/8] msm: scm: Move scm-boot files to drivers/soc and include/soc
  2014-08-18 22:23 ` [PATCH v3 1/8] msm: scm: Move scm-boot files to drivers/soc and include/soc Lina Iyer
@ 2014-08-27 17:18   ` Kevin Hilman
  2014-08-27 18:57     ` Lina Iyer
  0 siblings, 1 reply; 21+ messages in thread
From: Kevin Hilman @ 2014-08-27 17:18 UTC (permalink / raw
  To: Lina Iyer
  Cc: daniel.lezcano, sboyd, davidb, galak, linux-arm-msm,
	lorenzo.pieralisi, msivasub

Lina Iyer <lina.iyer@linaro.org> writes:

> Signed-off-by: Lina Iyer <lina.iyer@linaro.org>

Why the move?  It looks like scm-boot.c still calls into the main
scm_call() stuff that still lives under arch/arm/mach-qcom, and not in
arm64, so I'm not seeing the motiviation for the change (and the
changelog didn't help explain either  :)

Kevin


>  arch/arm/mach-qcom/Makefile                         | 1 -
>  arch/arm/mach-qcom/platsmp.c                        | 2 +-
>  drivers/soc/qcom/Makefile                           | 2 +-
>  {arch/arm/mach-qcom => drivers/soc/qcom}/scm-boot.c | 4 ++--
>  {arch/arm/mach-qcom => include/soc/qcom}/scm-boot.h | 0
>  5 files changed, 4 insertions(+), 5 deletions(-)
>  rename {arch/arm/mach-qcom => drivers/soc/qcom}/scm-boot.c (97%)
>  rename {arch/arm/mach-qcom => include/soc/qcom}/scm-boot.h (100%)
>
> diff --git a/arch/arm/mach-qcom/Makefile b/arch/arm/mach-qcom/Makefile
> index db41e8c..e324375 100644
> --- a/arch/arm/mach-qcom/Makefile
> +++ b/arch/arm/mach-qcom/Makefile
> @@ -1,3 +1,2 @@
>  obj-y			:= board.o
>  obj-$(CONFIG_SMP)	+= platsmp.o
> -obj-$(CONFIG_QCOM_SCM)	+= scm-boot.o
> diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c
> index d690856..a692bcb 100644
> --- a/arch/arm/mach-qcom/platsmp.c
> +++ b/arch/arm/mach-qcom/platsmp.c
> @@ -20,7 +20,7 @@
>  
>  #include <asm/smp_plat.h>
>  
> -#include "scm-boot.h"
> +#include <soc/qcom/scm-boot.h>
>  
>  #define VDD_SC1_ARRAY_CLAMP_GFS_CTL	0x35a0
>  #define SCSS_CPU1CORE_RESET		0x2d80
> diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
> index a39446d..70d52ed 100644
> --- a/drivers/soc/qcom/Makefile
> +++ b/drivers/soc/qcom/Makefile
> @@ -1,3 +1,3 @@
>  obj-$(CONFIG_QCOM_GSBI)	+=	qcom_gsbi.o
>  CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
> -obj-$(CONFIG_QCOM_SCM) += scm.o
> +obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o
> diff --git a/arch/arm/mach-qcom/scm-boot.c b/drivers/soc/qcom/scm-boot.c
> similarity index 97%
> rename from arch/arm/mach-qcom/scm-boot.c
> rename to drivers/soc/qcom/scm-boot.c
> index 5add20e..60ff7b4 100644
> --- a/arch/arm/mach-qcom/scm-boot.c
> +++ b/drivers/soc/qcom/scm-boot.c
> @@ -17,9 +17,9 @@
>  
>  #include <linux/module.h>
>  #include <linux/slab.h>
> -#include <soc/qcom/scm.h>
>  
> -#include "scm-boot.h"
> +#include <soc/qcom/scm.h>
> +#include <soc/qcom/scm-boot.h>
>  
>  /*
>   * Set the cold/warm boot address for one of the CPU cores.
> diff --git a/arch/arm/mach-qcom/scm-boot.h b/include/soc/qcom/scm-boot.h
> similarity index 100%
> rename from arch/arm/mach-qcom/scm-boot.h
> rename to include/soc/qcom/scm-boot.h

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 1/8] msm: scm: Move scm-boot files to drivers/soc and include/soc
  2014-08-27 17:18   ` Kevin Hilman
@ 2014-08-27 18:57     ` Lina Iyer
  2014-08-27 20:24       ` Kevin Hilman
  0 siblings, 1 reply; 21+ messages in thread
From: Lina Iyer @ 2014-08-27 18:57 UTC (permalink / raw
  To: Kevin Hilman
  Cc: daniel.lezcano, sboyd, davidb, galak, linux-arm-msm,
	lorenzo.pieralisi, msivasub

On Wed, Aug 27, 2014 at 10:18:24AM -0700, Kevin Hilman wrote:
>Lina Iyer <lina.iyer@linaro.org> writes:
>
>> Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
>
>Why the move?  It looks like scm-boot.c still calls into the main
>scm_call() stuff that still lives under arch/arm/mach-qcom, and not in
>arm64, so I'm not seeing the motiviation for the change (and the
>changelog didn't help explain either  :)
>
>Kevin

I dint intend on moving the scm-boot for 64 bit purposes, but that
would be a good argument :) My motivation was to move the scm-boot.h, but
figured might as well clean up the mach-qcom in the process, per
guidance.

>
>
>>  arch/arm/mach-qcom/Makefile                         | 1 -
>>  arch/arm/mach-qcom/platsmp.c                        | 2 +-
>>  drivers/soc/qcom/Makefile                           | 2 +-
>>  {arch/arm/mach-qcom => drivers/soc/qcom}/scm-boot.c | 4 ++--
>>  {arch/arm/mach-qcom => include/soc/qcom}/scm-boot.h | 0
>>  5 files changed, 4 insertions(+), 5 deletions(-)
>>  rename {arch/arm/mach-qcom => drivers/soc/qcom}/scm-boot.c (97%)
>>  rename {arch/arm/mach-qcom => include/soc/qcom}/scm-boot.h (100%)
>>
>> diff --git a/arch/arm/mach-qcom/Makefile b/arch/arm/mach-qcom/Makefile
>> index db41e8c..e324375 100644
>> --- a/arch/arm/mach-qcom/Makefile
>> +++ b/arch/arm/mach-qcom/Makefile
>> @@ -1,3 +1,2 @@
>>  obj-y			:= board.o
>>  obj-$(CONFIG_SMP)	+= platsmp.o
>> -obj-$(CONFIG_QCOM_SCM)	+= scm-boot.o
>> diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c
>> index d690856..a692bcb 100644
>> --- a/arch/arm/mach-qcom/platsmp.c
>> +++ b/arch/arm/mach-qcom/platsmp.c
>> @@ -20,7 +20,7 @@
>>
>>  #include <asm/smp_plat.h>
>>
>> -#include "scm-boot.h"
>> +#include <soc/qcom/scm-boot.h>
>>
>>  #define VDD_SC1_ARRAY_CLAMP_GFS_CTL	0x35a0
>>  #define SCSS_CPU1CORE_RESET		0x2d80
>> diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
>> index a39446d..70d52ed 100644
>> --- a/drivers/soc/qcom/Makefile
>> +++ b/drivers/soc/qcom/Makefile
>> @@ -1,3 +1,3 @@
>>  obj-$(CONFIG_QCOM_GSBI)	+=	qcom_gsbi.o
>>  CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
>> -obj-$(CONFIG_QCOM_SCM) += scm.o
>> +obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o
>> diff --git a/arch/arm/mach-qcom/scm-boot.c b/drivers/soc/qcom/scm-boot.c
>> similarity index 97%
>> rename from arch/arm/mach-qcom/scm-boot.c
>> rename to drivers/soc/qcom/scm-boot.c
>> index 5add20e..60ff7b4 100644
>> --- a/arch/arm/mach-qcom/scm-boot.c
>> +++ b/drivers/soc/qcom/scm-boot.c
>> @@ -17,9 +17,9 @@
>>
>>  #include <linux/module.h>
>>  #include <linux/slab.h>
>> -#include <soc/qcom/scm.h>
>>
>> -#include "scm-boot.h"
>> +#include <soc/qcom/scm.h>
>> +#include <soc/qcom/scm-boot.h>
>>
>>  /*
>>   * Set the cold/warm boot address for one of the CPU cores.
>> diff --git a/arch/arm/mach-qcom/scm-boot.h b/include/soc/qcom/scm-boot.h
>> similarity index 100%
>> rename from arch/arm/mach-qcom/scm-boot.h
>> rename to include/soc/qcom/scm-boot.h

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 1/8] msm: scm: Move scm-boot files to drivers/soc and include/soc
  2014-08-27 18:57     ` Lina Iyer
@ 2014-08-27 20:24       ` Kevin Hilman
  2014-08-27 20:31         ` Lina Iyer
  0 siblings, 1 reply; 21+ messages in thread
From: Kevin Hilman @ 2014-08-27 20:24 UTC (permalink / raw
  To: Lina Iyer
  Cc: daniel.lezcano, sboyd, davidb, galak, linux-arm-msm,
	lorenzo.pieralisi, msivasub

Lina Iyer <lina.iyer@linaro.org> writes:

> On Wed, Aug 27, 2014 at 10:18:24AM -0700, Kevin Hilman wrote:
>>Lina Iyer <lina.iyer@linaro.org> writes:
>>
>>> Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
>>
>>Why the move?  It looks like scm-boot.c still calls into the main
>>scm_call() stuff that still lives under arch/arm/mach-qcom, and not in
>>arm64, so I'm not seeing the motiviation for the change (and the
>>changelog didn't help explain either  :)
>>
>>Kevin
>
> I dint intend on moving the scm-boot for 64 bit purposes, but that
> would be a good argument :) My motivation was to move the scm-boot.h, but
> figured might as well clean up the mach-qcom in the process, per
> guidance.

Thanks for clarifying.

I suspect that should be a separate cleanup series with its own
descriptive changelog, because to me it only looks like a partial
cleanup since only some of the stuff was moved out, and it's not abvious
what it will be sharing that code.

Kevin

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 1/8] msm: scm: Move scm-boot files to drivers/soc and include/soc
  2014-08-27 20:24       ` Kevin Hilman
@ 2014-08-27 20:31         ` Lina Iyer
  0 siblings, 0 replies; 21+ messages in thread
From: Lina Iyer @ 2014-08-27 20:31 UTC (permalink / raw
  To: Kevin Hilman
  Cc: daniel.lezcano, sboyd, davidb, galak, linux-arm-msm,
	lorenzo.pieralisi, msivasub

On Wed, Aug 27, 2014 at 01:24:44PM -0700, Kevin Hilman wrote:
>Lina Iyer <lina.iyer@linaro.org> writes:
>
>> On Wed, Aug 27, 2014 at 10:18:24AM -0700, Kevin Hilman wrote:
>>>Lina Iyer <lina.iyer@linaro.org> writes:
>>>
>>>> Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
>>>
>>>Why the move?  It looks like scm-boot.c still calls into the main
>>>scm_call() stuff that still lives under arch/arm/mach-qcom, and not in
>>>arm64, so I'm not seeing the motiviation for the change (and the
>>>changelog didn't help explain either  :)
>>>
>>>Kevin
>>
>> I dint intend on moving the scm-boot for 64 bit purposes, but that
>> would be a good argument :) My motivation was to move the scm-boot.h, but
>> figured might as well clean up the mach-qcom in the process, per
>> guidance.
>
>Thanks for clarifying.
>
>I suspect that should be a separate cleanup series with its own
>descriptive changelog, because to me it only looks like a partial
>cleanup since only some of the stuff was moved out, and it's not abvious
>what it will be sharing that code.
Okay, I will split this change out of the series.

>
>Kevin

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2014-08-27 20:31 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-08-18 22:23 [PATCH v3 0/8] QCOM 8074 cpuidle driver Lina Iyer
2014-08-18 22:23 ` [PATCH v3 1/8] msm: scm: Move scm-boot files to drivers/soc and include/soc Lina Iyer
2014-08-27 17:18   ` Kevin Hilman
2014-08-27 18:57     ` Lina Iyer
2014-08-27 20:24       ` Kevin Hilman
2014-08-27 20:31         ` Lina Iyer
2014-08-18 22:23 ` [PATCH v3 2/8] msm: scm: Add SCM warmboot flags for quad core targets Lina Iyer
2014-08-18 22:23 ` [PATCH v3 3/8] qcom: spm: Add Subsystem Power Manager driver (SAW2) Lina Iyer
2014-08-19 14:07   ` Kumar Gala
2014-08-19 15:28     ` Lina Iyer
2014-08-18 22:23 ` [PATCH v3 4/8] qcom: spm-devices: Add SPM device manager for the SoC Lina Iyer
2014-08-19  9:29   ` Pramod Gurav
2014-08-19 14:51     ` Lina Iyer
2014-08-18 22:23 ` [PATCH v3 5/8] arm: dts: qcom: Add SPM device bindings for 8974 Lina Iyer
2014-08-18 22:23 ` [PATCH v3 6/8] qcom: msm-pm: Add cpu low power mode functions Lina Iyer
2014-08-18 22:23 ` [PATCH v3 7/8] qcom: cpuidle: Add cpuidle driver for QCOM cpus Lina Iyer
2014-08-19  7:41   ` Pramod Gurav
2014-08-19 14:54     ` Lina Iyer
2014-08-19 15:01       ` Pramod Gurav
2014-08-18 22:23 ` [PATCH v3 8/8] arm: dts: qcom: Add idle states device nodes for 8974 Lina Iyer
2014-08-19 15:30 ` [PATCH v3 0/8] QCOM 8074 cpuidle driver Lina Iyer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.