Re: [PATCH v4 19/20] cpufreq: add support for CPU DVFS based on SCMI message protocol

2017-11-06 Thread Viresh Kumar
On 03-11-17, 14:47, Sudeep Holla wrote:
> On some ARM based systems, a separate Cortex-M based System Control
> Processor(SCP) provides the overall power, clock, reset and system
> control including CPU DVFS. SCMI Message Protocol is used to
> communicate with the SCP.
> 
> This patch adds a cpufreq driver for such systems using SCMI interface
> to drive CPU DVFS.
> 
> Cc: "Rafael J. Wysocki" 
> Cc: Viresh Kumar 
> Cc: linux...@vger.kernel.org
> Signed-off-by: Sudeep Holla 
> ---
>  MAINTAINERS|   2 +-
>  drivers/cpufreq/Kconfig.arm|  11 ++
>  drivers/cpufreq/Makefile   |   1 +
>  drivers/cpufreq/scmi-cpufreq.c | 274 
> +
>  4 files changed, 287 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/cpufreq/scmi-cpufreq.c

Acked-by: Viresh Kumar 

-- 
viresh


[PATCH v4 19/20] cpufreq: add support for CPU DVFS based on SCMI message protocol

2017-11-03 Thread Sudeep Holla
On some ARM based systems, a separate Cortex-M based System Control
Processor(SCP) provides the overall power, clock, reset and system
control including CPU DVFS. SCMI Message Protocol is used to
communicate with the SCP.

This patch adds a cpufreq driver for such systems using SCMI interface
to drive CPU DVFS.

Cc: "Rafael J. Wysocki" 
Cc: Viresh Kumar 
Cc: linux...@vger.kernel.org
Signed-off-by: Sudeep Holla 
---
 MAINTAINERS|   2 +-
 drivers/cpufreq/Kconfig.arm|  11 ++
 drivers/cpufreq/Makefile   |   1 +
 drivers/cpufreq/scmi-cpufreq.c | 274 +
 4 files changed, 287 insertions(+), 1 deletion(-)
 create mode 100644 drivers/cpufreq/scmi-cpufreq.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 1f9004d68ad4..f0a4251461a7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12955,7 +12955,7 @@ L:  linux-arm-ker...@lists.infradead.org
 S: Maintained
 F: Documentation/devicetree/bindings/arm/arm,sc[mp]i.txt
 F: drivers/clk/clk-sc[mp]i.c
-F: drivers/cpufreq/scpi-cpufreq.c
+F: drivers/cpufreq/sc[mp]i-cpufreq.c
 F: drivers/firmware/arm_scpi.c
 F: drivers/firmware/arm_scmi/
 F: include/linux/sc[mp]i_protocol.h
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index bdce4488ded1..e21f84cbd9b4 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -205,6 +205,17 @@ config ARM_SA1100_CPUFREQ
 config ARM_SA1110_CPUFREQ
bool
 
+config ARM_SCMI_CPUFREQ
+   tristate "SCMI based CPUfreq driver"
+   depends on ARM_SCMI_PROTOCOL || COMPILE_TEST
+   select PM_OPP
+   help
+ This adds the CPUfreq driver support for ARM platforms using SCMI
+ protocol for CPU power management.
+
+ This driver uses SCMI Message Protocol driver to interact with the
+ firmware providing the CPU DVFS functionality.
+
 config ARM_SCPI_CPUFREQ
 tristate "SCPI based CPUfreq driver"
depends on ARM_BIG_LITTLE_CPUFREQ && ARM_SCPI_PROTOCOL && 
COMMON_CLK_SCPI
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index c7af9b2a255e..1206207f9b62 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -71,6 +71,7 @@ obj-$(CONFIG_ARM_S3C64XX_CPUFREQ) += s3c64xx-cpufreq.o
 obj-$(CONFIG_ARM_S5PV210_CPUFREQ)  += s5pv210-cpufreq.o
 obj-$(CONFIG_ARM_SA1100_CPUFREQ)   += sa1100-cpufreq.o
 obj-$(CONFIG_ARM_SA1110_CPUFREQ)   += sa1110-cpufreq.o
+obj-$(CONFIG_ARM_SCMI_CPUFREQ) += scmi-cpufreq.o
 obj-$(CONFIG_ARM_SCPI_CPUFREQ) += scpi-cpufreq.o
 obj-$(CONFIG_ARM_SPEAR_CPUFREQ)+= spear-cpufreq.o
 obj-$(CONFIG_ARM_STI_CPUFREQ)  += sti-cpufreq.o
diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
new file mode 100644
index ..b1057a13e6a7
--- /dev/null
+++ b/drivers/cpufreq/scmi-cpufreq.c
@@ -0,0 +1,274 @@
+/*
+ * System Control and Power Interface (SCMI) based CPUFreq Interface driver
+ *
+ * Copyright (C) 2017 ARM Ltd.
+ * Sudeep Holla 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct scmi_data {
+   int domain_id;
+   struct device *cpu_dev;
+   struct thermal_cooling_device *cdev;
+};
+
+static const struct scmi_handle *handle;
+
+unsigned int scmi_cpufreq_get_rate(unsigned int cpu)
+{
+   struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu);
+   struct scmi_perf_ops *perf_ops = handle->perf_ops;
+   struct scmi_data *priv = policy->driver_data;
+   unsigned long rate;
+   int ret;
+
+   ret = perf_ops->freq_get(handle, priv->domain_id, &rate, false);
+   if (ret)
+   return 0;
+   return rate / 1000;
+}
+
+/*
+ * perf_ops->freq_set is not a synchronous, the actual OPP change will
+ * happen asynchronously and can get notified if the events are
+ * subscribed for by the SCMI firmware
+ */
+static int
+scmi_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index)
+{
+   struct scmi_data *priv = policy->driver_data;
+   struct scmi_perf_ops *perf_ops = handle->perf_ops;
+   u64 freq = policy->freq_table[index].frequency * 1000;
+
+   return perf_ops->freq_set(handle, priv->domain_id, freq, false);
+}
+
+static int
+scmi_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
+{
+   int cpu, domain, tdomain;
+   struct device *tcpu_dev;
+
+   domain = handle->perf_op