Skip to content

Commit

Permalink
gaming_control: add custom gpu/cpus freq and voltage selections
Browse files Browse the repository at this point in the history
  • Loading branch information
xxmustafacooTR committed Jul 1, 2023
1 parent dfc0962 commit 983fa37
Show file tree
Hide file tree
Showing 5 changed files with 209 additions and 11 deletions.
4 changes: 4 additions & 0 deletions drivers/gpu/arm/exynos/frontend/gpex_clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,8 +379,12 @@ void gpex_clock_term()

int gpex_clock_get_table_idx(int clock)
{
int fake_freq = fake_freq_gaming(DVFS_G3D);
int i;

if (fake_freq)
clock = fake_freq;

if (clock < clk_info.gpu_min_clock)
return -1;

Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/arm/exynos/frontend/gpex_dvfs_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@
#define _GPEX_DVFS_INTERNAL_H_

#include <gpex_clock.h>
#include <linux/gaming_control.h>

#define DVFS_ASSERT(x) \
do { \
if (x) \
if (x || fake_freq_gaming(DVFS_G3D)) \
break; \
printk(KERN_EMERG "### ASSERTION FAILED %s: %s: %d: %s\n", __FILE__, __func__, \
__LINE__, #x); \
Expand Down
190 changes: 181 additions & 9 deletions drivers/misc/gaming_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,19 @@
#include <linux/slab.h>
#include <linux/pm_qos.h>
#include <linux/gaming_control.h>

#include <soc/samsung/cal-if.h>
#include <soc/samsung/exynos-cpu_hotplug.h>
#include <dt-bindings/clock/exynos9810.h>
#include "../soc/samsung/cal-if/exynos9810/cmucal-vclk.h"
#include "../soc/samsung/cal-if/exynos9810/cmucal-node.h"

extern unsigned long arg_cpu_max_c1;
extern unsigned long arg_cpu_min_c1;
extern unsigned long arg_cpu_max_c2;
extern unsigned long arg_cpu_min_c2;
extern unsigned long arg_gpu_min;
extern unsigned long arg_gpu_max;
extern int exynos_cpufreq_update_volt_table(void);
extern void exynos_cpufreq_set_gaming_mode(void);

/* PM QoS implementation */
Expand All @@ -43,9 +55,13 @@ static unsigned int min_big_freq = 1469000;
static unsigned int max_big_freq = 2886000;
static unsigned int min_gpu_freq = 598000;
static unsigned int max_gpu_freq = 598000;
static unsigned int custom_little_freq, custom_little_voltage, custom_big_freq, custom_big_voltage, custom_gpu_freq, custom_gpu_voltage = 0;
static unsigned int back_little_freq, back_little_voltage, back_big_freq, back_big_voltage, back_gpu_freq, back_gpu_voltage = 0;
static int nr_running_games = 0;
static bool always_on = 0;
static bool battery_idle = 0;
static bool gaming_mode_initialized = 0;

bool gaming_mode;

char games_list[GAME_LIST_LENGTH] = {0};
Expand All @@ -55,25 +71,169 @@ pid_t games_pid[NUM_SUPPORTED_RUNNING_GAMES] = {

static inline void set_gaming_mode(bool mode, bool force)
{
unsigned int little_max, little_min, big_max, big_min, gpu_max, gpu_min;

if (always_on)
mode = 1;

if (mode == gaming_mode && !force)
return;
else
gaming_mode = mode;


if (!mode)
gaming_mode_initialized = 0;

little_max = max_little_freq;
little_min = min_little_freq;
big_max = max_big_freq;
big_min = min_big_freq;
gpu_max = max_gpu_freq;
gpu_min = min_gpu_freq;

if (custom_little_freq) {
if (custom_little_freq <= arg_cpu_min_c1)
little_max = little_min = arg_cpu_min_c1;
else if (custom_little_freq >= arg_cpu_max_c1)
little_max = little_min = arg_cpu_max_c1;
}

if (!back_little_freq)
back_little_freq = little_max;

if (custom_little_voltage && mode && !back_little_voltage) {
back_little_voltage = fvmap_read(DVFS_CPUCL0, READ_VOLT, back_little_freq);
fvmap_patch(DVFS_CPUCL0, back_little_freq, custom_little_voltage);
} else if (!mode && back_little_voltage) {
fvmap_patch(DVFS_CPUCL0, back_little_freq, back_little_voltage);
back_little_freq = back_little_voltage = 0;
}

if (custom_big_freq) {
if (custom_big_freq <= arg_cpu_min_c2)
big_max = big_min = arg_cpu_min_c2;
else if (custom_big_freq >= arg_cpu_max_c2)
big_max = big_min = arg_cpu_max_c2;
}

if (!back_big_freq)
back_big_freq = big_max;

if (custom_big_voltage && mode && !back_big_voltage) {
back_big_voltage = fvmap_read(DVFS_CPUCL1, READ_VOLT, back_big_freq);
fvmap_patch(DVFS_CPUCL1, back_big_freq, custom_big_voltage);
} else if (!mode && back_big_voltage) {
fvmap_patch(DVFS_CPUCL1, back_big_freq, back_big_voltage);
back_big_freq = back_big_voltage = 0;
}

if (custom_gpu_freq) {
if (custom_gpu_freq <= arg_gpu_min)
gpu_max = gpu_min = arg_gpu_min;
else if (custom_gpu_freq >= arg_gpu_max)
gpu_max = gpu_min = arg_gpu_max;
}

if (!back_gpu_freq)
back_gpu_freq = gpu_max;

if (custom_gpu_voltage && mode && !back_gpu_voltage) {
back_gpu_voltage = gpex_clock_get_voltage(back_gpu_freq);
fvmap_patch(DVFS_G3D, back_gpu_freq, custom_gpu_voltage);
} else if (!mode && back_gpu_voltage) {
fvmap_patch(DVFS_G3D, back_gpu_freq, back_gpu_voltage);
back_gpu_freq = back_gpu_voltage = 0;
}

gpex_clock_update_config_data_from_dt();
exynos_cpufreq_update_volt_table();
exynos_cpufreq_set_gaming_mode();

pm_qos_update_request(&gaming_control_min_int_qos, mode && min_int_freq ? min_int_freq : PM_QOS_DEVICE_THROUGHPUT_DEFAULT_VALUE);
pm_qos_update_request(&gaming_control_min_mif_qos, mode && min_mif_freq ? min_mif_freq : PM_QOS_BUS_THROUGHPUT_DEFAULT_VALUE);
pm_qos_update_request(&gaming_control_min_little_qos, mode && min_little_freq ? min_little_freq : PM_QOS_CLUSTER0_FREQ_MIN_DEFAULT_VALUE);
pm_qos_update_request(&gaming_control_max_little_qos, mode && max_little_freq ? max_little_freq : PM_QOS_CLUSTER0_FREQ_MAX_DEFAULT_VALUE);
pm_qos_update_request(&gaming_control_min_big_qos, mode && min_big_freq ? min_big_freq : PM_QOS_CLUSTER1_FREQ_MIN_DEFAULT_VALUE);
pm_qos_update_request(&gaming_control_max_big_qos, mode && max_big_freq ? max_big_freq : PM_QOS_CLUSTER1_FREQ_MAX_DEFAULT_VALUE);

gpu_custom_max_clock(mode ? max_gpu_freq : 0);
gpu_custom_min_clock(mode ? min_gpu_freq : 0);
pm_qos_update_request(&gaming_control_min_little_qos, mode && little_min ? little_min : PM_QOS_CLUSTER0_FREQ_MIN_DEFAULT_VALUE);
pm_qos_update_request(&gaming_control_max_little_qos, mode && little_max ? little_max : PM_QOS_CLUSTER0_FREQ_MAX_DEFAULT_VALUE);
pm_qos_update_request(&gaming_control_min_big_qos, mode && big_min ? big_min : PM_QOS_CLUSTER1_FREQ_MIN_DEFAULT_VALUE);
pm_qos_update_request(&gaming_control_max_big_qos, mode && big_max ? big_max : PM_QOS_CLUSTER1_FREQ_MAX_DEFAULT_VALUE);

gpu_custom_max_clock(mode ? gpu_max : 0);
gpu_custom_min_clock(mode ? gpu_min : 0);

if (mode)
gaming_mode_initialized = 1;

if (custom_little_freq) {
__cal_dfs_set_rate(ACPM_DVFS_CPUCL0, mode ? custom_little_freq : little_max);
__cal_dfs_set_rate(VCLK_CLUSTER0, (mode ? custom_little_freq : little_max) * 1000);
__cal_dfs_set_rate(PLL_CPUCL0, (mode ? custom_little_freq : little_max) * 1000);
}

if (custom_big_freq) {
__cal_dfs_set_rate(ACPM_DVFS_CPUCL1, mode ? custom_big_freq : big_max);
__cal_dfs_set_rate(VCLK_CLUSTER1, (mode ? custom_big_freq : big_max) * 1000);
__cal_dfs_set_rate(PLL_CPUCL1, (mode ? custom_big_freq : big_max) * 1000);
}

if (custom_gpu_freq) {
__cal_dfs_set_rate(ACPM_DVFS_G3D, mode ? custom_gpu_freq : gpu_max);
__cal_dfs_set_rate(VCLK_GPU, (mode ? custom_gpu_freq : gpu_max) * 1000);
__cal_dfs_set_rate(PLL_G3D, (mode ? custom_gpu_freq : gpu_max) * 1000);
}
}

unsigned long cal_dfs_check_gaming_mode(unsigned int id) {
unsigned long ret = 0;

if (!gaming_mode_initialized)
return ret;

switch (id) {
/* LITTLE */
case ACPM_DVFS_CPUCL0:
ret = custom_little_freq;
break;
/* BIG */
case ACPM_DVFS_CPUCL1:
ret = custom_big_freq;
break;
/* GPU */
case ACPM_DVFS_G3D:
ret = custom_gpu_freq;
break;
default:
break;
}

return ret;
}

int fake_freq_gaming(int id) {
int ret = 0;

if (!gaming_mode)
return ret;

switch (id) {
/* LITTLE */
case ACPM_DVFS_CPUCL0:
case DVFS_CPUCL0:
ret = back_little_freq;
break;
/* BIG */
case ACPM_DVFS_CPUCL1:
case DVFS_CPUCL1:
ret = back_big_freq;
break;
/* GPU */
case ACPM_DVFS_G3D:
case DVFS_G3D:
ret = back_gpu_freq;
break;
default:
break;
}

return ret;
}

bool battery_idle_gaming(void) {
Expand Down Expand Up @@ -250,6 +410,12 @@ attr_value(min_big_freq);
attr_value(max_big_freq);
attr_value(min_gpu_freq);
attr_value(max_gpu_freq);
attr_value(custom_little_freq);
attr_value(custom_little_voltage);
attr_value(custom_big_freq);
attr_value(custom_big_voltage);
attr_value(custom_gpu_freq);
attr_value(custom_gpu_voltage);

static ssize_t version_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
Expand All @@ -276,6 +442,12 @@ static struct attribute *gaming_control_attributes[] = {
&max_big_freq_attribute.attr,
&min_gpu_freq_attribute.attr,
&max_gpu_freq_attribute.attr,
&custom_little_freq_attribute.attr,
&custom_little_voltage_attribute.attr,
&custom_big_freq_attribute.attr,
&custom_big_voltage_attribute.attr,
&custom_gpu_freq_attribute.attr,
&custom_gpu_voltage_attribute.attr,
NULL
};

Expand Down
15 changes: 15 additions & 0 deletions drivers/soc/samsung/cal-if/cal-if.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <soc/samsung/ect_parser.h>
#include <soc/samsung/cal-if.h>
#include <soc/samsung/acpm_mfd.h>
#include <linux/gaming_control.h>

#include "pwrcal-env.h"
#include "pwrcal-rae.h"
Expand Down Expand Up @@ -67,6 +68,9 @@ int __cal_dfs_set_rate(unsigned int id, unsigned long rate)

int cal_dfs_set_rate(unsigned int id, unsigned long rate)
{
if (cal_dfs_check_gaming_mode(id))
return 0;

return __cal_dfs_set_rate(id, rate);
}

Expand Down Expand Up @@ -101,6 +105,10 @@ unsigned long cal_dfs_get_rate(unsigned int id)
{
int ret;

ret = cal_dfs_check_gaming_mode(id);
if (ret)
return ret;

ret = vclk_recalc_rate(id);

return ret;
Expand All @@ -119,6 +127,9 @@ int cal_clk_setrate(unsigned int id, unsigned long rate)
{
int ret = -EINVAL;

if (cal_dfs_check_gaming_mode(id))
return 0;

ret = vclk_set_rate(id, rate);

return ret;
Expand All @@ -128,6 +139,10 @@ unsigned long cal_clk_getrate(unsigned int id)
{
int ret = 0;

ret = cal_dfs_check_gaming_mode(id);
if (ret)
return ret;

ret = vclk_recalc_rate(id);

return ret;
Expand Down
8 changes: 7 additions & 1 deletion include/linux/gaming_control.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

#define GAME_LIST_LENGTH 1024
#define NUM_SUPPORTED_RUNNING_GAMES 20
#define GAMING_CONTROL_VERSION "0.4"
#define GAMING_CONTROL_VERSION "0.6"

#define TASK_STARTED 1

Expand All @@ -47,17 +47,23 @@ enum dvfs_id {
DVFS_CP,
};

int gpex_clock_update_config_data_from_dt(void);
int gpex_clock_get_voltage(int clk);
int gpu_custom_min_clock(int gpu_min_clock);
int gpu_custom_max_clock(int gpu_max_clock);

#ifdef CONFIG_GAMING_CONTROL
extern bool gaming_mode;
extern void game_option(struct task_struct *tsk, enum game_opts opts);
extern bool battery_idle_gaming(void);
extern int fake_freq_gaming(int id);
extern unsigned long cal_dfs_check_gaming_mode(unsigned int id);
#else
static bool gaming_mode = 0;
static void game_option(struct task_struct *tsk, enum game_opts opts) {};
static bool battery_idle_gaming(void) {return false;};
static int fake_freq_gaming(int id) {return 0;};
static unsigned long cal_dfs_check_gaming_mode(unsigned int id) {return 0;};
#endif /* CONFIG_GAMING_CONTROL */

#endif /* _GAMING_CONTROL_H_ */

0 comments on commit 983fa37

Please sign in to comment.