[PATCH v4 6/6] soc: qcom: rpmhpd: Add RPMh Power domain driver

2018-06-26 Thread Rajendra Nayak
The RPMh Power domain driver aggregates the corner votes from various
consumers for the ARC resources and communicates it to RPMh.

With RPMh we use 2 different numbering space for corners, one used
by the clients to express their performance needs, and another used
to communicate to RPMh hardware.

The clients express their performance requirements using a sparse
numbering space which are mapped to meaningful levels like RET, SVS,
NOMINAL, TURBO etc which then get mapped to another number space
between 0 and 15 which is communicated to RPMh. The sparse number space,
also referred to as vlvl is mapped to the continuous number space of 0
to 15, also referred to as hlvl, using command DB.

Some power domain clients could request a performance state only while
the CPU is active, while some others could request for a certain
performance state all the time regardless of the state of the CPU.
We handle this by internally aggregating the votes from both type of
clients and then send the aggregated votes to RPMh.

There are also 3 different types of Votes that are comunicated to RPMh
for every resource.
1. ACTIVE_ONLY: This specifies the requirement for the resource when the
CPU is active
2. SLEEP: This specifies the requirement for the resource when the CPU
is going to sleep
3. WAKE_ONLY: This specifies the requirement for the resource when the
CPU is coming out of sleep to active state

We add data for all power domains on sdm845 SoC as part of the patch.
The driver can be extended to support other SoCs which support RPMh

Signed-off-by: Rajendra Nayak 
Reviewed-by: Ulf Hansson 
---
 drivers/soc/qcom/Kconfig  |   9 +
 drivers/soc/qcom/Makefile |   1 +
 drivers/soc/qcom/rpmhpd.c | 406 ++
 3 files changed, 416 insertions(+)
 create mode 100644 drivers/soc/qcom/rpmhpd.c

diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 131da9d34a40..3cb6085a851d 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -74,6 +74,15 @@ config QCOM_RMTFS_MEM
 
  Say y here if you intend to boot the modem remoteproc.
 
+config QCOM_RPMHPD
+   bool "Qualcomm RPMh Power domain driver"
+   depends on QCOM_RPMH && QCOM_COMMAND_DB
+   help
+ QCOM RPMh Power domain driver to support power-domains with
+ performance states. The driver communicates a performance state
+ value to RPMh which then translates it into corresponding voltage
+ for the voltage rail.
+
 config QCOM_RPMPD
bool "Qualcomm RPM Power domain driver"
depends on MFD_QCOM_RPM && QCOM_SMD_RPM
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index 9550c170de93..499513f63bef 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_QCOM_SMSM)   += smsm.o
 obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
 obj-$(CONFIG_QCOM_APR) += apr.o
 obj-$(CONFIG_QCOM_RPMPD) += rpmpd.o
