226 lines
5.7 KiB
C
Executable file
226 lines
5.7 KiB
C
Executable file
/* linux/include/soc/samsung/exynos-dm.h
|
|
*
|
|
* Copyright (C) 2016 Samsung Electronics Co., Ltd.
|
|
* http://www.samsung.com
|
|
*
|
|
* EXYNOS5 - Header file for exynos DVFS Manager support
|
|
*
|
|
* 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_DM_H
|
|
#define __EXYNOS_DM_H
|
|
|
|
#include <linux/irq_work.h>
|
|
#include <linux/kthread.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/sched/types.h>
|
|
|
|
#define EXYNOS_DM_MODULE_NAME "exynos-dm"
|
|
#define EXYNOS_DM_TYPE_NAME_LEN 16
|
|
#define EXYNOS_DM_ATTR_NAME_LEN (EXYNOS_DM_TYPE_NAME_LEN + 12)
|
|
|
|
#define EXYNOS_DM_RELATION_L 0
|
|
#define EXYNOS_DM_RELATION_H 1
|
|
|
|
enum exynos_dm_type {
|
|
DM_CPU_CL0 = 0,
|
|
DM_CPU_CL1,
|
|
DM_CPU_CL2,
|
|
DM_MIF,
|
|
DM_INT,
|
|
DM_NPU,
|
|
DM_DSU,
|
|
DM_DISP,
|
|
DM_AUD,
|
|
DM_GPU,
|
|
DM_INTCAM,
|
|
DM_CAM,
|
|
DM_CSIS,
|
|
DM_VPC,
|
|
DM_MFC,
|
|
DM_ISP,
|
|
DM_MFC1,
|
|
DM_TYPE_END
|
|
};
|
|
|
|
enum exynos_constraint_type {
|
|
CONSTRAINT_MIN = 0,
|
|
CONSTRAINT_MAX,
|
|
CONSTRAINT_END
|
|
};
|
|
|
|
enum dvfs_direction {
|
|
DOWN = 0,
|
|
UP,
|
|
DIRECTION_END
|
|
};
|
|
|
|
struct exynos_dm_freq {
|
|
u32 master_freq;
|
|
u32 slave_freq;
|
|
};
|
|
|
|
struct exynos_dm_attrs {
|
|
struct device_attribute attr;
|
|
char name[EXYNOS_DM_ATTR_NAME_LEN];
|
|
};
|
|
|
|
struct exynos_dm_constraint {
|
|
int dm_master;
|
|
int dm_slave;
|
|
|
|
struct list_head master_domain;
|
|
struct list_head slave_domain;
|
|
|
|
bool guidance; /* check constraint table by hw guide */
|
|
bool support_dynamic_disable;
|
|
u32 table_length;
|
|
|
|
enum exynos_constraint_type constraint_type;
|
|
char dm_type_name[EXYNOS_DM_TYPE_NAME_LEN];
|
|
struct exynos_dm_freq *freq_table;
|
|
struct exynos_dm_freq *variable_freq_table[2];
|
|
bool support_variable_freq_table;
|
|
|
|
u32 const_freq;
|
|
u32 gov_freq;
|
|
|
|
struct exynos_dm_constraint *sub_constraint;
|
|
};
|
|
|
|
struct exynos_dm_data {
|
|
bool available; /* use for DVFS domain available */
|
|
#if defined(CONFIG_EXYNOS_ACPM) || defined(CONFIG_EXYNOS_ACPM_MODULE)
|
|
bool policy_use;
|
|
#endif
|
|
int dm_type;
|
|
char dm_type_name[EXYNOS_DM_TYPE_NAME_LEN];
|
|
|
|
int my_order; // Scaling order in domain_order
|
|
int indegree; // Number of min masters
|
|
|
|
u32 cur_freq; // Current frequency
|
|
u32 next_target_freq; // Next target frequency determined by current status
|
|
u32 governor_freq; // Frequency determined by DVFS governor
|
|
u32 gov_min; // Constraint by current frequency of min master domains
|
|
u32 policy_min; // Min frequency limition in this domin
|
|
u32 policy_max; // Min frequency limition in this domin
|
|
u32 const_min; // Constraint by min frequency of min master domains
|
|
u32 const_max; // Constraint1 by max frequency of max master domains
|
|
|
|
/* For Fast Switch */
|
|
bool fast_switch; // Use Fast Switch
|
|
bool fast_switch_post_in_progress;
|
|
struct irq_work fast_switch_post_irq_work;
|
|
struct task_struct *fast_switch_post_worker;
|
|
struct mutex fast_switch_lock;
|
|
|
|
int (*freq_scaler)(int dm_type, void *devdata, u32 target_freq, unsigned int relation);
|
|
|
|
struct list_head min_slaves;
|
|
struct list_head max_slaves;
|
|
struct list_head min_masters;
|
|
struct list_head max_masters;
|
|
|
|
#if defined(CONFIG_EXYNOS_ACPM) || defined(CONFIG_EXYNOS_ACPM_MODULE)
|
|
u32 cal_id;
|
|
#endif
|
|
|
|
void *devdata;
|
|
|
|
struct exynos_dm_attrs dm_policy_attr;
|
|
struct exynos_dm_attrs constraint_table_attr;
|
|
};
|
|
|
|
struct exynos_dm_device {
|
|
struct device *dev;
|
|
struct mutex lock;
|
|
int domain_count;
|
|
int constraint_domain_count;
|
|
int *domain_order;
|
|
struct exynos_dm_data *dm_data;
|
|
int dynamic_disable;
|
|
unsigned int fast_switch_ch;
|
|
};
|
|
|
|
struct exynos_dm_fast_switch_notify_data {
|
|
u32 domain;
|
|
u32 freq;
|
|
ktime_t time;
|
|
};
|
|
|
|
/* External Function call */
|
|
#if defined(CONFIG_EXYNOS_DVFS_MANAGER) || defined(CONFIG_EXYNOS_DVFS_MANAGER_MODULE)
|
|
extern int exynos_dm_data_init(int dm_type, void *data,
|
|
u32 min_freq, u32 max_freq, u32 cur_freq);
|
|
extern int register_exynos_dm_constraint_table(int dm_type,
|
|
struct exynos_dm_constraint *constraint);
|
|
extern int unregister_exynos_dm_constraint_table(int dm_type,
|
|
struct exynos_dm_constraint *constraint);
|
|
extern int register_exynos_dm_freq_scaler(int dm_type,
|
|
int (*scaler_func)(int dm_type, void *devdata, u32 target_freq, unsigned int relation));
|
|
extern int unregister_exynos_dm_freq_scaler(int dm_type);
|
|
extern int policy_update_call_to_DM(int dm_type, u32 min_freq, u32 max_freq);
|
|
extern int DM_CALL(int dm_type, unsigned long *target_freq);
|
|
extern void exynos_dm_dynamic_disable(int flag);
|
|
extern int exynos_dm_fast_switch_notifier_register(struct notifier_block *n);
|
|
extern int exynos_dm_change_freq_table(struct exynos_dm_constraint *constraint, int idx);
|
|
#else
|
|
static inline
|
|
int exynos_dm_data_init(int dm_type, void *data,
|
|
u32 min_freq, u32 max_freq, u32 cur_freq)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
static inline
|
|
int register_exynos_dm_constraint_table(int dm_type,
|
|
struct exynos_dm_constraint *constraint)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
static inline
|
|
int unregister_exynos_dm_constraint_table(int dm_type,
|
|
struct exynos_dm_constraint *constraint)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
static inline
|
|
int register_exynos_dm_freq_scaler(int dm_type,
|
|
int (*scaler_func)(int dm_type, void *devdata, u32 target_freq, unsigned int relation))
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
static inline
|
|
int unregister_exynos_dm_freq_scaler(int dm_type)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
static inline
|
|
int policy_update_call_to_DM(int dm_type, u32 min_freq, u32 max_freq)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
static inline
|
|
int DM_CALL(int dm_type, unsigned long *target_freq)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
static inline
|
|
void exynos_dm_dynamic_disable(int flag)
|
|
{
|
|
return;
|
|
}
|
|
static inline int exynos_dm_fast_switch_notifier_register(struct notifier_block *n)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline int exynos_dm_change_freq_table(struct exynos_dm_constraint *constraint, int idx)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
#endif
|
|
|
|
#endif /* __EXYNOS_DM_H */
|