mirror of
				https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
				synced 2025-10-30 23:58:51 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			364 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			364 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #ifndef __PWRCAL_VCLK_H__
 | |
| #define __PWRCAL_VCLK_H__
 | |
| 
 | |
| #include "pwrcal-env.h"
 | |
| #include "pwrcal-clk.h"
 | |
| 
 | |
| #define	vclk_group_grpgate	(0x0A000000 | 0x00000000)
 | |
| #define	vclk_group_m1d1g1	(0x0A000000 | 0x00010000)
 | |
| #define	vclk_group_p1	(0x0A000000 | 0x00020000)
 | |
| #define	vclk_group_m1	(0x0A000000 | 0x00030000)
 | |
| #define	vclk_group_d1	(0x0A000000 | 0x00040000)
 | |
| #define	vclk_group_pxmxdx	(0x0A000000 | 0x00050000)
 | |
| #define	vclk_group_umux	(0x0A000000 | 0x00060000)
 | |
| #define	vclk_group_dfs	(0x0A000000 | 0x00070000)
 | |
| #define	vclk_group_mask	(0x0A000000 | 0x000F0000)
 | |
| 
 | |
| struct vclk {
 | |
| 	unsigned int type;
 | |
| 	struct vclk *parent;
 | |
| 	int ref_count;
 | |
| 	unsigned long vfreq;
 | |
| 	char *name;
 | |
| 	struct vclk_ops *ops;
 | |
| };
 | |
| 
 | |
| struct vclk_ops {
 | |
| 	int (*enable)(struct vclk *vclk);
 | |
| 	int (*disable)(struct vclk *vclk);
 | |
| 	int (*is_enabled)(struct vclk *vclk);
 | |
| 	unsigned long (*get_rate)(struct vclk *vclk);
 | |
| 	int (*set_rate)(struct vclk *vclk, unsigned long rate);
 | |
| };
 | |
| 
 | |
| extern struct vclk_ops grpgate_ops;
 | |
| extern struct vclk_ops m1d1g1_ops;
 | |
| extern struct vclk_ops p1_ops;
 | |
| extern struct vclk_ops m1_ops;
 | |
| extern struct vclk_ops d1_ops;
 | |
| extern struct vclk_ops pxmxdx_ops;
 | |
| extern struct vclk_ops umux_ops;
 | |
| extern struct vclk_ops dfs_ops;
 | |
| 
 | |
| struct pwrcal_vclk_grpgate {
 | |
| 	struct vclk vclk;
 | |
| 	struct pwrcal_clk **gates;
 | |
| };
 | |
| 
 | |
| struct pwrcal_vclk_m1d1g1 {
 | |
| 	struct vclk vclk;
 | |
| 	struct pwrcal_clk *mux;
 | |
| 	struct pwrcal_clk *div;
 | |
| 	struct pwrcal_clk *gate;
 | |
| 	struct pwrcal_clk *extramux;
 | |
| };
 | |
| 
 | |
| struct pwrcal_vclk_umux {
 | |
| 	struct vclk vclk;
 | |
| 	struct pwrcal_clk *umux;
 | |
| };
 | |
| 
 | |
| struct pwrcal_vclk_p1 {
 | |
| 	struct vclk vclk;
 | |
| 	struct pwrcal_clk *pll;
 | |
| };
 | |
| 
 | |
| struct pwrcal_vclk_m1 {
 | |
| 	struct vclk vclk;
 | |
| 	struct pwrcal_clk *mux;
 | |
| };
 | |
| 
 | |
| struct pwrcal_vclk_d1 {
 | |
| 	struct vclk vclk;
 | |
| 	struct pwrcal_clk *div;
 | |
| };
 | |
| 
 | |
| struct pwrcal_clk_set {
 | |
| 	struct pwrcal_clk *clk;
 | |
| 	int config0;
 | |
| 	int config1;
 | |
| };
 | |
| 
 | |
| extern int is_config(struct pwrcal_clk_set *table, int config);
 | |
| extern int set_config(struct pwrcal_clk_set *table, int config);
 | |
| 
 | |
