adreno_tz: Use context aware dcvs calls, if available

Add support to use context aware dcvs, if it is supported
by TZ. Context aware dcvs helps in handling sudden workload
scenarios.

Change-Id: I5e6e6003a5c61eacb4f5af91910994919a5a7684
Signed-off-by: Deepak Kumar <dkumar@codeaurora.org>
Signed-off-by: Divya Ponnusamy <pdivya@codeaurora.org>
This commit is contained in:
Deepak Kumar 2016-02-01 19:48:46 +05:30 committed by David Keitel
parent f50a4a1dc7
commit e22d001089
2 changed files with 85 additions and 7 deletions

View file

@ -53,6 +53,8 @@ static DEFINE_SPINLOCK(suspend_lock);
#define TZ_V2_UPDATE_ID_64 0xA
#define TZ_V2_INIT_ID_64 0xB
#define TZ_V2_INIT_CA_ID_64 0xC
#define TZ_V2_UPDATE_WITH_CA_ID_64 0xD
#define TAG "msm_adreno_tz: "
@ -187,13 +189,13 @@ static int __secure_tz_reset_entry2(unsigned int *scm_data, u32 size_scm_data,
}
static int __secure_tz_update_entry3(unsigned int *scm_data, u32 size_scm_data,
int *val, u32 size_val, bool is_64)
int *val, u32 size_val, struct devfreq_msm_adreno_tz_data *priv)
{
int ret;
/* sync memory before sending the commands to tz */
__iowmb();
if (!is_64) {
if (!priv->is_64) {
spin_lock(&tz_lock);
ret = scm_call_atomic3(SCM_SVC_IO, TZ_UPDATE_ID,
scm_data[0], scm_data[1], scm_data[2]);
@ -201,13 +203,23 @@ static int __secure_tz_update_entry3(unsigned int *scm_data, u32 size_scm_data,
*val = ret;
} else {
if (is_scm_armv8()) {
unsigned int cmd_id;
struct scm_desc desc = {0};
desc.args[0] = scm_data[0];
desc.args[1] = scm_data[1];
desc.args[2] = scm_data[2];
desc.arginfo = SCM_ARGS(3);
ret = scm_call2(SCM_SIP_FNID(SCM_SVC_DCVS,
TZ_V2_UPDATE_ID_64), &desc);
if (!priv->ctxt_aware_enable) {
desc.arginfo = SCM_ARGS(3);
cmd_id = TZ_V2_UPDATE_ID_64;
} else {
/* Add context count infomration to update*/
desc.args[3] = scm_data[3];
desc.arginfo = SCM_ARGS(4);
cmd_id = TZ_V2_UPDATE_WITH_CA_ID_64;
}
ret = scm_call2(SCM_SIP_FNID(SCM_SVC_DCVS, cmd_id),
&desc);
*val = desc.ret[0];
} else {
ret = scm_call(SCM_SVC_DCVS, TZ_UPDATE_ID_64, scm_data,
@ -217,6 +229,40 @@ static int __secure_tz_update_entry3(unsigned int *scm_data, u32 size_scm_data,
return ret;
}
static int tz_init_ca(struct devfreq_msm_adreno_tz_data *priv)
{
unsigned int tz_ca_data[2];
struct scm_desc desc = {0};
unsigned int *tz_buf;
int ret;
/* Set data for TZ */
tz_ca_data[0] = priv->bin.ctxt_aware_target_pwrlevel;
tz_ca_data[1] = priv->bin.ctxt_aware_busy_penalty;
tz_buf = kzalloc(PAGE_ALIGN(sizeof(tz_ca_data)), GFP_KERNEL);
if (!tz_buf)
return -ENOMEM;
memcpy(tz_buf, tz_ca_data, sizeof(tz_ca_data));
/* Ensure memcpy completes execution */
mb();
dmac_flush_range(tz_buf,
tz_buf + PAGE_ALIGN(sizeof(tz_ca_data)));
desc.args[0] = virt_to_phys(tz_buf);
desc.args[1] = sizeof(tz_ca_data);
desc.arginfo = SCM_ARGS(2, SCM_RW, SCM_VAL);
ret = scm_call2(SCM_SIP_FNID(SCM_SVC_DCVS,
TZ_V2_INIT_CA_ID_64),
&desc);
kzfree(tz_buf);
return ret;
}
static int tz_init(struct devfreq_msm_adreno_tz_data *priv,
unsigned int *tz_pwrlevels, u32 size_pwrlevels,
unsigned int *version, u32 size_version)
@ -264,6 +310,30 @@ static int tz_init(struct devfreq_msm_adreno_tz_data *priv,
} else
ret = -EINVAL;
/* Initialize context aware feature, if enabled. */
if (!ret && priv->ctxt_aware_enable) {
if (priv->is_64 &&
(scm_is_call_available(SCM_SVC_DCVS,
TZ_V2_INIT_CA_ID_64)) &&
(scm_is_call_available(SCM_SVC_DCVS,
TZ_V2_UPDATE_WITH_CA_ID_64))) {
ret = tz_init_ca(priv);
/*
* If context aware feature intialization fails,
* just print an error message and return
* success as normal DCVS will still work.
*/
if (ret) {
pr_err(TAG "tz: context aware DCVS init failed\n");
priv->ctxt_aware_enable = false;
return 0;
}
} else {
pr_warn(TAG "tz: context aware DCVS not supported\n");
priv->ctxt_aware_enable = false;
}
}
return ret;
}
@ -274,7 +344,8 @@ static int tz_get_target_freq(struct devfreq *devfreq, unsigned long *freq,
struct devfreq_msm_adreno_tz_data *priv = devfreq->data;
struct devfreq_dev_status stats;
int val, level = 0;
unsigned int scm_data[3];
unsigned int scm_data[4];
int context_count = 0;
/* keeps stats.private_data == NULL */
result = devfreq->profile->get_dev_status(devfreq->dev.parent, &stats);
@ -287,6 +358,9 @@ static int tz_get_target_freq(struct devfreq *devfreq, unsigned long *freq,
priv->bin.total_time += stats.total_time;
priv->bin.busy_time += stats.busy_time;
if (stats.private_data)
context_count = *((int *)stats.private_data);
/* Update the GPU load statistics */
compute_work_load(&stats, priv, devfreq);
/*
@ -319,8 +393,9 @@ static int tz_get_target_freq(struct devfreq *devfreq, unsigned long *freq,
scm_data[0] = level;
scm_data[1] = priv->bin.total_time;
scm_data[2] = priv->bin.busy_time;
scm_data[3] = context_count;
__secure_tz_update_entry3(scm_data, sizeof(scm_data),
&val, sizeof(val), priv->is_64);
&val, sizeof(val), priv);
}
priv->bin.total_time = 0;
priv->bin.busy_time = 0;

View file

@ -28,6 +28,8 @@ struct devfreq_msm_adreno_tz_data {
struct {
s64 total_time;
s64 busy_time;
u32 ctxt_aware_target_pwrlevel;
u32 ctxt_aware_busy_penalty;
} bin;
struct {
u64 total_time;
@ -47,6 +49,7 @@ struct devfreq_msm_adreno_tz_data {
unsigned int device_id;
bool is_64;
bool disable_busy_time_burst;
bool ctxt_aware_enable;
};
struct msm_adreno_extended_profile {