unplugged-kernel/drivers/misc/mediatek/ppm_v3/inc/mtk_ppm_internal.h

336 lines
9.9 KiB
C
Raw Normal View History

/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2019 MediaTek Inc.
*/
#ifndef __MT_PPM_INTERNAL_H__
#define __MT_PPM_INTERNAL_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/cpufreq.h>
#include <linux/mutex.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/printk.h>
#include <linux/sched.h>
#include <linux/cpumask.h>
#include "mtk_ppm_api.h"
#include "mtk_ppm_platform.h"
#include "mtk_ppm_ipi.h"
#ifdef CONFIG_MTK_UNIFY_POWER
#include "mtk_common_upower.h"
#endif
/*==============================================================*/
/* Definitions */
/*==============================================================*/
/* POLICY */
/* If priority value is the same, it will decide by ppm_policy enum value */
#define PPM_POLICY_PRIO_HIGHEST (0x0)
#define PPM_POLICY_PRIO_POWER_BUDGET_BASE (0x1)
#define PPM_POLICY_PRIO_USER_SPECIFY_BASE (0x40)
#define PPM_POLICY_PRIO_PERFORMANCE_BASE (0x80)
#define PPM_POLICY_PRIO_SYSTEM_BASE (0xC0)
#define PPM_POLICY_PRIO_LOWEST (0xFF)
/* Cluster setting */
#define get_cluster_min_cpufreq_idx(id) \
(ppm_main_info.cluster_info[id].dvfs_opp_num - 1)
#define get_cluster_max_cpufreq_idx(id) (0)
#define get_cluster_min_cpu_core(id) (0)
#define get_cluster_max_cpu_core(id) \
(ppm_main_info.cluster_info[id].core_num)
#define get_cluster_max_cpufreq(id) \
((ppm_main_info.cluster_info[id].dvfs_tbl) \
? ppm_main_info.cluster_info[id].dvfs_tbl[0].frequency \
: ~0)
#define get_cluster_min_cpufreq(id) \
((ppm_main_info.cluster_info[id].dvfs_tbl) \
? ppm_main_info.cluster_info[id].dvfs_tbl[DVFS_OPP_NUM-1].frequency \
: 0)
/* loop macros */
#define for_each_ppm_clusters(i) \
for (i = 0; i < ppm_main_info.cluster_num; i++)
#define for_each_ppm_clients(i) for (i = 0; i < NR_PPM_CLIENTS; i++)
/* operation */
#ifndef MAX
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
#endif
#ifndef MIN
#define MIN(a, b) ((a) >= (b) ? (b) : (a))
#endif
/* LOCK */
#define ppm_lock(lock) mutex_lock(lock)
#define ppm_unlock(lock) mutex_unlock(lock)
/* PROCFS */
#define PROC_FOPS_RW(name) \
static int ppm_ ## name ## _proc_open(struct inode *inode, struct file *file) \
{ \
return single_open(file, ppm_ ## name ## _proc_show, PDE_DATA(inode));\
} \
static const struct file_operations ppm_ ## name ## _proc_fops = { \
.owner = THIS_MODULE, \
.open = ppm_ ## name ## _proc_open, \
.read = seq_read, \
.llseek = seq_lseek, \
.release = single_release, \
.write = ppm_ ## name ## _proc_write, \
}
#define PROC_FOPS_RO(name) \
static int ppm_ ## name ## _proc_open(struct inode *inode, struct file *file) \
{ \
return single_open(file, ppm_ ## name ## _proc_show, PDE_DATA(inode));\
} \
static const struct file_operations ppm_ ## name ## _proc_fops = { \
.owner = THIS_MODULE, \
.open = ppm_ ## name ## _proc_open, \
.read = seq_read, \
.llseek = seq_lseek, \
.release = single_release, \
}
#define PROC_ENTRY(name) {__stringify(name), &ppm_ ## name ## _proc_fops}
/* LOG */
#undef TAG
#define TAG "[Power/PPM] "
#define ppm_err ppm_info
#define ppm_warn ppm_info
#define ppm_info(fmt, args...) pr_notice(TAG""fmt, ##args)
#define ppm_dbg(type, fmt, args...) \
do { \
if (ppm_debug & ALL || ppm_debug & type) \
ppm_info(fmt, ##args); \
else if (type == MAIN) \
pr_debug(TAG""fmt, ##args); \
} while (0)
#define ppm_ver(fmt, args...) \
do { \
if (ppm_debug == ALL) \
ppm_info(fmt, ##args); \
} while (0)
#define FUNC_LV_MODULE BIT(0) /* module, platform driver interface */
#define FUNC_LV_API BIT(1) /* mt_ppm driver global function */
#define FUNC_LV_MAIN BIT(2) /* mt_ppm driver main function */
#define FUNC_LV_POLICY BIT(4) /* mt_ppm driver policy function */
#define FUNC_ENTER(lv) \
do { if ((lv) & ppm_func_lv_mask) \
ppm_info(">> %s()\n", __func__); } while (0)
#define FUNC_EXIT(lv) \
do { if ((lv) & ppm_func_lv_mask) \
ppm_info("<< %s():%d\n", __func__, __LINE__); } while (0)
/* cpufreq */
static inline void mtk_cpu_update_policy(void)
{
#ifdef CONFIG_CPU_FREQ
if (strcmp(CONFIG_MTK_PLATFORM, "mt6779"))
ppm_info("trigger cpufreq_update_policy(*)\n");
cpufreq_update_policy(0); /* little core */
cpufreq_update_policy(CORE_NUM_L); /* big core */
#endif
}
/*==============================================================*/
/* Enum */
/*==============================================================*/
enum {
NO_LOG = 0,
ALL = 1 << 0,
MAIN = 1 << 1,
HICA = 1 << 2,
DLPT = 1 << 3,
USER_LIMIT = 1 << 4,
TIME_PROFILE = 1 << 5,
COBRA = 1 << 6,
SYS_BOOST = 1 << 7,
IPI = 1 << 8,
CPI = 1 << 9,
HARD_USER_LIMIT = 1 << 10,
};
enum ppm_policy {
PPM_POLICY_PTPOD = 0, /* highest priority */
PPM_POLICY_UT,
PPM_POLICY_FORCE_LIMIT,
PPM_POLICY_PWR_THRO,
PPM_POLICY_THERMAL,
PPM_POLICY_DLPT,
PPM_POLICY_HARD_USER_LIMIT,
PPM_POLICY_USER_LIMIT,
PPM_POLICY_LCM_OFF,
PPM_POLICY_SYS_BOOST,
PPM_POLICY_HICA,
NR_PPM_POLICIES,
};
/*==============================================================*/
/* Data Structures */
/*==============================================================*/
struct ppm_cluster_limit {
int min_cpufreq_idx;
int max_cpufreq_idx;
unsigned int min_cpu_core;
unsigned int max_cpu_core;
};
struct ppm_policy_req {
unsigned int cluster_num;
unsigned int power_budget;
unsigned int perf_idx;
struct ppm_cluster_limit *limit;
};
struct ppm_policy_data {
/* settings */
const char *name;
enum ppm_policy policy;
unsigned int priority; /* smaller value has higher priority */
/* status */
bool is_enabled;
bool is_activated;
bool is_limit_updated;
/* lock */
struct mutex lock;
/* list link */
struct list_head link;
/* request to PPM */
struct ppm_policy_req req;
/* callbacks */
void (*update_limit_cb)(void);
void (*status_change_cb)(bool enable);
};
struct ppm_cluster_info {
unsigned int cluster_id;
unsigned int core_num;
unsigned int cpu_id; /* cpu id of the dvfs policy owner */
unsigned int dvfs_opp_num;
unsigned int max_freq_except_userlimit;
unsigned int freq_khz;
/* unsigned int volt_uv; */
struct cpufreq_frequency_table *dvfs_tbl; /* from DVFS driver */
int doe_max;
int doe_min;
};
struct ppm_data {
bool is_enabled;
bool is_doe_enabled;
bool is_in_suspend;
unsigned int min_power_budget;
cpumask_var_t exclusive_core;
/* platform settings */
unsigned int cluster_num;
enum dvfs_table_type dvfs_tbl_type;
/* platform dev/driver */
const struct dev_pm_ops ppm_pm_ops;
struct platform_device ppm_pdev;
struct platform_driver ppm_pdrv;
/* PPM core data */
struct mutex lock;
struct ppm_cluster_info *cluster_info;
struct ppm_client_data client_info[NR_PPM_CLIENTS];
struct ppm_client_req client_req;
struct ppm_client_req last_req; /* for debugging purpose */
struct list_head policy_list;
};
struct ppm_user_limit {
int min_freq_idx;
int max_freq_idx;
int min_core_num;
int max_core_num;
};
struct ppm_userlimit_data {
bool is_freq_limited_by_user;
bool is_core_limited_by_user;
struct ppm_user_limit *limit;
};
/*==============================================================*/
/* Global variables */
/*==============================================================*/
extern struct ppm_data ppm_main_info;
extern struct proc_dir_entry *policy_dir;
extern struct proc_dir_entry *profile_dir;
extern struct proc_dir_entry *cpi_dir;
extern unsigned int ppm_func_lv_mask;
extern unsigned int ppm_debug;
/*==============================================================*/
/* APIs */
/*==============================================================*/
extern int mt_ppm_main(void);
/* procfs */
extern int ppm_procfs_init(void);
extern char *ppm_copy_from_user_for_proc(
const char __user *buffer, size_t count);
/* platform dependent APIs */
extern void ppm_update_req_by_pwr(struct ppm_policy_req *req);
extern int ppm_get_min_pwr_idx(void);
extern int ppm_get_max_pwr_idx(void);
/* main */
extern int ppm_main_freq_to_idx(unsigned int cluster_id,
unsigned int freq, unsigned int relation);
extern void ppm_clear_policy_limit(struct ppm_policy_data *policy);
extern void ppm_main_clear_client_req(struct ppm_client_req *c_req);
extern int ppm_main_register_policy(struct ppm_policy_data *policy);
extern void ppm_main_unregister_policy(struct ppm_policy_data *policy);
/* profiling */
extern int ppm_profile_init(void);
extern void ppm_profile_exit(void);
extern void ppm_profile_update_client_exec_time(
enum ppm_client client, unsigned long long time);
#ifdef PPM_SSPM_SUPPORT
extern void ppm_profile_update_ipi_exec_time(int id, unsigned long long time);
#endif
/* SRAM debugging */
#ifdef CONFIG_MTK_RAM_CONSOLE
extern void aee_rr_rec_ppm_cluster_limit(int id, u32 val);
extern void aee_rr_rec_ppm_step(u8 val);
extern void aee_rr_rec_ppm_min_pwr_bgt(u32 val);
extern void aee_rr_rec_ppm_policy_mask(u32 val);
extern void aee_rr_rec_ppm_waiting_for_pbm(u8 val);
#endif
#ifdef __cplusplus
}
#endif
#endif