| struct pwrcal_vclk_pxmxdx {
 | |
| 	struct vclk vclk;
 | |
| 	struct pwrcal_clk_set *clk_list;
 | |
| };
 | |
| extern unsigned int _cal_vclk_get(char *name);
 | |
| extern struct vclk *cal_get_vclk(unsigned int id);
 | |
| 
 | |
| 
 | |
| #define REPRESENT_RATE		CLK_NONE
 | |
| 
 | |
| struct dfs_switch {
 | |
| 	unsigned int switch_rate;
 | |
| 	unsigned int mux_value;
 | |
| 	unsigned int div_value;
 | |
| };
 | |
| 
 | |
| struct dfs_table {
 | |
| 	struct pwrcal_clk **members;
 | |
| 	unsigned int *rate_table;
 | |
| 	int num_of_members;
 | |
| 	int num_of_lv;
 | |
| 	unsigned long max_freq;	/* KHZ */
 | |
| 	unsigned long min_freq;	/* KHZ */
 | |
| 
 | |
| 	struct dfs_switch *switches;
 | |
| 	int num_of_switches;
 | |
| 	struct pwrcal_clk *switch_mux;
 | |
| 	unsigned int switch_use;
 | |
| 	unsigned int switch_notuse;
 | |
| 	struct pwrcal_clk *switch_src_mux;
 | |
| 	struct pwrcal_clk *switch_src_div;
 | |
| 	struct pwrcal_clk *switch_src_gate;
 | |
| 	struct pwrcal_clk *switch_src_usermux;
 | |
| 
 | |
| 	void (*trans_pre)(unsigned int rate_from, unsigned int rate_to);
 | |
| 	void (*trans_post)(unsigned int rate_from, unsigned int rate_to);
 | |
| 	void (*switch_pre)(unsigned int rate_from, unsigned int rate_to);
 | |
| 	void (*switch_post)(unsigned int rate_from, unsigned int rate_to);
 | |
| 	int (*private_trans)(unsigned int rate_from, unsigned int rate_to,
 | |
| 					struct dfs_table *table);
 | |
| 	int (*private_switch)(unsigned int rate_from, unsigned int rate_switch,
 | |
| 					struct dfs_table *table);
 | |
| 	unsigned long (*private_getrate)(struct dfs_table *table);
 | |
| };
 | |
| 
 | |
| /* dfs ops */
 | |
| struct vclk_dfs_ops {
 | |
| 	int (*set_ema)(unsigned int volt);
 | |
| 	int (*init_smpl)(void);
 | |
| 	int (*set_smpl)(void);
 | |
| 	int (*get_smpl)(void);
 | |
| 	int (*dvs)(int command);	/* 0: DVS on  1: DVS off   2: DVS init */
 | |
| 	int (*is_dll_on)(void);
 | |
| 	int (*get_target_rate)(char *member, unsigned long rate);
 | |
| 	int (*get_rate_table)(unsigned long *table);
 | |
| 	int (*get_asv_table)(unsigned int *table);
 | |
| 	int (*set_voltage)(unsigned int uv);
 | |
| 	int (*cpu_idle_clock_down)(unsigned int enable);
 | |
| 	int (*get_margin_param)(unsigned int id);
 | |
| };
 | |
| 
 | |
| struct pwrcal_vclk_dfs {
 | |
| 	struct vclk vclk;
 | |
| 	struct pwrcal_clk **clks;
 | |
| 	struct pwrcal_clk_set *en_clks;
 | |
| 	struct dfs_table *table;
 | |
| 	struct vclk_dfs_ops *dfsops;
 | |
| 	int volt_margin;
 | |
| 	spinlock_t	*lock;
 | |
| 
 | |
| };
 | |
| extern struct vclk_ops dfs_ops;
 | |
| 
 | |
| 
 | |
| struct pwrcal_vclk_none {
 | |
| 	struct vclk vclk;
 | |
| };
 | |
| 
 | |
| #define VCLK(_id)		((struct vclk *)(&((vclk_##_id).vclk)))
 | |
| 
 | |
| extern struct pwrcal_vclk_none vclk_0;
 | |
| #define VCLK_NONE	(&(vclk_0.vclk))
 | |
