kernel_samsung_a53x/include/soc/samsung/exynos-devfreq.h
2024-06-15 16:02:09 -03:00

296 lines
8 KiB
C
Executable file

/* linux/arch/arm64/mach-exynos/include/mach/exynos-devfreq.h
*
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __EXYNOS_DEVFREQ_H_
#define __EXYNOS_DEVFREQ_H_
#include <linux/devfreq.h>
#include <soc/samsung/exynos_pm_qos.h>
#include <linux/clk.h>
#if defined(CONFIG_EXYNOS_DVFS_MANAGER) || defined(CONFIG_EXYNOS_DVFS_MANAGER_MODULE)
#include <soc/samsung/exynos-dm.h>
#endif
#include <soc/samsung/exynos-wow.h>
#define EXYNOS_DEVFREQ_MODULE_NAME "exynos-devfreq"
#define VOLT_STEP 25000
#define MAX_NR_CONSTRAINT DM_TYPE_END
#define DATA_INIT 5
#define SET_CONST 1
#define RELEASE 2
/* DEVFREQ GOV TYPE */
#define SIMPLE_INTERACTIVE 0
int devfreq_simple_interactive_init(void);
#if defined(CONFIG_EXYNOS_ALT_DVFS) || defined(CONFIG_EXYNOS_ALT_DVFS_MODULE)
#define LOAD_BUFFER_MAX 10
#if defined(CONFIG_EXYNOS_ALT_DVFS_DEBUG) || defined(CONFIG_EXYNOS_ALT_DVFS_DEBUG_MODULE)
#define MAX_LOG_TIME 300
#endif
struct devfreq_alt_load {
unsigned long long delta;
unsigned int load;
#if defined(CONFIG_EXYNOS_ALT_DVFS_DEBUG) || defined(CONFIG_EXYNOS_ALT_DVFS_DEBUG_MODULE)
unsigned long long clock;
unsigned int alt_freq;
#endif
};
#define ALTDVFS_MIN_SAMPLE_TIME 15
#define ALTDVFS_HOLD_SAMPLE_TIME 100
#define ALTDVFS_TARGET_LOAD 75
#define ALTDVFS_NUM_TARGET_LOAD 1
#define ALTDVFS_HISPEED_LOAD 99
#define ALTDVFS_HISPEED_FREQ 1000000
#define ALTDVFS_TOLERANCE 1
struct devfreq_alt_dvfs_data {
struct devfreq_alt_load buffer[LOAD_BUFFER_MAX];
struct devfreq_alt_load *front;
struct devfreq_alt_load *rear;
unsigned long long busy;
unsigned long long total;
unsigned int min_load;
unsigned int max_load;
unsigned long long max_spent;
struct devfreq_alt_dvfs_param *alt_param;
struct devfreq_alt_dvfs_param *alt_param_set;
struct devfreq_alt_dvfs_param *alt_user_mode;
int default_mode, current_mode, num_modes;
#if defined(CONFIG_EXYNOS_ALT_DVFS_DEBUG) || defined(CONFIG_EXYNOS_ALT_DVFS_DEBUG_MODULE)
bool load_track;
unsigned int log_top;
struct devfreq_alt_load *log;
#endif
};
struct devfreq_alt_dvfs_param {
/* ALT-DVFS parameter */
unsigned int *target_load;
unsigned int num_target_load;
unsigned int min_sample_time;
unsigned int hold_sample_time;
unsigned int hispeed_load;
unsigned int hispeed_freq;
unsigned int tolerance;
};
#endif /* ALT_DVFS */
#define DEFAULT_DELAY_TIME 10 /* msec */
#define DEFAULT_NDELAY_TIME 1
#define DELAY_TIME_RANGE 10
#define BOUND_CPU_NUM 0
struct devfreq_notifier_block {
struct notifier_block nb;
struct devfreq *df;
};
struct devfreq_simple_interactive_data {
bool use_delay_time;
int *delay_time;
int ndelay_time;
unsigned long prev_freq;
u64 changed_time;
struct timer_list freq_timer;
struct timer_list freq_slack_timer;
struct task_struct *change_freq_task;
int pm_qos_class;
int pm_qos_class_max;
struct devfreq_notifier_block nb;
struct devfreq_notifier_block nb_max;
#if defined(CONFIG_EXYNOS_ALT_DVFS) || defined(CONFIG_EXYNOS_ALT_DVFS_MODULE)
struct devfreq_alt_dvfs_data alt_data;
unsigned int governor_freq;
#endif
};
struct exynos_devfreq_opp_table {
u32 idx;
u32 freq;
u32 volt;
};
struct um_exynos {
struct list_head node;
void __iomem **va_base;
u32 *pa_base;
u32 *mask_v;
u32 *mask_a;
u32 *channel;
unsigned int um_count;
u64 val_ccnt;
u64 val_pmcnt;
};
struct exynos_devfreq_freq_infos {
/* Basic freq infos */
// min/max frequency
u32 max_freq;
u32 min_freq;
// cur_freq pointer
const u32 *cur_freq;
// min/max pm_qos node
u32 pm_qos_class;
u32 pm_qos_class_max;
// num of freqs
u32 max_state;
};
struct exynos_devfreq_profile {
int num_stats;
int enabled;
struct exynos_wow_profile last_wow_profile;
struct exynos_wow_profile *profile_in_state;
/* Total time in state */
ktime_t *time_in_state;
ktime_t last_time_in_state;
/* Active time in state */
ktime_t *active_time_in_state;
ktime_t last_active_time_in_state;
u64 **freq_stats;
u64 *last_freq_stats;
};
struct exynos_devfreq_data {
struct device *dev;
struct devfreq *devfreq;
struct mutex lock;
struct clk *clk;
bool devfreq_disabled;
u32 devfreq_type;
struct exynos_devfreq_opp_table *opp_list;
u32 default_qos;
u32 max_state;
struct devfreq_dev_profile devfreq_profile;
u32 gov_type;
const char *governor_name;
u32 cal_qos_max;
void *governor_data;
struct devfreq_simple_interactive_data simple_interactive_data;
u32 dfs_id;
s32 old_idx;
s32 new_idx;
u32 old_freq;
u32 new_freq;
u32 min_freq;
u32 max_freq;
u32 reboot_freq;
u32 boot_freq;
u64 suspend_freq;
bool suspend_flag;
u32 old_volt;
u32 new_volt;
u32 pm_qos_class;
u32 pm_qos_class_max;
struct exynos_pm_qos_request sys_pm_qos_min;
struct exynos_pm_qos_request sys_pm_qos_max;
#if defined(CONFIG_ARM_EXYNOS_DEVFREQ_DEBUG) || defined(CONFIG_ARM_EXYNOS_DEVFREQ_DEBUG_MODULE)
struct exynos_pm_qos_request debug_pm_qos_min;
struct exynos_pm_qos_request debug_pm_qos_max;
#endif
struct exynos_pm_qos_request default_pm_qos_min;
struct exynos_pm_qos_request default_pm_qos_max;
struct exynos_pm_qos_request boot_pm_qos;
u32 boot_qos_timeout;
struct notifier_block reboot_notifier;
bool sysbusy;
struct notifier_block sysbusy_notifier;
struct exynos_pm_qos_request sysbusy_pm_qos;
u32 ess_flag;
s32 target_delay;
#if defined(CONFIG_EXYNOS_DVFS_MANAGER) || defined(CONFIG_EXYNOS_DVFS_MANAGER_MODULE)
u32 dm_type;
u32 nr_constraint;
struct exynos_dm_constraint **constraint;
#endif
void *private_data;
bool use_acpm;
bool bts_update;
bool update_fvp;
bool use_get_dev;
bool use_dtm;
struct devfreq_notifier_block *um_nb;
struct um_exynos um_data;
u64 last_monitor_period;
u64 last_monitor_time;
u32 last_um_usage_rate;
struct exynos_pm_domain *pm_domain;
unsigned long previous_freq;
unsigned long *time_in_state;
unsigned long last_stat_updated;
struct exynos_devfreq_profile *profile;
};
struct exynos_profile_data {
unsigned long long total_time;
unsigned long long busy_time;
unsigned long long delta_time;
struct exynos_wow_profile wow_profile;
struct exynos_wow_profile prev_wow_profile;
};
s32 exynos_devfreq_get_opp_idx(struct exynos_devfreq_opp_table *table,
unsigned int size, u32 freq);
#if (defined(CONFIG_ARM_EXYNOS_DEVFREQ) && defined(CONFIG_EXYNOS_DVFS_MANAGER)) && \
(defined(CONFIG_ARM_EXYNOS_DEVFREQ_MODULE) && defined(CONFIG_EXYNOS_DVFS_MANAGER_MODULE))
u32 exynos_devfreq_get_dm_type(u32 devfreq_type);
u32 exynos_devfreq_get_devfreq_type(int dm_type);
struct devfreq *find_exynos_devfreq_device(void *devdata);
int find_exynos_devfreq_dm_type(struct device *dev, int *dm_type);
#endif
#if defined(CONFIG_EXYNOS_ALT_DVFS) || defined(CONFIG_EXYNOS_ALT_DVFS_MODULE)
extern exynos_devfreq_alt_mode_change(unsigned int devfreq_type, int new_mode);
extern void exynos_alt_call_chain(void);
#endif
#if defined(CONFIG_ARM_EXYNOS_DEVFREQ) || defined(CONFIG_ARM_EXYNOS_DEVFREQ_MODULE)
extern unsigned long exynos_devfreq_get_domain_freq(unsigned int devfreq_type);
extern void exynos_devfreq_get_freq_infos(unsigned int devfreq_type, struct exynos_devfreq_freq_infos *infos);
extern void exynos_devfreq_set_profile(unsigned int devfreq_type, int enable);
#if defined(CONFIG_SOC_S5E9925_EVT0) || defined(CONFIG_SOC_S5E8825)
extern void exynos_devfreq_get_profile(unsigned int devfreq_type, ktime_t **time_in_state, u64 **tables);
#else
extern void exynos_devfreq_get_profile(unsigned int devfreq_type, ktime_t **time_in_state, struct exynos_wow_profile *profile_in_state);
#endif
#else
static inline unsigned long exynos_devfreq_get_domain_freq(unsigned int devfreq_type)
{
return 0;
}
static void exynos_devfreq_set_profile(unsigned int devfreq_type, int enable)
{
}
#endif
#endif /* __EXYNOS_DEVFREQ_H_ */