diff options
| author | Deepak Kumar <dkumar@codeaurora.org> | 2016-02-01 19:48:46 +0530 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-25 16:04:07 -0700 |
| commit | e22d001089f69c82f26a015a7f63b2330e6a4298 (patch) | |
| tree | 1e0b0eff98c193dd3ed4104a69517319a78f6aa8 /drivers/devfreq | |
| parent | f50a4a1dc7a0196eb94bfaa18abb95dd387fee1e (diff) | |
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>
Diffstat (limited to 'drivers/devfreq')
| -rw-r--r-- | drivers/devfreq/governor_msm_adreno_tz.c | 89 |
1 files changed, 82 insertions, 7 deletions
diff --git a/drivers/devfreq/governor_msm_adreno_tz.c b/drivers/devfreq/governor_msm_adreno_tz.c index e1635cc64b7e..eb5e3fc127e0 100644 --- a/drivers/devfreq/governor_msm_adreno_tz.c +++ b/drivers/devfreq/governor_msm_adreno_tz.c @@ -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; |