| 
 | |
| 
 | |
| #define GRPGATE_EXTERN(_id)	\
 | |
| 	extern struct pwrcal_vclk_grpgate vclk_##_id;
 | |
| #define M1D1G1_EXTERN(_id)	\
 | |
| 	extern struct pwrcal_vclk_m1d1g1 vclk_##_id;
 | |
| #define P1_EXTERN(_id)		\
 | |
| 	extern struct pwrcal_vclk_p1 vclk_##_id;
 | |
| #define M1_EXTERN(_id)		\
 | |
| 	extern struct pwrcal_vclk_m1 vclk_##_id;
 | |
| #define D1_EXTERN(_id)		\
 | |
| 	extern struct pwrcal_vclk_d1 vclk_##_id;
 | |
| #define PXMXDX_EXTERN(_id)	\
 | |
| 	extern struct pwrcal_vclk_pxmxdx vclk_##_id;
 | |
| #define UMUX_EXTERN(_id)	\
 | |
| 	extern struct pwrcal_vclk_umux vclk_##_id;
 | |
| #define DFS_EXTERN(_id)		\
 | |
| 	extern struct pwrcal_vclk_dfs vclk_##_id;
 | |
| 
 | |
| 
 | |
| /* Macro to define GRPGATE */
 | |
| #define GRPGATE(_id, _parent, _gates)		\
 | |
| struct pwrcal_vclk_grpgate vclk_##_id __attribute__((unused, aligned(8), section(".vclk_grpgate."))) = {	\
 | |
| 	.vclk.type	= vclk_group_grpgate,				\
 | |