+obj-$(CONFIG_QCOM_RPMHPD) += rpmhpd.o
diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c
new file mode 100644
index ..a364fa5aac57
--- /dev/null
+++ b/drivers/soc/qcom/rpmhpd.c
@@ -0,0 +1,406 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.*/
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define domain_to_rpmhpd(domain) container_of(domain, struct rpmhpd, pd)
+
+#define DEFINE_RPMHPD_AO(_platform, _name, _active)\
+   static struct rpmhpd _platform##_##_active; \
+   static struct rpmhpd _platform##_##_name = {\
+   .pd = { .name = #_name, },  \
+   .peer = &_platform##_##_active, \
+   .res_name = #_name".lvl",   \
+   };  \
+   static struct rpmhpd _platform##_##_active = {  \
+   .pd = { .name = #_active, },\
+   .peer = &_platform##_##_name,   \
+   .active_only = true,\
+   .res_name = #_name".lvl",   \
+   }
+
+#define DEFINE_RPMHPD(_platform, _name)
\
+   static struct rpmhpd _platform##_##_name = {\
+   .pd = { .name = #_name, },  \
+   .res_name = #_name".lvl",   \
+   }
+
+/*
+ * This is the number of bytes used for each command DB aux data entry of an
+ * ARC resource.
+ */
+#define RPMH_ARC_LEVEL_SIZE2
+#define RPMH_ARC_MAX_LEVELS16
+
+/**
+ * struct rpmhpd - top level RPMh power domain resource data structure
+ 

[PATCH v4 6/6] soc: qcom: rpmhpd: Add RPMh Power domain driver

2018-06-26 Thread Rajendra Nayak
The RPMh Power domain driver aggregates the corner votes from various
consumers for the ARC resources and communicates it to RPMh.

With RPMh we use 2 different numbering space for corners, one used
by the clients to express their performance needs, and another used
to communicate to RPMh hardware.

The clients express their performance requirements using a sparse
numbering space which are mapped to meaningful levels like RET, SVS,
NOMINAL, TURBO etc which then get mapped to another number space
between 0 and 15 which is communicated to RPMh. The sparse number space,
also referred to as vlvl is mapped to the continuous number space of 0
to 15, also referred to as hlvl, using command DB.

Some power domain clients could request a performance state only while
the CPU is active, while some others could request for a certain
performance state all the time regardless of the state of the CPU.
We handle this by internally aggregating the votes from both type of
clients and then send the aggregated votes to RPMh.

There are also 3 different types of Votes that are comunicated to RPMh
for every resource.
1. ACTIVE_ONLY: This specifies the requirement for the resource when the
CPU is active
2. SLEEP: This specifies the requirement for the resource when the CPU
is going to sleep
3. WAKE_ONLY: This specifies the requirement for the resource when the
CPU is coming out of sleep to active state

We add data for all power domains on sdm845 SoC as part of the patch.
The driver can be extended to support other SoCs which support RPMh

Signed-off-by: Rajendra Nayak 
Reviewed-by: Ulf Hansson 
---
 drivers/soc/qcom/Kconfig  |   9 +
 drivers/soc/qcom/Makefile |   1 +
 drivers/soc/qcom/rpmhpd.c | 406 ++
 3 files changed, 416 insertions(+)
 create mode 100644 drivers/soc/qcom/rpmhpd.c

diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 131da9d34a40..3cb6085a851d 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -74,6 +74,15 @@ config QCOM_RMTFS_MEM
 
  Say y here if you intend to boot the modem remoteproc.
 
+config QCOM_RPMHPD
+   bool "Qualcomm RPMh Power domain driver"
+   depends on QCOM_RPMH && QCOM_COMMAND_DB
+   help
+ QCOM RPMh Power domain driver to support power-domains with
+ performance states. The driver communicates a performance state
+ value to RPMh which then translates it into corresponding voltage
+ for the voltage rail.
+
 config QCOM_RPMPD
bool "Qualcomm RPM Power domain driver"
depends on MFD_QCOM_RPM && QCOM_SMD_RPM
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index 9550c170de93..499513f63bef 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_QCOM_SMSM)   += smsm.o
 obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
 obj-$(CONFIG_QCOM_APR) += apr.o
 obj-$(CONFIG_QCOM_RPMPD) += rpmpd.o
+obj-$(CONFIG_QCOM_RPMHPD) += rpmhpd.o
diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c
new file mode 100644
index ..a364fa5aac57
--- /dev/null
+++ b/drivers/soc/qcom/rpmhpd.c
@@ -0,0 +1,406 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.*/
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define domain_to_rpmhpd(domain) container_of(domain, struct rpmhpd, pd)
+
+#define DEFINE_RPMHPD_AO(_platform, _name, _active)\
+   static struct rpmhpd _platform##_##_active; \
+   static struct rpmhpd _platform##_##_name = {\
+   .pd = { .name = #_name, },  \
+   .peer = &_platform##_##_active, \
+   .res_name = #_name".lvl",   \
+   };  \
+   static struct rpmhpd _platform##_##_active = {  \
+   .pd = { .name = #_active, },\
+   .peer = &_platform##_##_name,   \
+   .active_only = true,\
+   .res_name = #_name".lvl",   \
+   }
+
+#define DEFINE_RPMHPD(_platform, _name)
\
+   static struct rpmhpd _platform##_##_name = {\
+   .pd = { .name = #_name, },  \
+   .res_name = #_name".lvl",   \
+   }
+
+/*
+ * This is the number of bytes used for each command DB aux data entry of an
+ * ARC resource.
+ */
+#define RPMH_ARC_LEVEL_SIZE2
+#define RPMH_ARC_MAX_LEVELS16
+
+/**
+ * struct rpmhpd - top level RPMh power domain resource data structure
+