android_kernel_samsung_on5x.../drivers/soc/samsung/pwrcal/pwrcal-vclk.h
2018-06-19 23:16:04 +02:00

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