ANDROID: GKI: clk: Add support for voltage voting
This change adds support for voltage voting in the clock framework. This will NOT be carried over to newer kernels. Bug: 150506629 Signed-off-by: David Collins <collinsd@codeaurora.org> Signed-off-by: David Dai <daidavid1@codeaurora.org> Signed-off-by: Deepak Katragadda <dkatraga@codeaurora.org> Signed-off-by: Shefali Jain <shefjain@codeaurora.org> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Taniya Das <tdas@codeaurora.org> [saravanak: Squashed the following commits and dropped some debug code and code whose functionality that's replaced by clk_sync_state()ff5ce501baclk: do not vote for vdd_class level with 0 Hz rate_max96f0596cc0clk: provider: cleanup of unused use_max_uV83d12e55baclk: Always vote INT_MAX as maximum voltage for a rail352850e657clk: handle reentrant clk_set_rate() calls from clock supply regulators0d8060cd6bclk: add bus voting to rate_get, rate_set, enable_set debug functionsd4c36a3d10clk: remove prepare lock and bus voting in clk_debug_print_hw813f666281clk: add bus voting ops for debug purposes7e0561072dclk: qcom: Fix return value check for round rate during clock registrationc4540b8ee3clk: fix conflicting bit for measure clock flagfa9b30447fclk: correct vdd_class voting scheme used during clock rate changes61dad2894fclk: Move VDD voltage voting from core clock to top clock0cbef8b6fcclk: qcom: Add support to log PLL/RCGR values in case of failurebcc43f7a19clk: qcom: Add support for debugfs measure clock1ac9516f74clk: Export the clock driver's voltage voting APIsc4316254d2clk: add/modify debugfs support for clocksd30b895f21clk: move check for CLK_ENABLE_HAND_OFF at unused tree11032174caclk: Add support to provide OPP tables for clocksf349485712clk: Add support to vote to regulator framework from clk framework81286aed66clk: Check for failure at clk_change_rate6a4951a830clk: qcom: clk-voter: Add support for voter clocksb904878a04clk: Add support to set custom flags with clk_set_flags ] Signed-off-by: Saravana Kannan <saravanak@google.com> Change-Id: I95574f11053e8f3762c8d660183ce5004ff5cc5b
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -14,6 +14,7 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_clk.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#ifdef CONFIG_COMMON_CLK
|
||||
|
||||
@@ -41,6 +42,12 @@
|
||||
/* duty cycle call may be forwarded to the parent clock */
|
||||
#define CLK_DUTY_CYCLE_PARENT BIT(13)
|
||||
#define CLK_DONT_HOLD_STATE BIT(14) /* Don't hold state */
|
||||
#define CLK_ENABLE_HAND_OFF BIT(15) /* enable clock when registered. */
|
||||
/*
|
||||
* hand-off enable_count & prepare_count
|
||||
* to first consumer that enables clk
|
||||
*/
|
||||
#define CLK_IS_MEASURE BIT(16) /* measure clock */
|
||||
|
||||
struct clk;
|
||||
struct clk_hw;
|
||||
@@ -203,6 +210,18 @@ struct clk_duty {
|
||||
* directory is provided as an argument. Called with
|
||||
* prepare_lock held. Returns 0 on success, -EERROR otherwise.
|
||||
*
|
||||
* @set_flags: Set custom flags which deal with hardware specifics. Returns 0
|
||||
* on success, -EERROR otherwise.
|
||||
*
|
||||
* @list_registers: Queries the hardware to get the current register contents.
|
||||
* This callback is optional.
|
||||
*
|
||||
* @list_rate: On success, return the nth supported frequency for a given
|
||||
* clock that is below rate_max. Return -ENXIO in case there is
|
||||
* no frequency table.
|
||||
*
|
||||
* @bus_vote: Votes for bandwidth on certain config slaves to connect
|
||||
* ports in order to gain access to clock controllers.
|
||||
*
|
||||
* The clk_enable/clk_disable and clk_prepare/clk_unprepare pairs allow
|
||||
* implementations to split any work between atomic (enable) and sleepable
|
||||
@@ -247,6 +266,12 @@ struct clk_ops {
|
||||
struct clk_duty *duty);
|
||||
void (*init)(struct clk_hw *hw);
|
||||
void (*debug_init)(struct clk_hw *hw, struct dentry *dentry);
|
||||
int (*set_flags)(struct clk_hw *hw, unsigned int flags);
|
||||
void (*list_registers)(struct seq_file *f,
|
||||
struct clk_hw *hw);
|
||||
long (*list_rate)(struct clk_hw *hw, unsigned int n,
|
||||
unsigned long rate_max);
|
||||
void (*bus_vote)(struct clk_hw *hw, bool enable);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -258,15 +283,86 @@ struct clk_ops {
|
||||
* @parent_names: array of string names for all possible parents
|
||||
* @num_parents: number of possible parents
|
||||
* @flags: framework-level hints and quirks
|
||||
* @vdd_class: voltage scaling requirement class
|
||||
* @rate_max: maximum clock rate in Hz supported at each voltage level
|
||||
* @num_rate_max: number of maximum voltage level supported
|
||||
* @bus_cl_id: client id registered with the bus driver used for bw votes
|
||||
*/
|
||||
struct clk_init_data {
|
||||
const char *name;
|
||||
const struct clk_ops *ops;
|
||||
const char * const *parent_names;
|
||||
u8 num_parents;
|
||||
unsigned int num_parents;
|
||||
unsigned long flags;
|
||||
struct clk_vdd_class *vdd_class;
|
||||
unsigned long *rate_max;
|
||||
int num_rate_max;
|
||||
unsigned int bus_cl_id;
|
||||
};
|
||||
|
||||
struct regulator;
|
||||
|
||||
/**
|
||||
* struct clk_vdd_class - Voltage scaling class
|
||||
* @class_name: name of the class
|
||||
* @regulator: array of regulators
|
||||
* @num_regulators: size of regulator array. Standard regulator APIs will be
|
||||
used if this field > 0
|
||||
* @set_vdd: function to call when applying a new voltage setting
|
||||
* @vdd_uv: sorted 2D array of legal voltage settings. Indexed by level, then
|
||||
regulator
|
||||
* @level_votes: array of votes for each level
|
||||
* @num_levels: specifies the size of level_votes array
|
||||
* @skip_handoff: do not vote for the max possible voltage during init
|
||||
* @cur_level: the currently set voltage level
|
||||
* @lock: lock to protect this struct
|
||||
*/
|
||||
struct clk_vdd_class {
|
||||
const char *class_name;
|
||||
struct regulator **regulator;
|
||||
int num_regulators;
|
||||
int (*set_vdd)(struct clk_vdd_class *v_class, int level);
|
||||
int *vdd_uv;
|
||||
int *level_votes;
|
||||
int num_levels;
|
||||
bool skip_handoff;
|
||||
unsigned long cur_level;
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
#define DEFINE_VDD_CLASS(_name, _set_vdd, _num_levels) \
|
||||
struct clk_vdd_class _name = { \
|
||||
.class_name = #_name, \
|
||||
.set_vdd = _set_vdd, \
|
||||
.level_votes = (int [_num_levels]) {}, \
|
||||
.num_levels = _num_levels, \
|
||||
.cur_level = _num_levels, \
|
||||
.lock = __MUTEX_INITIALIZER(_name.lock) \
|
||||
}
|
||||
|
||||
#define DEFINE_VDD_REGULATORS(_name, _num_levels, _num_regulators, _vdd_uv) \
|
||||
struct clk_vdd_class _name = { \
|
||||
.class_name = #_name, \
|
||||
.vdd_uv = _vdd_uv, \
|
||||
.regulator = (struct regulator * [_num_regulators]) {}, \
|
||||
.num_regulators = _num_regulators, \
|
||||
.level_votes = (int [_num_levels]) {}, \
|
||||
.num_levels = _num_levels, \
|
||||
.cur_level = _num_levels, \
|
||||
.lock = __MUTEX_INITIALIZER(_name.lock) \
|
||||
}
|
||||
|
||||
#define DEFINE_VDD_REGS_INIT(_name, _num_regulators) \
|
||||
struct clk_vdd_class _name = { \
|
||||
.class_name = #_name, \
|
||||
.regulator = (struct regulator * [_num_regulators]) {}, \
|
||||
.num_regulators = _num_regulators, \
|
||||
.lock = __MUTEX_INITIALIZER(_name.lock) \
|
||||
}
|
||||
|
||||
int clk_vote_vdd_level(struct clk_vdd_class *vdd_class, int level);
|
||||
int clk_unvote_vdd_level(struct clk_vdd_class *vdd_class, int level);
|
||||
|
||||
/**
|
||||
* struct clk_hw - handle for traversing from a struct clk to its corresponding
|
||||
* hardware-specific structure. struct clk_hw should be declared within struct
|
||||
@@ -804,6 +900,11 @@ void clk_hw_reparent(struct clk_hw *hw, struct clk_hw *new_parent);
|
||||
void clk_hw_set_rate_range(struct clk_hw *hw, unsigned long min_rate,
|
||||
unsigned long max_rate);
|
||||
|
||||
unsigned long clk_aggregate_rate(struct clk_hw *hw,
|
||||
const struct clk_core *parent);
|
||||
int clk_vote_rate_vdd(struct clk_core *core, unsigned long rate);
|
||||
void clk_unvote_rate_vdd(struct clk_core *core, unsigned long rate);
|
||||
|
||||
static inline void __clk_hw_set_clk(struct clk_hw *dst, struct clk_hw *src)
|
||||
{
|
||||
dst->clk = src->clk;
|
||||
|
||||
Reference in New Issue
Block a user