| 	.vclk.parent	= &((vclk_##_parent).vclk),	\
 | |
| 	.vclk.ref_count	= 0,				\
 | |
| 	.vclk.name	= #_id,				\
 | |
| 	.vclk.ops	= &grpgate_ops,				\
 | |
| 	.gates		= _gates,		\
 | |
| }
 | |
| 
 | |
| /* Macro to define PXMXDX */
 | |
| #define PXMXDX(_id, _parent, _clk_list)		\
 | |
| struct pwrcal_vclk_pxmxdx vclk_##_id __attribute__((unused, aligned(8), section(".vclk_pxmxdx."))) = {	\
 | |
| 	.vclk.type	= vclk_group_pxmxdx,				\
 | |
| 	.vclk.parent	= &((vclk_##_parent).vclk),	\
 | |
| 	.vclk.ref_count	= 0,				\
 | |
| 	.vclk.name	= #_id,				\
 | |
| 	.vclk.ops	= &pxmxdx_ops,			\
 | |
| 	.clk_list		= _clk_list,			\
 | |
| }
 | |
| 
 | |
| /* Macro to define UMUX */
 | |
| #define UMUX(_id, _parent, _umux)		\
 | |
| struct pwrcal_vclk_umux vclk_##_id __attribute__((unused, aligned(8), section(".vclk_umux."))) = {	\
 | |
| 	.vclk.type	= vclk_group_umux,				\
 | |
| 	.vclk.parent	= &((vclk_##_parent).vclk),	\
 | |
| 	.vclk.ref_count	= 0,				\
 | |
| 	.vclk.name	= #_id,				\
 | |
| 	.vclk.ops	= &umux_ops,			\
 | |
| 	.umux		= &((clk_##_umux).clk),		\
 | |
| }
 | |
| 
 | |
| /* Macro to define M1D1G1 */
 | |
| #define M1D1G1(_id, _parent,			\
 | |
| 		_mux, _div, _gate, _extramux)		\
 | |
| struct pwrcal_vclk_m1d1g1 vclk_##_id __attribute__((unused, aligned(8), section(".vclk_m1d1g1."))) = {	\
 | |
| 	.vclk.type	= vclk_group_m1d1g1,				\
 | |
| 	.vclk.parent	= &((vclk_##_parent).vclk),	\
 | |
| 	.vclk.ref_count	= 0,				\
 | |
| 	.vclk.name	= #_id,				\
 | |
| 	.vclk.ops	= &m1d1g1_ops,			\
 | |
| 	.mux		= &((clk_##_mux).clk),		\
 | |
| 	.div		= &((clk_##_div).clk),		\
 | |
| 	.gate		= &((clk_##_gate).clk),		\
 | |
| 	.extramux	= &((clk_##_extramux).clk),	\
 | |
| }
 | |
| 
 | |
| /* Macro to define P1 */
 | |
| #define P1(_id, _parent, _pll)			\
 | |
| struct pwrcal_vclk_p1 vclk_##_id __attribute__((unused, aligned(8), section(".vclk_p1."))) = {	\
 | |
| 	.vclk.type	= vclk_group_p1,				\
 | |
| 	.vclk.parent	= &((vclk_##_parent).vclk),	\
 | |
| 	.vclk.ref_count	= 0,				\
 | |
| 	.vclk.name	= #_id,				\
 | |
| 	.vclk.ops	= &p1_ops,			\
 | |
| 	.pll		= &((clk_##_pll).clk),		\
 | |
| }
 | |
| 
 | |
| /* Macro to define M1 */
 | |
| #define M1(_id, _parent, _mux)			\
 | |
| struct pwrcal_vclk_m1 vclk_##_id __attribute__((unused, aligned(8), section(".vclk_m1."))) = {	\
 | |
| 	.vclk.type	= vclk_group_m1,				\
 | |
| 	.vclk.parent	= &((vclk_##_parent).vclk),	\
 | |
| 	.vclk.ref_count	= 0,				\
 | |
| 	.vclk.name	= #_id,				\
 | |
| 	.vclk.ops	= &m1_ops,			\
 | |
| 	.mux		= &((clk_##_mux).clk),		\
 | |
| }
 | |
| 
 | |
| /* Macro to define D1 */
 | |
| #define D1(_id, _parent, _div)			\
 | |
| struct pwrcal_vclk_d1 vclk_##_id __attribute__((unused, aligned(8), section(".vclk_d1."))) = {	\
 | |
| 	.vclk.type	= vclk_group_d1,				\
 | |
| 	.vclk.parent	= &((vclk_##_parent).vclk),	\
 | |
| 	.vclk.ref_count	= 0,				\
 | |
| 	.vclk.name	= #_id,				\
 | |
| 	.vclk.ops	= &d1_ops,			\
 | |
| 	.div		= &((clk_##_div).clk),		\
 | |
| }
 | |
| 
 | |
| #define DFS(_id)	struct pwrcal_vclk_dfs vclk_##_id __attribute__((unused, aligned(8), section(".vclk_dfs.")))
 | |
| 
 | |
| 
 | |
| extern struct pwrcal_vclk_grpgate *vclk_grpgate_list[];
 | |
| extern struct pwrcal_vclk_m1d1g1 *vclk_m1d1g1_list[];
 | |
| extern struct pwrcal_vclk_p1 *vclk_p1_list[];
 | |
| extern struct pwrcal_vclk_m1 *vclk_m1_list[];
 | |
| extern struct pwrcal_vclk_d1 *vclk_d1_list[];
 | |
| extern struct pwrcal_vclk_pxmxdx *vclk_pxmxdx_list[];
 | |
| extern struct pwrcal_vclk_umux *vclk_umux_list[];
 | |
| extern struct pwrcal_vclk_dfs *vclk_dfs_list[];
 | |
| extern unsigned int vclk_grpgate_list_size;
 | |
| extern unsigned int vclk_m1d1g1_list_size;
 | |
| extern unsigned int vclk_p1_list_size;
 | |
| extern unsigned int vclk_m1_list_size;
 | |
| extern unsigned int vclk_d1_list_size;
 | |
| extern unsigned int vclk_pxmxdx_list_size;
 | |
| extern unsigned int vclk_umux_list_size;
 | |
| extern unsigned int vclk_dfs_list_size;
 | |
| 
 | |
| 
 | |
| #define to_grpgate(_vclk) container_of(_vclk, struct pwrcal_vclk_grpgate, vclk)
 | |
| #define to_pxmxdx(_vclk) container_of(_vclk, struct pwrcal_vclk_pxmxdx, vclk)
 | |
| #define to_umux(_vclk) container_of(_vclk, struct pwrcal_vclk_umux, vclk)
 | |
| #define to_m1d1g1(_vclk) container_of(_vclk, struct pwrcal_vclk_m1d1g1, vclk)
 | |
| #define to_p1(_vclk) container_of(_vclk, struct pwrcal_vclk_p1, vclk)
 | |
| #define to_m1(_vclk) container_of(_vclk, struct pwrcal_vclk_m1, vclk)
 | |
| #define to_d1(_vclk) container_of(_vclk, struct pwrcal_vclk_d1, vclk)
 | |
| #define to_dfs(_vclk) container_of(_vclk, struct pwrcal_vclk_dfs, vclk)
 | |
| 
 | |
| extern int vclk_setrate(struct vclk *vclk, unsigned long rate);
 | |
| extern unsigned long vclk_getrate(struct vclk *vclk);
 | |
| extern int vclk_enable(struct vclk *vclk);
 | |
| extern int vclk_disable(struct vclk *vclk);
 | |
| 
 | |
| extern int dfs_get_rate_table(struct dfs_table *dfs, unsigned long *table);
 | |
| extern int dfs_get_target_rate_table(struct dfs_table *dfs,
 | |
| 				unsigned int mux,
 | |
| 				unsigned int div,
 | |
| 				unsigned long *table);
 | |
| extern int dfs_set_rate(struct vclk *vclk, unsigned long to);
 | |
| extern unsigned long dfs_get_rate(struct vclk *vclk);
 | |
| extern int dfs_enable(struct vclk *vclk);
 | |
| extern int dfs_disable(struct vclk *vclk);
 | |
| extern int dfs_is_enabled(struct vclk *vclk);
 | |
| extern unsigned long dfs_get_max_freq(struct vclk *vclk);
 | |
| extern unsigned long dfs_get_min_freq(struct vclk *vclk);
 | |
| extern void vclk_unused_disable(void);
 | |
| extern void vclk_init(void);
 | |
| 
 | |
| /* for debug */
 | |
| #define NUM_OF_DEBUG_CLKS		64
 | |
| 
 | |
| struct cal_vclk_debug_info {
 | |
| 	unsigned int type;
 | |
| 	unsigned int *parent;
 | |
| 	unsigned int *blkpwr;
 | |
| 	int state;
 | |
| 	int ref_count;
 | |
| 	int dtci;
 | |
| 	unsigned int clks[NUM_OF_DEBUG_CLKS];
 | |
| 	unsigned long rates[NUM_OF_DEBUG_CLKS];
 | |
| 	int num_of_clks;
 | |
| 	char *name;
 | |
| };
 | |
| 
 | |
| extern int cal_vclk_get_debug(unsigned int id,
 | |
| 				struct cal_vclk_debug_info *info);
 | |
| 
 | |
| struct cal_clk_debug_info {
 | |
| 	unsigned int type;
 | |
| 	unsigned int config;
 | |
| 	unsigned int addr;
 | |
| 	unsigned int shift;
 | |
| 	unsigned int mask;
 | |
| 	unsigned int stat;
 | |
| 	unsigned int stat_addr;
 | |
| 	unsigned int stat_shift;
 | |
| 	unsigned int stat_mask;
 | |
| 	unsigned int parent;
 | |
| 	char *name;
 | |
| };
 | |
| 
 | |
| extern int cal_clk_get_debug(unsigned int id, struct cal_clk_debug_info *info);
 | |
| 
 | |
| #define NUM_OF_DEBUG_CLKPATH		16
 | |
| struct cal_clk_debug_clkpath {
 | |
| 	unsigned int clks[NUM_OF_DEBUG_CLKPATH];
 | |
| 	unsigned long rates[NUM_OF_DEBUG_CLKPATH];		/* KHZ */
 | |
| 	const char *name[NUM_OF_DEBUG_CLKPATH];
 | |
| };
 | |
| 
 | |
| extern unsigned long cal_clk_get_path_debug(unsigned int id,
 | |
| 				struct cal_clk_debug_clkpath *clkpath);
 | |
| extern void cal_vclk_dbg_print_all(void);
 | |
| 
 | |
| #endif
 | 
