mirror of
https://github.com/torvalds/linux.git
synced 2026-06-08 14:42:37 +02:00
cpufreq: interactive: add touch boost and init some param on rockchip platform
Change-Id: Iebc2edaedbeeb5a3a758b963230b5f95136b2af6 Signed-off-by: Chen Liang <cl@rock-chips.com>
This commit is contained in:
parent
5d9ccf47ca
commit
0d162fd338
|
|
@ -19,6 +19,9 @@
|
|||
#include <linux/cpu.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#ifdef CONFIG_ARCH_ROCKCHIP
|
||||
#include <linux/input.h>
|
||||
#endif
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/rwsem.h>
|
||||
|
|
@ -106,6 +109,14 @@ struct cpufreq_interactive_tunables {
|
|||
int boostpulse_duration_val;
|
||||
/* End time of boost pulse in ktime converted to usecs */
|
||||
u64 boostpulse_endtime;
|
||||
#ifdef CONFIG_ARCH_ROCKCHIP
|
||||
/* Frequency to which a touch boost takes the cpus to */
|
||||
unsigned long touchboost_freq;
|
||||
/* Duration of a touchboost pulse in usecs */
|
||||
int touchboostpulse_duration_val;
|
||||
/* End time of touchboost pulse in ktime converted to usecs */
|
||||
u64 touchboostpulse_endtime;
|
||||
#endif
|
||||
bool boosted;
|
||||
/*
|
||||
* Max additional time to wait in idle, beyond timer_rate, at speeds
|
||||
|
|
@ -383,7 +394,12 @@ static void cpufreq_interactive_timer(unsigned long data)
|
|||
pcpu->policy->cur < tunables->hispeed_freq)
|
||||
new_freq = tunables->hispeed_freq;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_ROCKCHIP
|
||||
if ((now < tunables->touchboostpulse_endtime) &&
|
||||
(new_freq < tunables->touchboost_freq)) {
|
||||
new_freq = tunables->touchboost_freq;
|
||||
}
|
||||
#endif
|
||||
if (pcpu->policy->cur >= tunables->hispeed_freq &&
|
||||
new_freq > pcpu->policy->cur &&
|
||||
now - pcpu->pol_hispeed_val_time <
|
||||
|
|
@ -1133,6 +1149,147 @@ static struct notifier_block cpufreq_interactive_idle_nb = {
|
|||
.notifier_call = cpufreq_interactive_idle_notifier,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ARCH_ROCKCHIP
|
||||
static void cpufreq_interactive_input_event(struct input_handle *handle,
|
||||
unsigned int type,
|
||||
unsigned int code,
|
||||
int value)
|
||||
{
|
||||
u64 now, endtime;
|
||||
int i;
|
||||
int anyboost = 0;
|
||||
unsigned long flags[2];
|
||||
struct cpufreq_interactive_cpuinfo *pcpu;
|
||||
struct cpufreq_interactive_tunables *tunables;
|
||||
|
||||
if ((type != EV_ABS) && (type != EV_KEY))
|
||||
return;
|
||||
|
||||
trace_cpufreq_interactive_boost("touch");
|
||||
spin_lock_irqsave(&speedchange_cpumask_lock, flags[0]);
|
||||
|
||||
now = ktime_to_us(ktime_get());
|
||||
for_each_online_cpu(i) {
|
||||
pcpu = &per_cpu(cpuinfo, i);
|
||||
if (have_governor_per_policy())
|
||||
tunables = pcpu->policy->governor_data;
|
||||
else
|
||||
tunables = common_tunables;
|
||||
if (!tunables)
|
||||
continue;
|
||||
|
||||
endtime = now + tunables->touchboostpulse_duration_val;
|
||||
if (endtime < (tunables->touchboostpulse_endtime +
|
||||
10 * USEC_PER_MSEC))
|
||||
continue;
|
||||
tunables->touchboostpulse_endtime = endtime;
|
||||
|
||||
spin_lock_irqsave(&pcpu->target_freq_lock, flags[1]);
|
||||
if (pcpu->target_freq < tunables->touchboost_freq) {
|
||||
pcpu->target_freq = tunables->touchboost_freq;
|
||||
cpumask_set_cpu(i, &speedchange_cpumask);
|
||||
pcpu->loc_hispeed_val_time =
|
||||
ktime_to_us(ktime_get());
|
||||
anyboost = 1;
|
||||
}
|
||||
|
||||
pcpu->floor_freq = tunables->touchboost_freq;
|
||||
pcpu->loc_floor_val_time = ktime_to_us(ktime_get());
|
||||
|
||||
spin_unlock_irqrestore(&pcpu->target_freq_lock, flags[1]);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&speedchange_cpumask_lock, flags[0]);
|
||||
|
||||
if (anyboost)
|
||||
wake_up_process(speedchange_task);
|
||||
}
|
||||
|
||||
static int cpufreq_interactive_input_connect(struct input_handler *handler,
|
||||
struct input_dev *dev,
|
||||
const struct input_device_id *id)
|
||||
{
|
||||
struct input_handle *handle;
|
||||
int error;
|
||||
|
||||
handle = kzalloc(sizeof(*handle), GFP_KERNEL);
|
||||
if (!handle)
|
||||
return -ENOMEM;
|
||||
|
||||
handle->dev = dev;
|
||||
handle->handler = handler;
|
||||
handle->name = "cpufreq";
|
||||
|
||||
error = input_register_handle(handle);
|
||||
if (error)
|
||||
goto err2;
|
||||
|
||||
error = input_open_device(handle);
|
||||
if (error)
|
||||
goto err1;
|
||||
|
||||
return 0;
|
||||
err1:
|
||||
input_unregister_handle(handle);
|
||||
err2:
|
||||
kfree(handle);
|
||||
return error;
|
||||
}
|
||||
|
||||
static void cpufreq_interactive_input_disconnect(struct input_handle *handle)
|
||||
{
|
||||
input_close_device(handle);
|
||||
input_unregister_handle(handle);
|
||||
kfree(handle);
|
||||
}
|
||||
|
||||
static const struct input_device_id cpufreq_interactive_ids[] = {
|
||||
{
|
||||
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
|
||||
INPUT_DEVICE_ID_MATCH_ABSBIT,
|
||||
.evbit = { BIT_MASK(EV_ABS) },
|
||||
.absbit = { [BIT_WORD(ABS_MT_POSITION_X)] =
|
||||
BIT_MASK(ABS_MT_POSITION_X) |
|
||||
BIT_MASK(ABS_MT_POSITION_Y) },
|
||||
},
|
||||
{
|
||||
.flags = INPUT_DEVICE_ID_MATCH_KEYBIT |
|
||||
INPUT_DEVICE_ID_MATCH_ABSBIT,
|
||||
.keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
|
||||
.absbit = { [BIT_WORD(ABS_X)] =
|
||||
BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
|
||||
},
|
||||
{
|
||||
.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
|
||||
.evbit = { BIT_MASK(EV_KEY) },
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct input_handler cpufreq_interactive_input_handler = {
|
||||
.event = cpufreq_interactive_input_event,
|
||||
.connect = cpufreq_interactive_input_connect,
|
||||
.disconnect = cpufreq_interactive_input_disconnect,
|
||||
.name = "cpufreq_interactive",
|
||||
.id_table = cpufreq_interactive_ids,
|
||||
};
|
||||
|
||||
static void rockchip_cpufreq_policy_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct cpufreq_interactive_tunables *tunables = policy->governor_data;
|
||||
|
||||
tunables->min_sample_time = 40 * USEC_PER_MSEC;
|
||||
tunables->boostpulse_duration_val = 40 * USEC_PER_MSEC;
|
||||
if (policy->cpu == 0) {
|
||||
tunables->hispeed_freq = 1008000;
|
||||
tunables->touchboostpulse_duration_val = 500 * USEC_PER_MSEC;
|
||||
tunables->touchboost_freq = 1200000;
|
||||
} else {
|
||||
tunables->hispeed_freq = 816000;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
|
||||
unsigned int event)
|
||||
{
|
||||
|
|
@ -1186,6 +1343,10 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
|
|||
common_tunables = tunables;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_ROCKCHIP
|
||||
rockchip_cpufreq_policy_init(policy);
|
||||
#endif
|
||||
|
||||
rc = sysfs_create_group(get_governor_parent_kobj(policy),
|
||||
get_sysfs_attr());
|
||||
if (rc) {
|
||||
|
|
@ -1201,6 +1362,10 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
|
|||
idle_notifier_register(&cpufreq_interactive_idle_nb);
|
||||
cpufreq_register_notifier(&cpufreq_notifier_block,
|
||||
CPUFREQ_TRANSITION_NOTIFIER);
|
||||
#ifdef CONFIG_ARCH_ROCKCHIP
|
||||
rc = input_register_handler(&cpufreq_interactive_input_handler);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -1208,6 +1373,9 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
|
|||
case CPUFREQ_GOV_POLICY_EXIT:
|
||||
if (!--tunables->usage_count) {
|
||||
if (policy->governor->initialized == 1) {
|
||||
#ifdef CONFIG_ARCH_ROCKCHIP
|
||||
input_unregister_handler(&cpufreq_interactive_input_handler);
|
||||
#endif
|
||||
cpufreq_unregister_notifier(&cpufreq_notifier_block,
|
||||
CPUFREQ_TRANSITION_NOTIFIER);
|
||||
idle_notifier_unregister(&cpufreq_interactive_idle_nb);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user