mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-10-30 15:48:52 +01:00
299 lines
8.6 KiB
C
Executable file
299 lines
8.6 KiB
C
Executable file
#ifndef __PWRCAL_CLK_H__
|
|
#define __PWRCAL_CLK_H__
|
|
|
|
#ifndef NULL
|
|
#define NULL (0)
|
|
#endif
|
|
|
|
#ifndef MHZ
|
|
#define MHZ ((unsigned long long)1000000)
|
|
#endif
|
|
#ifndef KHZ
|
|
#define KHZ ((unsigned int)1000)
|
|
#endif
|
|
|
|
#ifndef FIN_HZ
|
|
#if defined(CONFIG_BOARD_FPGA)
|
|
#define FIN_HZ (5*MHZ)
|
|
#else
|
|
#define FIN_HZ (24*MHZ)
|
|
#endif
|
|
#endif
|
|
|
|
#define CLK_WAIT_CNT 1000
|
|
|
|
#define TO_MASK(_size) (((unsigned int)1<<(_size))-1)
|
|
|
|
#define invalid_mux_src_num 0xFF
|
|
#define mux_flag_user_mux (1<<0)
|
|
#define mux_flag_alwayson (1<<1)
|
|
|
|
|
|
#define mask_of_type 0x0F000000
|
|
#define mask_of_group 0x00FF0000
|
|
#define mask_of_id 0x00000FFF
|
|
#define fixed_rate_type 0x01000000
|
|
#define fixed_factor_type 0x02000000
|
|
#define pll_type 0x05000000
|
|
#define mux_type 0x06000000
|
|
#define user_mux_type 0x06001000
|
|
#define div_type 0x07000000
|
|
#define gate_type 0x08000000
|
|
#define gate_root_type 0x09000000
|
|
#define vclk_type 0x0A000000
|
|
#define invalid_clk_id mask_of_id
|
|
#define empty_clk_id mask_of_id
|
|
|
|
#define is_pll(a) (a && (a->id & mask_of_type) == pll_type)
|
|
#define is_mux(a) (a && (a->id & mask_of_type) == mux_type)
|
|
#define is_div(a) (a && (a->id & mask_of_type) == div_type)
|
|
#define is_gate(a) (a && (a->id & mask_of_type) == gate_type)
|
|
|
|
enum clk_id;
|
|
|
|
struct pwrcal_clk {
|
|
unsigned int id;
|
|
struct pwrcal_clk *parent;
|
|
unsigned int *offset;
|
|
unsigned short shift;
|
|
unsigned short width;
|
|
unsigned int *status; /* or lock_offset of pll */
|
|
unsigned short s_shift;
|
|
unsigned short s_width;
|
|
unsigned int *enable;
|
|
unsigned short e_shift;
|
|
unsigned short e_width;
|
|
const char *name;
|
|
};
|
|
|
|
struct pwrcal_clk_none {
|
|
struct pwrcal_clk clk;
|
|
};
|
|
extern struct pwrcal_clk_none clk_0;
|
|
#define CLK_NONE (&(clk_0.clk))
|
|
#define CLK(_id) ((struct pwrcal_clk *)(&((clk_##_id).clk)))
|
|
|
|
|
|
struct pll_spec {
|
|
unsigned int pdiv_min;
|
|
unsigned int pdiv_max;
|
|
unsigned int mdiv_min;
|
|
unsigned int mdiv_max;
|
|
unsigned int sdiv_min;
|
|
unsigned int sdiv_max;
|
|
signed short kdiv_min;
|
|
signed short kdiv_max;
|
|
unsigned long long fref_min;
|
|
unsigned long long fref_max;
|
|
unsigned long long fvco_min;
|
|
unsigned long long fvco_max;
|
|
unsigned long long fout_min;
|
|
unsigned long long fout_max;
|
|
};
|
|
|
|
struct pwrcal_pll_rate_table {
|
|
unsigned long long rate;
|
|
unsigned short pdiv;
|
|
unsigned short mdiv;
|
|
unsigned short sdiv;
|
|
signed short kdiv;
|
|
};
|
|
|
|
struct pwrcal_pll_ops {
|
|
int (*is_enabled)(struct pwrcal_clk *clk);
|
|
int (*enable)(struct pwrcal_clk *clk);
|
|
int (*disable)(struct pwrcal_clk *clk);
|
|
int (*set_rate)(struct pwrcal_clk *clk, unsigned long long rate);
|
|
unsigned long long (*get_rate)(struct pwrcal_clk *clk);
|
|
};
|
|
|
|
struct pwrcal_pll {
|
|
struct pwrcal_clk clk;
|
|
unsigned int type;
|
|
struct pwrcal_pll_rate_table *rate_table;
|
|
unsigned int rate_count;
|
|
struct pwrcal_clk *mux;
|
|
struct pwrcal_pll_ops *ops;
|
|
};
|
|
|
|
#define CLK_PLL(_typ, _id, _pid, _lock, _con, _rtable, _mux, _ops) \
|
|
struct pwrcal_pll clk_##_id __attribute__((unused, aligned(8), section(".clk_pll."))) = { \
|
|
.clk.id = _id, \
|
|
.clk.parent = &((clk_##_pid).clk), \
|
|
.clk.offset = _con, \
|
|
.clk.status = _lock, \
|
|
.clk.name = #_id, \
|
|
.type = _typ, \
|
|
.rate_table = _rtable, \
|
|
.rate_count = (sizeof(_rtable) / sizeof((_rtable)[0])), \
|
|
.mux = &((clk_##_mux).clk), \
|
|
.ops = _ops \
|
|
}
|
|
|
|
|
|
extern struct pwrcal_clk_ops frate_ops;
|
|
struct pwrcal_clk_fixed_rate {
|
|
struct pwrcal_clk clk;
|
|
unsigned long long fixed_rate;
|
|
struct pwrcal_clk *gate;
|
|
};
|
|
|
|
#define FIXEDRATE(_id, _frate, _gate) \
|
|
struct pwrcal_clk_fixed_rate clk_##_id __attribute__((unused, aligned(8), section(".clk_fixed_rate."))) = { \
|
|
.clk.id = _id, \
|
|
.clk.parent = &(clk_0.clk), \
|
|
.clk.name = #_id, \
|
|
.fixed_rate = _frate, \
|
|
.gate = &((clk_##_gate).clk), \
|
|
}
|
|
|
|
|
|
extern struct pwrcal_clk_ops fdiv_ops;
|
|
struct pwrcal_clk_fixed_factor {
|
|
struct pwrcal_clk clk;
|
|
unsigned short ratio;
|
|
struct pwrcal_clk *gate;
|
|
};
|
|
|
|
#define FIXEDFACTOR(_id, _pid, _ratio, _gate) \
|
|
struct pwrcal_clk_fixed_factor clk_##_id __attribute__((unused, aligned(8), section(".clk_fixed_factor."))) = { \
|
|
.clk.id = _id, \
|
|
.clk.parent = &((clk_##_pid).clk), \
|
|
.clk.name = #_id, \
|
|
.ratio = _ratio, \
|
|
.gate = &((clk_##_gate).clk), \
|
|
}
|
|
|
|
|
|
extern struct pwrcal_clk_ops mux_ops;
|
|
struct pwrcal_mux {
|
|
struct pwrcal_clk clk;
|
|
struct pwrcal_clk **parents;
|
|
unsigned char num_parents;
|
|
struct pwrcal_clk *gate;
|
|
};
|
|
|
|
#define CLK_MUX(_id, _pids, _o, _s, _w, _so, _ss, _sw, \
|
|
_eo, _es, _gate) \
|
|
struct pwrcal_mux clk_##_id __attribute__((unused, aligned(8), section(".clk_mux."))) = { \
|
|
.clk.id = _id, \
|
|
.clk.name = #_id, \
|
|
.clk.offset = _o, \
|
|
.clk.shift = _s, \
|
|
.clk.width = _w, \
|
|
.clk.status = _so, \
|
|
.clk.s_shift = _ss, \
|
|
.clk.s_width = _sw, \
|
|
.clk.enable = _eo, \
|
|
.clk.e_shift = _es, \
|
|
.parents = _pids, \
|
|
.num_parents = (sizeof(_pids) / sizeof((_pids)[0])), \
|
|
.gate = &((clk_##_gate).clk), \
|
|
}
|
|
|
|
|
|
extern struct pwrcal_clk_ops div_ops;
|
|
struct pwrcal_div {
|
|
struct pwrcal_clk clk;
|
|
struct pwrcal_clk *gate;
|
|
};
|
|
|
|
#define CLK_DIV(_id, _pid, _o, _s, _w, _so, _ss, _sw, _gate) \
|
|
struct pwrcal_div clk_##_id __attribute__((unused, aligned(8), section(".clk_div."))) = { \
|
|
.clk.id = _id, \
|
|
.clk.name = #_id, \
|
|
.clk.parent = &((clk_##_pid).clk), \
|
|
.clk.offset = _o, \
|
|
.clk.shift = _s, \
|
|
.clk.width = _w, \
|
|
.clk.status = _so, \
|
|
.clk.s_shift = _ss, \
|
|
.clk.s_width = _sw, \
|
|
.gate = &((clk_##_gate).clk), \
|
|
}
|
|
|
|
|
|
extern struct pwrcal_clk_ops gate_ops;
|
|
struct pwrcal_gate {
|
|
struct pwrcal_clk clk;
|
|
};
|
|
|
|
#define CLK_GATE(_id, _pid, _o, _s) \
|
|
struct pwrcal_gate clk_##_id __attribute__((unused, aligned(8), section(".clk_gate."))) = { \
|
|
.clk.id = _id, \
|
|
.clk.name = #_id, \
|
|
.clk.parent = &((clk_##_pid).clk), \
|
|
.clk.offset = _o, \
|
|
.clk.shift = _s, \
|
|
}
|
|
|
|
#define PLL_EXTERN(_id) \
|
|
extern struct pwrcal_pll clk_##_id;
|
|
#define FIXEDRATE_EXTERN(_id) \
|
|
extern struct pwrcal_clk_fixed_rate clk_##_id;
|
|
#define FIXEDFACTOR_EXTERN(_id) \
|
|
extern struct pwrcal_clk_fixed_factor clk_##_id;
|
|
#define MUX_EXTERN(_id) \
|
|
extern struct pwrcal_mux clk_##_id;
|
|
#define DIV_EXTERN(_id) \
|
|
extern struct pwrcal_div clk_##_id;
|
|
#define GATE_EXTERN(_id) \
|
|
extern struct pwrcal_gate clk_##_id;
|
|
|
|
|
|
#define to_pll(_clk) container_of(_clk, struct pwrcal_pll, clk)
|
|
#define to_frate(_clk) container_of(_clk, struct pwrcal_clk_fixed_rate, clk)
|
|
#define to_ffactor(_clk) container_of(_clk, struct pwrcal_clk_fixed_factor, clk)
|
|
#define to_mux(_clk) container_of(_clk, struct pwrcal_mux, clk)
|
|
#define to_div(_clk) container_of(_clk, struct pwrcal_div, clk)
|
|
#define to_gate(_clk) container_of(_clk, struct pwrcal_gate, clk)
|
|
|
|
struct clk_entry {
|
|
unsigned int id;
|
|
struct pwrcal_clk *clk;
|
|
};
|
|
extern struct clk_entry pwrcal_clk_list[];
|
|
|
|
extern int pwrcal_mux_is_enabled(struct pwrcal_clk *clk);
|
|
extern int pwrcal_mux_enable(struct pwrcal_clk *clk);
|
|
extern int pwrcal_mux_disable(struct pwrcal_clk *clk);
|
|
extern int pwrcal_mux_get_src(struct pwrcal_clk *clk);
|
|
extern int pwrcal_mux_set_src(struct pwrcal_clk *clk, unsigned int src);
|
|
extern int pwrcal_mux_get_parents(struct pwrcal_clk *clk,
|
|
struct pwrcal_clk **parents);
|
|
extern struct pwrcal_clk *pwrcal_mux_get_parent(struct pwrcal_clk *clk);
|
|
extern int _pwrcal_is_private_mux_set_src(struct pwrcal_clk *clk);
|
|
extern int _pwrcal_private_mux_set_src(struct pwrcal_clk *clk,
|
|
unsigned int src);
|
|
|
|
extern int pwrcal_div_is_enabled(struct pwrcal_clk *clk);
|
|
extern int pwrcal_div_enable(struct pwrcal_clk *clk);
|
|
extern int pwrcal_div_disable(struct pwrcal_clk *clk);
|
|
extern unsigned int pwrcal_div_get_ratio(struct pwrcal_clk *clk);
|
|
extern int pwrcal_div_set_ratio(struct pwrcal_clk *clk, unsigned int ratio);
|
|
extern unsigned int pwrcal_div_get_max_ratio(struct pwrcal_clk *clk);
|
|
|
|
extern int pwrcal_pll_is_enabled(struct pwrcal_clk *clk);
|
|
extern int pwrcal_pll_enable(struct pwrcal_clk *clk);
|
|
extern int pwrcal_pll_disable(struct pwrcal_clk *clk);
|
|
extern unsigned long long pwrcal_pll_get_rate(struct pwrcal_clk *clk);
|
|
extern int pwrcal_pll_set_rate(struct pwrcal_clk *clk, unsigned long long rate);
|
|
extern unsigned long long clk_pll_getmaxfreq(struct pwrcal_clk *clk);
|
|
extern struct pll_spec *clk_pll_get_spec(struct pwrcal_clk *clk);
|
|
|
|
extern int pwrcal_gate_is_enabled(struct pwrcal_clk *clk);
|
|
extern int pwrcal_gate_enable(struct pwrcal_clk *clk);
|
|
extern int pwrcal_gate_disable(struct pwrcal_clk *clk);
|
|
|
|
extern struct pwrcal_clk *pwrcal_clk_get_parent(struct pwrcal_clk *clk);
|
|
extern unsigned long long pwrcal_clk_get_rate(struct pwrcal_clk *clk);
|
|
extern int pwrcal_clk_set_rate(struct pwrcal_clk *clk, unsigned long long rate);
|
|
extern int pwrcal_clk_enable(struct pwrcal_clk *clk);
|
|
extern int pwrcal_clk_disable(struct pwrcal_clk *clk);
|
|
|
|
extern unsigned int _cal_clk_get(char *name);
|
|
extern struct pwrcal_clk *cal_get_clk(unsigned int id);
|
|
|
|
extern void clk_init(void);
|
|
extern struct pwrcal_clk *clk_find(char *clk_name);
|
|
#endif
|