forked from enlightenment/enlightenment
add intel pstate support in cpufreq for kernel 3.9 and newer.
This commit is contained in:
parent
0bf55848ab
commit
6b532aadad
|
@ -40,6 +40,7 @@ static void _button_cb_mouse_down(void *data, Evas *e, Evas_Object *obj, vo
|
||||||
static void _menu_cb_post(void *data, E_Menu *m);
|
static void _menu_cb_post(void *data, E_Menu *m);
|
||||||
static void _cpufreq_set_governor(const char *governor);
|
static void _cpufreq_set_governor(const char *governor);
|
||||||
static void _cpufreq_set_frequency(int frequency);
|
static void _cpufreq_set_frequency(int frequency);
|
||||||
|
static void _cpufreq_set_pstate(int min, int max, int turbo);
|
||||||
static Eina_Bool _cpufreq_cb_check(void *data);
|
static Eina_Bool _cpufreq_cb_check(void *data);
|
||||||
static Status *_cpufreq_status_new(void);
|
static Status *_cpufreq_status_new(void);
|
||||||
static void _cpufreq_status_free(Status *s);
|
static void _cpufreq_status_free(Status *s);
|
||||||
|
@ -62,6 +63,8 @@ static void _cpufreq_menu_auto_powersave(void *data, E_Menu *m, E_Menu_Item
|
||||||
static void _cpufreq_menu_governor(void *data, E_Menu *m, E_Menu_Item *mi);
|
static void _cpufreq_menu_governor(void *data, E_Menu *m, E_Menu_Item *mi);
|
||||||
static void _cpufreq_menu_powersave_governor(void *data, E_Menu *m, E_Menu_Item *mi);
|
static void _cpufreq_menu_powersave_governor(void *data, E_Menu *m, E_Menu_Item *mi);
|
||||||
static void _cpufreq_menu_frequency(void *data, E_Menu *m, E_Menu_Item *mi);
|
static void _cpufreq_menu_frequency(void *data, E_Menu *m, E_Menu_Item *mi);
|
||||||
|
static void _cpufreq_menu_pstate_min(void *data, E_Menu *m, E_Menu_Item *mi);
|
||||||
|
static void _cpufreq_menu_pstate_max(void *data, E_Menu *m, E_Menu_Item *mi);
|
||||||
static void _cpufreq_poll_interval_update(void);
|
static void _cpufreq_poll_interval_update(void);
|
||||||
|
|
||||||
static E_Config_DD *conf_edd = NULL;
|
static E_Config_DD *conf_edd = NULL;
|
||||||
|
@ -330,6 +333,47 @@ _button_cb_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cpufreq_config->status->pstate)
|
||||||
|
{
|
||||||
|
int set;
|
||||||
|
|
||||||
|
mo = e_menu_new();
|
||||||
|
cpufreq_config->menu_pstate1 = mo;
|
||||||
|
|
||||||
|
set = 0;
|
||||||
|
#define VALMIN(_n) \
|
||||||
|
mi = e_menu_item_new(mo); \
|
||||||
|
e_menu_item_label_set(mi, #_n); \
|
||||||
|
e_menu_item_radio_set(mi, 1); \
|
||||||
|
e_menu_item_radio_group_set(mi, 1); \
|
||||||
|
if ((!set) && (cpufreq_config->status->pstate_min <= _n)) \
|
||||||
|
{ set = 1; e_menu_item_toggle_set(mi, 1); } \
|
||||||
|
e_menu_item_callback_set(mi, _cpufreq_menu_pstate_min, (void *)_n)
|
||||||
|
VALMIN(0);
|
||||||
|
VALMIN(25);
|
||||||
|
VALMIN(50);
|
||||||
|
VALMIN(75);
|
||||||
|
VALMIN(100);
|
||||||
|
|
||||||
|
mo = e_menu_new();
|
||||||
|
cpufreq_config->menu_pstate2 = mo;
|
||||||
|
|
||||||
|
set = 0;
|
||||||
|
#define VALMAX(_n) \
|
||||||
|
mi = e_menu_item_new(mo); \
|
||||||
|
e_menu_item_label_set(mi, #_n); \
|
||||||
|
e_menu_item_radio_set(mi, 1); \
|
||||||
|
e_menu_item_radio_group_set(mi, 1); \
|
||||||
|
if ((!set) && (cpufreq_config->status->pstate_max <= _n)) \
|
||||||
|
{ set = 1; e_menu_item_toggle_set(mi, 1); } \
|
||||||
|
e_menu_item_callback_set(mi, _cpufreq_menu_pstate_max, (void *)_n)
|
||||||
|
VALMAX(5);
|
||||||
|
VALMAX(25);
|
||||||
|
VALMAX(50);
|
||||||
|
VALMAX(75);
|
||||||
|
VALMAX(100);
|
||||||
|
}
|
||||||
|
|
||||||
mg = e_menu_new();
|
mg = e_menu_new();
|
||||||
mi = e_menu_item_new(mg);
|
mi = e_menu_item_new(mg);
|
||||||
e_menu_item_label_set(mi, _("Time Between Updates"));
|
e_menu_item_label_set(mi, _("Time Between Updates"));
|
||||||
|
@ -354,6 +398,18 @@ _button_cb_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED_
|
||||||
e_menu_item_label_set(mi, _("Powersaving behavior"));
|
e_menu_item_label_set(mi, _("Powersaving behavior"));
|
||||||
e_menu_item_submenu_set(mi, cpufreq_config->menu_powersave);
|
e_menu_item_submenu_set(mi, cpufreq_config->menu_powersave);
|
||||||
}
|
}
|
||||||
|
if (cpufreq_config->menu_pstate1)
|
||||||
|
{
|
||||||
|
mi = e_menu_item_new(mg);
|
||||||
|
e_menu_item_label_set(mi, _("Power State Min"));
|
||||||
|
e_menu_item_submenu_set(mi, cpufreq_config->menu_pstate1);
|
||||||
|
}
|
||||||
|
if (cpufreq_config->menu_pstate2)
|
||||||
|
{
|
||||||
|
mi = e_menu_item_new(mg);
|
||||||
|
e_menu_item_label_set(mi, _("Power State Max"));
|
||||||
|
e_menu_item_submenu_set(mi, cpufreq_config->menu_pstate2);
|
||||||
|
}
|
||||||
|
|
||||||
e_gadcon_canvas_zone_geometry_get(inst->gcc->gadcon,
|
e_gadcon_canvas_zone_geometry_get(inst->gcc->gadcon,
|
||||||
&cx, &cy, NULL, NULL);
|
&cx, &cy, NULL, NULL);
|
||||||
|
@ -411,6 +467,10 @@ _menu_cb_post(void *data, E_Menu *m __UNUSED__)
|
||||||
cpufreq_config->menu_frequency = NULL;
|
cpufreq_config->menu_frequency = NULL;
|
||||||
if (cpufreq_config->menu_powersave)
|
if (cpufreq_config->menu_powersave)
|
||||||
e_object_del(E_OBJECT(cpufreq_config->menu_powersave));
|
e_object_del(E_OBJECT(cpufreq_config->menu_powersave));
|
||||||
|
if (cpufreq_config->menu_pstate1)
|
||||||
|
e_object_del(E_OBJECT(cpufreq_config->menu_pstate1));
|
||||||
|
if (cpufreq_config->menu_pstate2)
|
||||||
|
e_object_del(E_OBJECT(cpufreq_config->menu_pstate2));
|
||||||
cpufreq_config->menu_powersave = NULL;
|
cpufreq_config->menu_powersave = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,6 +558,35 @@ _cpufreq_set_frequency(int frequency)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cpufreq_set_pstate(int min, int max, int turbo)
|
||||||
|
{
|
||||||
|
char buf[4096];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf),
|
||||||
|
"%s %s %i %i %i", cpufreq_config->set_exe_path, "pstate", min, max, turbo);
|
||||||
|
fprintf(stderr, buf);
|
||||||
|
ret = system(buf);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
E_Dialog *dia;
|
||||||
|
E_Container *con;
|
||||||
|
|
||||||
|
con = e_container_current_get(e_manager_current_get());
|
||||||
|
if (!(dia = e_dialog_new(con, "E", "_e_mod_cpufreq_error_setfreq")))
|
||||||
|
return;
|
||||||
|
e_dialog_title_set(dia, "Enlightenment Cpufreq Module");
|
||||||
|
e_dialog_icon_set(dia, "enlightenment", 64);
|
||||||
|
e_dialog_text_set(dia, _("There was an error trying to set the<br>"
|
||||||
|
"cpu power state setting via the module's<br>"
|
||||||
|
"setfreq utility."));
|
||||||
|
e_dialog_button_add(dia, _("OK"), NULL, NULL, NULL);
|
||||||
|
e_win_centered_set(dia->win, 1);
|
||||||
|
e_dialog_show(dia);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_cpufreq_cb_check(void *data __UNUSED__)
|
_cpufreq_cb_check(void *data __UNUSED__)
|
||||||
{
|
{
|
||||||
|
@ -859,6 +948,38 @@ _cpufreq_status_check_current(Status *s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
f = fopen("/sys/devices/system/cpu/intel_pstate/min_perf_pct", "r");
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
if (fgets(buf, sizeof(buf), f) != NULL)
|
||||||
|
{
|
||||||
|
s->pstate_min = atoi(buf);
|
||||||
|
s->pstate = 1;
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
f = fopen("/sys/devices/system/cpu/intel_pstate/max_perf_pct", "r");
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
if (fgets(buf, sizeof(buf), f) != NULL)
|
||||||
|
{
|
||||||
|
s->pstate_max = atoi(buf);
|
||||||
|
s->pstate = 1;
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
f = fopen("/sys/devices/system/cpu/intel_pstate/no_turbo", "r");
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
if (fgets(buf, sizeof(buf), f) != NULL)
|
||||||
|
{
|
||||||
|
s->pstate_turbo = atoi(buf);
|
||||||
|
if (s->pstate_turbo) s->pstate_turbo = 0;
|
||||||
|
else s->pstate_turbo = 1;
|
||||||
|
s->pstate = 1;
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1108,6 +1229,30 @@ _cpufreq_menu_frequency(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUS
|
||||||
if (frequency > 0) _cpufreq_set_frequency(frequency);
|
if (frequency > 0) _cpufreq_set_frequency(frequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cpufreq_menu_pstate_min(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
|
||||||
|
{
|
||||||
|
int min = (long)data;
|
||||||
|
cpufreq_config->pstate_min = min + 1;
|
||||||
|
if (cpufreq_config->pstate_max < cpufreq_config->pstate_min)
|
||||||
|
cpufreq_config->pstate_max = cpufreq_config->pstate_min;
|
||||||
|
_cpufreq_set_pstate(cpufreq_config->pstate_min - 1,
|
||||||
|
cpufreq_config->pstate_max - 1, 1);
|
||||||
|
e_config_save_queue();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cpufreq_menu_pstate_max(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
|
||||||
|
{
|
||||||
|
int max = (long)data;
|
||||||
|
cpufreq_config->pstate_max = max + 1;
|
||||||
|
if (cpufreq_config->pstate_min > cpufreq_config->pstate_max)
|
||||||
|
cpufreq_config->pstate_min = cpufreq_config->pstate_max;
|
||||||
|
_cpufreq_set_pstate(cpufreq_config->pstate_min - 1,
|
||||||
|
cpufreq_config->pstate_max - 1, 1);
|
||||||
|
e_config_save_queue();
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cpufreq_poll_interval_update(void)
|
_cpufreq_poll_interval_update(void)
|
||||||
{
|
{
|
||||||
|
@ -1143,6 +1288,8 @@ e_modapi_init(E_Module *m)
|
||||||
E_CONFIG_VAL(D, T, auto_powersave, INT);
|
E_CONFIG_VAL(D, T, auto_powersave, INT);
|
||||||
E_CONFIG_VAL(D, T, powersave_governor, STR);
|
E_CONFIG_VAL(D, T, powersave_governor, STR);
|
||||||
E_CONFIG_VAL(D, T, governor, STR);
|
E_CONFIG_VAL(D, T, governor, STR);
|
||||||
|
E_CONFIG_VAL(D, T, pstate_min, INT);
|
||||||
|
E_CONFIG_VAL(D, T, pstate_max, INT);
|
||||||
|
|
||||||
cpufreq_config = e_config_domain_load("module.cpufreq", conf_edd);
|
cpufreq_config = e_config_domain_load("module.cpufreq", conf_edd);
|
||||||
if ((cpufreq_config) &&
|
if ((cpufreq_config) &&
|
||||||
|
@ -1158,6 +1305,13 @@ e_modapi_init(E_Module *m)
|
||||||
cpufreq_config->auto_powersave = 1;
|
cpufreq_config->auto_powersave = 1;
|
||||||
cpufreq_config->powersave_governor = NULL;
|
cpufreq_config->powersave_governor = NULL;
|
||||||
cpufreq_config->governor = NULL;
|
cpufreq_config->governor = NULL;
|
||||||
|
cpufreq_config->pstate_min = 1;
|
||||||
|
cpufreq_config->pstate_max = 101;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (cpufreq_config->pstate_min == 0) cpufreq_config->pstate_min = 1;
|
||||||
|
if (cpufreq_config->pstate_max == 0) cpufreq_config->pstate_max = 101;
|
||||||
}
|
}
|
||||||
E_CONFIG_LIMIT(cpufreq_config->poll_interval, 1, 1024);
|
E_CONFIG_LIMIT(cpufreq_config->poll_interval, 1, 1024);
|
||||||
|
|
||||||
|
@ -1205,6 +1359,9 @@ e_modapi_init(E_Module *m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_cpufreq_set_pstate(cpufreq_config->pstate_min - 1,
|
||||||
|
cpufreq_config->pstate_max - 1, 1);
|
||||||
|
|
||||||
cpufreq_config->module = m;
|
cpufreq_config->module = m;
|
||||||
|
|
||||||
e_gadcon_provider_register(&_gadcon_class);
|
e_gadcon_provider_register(&_gadcon_class);
|
||||||
|
|
|
@ -17,9 +17,13 @@ struct _Status
|
||||||
int cur_min_frequency;
|
int cur_min_frequency;
|
||||||
int cur_max_frequency;
|
int cur_max_frequency;
|
||||||
int can_set_frequency;
|
int can_set_frequency;
|
||||||
|
int pstate_min;
|
||||||
|
int pstate_max;
|
||||||
char *cur_governor;
|
char *cur_governor;
|
||||||
const char *orig_governor;
|
const char *orig_governor;
|
||||||
unsigned char active;
|
unsigned char active;
|
||||||
|
unsigned char pstate;
|
||||||
|
unsigned char pstate_turbo;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Config
|
struct _Config
|
||||||
|
@ -31,6 +35,8 @@ struct _Config
|
||||||
int auto_powersave;
|
int auto_powersave;
|
||||||
const char *powersave_governor;
|
const char *powersave_governor;
|
||||||
const char *governor;
|
const char *governor;
|
||||||
|
int pstate_min;
|
||||||
|
int pstate_max;
|
||||||
/* just config state */
|
/* just config state */
|
||||||
E_Module *module;
|
E_Module *module;
|
||||||
Eina_List *instances;
|
Eina_List *instances;
|
||||||
|
@ -39,6 +45,8 @@ struct _Config
|
||||||
E_Menu *menu_governor;
|
E_Menu *menu_governor;
|
||||||
E_Menu *menu_frequency;
|
E_Menu *menu_frequency;
|
||||||
E_Menu *menu_powersave;
|
E_Menu *menu_powersave;
|
||||||
|
E_Menu *menu_pstate1;
|
||||||
|
E_Menu *menu_pstate2;
|
||||||
Status *status;
|
Status *status;
|
||||||
char *set_exe_path;
|
char *set_exe_path;
|
||||||
Ecore_Poller *frequency_check_poller;
|
Ecore_Poller *frequency_check_poller;
|
||||||
|
|
|
@ -16,14 +16,16 @@
|
||||||
|
|
||||||
static int sys_cpu_setall(const char *control, const char *value);
|
static int sys_cpu_setall(const char *control, const char *value);
|
||||||
static int sys_cpufreq_set(const char *control, const char *value);
|
static int sys_cpufreq_set(const char *control, const char *value);
|
||||||
|
static int sys_cpu_pstate(int min, int max, int turbo);
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
if (argc != 3)
|
if (argc < 3)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Invalid command. Syntax:\n");
|
fprintf(stderr, "Invalid command. Syntax:\n");
|
||||||
fprintf(stderr, "\tfreqset <frequency|governor> <freq-level|governor-name>\n");
|
fprintf(stderr, "\tfreqset <frequency|governor> <freq-level|governor-name>\n");
|
||||||
|
fprintf(stderr, "\tfreqset <pstate> <min> <max> <turbo>\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,6 +101,28 @@ main(int argc, char *argv[])
|
||||||
sys_cpufreq_set("conservative/ignore_nice_load", "0");
|
sys_cpufreq_set("conservative/ignore_nice_load", "0");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(argv[1], "pstate"))
|
||||||
|
{
|
||||||
|
int min, max, turbo;
|
||||||
|
|
||||||
|
if (argc < 5)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Invalid number of arguments.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
min = atoi(argv[2]);
|
||||||
|
max = atoi(argv[3]);
|
||||||
|
turbo = atoi(argv[4]);
|
||||||
|
if ((min < 0) || (min > 100) ||
|
||||||
|
(max < 0) || (max > 100) ||
|
||||||
|
(turbo < 0) || (turbo > 1))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Invalid pstate values.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
sys_cpu_pstate(min, max, turbo);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Unknown command.\n");
|
fprintf(stderr, "Unknown command.\n");
|
||||||
|
@ -156,3 +180,25 @@ sys_cpufreq_set(const char *control, const char *value)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sys_cpu_pstate(int min, int max, int turbo)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
f = fopen("/sys/devices/system/cpu/intel_pstate/min_perf_pct", "w");
|
||||||
|
if (!f) return 0;
|
||||||
|
fprintf(f, "%i\n", min);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
f = fopen("/sys/devices/system/cpu/intel_pstate/max_perf_pct", "w");
|
||||||
|
if (!f) return 0;
|
||||||
|
fprintf(f, "%i\n", max);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
f = fopen("/sys/devices/system/cpu/intel_pstate/no_turbo", "w");
|
||||||
|
if (!f) return 0;
|
||||||
|
fprintf(f, "%i\n", turbo ? 0 : 1);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue