mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
soc: rockchip: opp_select: Implement rockchip_set_read_margin()
Add common APIs to set read margin and set intermediate rate. Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com> Change-Id: I8fb1d16f4ca1a9ec0ba80019197a73e56391c14c
This commit is contained in:
@@ -1164,6 +1164,69 @@ int rockchip_get_read_margin(struct device *dev,
|
||||
}
|
||||
EXPORT_SYMBOL(rockchip_get_read_margin);
|
||||
|
||||
int rockchip_set_read_margin(struct device *dev,
|
||||
struct rockchip_opp_info *opp_info, u32 rm,
|
||||
bool is_set_rm)
|
||||
{
|
||||
if (!is_set_rm || !opp_info)
|
||||
return 0;
|
||||
if (!opp_info || !opp_info->volt_rm_tbl)
|
||||
return 0;
|
||||
if (!opp_info->data || !opp_info->data->set_read_margin)
|
||||
return 0;
|
||||
if (rm == opp_info->current_rm)
|
||||
return 0;
|
||||
|
||||
return opp_info->data->set_read_margin(dev, opp_info, rm);
|
||||
}
|
||||
EXPORT_SYMBOL(rockchip_set_read_margin);
|
||||
|
||||
int rockchip_set_intermediate_rate(struct device *dev,
|
||||
struct rockchip_opp_info *opp_info,
|
||||
struct clk *clk, unsigned long old_freq,
|
||||
unsigned long new_freq, bool is_scaling_up,
|
||||
bool is_set_clk)
|
||||
{
|
||||
if (!is_set_clk)
|
||||
return 0;
|
||||
if (!opp_info || !opp_info->volt_rm_tbl)
|
||||
return 0;
|
||||
if (!opp_info->data || !opp_info->data->set_read_margin)
|
||||
return 0;
|
||||
if (opp_info->target_rm == opp_info->current_rm)
|
||||
return 0;
|
||||
/*
|
||||
* There is no need to set intermediate rate if the new voltage
|
||||
* and the current voltage are high voltage.
|
||||
*/
|
||||
if ((opp_info->target_rm < opp_info->low_rm) &&
|
||||
(opp_info->current_rm < opp_info->low_rm))
|
||||
return 0;
|
||||
|
||||
if (is_scaling_up) {
|
||||
/*
|
||||
* If scaling up and the current frequency is less than
|
||||
* or equal to intermediate threshold frequency, there is
|
||||
* no need to set intermediate rate.
|
||||
*/
|
||||
if (opp_info->intermediate_threshold_freq &&
|
||||
old_freq <= opp_info->intermediate_threshold_freq)
|
||||
return 0;
|
||||
return clk_set_rate(clk, new_freq | OPP_SCALING_UP_INTER);
|
||||
}
|
||||
/*
|
||||
* If scaling down and the new frequency is less than or equal to
|
||||
* intermediate threshold frequency , there is no need to set
|
||||
* intermediate rate and set the new frequency directly.
|
||||
*/
|
||||
if (opp_info->intermediate_threshold_freq &&
|
||||
new_freq <= opp_info->intermediate_threshold_freq)
|
||||
return clk_set_rate(clk, new_freq);
|
||||
|
||||
return clk_set_rate(clk, new_freq | OPP_SCALING_DOWN_INTER);
|
||||
}
|
||||
EXPORT_SYMBOL(rockchip_set_intermediate_rate);
|
||||
|
||||
int rockchip_init_opp_table(struct device *dev, struct rockchip_opp_info *info,
|
||||
char *lkg_name, char *reg_name)
|
||||
{
|
||||
@@ -1171,6 +1234,7 @@ int rockchip_init_opp_table(struct device *dev, struct rockchip_opp_info *info,
|
||||
int bin = -EINVAL, process = -EINVAL;
|
||||
int scale = 0, volt_sel = -EINVAL;
|
||||
int ret = 0, num_clks = 0, i;
|
||||
u32 freq;
|
||||
|
||||
/* Get OPP descriptor node */
|
||||
np = of_parse_phandle(dev->of_node, "operating-points-v2", 0);
|
||||
@@ -1207,6 +1271,11 @@ int rockchip_init_opp_table(struct device *dev, struct rockchip_opp_info *info,
|
||||
info->grf = NULL;
|
||||
rockchip_get_volt_rm_table(dev, np, "volt-mem-read-margin",
|
||||
&info->volt_rm_tbl);
|
||||
of_property_read_u32(np, "low-volt-mem-read-margin",
|
||||
&info->low_rm);
|
||||
if (!of_property_read_u32(np, "intermediate-threshold-freq",
|
||||
&freq))
|
||||
info->intermediate_threshold_freq = freq * 1000;
|
||||
}
|
||||
if (info->data && info->data->get_soc_info)
|
||||
info->data->get_soc_info(dev, np, &bin, &process);
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
|
||||
#define VOLT_RM_TABLE_END ~1
|
||||
|
||||
#define OPP_INTERMEDIATE_MASK 0x3f
|
||||
#define OPP_INTERMEDIATE_RATE 0x01
|
||||
#define OPP_SCALING_UP_RATE 0x02
|
||||
#define OPP_SCALING_UP_INTER (OPP_INTERMEDIATE_RATE | OPP_SCALING_UP_RATE)
|
||||
#define OPP_SCALING_DOWN_INTER OPP_INTERMEDIATE_RATE
|
||||
|
||||
struct rockchip_opp_info;
|
||||
|
||||
struct volt_rm_table {
|
||||
@@ -30,7 +36,11 @@ struct rockchip_opp_info {
|
||||
struct regmap *dsu_grf;
|
||||
struct clk_bulk_data *clks;
|
||||
struct clk *scmi_clk;
|
||||
/* The threshold frequency for set intermediate rate */
|
||||
unsigned long intermediate_threshold_freq;
|
||||
int num_clks;
|
||||
/* The read margin for low voltage */
|
||||
u32 low_rm;
|
||||
u32 current_rm;
|
||||
u32 target_rm;
|
||||
};
|
||||
@@ -64,6 +74,14 @@ int rockchip_adjust_power_scale(struct device *dev, int scale);
|
||||
int rockchip_get_read_margin(struct device *dev,
|
||||
struct rockchip_opp_info *opp_info,
|
||||
unsigned long volt, u32 *target_rm);
|
||||
int rockchip_set_read_margin(struct device *dev,
|
||||
struct rockchip_opp_info *opp_info, u32 rm,
|
||||
bool is_set_rm);
|
||||
int rockchip_set_intermediate_rate(struct device *dev,
|
||||
struct rockchip_opp_info *opp_info,
|
||||
struct clk *clk, unsigned long old_freq,
|
||||
unsigned long new_freq, bool is_scaling_up,
|
||||
bool is_set_clk);
|
||||
int rockchip_init_opp_table(struct device *dev,
|
||||
struct rockchip_opp_info *info,
|
||||
char *lkg_name, char *reg_name);
|
||||
@@ -151,6 +169,22 @@ static inline int rockchip_get_read_margin(struct device *dev,
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
static inline int rockchip_set_read_margin(struct device *dev,
|
||||
struct rockchip_opp_info *opp_info,
|
||||
u32 rm, bool is_set_rm)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int
|
||||
rockchip_set_intermediate_rate(struct device *dev,
|
||||
struct rockchip_opp_info *opp_info,
|
||||
struct clk *clk, unsigned long old_freq,
|
||||
unsigned long new_freq, bool is_scaling_up,
|
||||
bool is_set_clk)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int rockchip_init_opp_table(struct device *dev,
|
||||
struct rockchip_opp_info *info,
|
||||
|
||||
Reference in New Issue
Block a user