adsprpc: set QoS only to silver cluster

Glink IRQ mostly is taken by the silver cluster. RPC driver vote
for sliver cluster prevents collapsing gold cluster. This saves
significant power.

Depends-On: I8ec5056ea6929d39e74b6e97114094da0a264edb
Change-Id: Ic24bddceb7ae37d1182d2fca683c622b4ab71a55
Acked-by: Tadakamalla Krishnaiah <ktadakam@qti.qualcomm.com>
Signed-off-by: Mohammed Nayeem Ur Rahman <mohara@codeaurora.org>
Signed-off-by: Edgar Flores <edgarf@codeaurora.org>
This commit is contained in:
Mohammed Nayeem Ur Rahman 2019-11-13 20:30:23 +05:30 • committed by Gerrit - the friendly Code Review server
commit 79a6b962f0

View file

@ -292,6 +292,11 @@ struct gid_list {
unsigned int gidcount;
};
struct qos_cores {
int *coreno;
int corecount;
};
struct fastrpc_file;
struct fastrpc_buf {
@ -456,6 +461,7 @@ struct fastrpc_apps {
/* Non-secure subsystem like CDSP will use regular client */
struct wakeup_source *wake_source;
uint32_t duplicate_rsp_err_cnt;
struct qos_cores silvercores;
};
struct fastrpc_mmap {
@ -540,7 +546,7 @@ struct fastrpc_file {
struct hlist_head perf;
struct dentry *debugfs_file;
struct mutex perf_mutex;
struct pm_qos_request pm_qos_req;
struct dev_pm_qos_request *dev_pm_qos_req;
int qos_request;
struct mutex map_mutex;
struct mutex internal_map_mutex;
@ -4738,6 +4744,7 @@ static int fastrpc_file_free(struct fastrpc_file *fl)
mutex_destroy(&fl->perf_mutex);
mutex_destroy(&fl->map_mutex);
mutex_destroy(&fl->internal_map_mutex);
kfree(fl->dev_pm_qos_req);
kfree(fl);
return 0;
}
@ -4745,14 +4752,23 @@ static int fastrpc_file_free(struct fastrpc_file *fl)
static int fastrpc_device_release(struct inode *inode, struct file *file)
{
struct fastrpc_file *fl = (struct fastrpc_file *)file->private_data;
struct fastrpc_apps *me = &gfa;
u32 ii;
if (fl) {
if (fl->qos_request && pm_qos_request_active(&fl->pm_qos_req))
pm_qos_remove_request(&fl->pm_qos_req);
debugfs_remove(fl->debugfs_file);
fastrpc_file_free(fl);
file->private_data = NULL;
if (!fl)
return 0;
if (fl->qos_request && fl->dev_pm_qos_req) {
for (ii = 0; ii < me->silvercores.corecount; ii++) {
if (!dev_pm_qos_request_active(&fl->dev_pm_qos_req[ii]))
continue;
dev_pm_qos_remove_request(&fl->dev_pm_qos_req[ii]);
}
}
debugfs_remove(fl->debugfs_file);
fastrpc_file_free(fl);
file->private_data = NULL;
return 0;
}
@ -5099,6 +5115,10 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
hlist_add_head(&fl->hn, &me->drivers);
spin_unlock(&me->hlock);
mutex_init(&fl->perf_mutex);
fl->dev_pm_qos_req = kcalloc(me->silvercores.corecount,
sizeof(struct dev_pm_qos_request),
GFP_KERNEL);
return 0;
}
@ -5215,6 +5235,8 @@ static int fastrpc_internal_control(struct fastrpc_file *fl,
{
int err = 0;
unsigned int latency;
struct fastrpc_apps *me = &gfa;
u32 silver_core_count = me->silvercores.corecount, ii = 0, cpu;
VERIFY(err, !IS_ERR_OR_NULL(fl) && !IS_ERR_OR_NULL(fl->apps));
if (err) {
@ -5236,12 +5258,33 @@ static int fastrpc_internal_control(struct fastrpc_file *fl,
err = -EINVAL;
goto bail;
}
if (!fl->qos_request) {
pm_qos_add_request(&fl->pm_qos_req,
PM_QOS_CPU_DMA_LATENCY, latency);
VERIFY(err, me->silvercores.coreno && fl->dev_pm_qos_req);
if (err)
goto bail;
for (ii = 0; ii < silver_core_count; ii++) {
cpu = me->silvercores.coreno[ii];
if (!fl->qos_request) {
err = dev_pm_qos_add_request(
get_cpu_device(cpu),
&fl->dev_pm_qos_req[ii],
DEV_PM_QOS_RESUME_LATENCY,
latency);
} else {
err = dev_pm_qos_update_request(
&fl->dev_pm_qos_req[ii],
latency);
}
if (err < 0) {
pr_warn("adsprpc: %s: %s: PM voting for cpu:%d failed, err %d, QoS update %d\n",
current->comm, __func__, cpu,
err, fl->qos_request);
break;
}
}
if (err >= 0)
fl->qos_request = 1;
} else
pm_qos_update_request(&fl->pm_qos_req, latency);
/* Ensure CPU feature map updated to DSP for early WakeUp */
fastrpc_send_cpuinfo_to_dsp(fl);
@ -6004,6 +6047,39 @@ bail:
}
}
static void init_qos_cores_list(struct device *dev, char *prop_name,
struct qos_cores *silvercores)
{
int err = 0;
u32 len = 0, i = 0;
u32 *coreslist = NULL;
if (!of_find_property(dev->of_node, prop_name, &len))
goto bail;
if (len == 0)
goto bail;
len /= sizeof(u32);
VERIFY(err, NULL != (coreslist = kcalloc(len, sizeof(u32),
GFP_KERNEL)));
if (err)
goto bail;
for (i = 0; i < len; i++) {
err = of_property_read_u32_index(dev->of_node, prop_name, i,
&coreslist[i]);
if (err) {
pr_err("adsprpc: %s: failed to read QOS cores list\n",
__func__);
goto bail;
}
}
silvercores->coreno = coreslist;
silvercores->corecount = len;
bail:
if (err) {
kfree(coreslist);
}
}
static void fastrpc_init_privileged_gids(struct device *dev, char *prop_name,
struct gid_list *gidlist)
{
@ -6102,6 +6178,8 @@ static int fastrpc_probe(struct platform_device *pdev)
&gcinfo[0].rhvm);
fastrpc_init_privileged_gids(dev, "qcom,fastrpc-gids",
&me->gidlist);
init_qos_cores_list(dev, "qcom,qos-cores",
&me->silvercores);
of_property_read_u32(dev->of_node, "qcom,rpc-latency-us",
&me->latency);