soc: qcom: Set QOS only to silver cluster

CDSPRM module implements a RPMSG interface to communicate with CDSP
while providing a way for CDSP to vote for CPU QoS to benefit CDSP
applications performance.Glink IRQ mostly is taken by the silver cluster.
CDSPRM driver vote for sliver cluster prevents collapsing gold cluster
This saves significant power.

Change-Id: I6cac71e7ab85d823dfc44b19dd85a0dde62455db
Acked-by: Sreekanth Gande <sgande@qti.qualcomm.com>
Signed-off-by: Bavyasritha Alahari <alahari@codeaurora.org>
This commit is contained in:
Bavyasritha Alahari 2021-09-06 18:00:15 +05:30 committed by Gerrit - the friendly Code Review server
parent 7edca00333
commit d05ee79996

View File

@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/completion.h>
#include <linux/string.h>
#include <linux/err.h>
@ -231,6 +232,7 @@ struct cdsprm {
bool b_rpmsg_register;
bool b_qosinitdone;
bool b_applyingNpuLimit;
bool b_silver_en;
int latency_request;
int b_cdsprm_devinit;
int b_hvxrm_devinit;
@ -245,6 +247,9 @@ struct cdsprm {
int (*set_l3_freq_cached)(unsigned int freq_khz);
int (*set_corner_limit)(enum cdsprm_npu_corner);
int (*set_corner_limit_cached)(enum cdsprm_npu_corner);
u32 *coreno;
u32 corecount;
struct dev_pm_qos_request *dev_pm_qos_req;
};
static struct cdsprm gcdsprm;
@ -594,8 +599,84 @@ void cdsprm_unregister_cdspl3gov(void)
}
EXPORT_SYMBOL(cdsprm_unregister_cdspl3gov);
static void qos_cores_init(struct device *dev)
{
int i, err = 0;
u32 *cpucores = NULL;
of_find_property(dev->of_node,
"qcom,qos-cores", &gcdsprm.corecount);
if (gcdsprm.corecount) {
gcdsprm.corecount /= sizeof(u32);
cpucores = kcalloc(gcdsprm.corecount,
sizeof(u32), GFP_KERNEL);
if (cpucores == NULL) {
dev_err(dev,
"kcalloc failed for cpucores\n");
gcdsprm.b_silver_en = false;
} else {
for (i = 0; i < gcdsprm.corecount; i++) {
err = of_property_read_u32_index(dev->of_node,
"qcom,qos-cores", i, &cpucores[i]);
if (err) {
dev_err(dev,
"%s: failed to read QOS coree for core:%d\n",
__func__, i);
gcdsprm.b_silver_en = false;
}
}
gcdsprm.coreno = cpucores;
gcdsprm.dev_pm_qos_req = kcalloc(gcdsprm.corecount,
sizeof(struct dev_pm_qos_request), GFP_KERNEL);
if (gcdsprm.dev_pm_qos_req == NULL) {
dev_err(dev,
"kcalloc failed for dev_pm_qos_req\n");
gcdsprm.b_silver_en = false;
}
}
}
}
static void set_qos_latency(int latency)
{
int err = 0;
u32 ii = 0;
int cpu;
if (gcdsprm.b_silver_en) {
for (ii = 0; ii < gcdsprm.corecount; ii++) {
cpu = gcdsprm.coreno[ii];
if (!gcdsprm.qos_request) {
err = dev_pm_qos_add_request(
get_cpu_device(cpu),
&gcdsprm.dev_pm_qos_req[ii],
DEV_PM_QOS_RESUME_LATENCY,
latency);
} else {
err = dev_pm_qos_update_request(
&gcdsprm.dev_pm_qos_req[ii],
latency);
}
if (err < 0) {
pr_err("%s: %s: PM voting cpu:%d fail,err %d,QoS update %d\n",
current->comm, __func__, cpu,
err, gcdsprm.qos_request);
break;
}
}
if (err >= 0)
gcdsprm.qos_request = true;
} else {
if (!gcdsprm.qos_request) {
cpu_latency_qos_add_request(&gcdsprm.pm_qos_req, latency);
gcdsprm.qos_request = true;
@ -604,6 +685,7 @@ static void set_qos_latency(int latency)
latency);
}
}
}
static void process_rm_request(struct sysmon_msg *msg)
{
@ -645,9 +727,9 @@ static void process_rm_request(struct sysmon_msg *msg)
} else if ((rm_msg->b_qos_flag ==
SYSMON_CDSP_QOS_FLAG_DISABLE) &&
(gcdsprm.latency_request !=
QOS_LATENCY_DISABLE_VALUE)) {
set_qos_latency(QOS_LATENCY_DISABLE_VALUE);
gcdsprm.latency_request = QOS_LATENCY_DISABLE_VALUE;
PM_QOS_RESUME_LATENCY_DEFAULT_VALUE)) {
set_qos_latency(PM_QOS_RESUME_LATENCY_DEFAULT_VALUE);
gcdsprm.latency_request = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE;
pr_debug("Set qos latency to %d\n",
gcdsprm.latency_request);
}
@ -688,8 +770,8 @@ static void process_delayed_rm_request(struct work_struct *work)
curr_timestamp = __arch_counter_get_cntvct();
}
set_qos_latency(QOS_LATENCY_DISABLE_VALUE);
gcdsprm.latency_request = QOS_LATENCY_DISABLE_VALUE;
set_qos_latency(PM_QOS_RESUME_LATENCY_DEFAULT_VALUE);
gcdsprm.latency_request = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE;
pr_debug("Set qos latency to %d\n", gcdsprm.latency_request);
gcdsprm.dt_state = CDSP_DELAY_THREAD_EXITING;
@ -1148,6 +1230,12 @@ static int cdsp_rm_driver_probe(struct platform_device *pdev)
struct thermal_cooling_device *tcdev = 0;
unsigned int cooling_cells = 0;
gcdsprm.b_silver_en = of_property_read_bool(dev->of_node,
"qcom,qos-cores");
if (gcdsprm.b_silver_en)
qos_cores_init(dev);
if (of_property_read_u32(dev->of_node,
"qcom,qos-latency-us", &gcdsprm.qos_latency_us)) {
return -EINVAL;
@ -1505,8 +1593,8 @@ static void __exit cdsprm_exit(void)
pr_info("Exit module called\n");
if (gcdsprm.qos_request) {
set_qos_latency(QOS_LATENCY_DISABLE_VALUE);
gcdsprm.latency_request = QOS_LATENCY_DISABLE_VALUE;
set_qos_latency(PM_QOS_RESUME_LATENCY_DEFAULT_VALUE);
gcdsprm.latency_request = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE;
}
if (gcdsprm.hvx_tcdev)