devfreq: msm_adreno_tz: Import Sony Changes
Signed-off-by: Sorayukii <sorayukii69@gmail.com>
This commit is contained in:
parent
aeb406a759
commit
84b9e8c0d8
1 changed files with 229 additions and 2 deletions
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
static DEFINE_SPINLOCK(tz_lock);
|
||||
static DEFINE_SPINLOCK(sample_lock);
|
||||
static DEFINE_SPINLOCK(sample_load_lock);
|
||||
static DEFINE_SPINLOCK(suspend_lock);
|
||||
/*
|
||||
* FLOOR is 5msec to capture up to 3 re-draws
|
||||
|
|
@ -58,9 +59,26 @@ static DEFINE_SPINLOCK(suspend_lock);
|
|||
|
||||
#define TAG "msm_adreno_tz: "
|
||||
|
||||
static u64 suspend_time;
|
||||
static u64 suspend_start;
|
||||
#define USEC_PER_MINUTE (1*60*1000*1000)
|
||||
#define NMAX (15*60*60+1)
|
||||
|
||||
struct gpu_load_data {
|
||||
unsigned long total_time;
|
||||
unsigned long busy_time;
|
||||
u64 update_time;
|
||||
};
|
||||
|
||||
struct gpu_load_queue {
|
||||
struct gpu_load_data *gpu_load;
|
||||
int head;
|
||||
int tail;
|
||||
};
|
||||
|
||||
static u64 suspend_time, suspend_time_idd;
|
||||
static u64 suspend_start, suspend_start_idd;
|
||||
static unsigned long acc_total, acc_relative_busy;
|
||||
static unsigned long gpu_load_total, gpu_load_rel_busy;
|
||||
static struct gpu_load_queue *gpu_load_infos;
|
||||
|
||||
static struct msm_adreno_extended_profile *partner_gpu_profile;
|
||||
static void do_partner_start_event(struct work_struct *work);
|
||||
|
|
@ -88,6 +106,21 @@ u64 suspend_time_ms(void)
|
|||
return time_diff;
|
||||
}
|
||||
|
||||
u64 suspend_time_ms_idd(void)
|
||||
{
|
||||
u64 suspend_sampling_time;
|
||||
u64 time_diff = 0;
|
||||
|
||||
if (suspend_start_idd == 0)
|
||||
return 0;
|
||||
|
||||
suspend_sampling_time = (u64)ktime_to_ms(ktime_get());
|
||||
time_diff = suspend_sampling_time - suspend_start_idd;
|
||||
/* Update the suspend_start sample again */
|
||||
suspend_start_idd = suspend_sampling_time;
|
||||
return time_diff;
|
||||
}
|
||||
|
||||
static ssize_t gpu_load_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
|
|
@ -109,6 +142,135 @@ static ssize_t gpu_load_show(struct device *dev,
|
|||
return snprintf(buf, PAGE_SIZE, "%lu\n", sysfs_busy_perc);
|
||||
}
|
||||
|
||||
int findItem(int head, int tail, u64 refTime)
|
||||
{
|
||||
int low = head, high = tail, middle;
|
||||
u64 update_time;
|
||||
|
||||
while (low < high) {
|
||||
middle = (low + high) / 2;
|
||||
update_time =
|
||||
gpu_load_infos->gpu_load[middle % NMAX].update_time;
|
||||
|
||||
if (update_time <= refTime)
|
||||
low = middle + 1;
|
||||
else if (update_time > refTime)
|
||||
high = middle - 1;
|
||||
}
|
||||
|
||||
update_time = gpu_load_infos->gpu_load[low % NMAX].update_time;
|
||||
if (update_time > refTime)
|
||||
low = low - 1;
|
||||
|
||||
if (low < tail) {
|
||||
u64 l = gpu_load_infos->gpu_load[low % NMAX].update_time;
|
||||
u64 r = gpu_load_infos->gpu_load[(low+1) % NMAX].update_time;
|
||||
|
||||
if (r - refTime < refTime - l)
|
||||
low = low + 1;
|
||||
}
|
||||
return low % NMAX;
|
||||
}
|
||||
|
||||
unsigned long cal_gpu_load(u64 current_time, u64 update_time,
|
||||
u64 begin_time, int minutes)
|
||||
{
|
||||
unsigned long sysfs_busy_perc;
|
||||
unsigned long tmp_act_relative_busy, tmp_act_total;
|
||||
int tail = gpu_load_infos->tail, head = gpu_load_infos->head;
|
||||
|
||||
if (current_time - update_time > minutes * USEC_PER_MINUTE) {
|
||||
sysfs_busy_perc = 0;
|
||||
} else {
|
||||
int tmpIndex = head;
|
||||
|
||||
if (current_time - begin_time <= minutes * USEC_PER_MINUTE) {
|
||||
tmpIndex = head;
|
||||
} else {
|
||||
u64 begin = current_time - minutes * USEC_PER_MINUTE;
|
||||
int tmpTail = (tail < head) ? tail + NMAX : tail;
|
||||
|
||||
tmpIndex = findItem(head, tmpTail-1, begin);
|
||||
}
|
||||
|
||||
tmp_act_relative_busy =
|
||||
gpu_load_infos->gpu_load[tail-1].busy_time -
|
||||
gpu_load_infos->gpu_load[tmpIndex].busy_time;
|
||||
|
||||
tmp_act_total = current_time -
|
||||
gpu_load_infos->gpu_load[tmpIndex].update_time;
|
||||
|
||||
sysfs_busy_perc = (tmp_act_relative_busy * 100 * 10) /
|
||||
tmp_act_total;
|
||||
}
|
||||
return sysfs_busy_perc;
|
||||
}
|
||||
|
||||
void convert_int_to_string(unsigned long perc, char *str, unsigned int size)
|
||||
{
|
||||
char low[6] = "0";
|
||||
char mid[] = ".";
|
||||
|
||||
snprintf(str, sizeof(low), "%lu", (perc / 10));
|
||||
snprintf(low, sizeof(low), "%lu", (perc % 10));
|
||||
strlcat(str, mid, size);
|
||||
strlcat(str, low, size);
|
||||
}
|
||||
|
||||
static ssize_t gpu_period_load_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
unsigned long sysfs_busy_perc[3];
|
||||
int tail, head;
|
||||
char load[3][6] = {"0", "0", "0"};
|
||||
int i;
|
||||
unsigned int size;
|
||||
spin_lock(&sample_load_lock);
|
||||
tail = gpu_load_infos->tail;
|
||||
head = gpu_load_infos->head;
|
||||
|
||||
if (tail == head) {
|
||||
sysfs_busy_perc[0] = 0;
|
||||
sysfs_busy_perc[1] = 0;
|
||||
sysfs_busy_perc[2] = 0;
|
||||
} else {
|
||||
u64 current_time = (u64)ktime_to_us(ktime_get());
|
||||
u64 update_time = gpu_load_infos->gpu_load[tail-1].update_time;
|
||||
u64 begin_time = gpu_load_infos->gpu_load[head].update_time;
|
||||
|
||||
sysfs_busy_perc[0] = cal_gpu_load(current_time,
|
||||
update_time, begin_time, 1);
|
||||
sysfs_busy_perc[1] = cal_gpu_load(current_time,
|
||||
update_time, begin_time, 5);
|
||||
sysfs_busy_perc[2] = cal_gpu_load(current_time,
|
||||
update_time, begin_time, 15);
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
size = sizeof(load[i]);
|
||||
convert_int_to_string(sysfs_busy_perc[i], load[i], size);
|
||||
}
|
||||
|
||||
spin_unlock(&sample_load_lock);
|
||||
return snprintf(buf, PAGE_SIZE, "%s %s %s\n",
|
||||
load[0],
|
||||
load[1],
|
||||
load[2]
|
||||
);
|
||||
}
|
||||
|
||||
static ssize_t gpu_load_idd_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
unsigned long busy, total;
|
||||
spin_lock(&sample_load_lock);
|
||||
busy = gpu_load_rel_busy;
|
||||
total = gpu_load_total;
|
||||
spin_unlock(&sample_load_lock);
|
||||
return snprintf(buf, PAGE_SIZE, "%lu %lu\n", busy, total);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the time in ms for which gpu was in suspend state
|
||||
* since last time the entry is read.
|
||||
|
|
@ -134,7 +296,30 @@ static ssize_t suspend_time_show(struct device *dev,
|
|||
return snprintf(buf, PAGE_SIZE, "%llu\n", time_diff);
|
||||
}
|
||||
|
||||
static ssize_t suspend_time_idd_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
u64 time_diff = 0;
|
||||
|
||||
spin_lock(&suspend_lock);
|
||||
time_diff = suspend_time_ms_idd();
|
||||
/*
|
||||
* Adding the previous suspend time also as the gpu
|
||||
* can go and come out of suspend states in between
|
||||
* reads also and we should have the total suspend
|
||||
* since last read.
|
||||
*/
|
||||
suspend_time_idd += time_diff;
|
||||
spin_unlock(&suspend_lock);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%llu\n", suspend_time_idd);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(gpu_load, 0444, gpu_load_show, NULL);
|
||||
static DEVICE_ATTR(gpu_period_load, 0444, gpu_period_load_show, NULL);
|
||||
static DEVICE_ATTR(gpu_load_idd, 0444, gpu_load_idd_show, NULL);
|
||||
static DEVICE_ATTR(gpu_suspend_idd, 0444, suspend_time_idd_show, NULL);
|
||||
|
||||
static DEVICE_ATTR(suspend_time, 0444,
|
||||
suspend_time_show,
|
||||
|
|
@ -142,10 +327,30 @@ static DEVICE_ATTR(suspend_time, 0444,
|
|||
|
||||
static const struct device_attribute *adreno_tz_attr_list[] = {
|
||||
&dev_attr_gpu_load,
|
||||
&dev_attr_gpu_period_load,
|
||||
&dev_attr_gpu_load_idd,
|
||||
&dev_attr_gpu_suspend_idd,
|
||||
&dev_attr_suspend_time,
|
||||
NULL
|
||||
};
|
||||
|
||||
void store_work_load(unsigned long gpu_load_total, unsigned long gpu_load_busy)
|
||||
{
|
||||
/* Queue item to gpu_load_queue */
|
||||
int index = gpu_load_infos->tail;
|
||||
int head = gpu_load_infos->head;
|
||||
|
||||
gpu_load_infos->gpu_load[index].total_time = gpu_load_total;
|
||||
gpu_load_infos->gpu_load[index].busy_time = gpu_load_busy;
|
||||
gpu_load_infos->gpu_load[index].update_time =
|
||||
(u64)ktime_to_us(ktime_get());
|
||||
|
||||
if ((index + 1) % NMAX == head)
|
||||
gpu_load_infos->head = (head + 1) % NMAX;
|
||||
|
||||
gpu_load_infos->tail = (index + 1) % NMAX;
|
||||
}
|
||||
|
||||
void compute_work_load(struct devfreq_dev_status *stats,
|
||||
struct devfreq_msm_adreno_tz_data *priv,
|
||||
struct devfreq *devfreq)
|
||||
|
|
@ -164,6 +369,15 @@ void compute_work_load(struct devfreq_dev_status *stats,
|
|||
acc_relative_busy += busy;
|
||||
|
||||
spin_unlock(&sample_lock);
|
||||
|
||||
spin_lock(&sample_load_lock);
|
||||
gpu_load_total += stats->total_time;
|
||||
gpu_load_rel_busy += (stats->busy_time * stats->current_frequency) /
|
||||
devfreq->profile->freq_table[0];
|
||||
|
||||
store_work_load(gpu_load_total, gpu_load_rel_busy);
|
||||
|
||||
spin_unlock(&sample_load_lock);
|
||||
}
|
||||
|
||||
/* Trap into the TrustZone, and call funcs there. */
|
||||
|
|
@ -236,6 +450,14 @@ static int __secure_tz_update_entry3(unsigned int *scm_data, u32 size_scm_data,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void tz_init_gpuloadinfos(void)
|
||||
{
|
||||
gpu_load_infos = kzalloc(sizeof(struct gpu_load_queue), GFP_KERNEL);
|
||||
gpu_load_infos->head = gpu_load_infos->tail = 0;
|
||||
gpu_load_infos->gpu_load =
|
||||
kcalloc(NMAX, sizeof(struct gpu_load_data), GFP_KERNEL);
|
||||
}
|
||||
|
||||
static int tz_init_ca(struct devfreq_msm_adreno_tz_data *priv)
|
||||
{
|
||||
unsigned int tz_ca_data[2];
|
||||
|
|
@ -275,6 +497,8 @@ static int tz_init(struct devfreq_msm_adreno_tz_data *priv,
|
|||
unsigned int *version, u32 size_version)
|
||||
{
|
||||
int ret;
|
||||
|
||||
tz_init_gpuloadinfos();
|
||||
/* Make sure all CMD IDs are avaialble */
|
||||
if (scm_is_call_available(SCM_SVC_DCVS, TZ_INIT_ID)) {
|
||||
ret = scm_call(SCM_SVC_DCVS, TZ_INIT_ID, tz_pwrlevels,
|
||||
|
|
@ -575,6 +799,7 @@ static int tz_handler(struct devfreq *devfreq, unsigned int event, void *data)
|
|||
spin_lock(&suspend_lock);
|
||||
/* Collect the start sample for suspend time */
|
||||
suspend_start = (u64)ktime_to_ms(ktime_get());
|
||||
suspend_start_idd = suspend_start;
|
||||
spin_unlock(&suspend_lock);
|
||||
}
|
||||
break;
|
||||
|
|
@ -582,8 +807,10 @@ static int tz_handler(struct devfreq *devfreq, unsigned int event, void *data)
|
|||
case DEVFREQ_GOV_RESUME:
|
||||
spin_lock(&suspend_lock);
|
||||
suspend_time += suspend_time_ms();
|
||||
suspend_time_idd += suspend_time_ms_idd();
|
||||
/* Reset the suspend_start when gpu resumes */
|
||||
suspend_start = 0;
|
||||
suspend_start_idd = 0;
|
||||
spin_unlock(&suspend_lock);
|
||||
/* fallthrough */
|
||||
case DEVFREQ_GOV_INTERVAL:
|
||||
|
|
|
|||
Loading…
Reference in a new issue