mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-10-29 23:28:52 +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
|