soc: rockchip: opp_select: Implements new opp APIs for kernel 6.1

Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
Change-Id: I3e1bef3d15d8ea290565fb3573d8e79b5bf18815
This commit is contained in:
Finley Xiao
2023-06-08 21:52:00 +08:00
committed by Tao Huang
parent dee8d6d889
commit c64369f0e4
2 changed files with 688 additions and 261 deletions

View File

@@ -83,6 +83,10 @@ struct otp_opp_info {
static int pvtm_value[PVTM_CH_MAX][PVTM_SUB_CH_MAX]; static int pvtm_value[PVTM_CH_MAX][PVTM_SUB_CH_MAX];
static int lkg_version; static int lkg_version;
static int rockchip_init_read_margin(struct device *dev,
struct rockchip_opp_info *opp_info,
const char *reg_name);
/* /*
* temp = temp * 10 * temp = temp * 10
* conv = exp(-ln(1.2) / 5 * (temp - 23)) * 100 * conv = exp(-ln(1.2) / 5 * (temp - 23)) * 100
@@ -652,9 +656,9 @@ int rockchip_of_get_leakage(struct device *dev, char *lkg_name, int *leakage)
} }
EXPORT_SYMBOL(rockchip_of_get_leakage); EXPORT_SYMBOL(rockchip_of_get_leakage);
void rockchip_of_get_lkg_sel(struct device *dev, struct device_node *np, static void rockchip_of_get_lkg_sel(struct device *dev, struct device_node *np,
char *lkg_name, int process, char *lkg_name, int process,
int *volt_sel, int *scale_sel) int *volt_sel, int *scale_sel)
{ {
struct property *prop = NULL; struct property *prop = NULL;
int leakage = -EINVAL, ret = 0; int leakage = -EINVAL, ret = 0;
@@ -713,7 +717,6 @@ next:
if (!ret) if (!ret)
dev_info(dev, "leakage-scale=%d\n", *scale_sel); dev_info(dev, "leakage-scale=%d\n", *scale_sel);
} }
EXPORT_SYMBOL(rockchip_of_get_lkg_sel);
static unsigned long rockchip_pvtpll_get_rate(struct rockchip_opp_info *info) static unsigned long rockchip_pvtpll_get_rate(struct rockchip_opp_info *info)
{ {
@@ -804,7 +807,7 @@ static int rockchip_init_pvtpll_info(struct rockchip_opp_info *info)
info->opp_table[i].u_volt_mem_min = opp->supplies[1].u_volt_min; info->opp_table[i].u_volt_mem_min = opp->supplies[1].u_volt_min;
info->opp_table[i].u_volt_mem_max = opp->supplies[1].u_volt_max; info->opp_table[i].u_volt_mem_max = opp->supplies[1].u_volt_max;
} }
info->opp_table[i++].rate = opp->rate; info->opp_table[i++].rate = opp->rates[0];
} }
mutex_unlock(&opp_table->lock); mutex_unlock(&opp_table->lock);
@@ -839,7 +842,7 @@ static int rockchip_pvtpll_set_clk(struct device *dev, struct clk *clk,
return ret; return ret;
} }
void rockchip_pvtpll_calibrate_opp(struct rockchip_opp_info *info) static void rockchip_pvtpll_calibrate_opp(struct rockchip_opp_info *info)
{ {
struct opp_table *opp_table; struct opp_table *opp_table;
struct dev_pm_opp *opp; struct dev_pm_opp *opp;
@@ -866,6 +869,14 @@ void rockchip_pvtpll_calibrate_opp(struct rockchip_opp_info *info)
if (!opp_table) if (!opp_table)
return; return;
if (info->clocks) {
ret = clk_bulk_prepare_enable(info->nclocks, info->clocks);
if (ret) {
dev_err(info->dev, "failed to enable opp clks\n");
return;
}
}
if ((!opp_table->regulators) || IS_ERR(opp_table->clk)) if ((!opp_table->regulators) || IS_ERR(opp_table->clk))
goto out_put; goto out_put;
@@ -980,11 +991,12 @@ out:
if (cur_rate < old_rate) if (cur_rate < old_rate)
rockchip_pvtpll_set_clk(info->dev, opp_table->clk, old_rate); rockchip_pvtpll_set_clk(info->dev, opp_table->clk, old_rate);
out_put: out_put:
if (info->clocks)
clk_bulk_disable_unprepare(info->nclocks, info->clocks);
dev_pm_opp_put_opp_table(opp_table); dev_pm_opp_put_opp_table(opp_table);
} }
EXPORT_SYMBOL(rockchip_pvtpll_calibrate_opp);
void rockchip_pvtpll_add_length(struct rockchip_opp_info *info) static void rockchip_pvtpll_add_length(struct rockchip_opp_info *info)
{ {
struct device_node *np; struct device_node *np;
struct opp_table *opp_table; struct opp_table *opp_table;
@@ -1018,13 +1030,13 @@ void rockchip_pvtpll_add_length(struct rockchip_opp_info *info)
mutex_lock(&opp_table->lock); mutex_lock(&opp_table->lock);
list_for_each_entry(opp, &opp_table->opp_list, node) { list_for_each_entry(opp, &opp_table->opp_list, node) {
if (opp->rate < min_rate * 1000 || opp->rate > max_rate * 1000) if (opp->rates[0] < min_rate * 1000 || opp->rates[0] > max_rate * 1000)
continue; continue;
ret = clk_set_rate(opp_table->clk, opp->rate | opp_flag); ret = clk_set_rate(opp_table->clk, opp->rates[0] | opp_flag);
if (ret) { if (ret) {
dev_err(info->dev, dev_err(info->dev,
"failed to change %lu len margin %d\n", "failed to change %lu len margin %d\n",
opp->rate, margin); opp->rates[0], margin);
break; break;
} }
} }
@@ -1034,10 +1046,9 @@ void rockchip_pvtpll_add_length(struct rockchip_opp_info *info)
dev_pm_opp_put_opp_table(opp_table); dev_pm_opp_put_opp_table(opp_table);
} }
EXPORT_SYMBOL(rockchip_pvtpll_add_length);
static int rockchip_get_pvtm_pvtpll(struct device *dev, struct device_node *np, static int rockchip_get_pvtm_pvtpll(struct device *dev, struct device_node *np,
char *reg_name) const char *reg_name)
{ {
struct regulator *reg; struct regulator *reg;
struct clk *clk; struct clk *clk;
@@ -1118,7 +1129,7 @@ out:
} }
static int rockchip_get_pvtm(struct device *dev, struct device_node *np, static int rockchip_get_pvtm(struct device *dev, struct device_node *np,
char *reg_name) const char *reg_name)
{ {
struct regulator *reg; struct regulator *reg;
struct clk *clk; struct clk *clk;
@@ -1164,9 +1175,9 @@ static int rockchip_get_pvtm(struct device *dev, struct device_node *np,
return pvtm; return pvtm;
} }
void rockchip_of_get_pvtm_sel(struct device *dev, struct device_node *np, static void rockchip_of_get_pvtm_sel(struct device *dev, struct device_node *np,
char *reg_name, int process, const char *reg_name, int process,
int *volt_sel, int *scale_sel) int *volt_sel, int *scale_sel)
{ {
struct property *prop = NULL; struct property *prop = NULL;
char name[NAME_MAX]; char name[NAME_MAX];
@@ -1206,10 +1217,9 @@ next:
if (!ret) if (!ret)
dev_info(dev, "pvtm-scale=%d\n", *scale_sel); dev_info(dev, "pvtm-scale=%d\n", *scale_sel);
} }
EXPORT_SYMBOL(rockchip_of_get_pvtm_sel);
void rockchip_of_get_bin_sel(struct device *dev, struct device_node *np, static void rockchip_of_get_bin_sel(struct device *dev, struct device_node *np,
int bin, int *scale_sel) int bin, int *scale_sel)
{ {
int ret = 0; int ret = 0;
@@ -1221,10 +1231,9 @@ void rockchip_of_get_bin_sel(struct device *dev, struct device_node *np,
if (!ret) if (!ret)
dev_info(dev, "bin-scale=%d\n", *scale_sel); dev_info(dev, "bin-scale=%d\n", *scale_sel);
} }
EXPORT_SYMBOL(rockchip_of_get_bin_sel);
void rockchip_of_get_bin_volt_sel(struct device *dev, struct device_node *np, static void rockchip_of_get_bin_volt_sel(struct device *dev, struct device_node *np,
int bin, int *bin_volt_sel) int bin, int *bin_volt_sel)
{ {
int ret = 0; int ret = 0;
@@ -1236,7 +1245,6 @@ void rockchip_of_get_bin_volt_sel(struct device *dev, struct device_node *np,
if (!ret) if (!ret)
dev_info(dev, "bin-volt-sel=%d\n", *bin_volt_sel); dev_info(dev, "bin-volt-sel=%d\n", *bin_volt_sel);
} }
EXPORT_SYMBOL(rockchip_of_get_bin_volt_sel);
void rockchip_get_opp_data(const struct of_device_id *matches, void rockchip_get_opp_data(const struct of_device_id *matches,
struct rockchip_opp_info *info) struct rockchip_opp_info *info)
@@ -1252,8 +1260,8 @@ void rockchip_get_opp_data(const struct of_device_id *matches,
} }
EXPORT_SYMBOL(rockchip_get_opp_data); EXPORT_SYMBOL(rockchip_get_opp_data);
int rockchip_get_volt_rm_table(struct device *dev, struct device_node *np, static int rockchip_get_volt_rm_table(struct device *dev, struct device_node *np,
char *porp_name, struct volt_rm_table **table) char *porp_name, struct volt_rm_table **table)
{ {
struct volt_rm_table *rm_table; struct volt_rm_table *rm_table;
const struct property *prop; const struct property *prop;
@@ -1292,11 +1300,10 @@ int rockchip_get_volt_rm_table(struct device *dev, struct device_node *np,
return 0; return 0;
} }
EXPORT_SYMBOL(rockchip_get_volt_rm_table);
void rockchip_get_scale_volt_sel(struct device *dev, char *lkg_name, static void rockchip_get_scale_volt_sel(struct device *dev, char *lkg_name,
char *reg_name, int bin, int process, const char *reg_name,
int *scale, int *volt_sel) struct rockchip_opp_info *info)
{ {
struct device_node *np; struct device_node *np;
int lkg_scale = 0, pvtm_scale = 0, bin_scale = 0; int lkg_scale = 0, pvtm_scale = 0, bin_scale = 0;
@@ -1309,45 +1316,188 @@ void rockchip_get_scale_volt_sel(struct device *dev, char *lkg_name,
return; return;
} }
rockchip_of_get_lkg_sel(dev, np, lkg_name, process, rockchip_of_get_lkg_sel(dev, np, lkg_name, info->process,
&lkg_volt_sel, &lkg_scale); &lkg_volt_sel, &lkg_scale);
rockchip_of_get_pvtm_sel(dev, np, reg_name, process, rockchip_of_get_pvtm_sel(dev, np, reg_name, info->process,
&pvtm_volt_sel, &pvtm_scale); &pvtm_volt_sel, &pvtm_scale);
rockchip_of_get_bin_sel(dev, np, bin, &bin_scale); rockchip_of_get_bin_sel(dev, np, info->bin, &bin_scale);
rockchip_of_get_bin_volt_sel(dev, np, bin, &bin_volt_sel); rockchip_of_get_bin_volt_sel(dev, np, info->bin, &bin_volt_sel);
if (scale) info->scale = max3(lkg_scale, pvtm_scale, bin_scale);
*scale = max3(lkg_scale, pvtm_scale, bin_scale); if (bin_volt_sel >= 0)
if (volt_sel) { info->volt_sel = bin_volt_sel;
if (bin_volt_sel >= 0) else
*volt_sel = bin_volt_sel; info->volt_sel = max(lkg_volt_sel, pvtm_volt_sel);
else
*volt_sel = max(lkg_volt_sel, pvtm_volt_sel);
}
of_node_put(np); of_node_put(np);
} }
EXPORT_SYMBOL(rockchip_get_scale_volt_sel);
struct opp_table *rockchip_set_opp_prop_name(struct device *dev, int process, static int rockchip_opp_set_config(struct device *dev, struct rockchip_opp_info *info,
int volt_sel) const char *clk_name, const char *reg_name)
{ {
char name[MAX_PROP_NAME_LEN]; char name[MAX_PROP_NAME_LEN];
struct dev_pm_opp_config config = {0};
struct clk *clk = NULL;
const char *reg_names[] = {NULL, NULL, NULL};
const char *clk_names[] = {NULL, NULL, NULL};
if (process >= 0) { if (clk_name) {
if (volt_sel >= 0) clk = clk_get(dev, clk_name);
snprintf(name, MAX_PROP_NAME_LEN, "P%d-L%d", if (!IS_ERR_OR_NULL(clk)) {
process, volt_sel); if (strstr(__clk_get_name(clk), "scmi"))
else info->is_scmi_clk = true;
snprintf(name, MAX_PROP_NAME_LEN, "P%d", process); clk_names[0] = clk_name;
} else if (volt_sel >= 0) { config.clk_names = clk_names;
snprintf(name, MAX_PROP_NAME_LEN, "L%d", volt_sel); clk_put(clk);
} else { }
return NULL; if (info->data && info->data->config_clks)
config.config_clks = info->data->config_clks;
} }
return dev_pm_opp_set_prop_name(dev, name); if (info->process >= 0) {
if (info->volt_sel >= 0)
snprintf(name, MAX_PROP_NAME_LEN, "P%d-L%d",
info->process, info->volt_sel);
else
snprintf(name, MAX_PROP_NAME_LEN, "P%d", info->process);
config.prop_name = name;
} else if (info->volt_sel >= 0) {
snprintf(name, MAX_PROP_NAME_LEN, "L%d", info->volt_sel);
config.prop_name = name;
}
if (info->data && info->data->config_regulators)
config.config_regulators = info->data->config_regulators;
if (info->supported_hw[0] || info->supported_hw[1]) {
config.supported_hw = kmemdup(info->supported_hw, 2 * sizeof(u32),
GFP_KERNEL);
config.supported_hw_count = 2;
}
if (reg_name) {
reg_names[0] = reg_name;
if (of_find_property(dev->of_node, "mem-supply", NULL))
reg_names[1] = "mem";
config.regulator_names = reg_names;
}
info->opp_token = dev_pm_opp_set_config(dev, &config);
if (info->opp_token < 0) {
dev_err(dev, "failed to set opp config\n");
return info->opp_token;
}
return 0;
} }
EXPORT_SYMBOL(rockchip_set_opp_prop_name);
void rockchip_opp_dvfs_lock(struct rockchip_opp_info *info)
{
if (info)
mutex_lock(&info->dvfs_mutex);
}
EXPORT_SYMBOL(rockchip_opp_dvfs_lock);
void rockchip_opp_dvfs_unlock(struct rockchip_opp_info *info)
{
if (info)
mutex_unlock(&info->dvfs_mutex);
}
EXPORT_SYMBOL(rockchip_opp_dvfs_unlock);
int rockchip_init_opp_info(struct device *dev, struct rockchip_opp_info *info,
char *clk_name, char *reg_name)
{
struct device_node *np;
int ret = 0, nclocks = 0, i;
u32 freq;
/* Get OPP descriptor node */
np = of_parse_phandle(dev->of_node, "operating-points-v2", 0);
if (!np) {
dev_dbg(dev, "Failed to find operating-points-v2\n");
return -ENOENT;
}
if (!info)
return -ENOMEM;
info->dev = dev;
info->bin = -EINVAL;
info->process = -EINVAL;
info->volt_sel = -EINVAL;
info->is_runtime_active = true;
mutex_init(&info->dvfs_mutex);
of_property_read_u32(np, "rockchip,init-freq", &info->init_freq);
info->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
if (IS_ERR(info->grf))
info->grf = NULL;
info->dsu_grf = syscon_regmap_lookup_by_phandle(np, "rockchip,dsu-grf");
if (IS_ERR(info->dsu_grf))
info->dsu_grf = NULL;
nclocks = of_clk_get_parent_count(np);
if (nclocks > 0) {
info->clocks = devm_kcalloc(dev, nclocks, sizeof(*info->clocks),
GFP_KERNEL);
if (!info->clocks) {
ret = -ENOMEM;
goto out;
}
for (i = 0; i < nclocks; i++) {
info->clocks[i].clk = of_clk_get(np, i);
if (IS_ERR(info->clocks[i].clk)) {
ret = PTR_ERR(info->clocks[i].clk);
dev_err(dev, "%s: failed to get clk %d\n",
np->name, i);
goto out;
}
}
info->nclocks = nclocks;
ret = clk_bulk_prepare_enable(info->nclocks, info->clocks);
if (ret) {
dev_err(dev, "failed to enable opp clks\n");
goto out;
}
}
if (info->data && info->data->set_read_margin) {
info->current_rm = UINT_MAX;
info->target_rm = UINT_MAX;
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;
rockchip_init_read_margin(dev, info, reg_name);
}
if (info->data && info->data->get_soc_info)
info->data->get_soc_info(dev, np, &info->bin, &info->process);
rockchip_get_scale_volt_sel(dev, "leakage", reg_name, info);
if (info && info->data && info->data->set_soc_info)
info->data->set_soc_info(dev, np, info);
ret = rockchip_opp_set_config(dev, info, clk_name, reg_name);
if (info->clocks)
clk_bulk_disable_unprepare(info->nclocks, info->clocks);
out:
of_node_put(np);
return ret;
}
EXPORT_SYMBOL(rockchip_init_opp_info);
void rockchip_uninit_opp_info(struct device *dev, struct rockchip_opp_info *info)
{
dev_pm_opp_clear_config(info->opp_token);
}
EXPORT_SYMBOL(rockchip_uninit_opp_info);
static int rockchip_adjust_opp_by_irdrop(struct device *dev, static int rockchip_adjust_opp_by_irdrop(struct device *dev,
struct device_node *np, struct device_node *np,
@@ -1380,7 +1530,7 @@ static int rockchip_adjust_opp_by_irdrop(struct device *dev,
if (!irdrop_table) { if (!irdrop_table) {
delta_irdrop = 0; delta_irdrop = 0;
} else { } else {
opp_rate = opp->rate / 1000000; opp_rate = opp->rates[0] / 1000000;
board_irdrop = -EINVAL; board_irdrop = -EINVAL;
for (i = 0; irdrop_table[i].sel != SEL_TABLE_END; i++) { for (i = 0; irdrop_table[i].sel != SEL_TABLE_END; i++) {
if (opp_rate >= irdrop_table[i].min) if (opp_rate >= irdrop_table[i].min)
@@ -1400,7 +1550,7 @@ static int rockchip_adjust_opp_by_irdrop(struct device *dev,
else else
opp->supplies[0].u_volt_max = max_volt; opp->supplies[0].u_volt_max = max_volt;
if (!reach_max_volt) if (!reach_max_volt)
tmp_safe_rate = opp->rate; tmp_safe_rate = opp->rates[0];
if (opp->supplies[0].u_volt == max_volt) if (opp->supplies[0].u_volt == max_volt)
reach_max_volt = true; reach_max_volt = true;
} else { } else {
@@ -1409,8 +1559,8 @@ static int rockchip_adjust_opp_by_irdrop(struct device *dev,
opp->supplies[0].u_volt_max = max_volt; opp->supplies[0].u_volt_max = max_volt;
} }
if (max_rate) if (max_rate)
*max_rate = opp->rate; *max_rate = opp->rates[0];
if (safe_rate && tmp_safe_rate != opp->rate) if (safe_rate && tmp_safe_rate != opp->rates[0])
*safe_rate = tmp_safe_rate; *safe_rate = tmp_safe_rate;
} }
mutex_unlock(&opp_table->lock); mutex_unlock(&opp_table->lock);
@@ -1479,9 +1629,9 @@ static void rockchip_adjust_opp_by_otp(struct device *dev,
list_for_each_entry(opp, &opp_table->opp_list, node) { list_for_each_entry(opp, &opp_table->opp_list, node) {
if (!opp->available) if (!opp->available)
continue; continue;
if (opp->rate < opp_info.min_freq * 1000000) if (opp->rates[0] < opp_info.min_freq * 1000000)
continue; continue;
if (opp->rate > opp_info.max_freq * 1000000) if (opp->rates[0] > opp_info.max_freq * 1000000)
continue; continue;
opp->supplies->u_volt += opp_info.volt * 1000; opp->supplies->u_volt += opp_info.volt * 1000;
@@ -1493,8 +1643,8 @@ static void rockchip_adjust_opp_by_otp(struct device *dev,
dev_pm_opp_put_opp_table(opp_table); dev_pm_opp_put_opp_table(opp_table);
} }
static int rockchip_adjust_opp_table(struct device *dev, static int rockchip_adjust_opp_by_scale(struct device *dev,
unsigned long scale_rate) unsigned long scale_rate)
{ {
struct dev_pm_opp *opp; struct dev_pm_opp *opp;
unsigned long rate; unsigned long rate;
@@ -1513,15 +1663,15 @@ static int rockchip_adjust_opp_table(struct device *dev,
ret = PTR_ERR(opp); ret = PTR_ERR(opp);
goto out; goto out;
} }
if (opp->rate > scale_rate) if (opp->rates[0] > scale_rate)
dev_pm_opp_disable(dev, opp->rate); dev_pm_opp_disable(dev, opp->rates[0]);
dev_pm_opp_put(opp); dev_pm_opp_put(opp);
} }
out: out:
return ret; return ret;
} }
int rockchip_adjust_power_scale(struct device *dev, int scale) static int rockchip_adjust_power_scale(struct device *dev, struct rockchip_opp_info *info)
{ {
struct device_node *np; struct device_node *np;
struct clk *clk; struct clk *clk;
@@ -1549,7 +1699,7 @@ int rockchip_adjust_power_scale(struct device *dev, int scale)
if (!safe_rate) if (!safe_rate)
goto out_np; goto out_np;
dev_dbg(dev, "Failed to get clk, safe_rate=%lu\n", safe_rate); dev_dbg(dev, "Failed to get clk, safe_rate=%lu\n", safe_rate);
ret = rockchip_adjust_opp_table(dev, safe_rate); ret = rockchip_adjust_opp_by_scale(dev, safe_rate);
if (ret) if (ret)
dev_err(dev, "Failed to adjust opp table\n"); dev_err(dev, "Failed to adjust opp table\n");
goto out_np; goto out_np;
@@ -1559,11 +1709,11 @@ int rockchip_adjust_power_scale(struct device *dev, int scale)
irdrop_scale = rockchip_pll_clk_rate_to_scale(clk, safe_rate); irdrop_scale = rockchip_pll_clk_rate_to_scale(clk, safe_rate);
if (max_rate) if (max_rate)
opp_scale = rockchip_pll_clk_rate_to_scale(clk, max_rate); opp_scale = rockchip_pll_clk_rate_to_scale(clk, max_rate);
target_scale = max(irdrop_scale, scale); target_scale = max(irdrop_scale, info->scale);
if (target_scale <= 0) if (target_scale <= 0)
goto out_clk; goto out_clk;
dev_dbg(dev, "target_scale=%d, irdrop_scale=%d, scale=%d\n", dev_dbg(dev, "target_scale=%d, irdrop_scale=%d, scale=%d\n",
target_scale, irdrop_scale, scale); target_scale, irdrop_scale, info->scale);
if (avs == AVS_SCALING_RATE) { if (avs == AVS_SCALING_RATE) {
ret = rockchip_pll_clk_adaptive_scaling(clk, target_scale); ret = rockchip_pll_clk_adaptive_scaling(clk, target_scale);
@@ -1580,7 +1730,7 @@ int rockchip_adjust_power_scale(struct device *dev, int scale)
goto out_clk; goto out_clk;
} }
dev_dbg(dev, "scale_rate=%lu\n", scale_rate); dev_dbg(dev, "scale_rate=%lu\n", scale_rate);
ret = rockchip_adjust_opp_table(dev, scale_rate); ret = rockchip_adjust_opp_by_scale(dev, scale_rate);
if (ret) if (ret)
dev_err(dev, "Failed to adjust opp table\n"); dev_err(dev, "Failed to adjust opp table\n");
} else if (avs == AVS_DELETE_OPP) { } else if (avs == AVS_DELETE_OPP) {
@@ -1595,7 +1745,7 @@ int rockchip_adjust_power_scale(struct device *dev, int scale)
goto out_clk; goto out_clk;
} }
dev_dbg(dev, "scale_rate=%lu\n", scale_rate); dev_dbg(dev, "scale_rate=%lu\n", scale_rate);
ret = rockchip_adjust_opp_table(dev, scale_rate); ret = rockchip_adjust_opp_by_scale(dev, scale_rate);
if (ret) if (ret)
dev_err(dev, "Failed to adjust opp table\n"); dev_err(dev, "Failed to adjust opp table\n");
} }
@@ -1607,7 +1757,37 @@ out_np:
return ret; return ret;
} }
EXPORT_SYMBOL(rockchip_adjust_power_scale);
static int rockchip_opp_parse_supplies(struct device *dev,
struct rockchip_opp_info *info)
{
struct opp_table *opp_table;
opp_table = dev_pm_opp_get_opp_table(dev);
if (IS_ERR(opp_table))
return PTR_ERR(opp_table);
if (opp_table->clk)
info->clk = opp_table->clk;
if (opp_table->regulators)
info->regulators = opp_table->regulators;
info->regulator_count = opp_table->regulator_count;
dev_pm_opp_put_opp_table(opp_table);
return 0;
}
int rockchip_adjust_opp_table(struct device *dev, struct rockchip_opp_info *info)
{
rockchip_opp_parse_supplies(dev, info);
rockchip_adjust_power_scale(dev, info);
rockchip_pvtpll_calibrate_opp(info);
rockchip_pvtpll_add_length(info);
return 0;
}
EXPORT_SYMBOL(rockchip_adjust_opp_table);
int rockchip_get_read_margin(struct device *dev, int rockchip_get_read_margin(struct device *dev,
struct rockchip_opp_info *opp_info, struct rockchip_opp_info *opp_info,
@@ -1647,9 +1827,9 @@ int rockchip_set_read_margin(struct device *dev,
} }
EXPORT_SYMBOL(rockchip_set_read_margin); EXPORT_SYMBOL(rockchip_set_read_margin);
int rockchip_init_read_margin(struct device *dev, static int rockchip_init_read_margin(struct device *dev,
struct rockchip_opp_info *opp_info, struct rockchip_opp_info *opp_info,
char *reg_name) const char *reg_name)
{ {
struct clk *clk; struct clk *clk;
struct regulator *reg; struct regulator *reg;
@@ -1701,7 +1881,6 @@ out:
return ret; return ret;
} }
EXPORT_SYMBOL(rockchip_init_read_margin);
int rockchip_set_intermediate_rate(struct device *dev, int rockchip_set_intermediate_rate(struct device *dev,
struct rockchip_opp_info *opp_info, struct rockchip_opp_info *opp_info,
@@ -1749,91 +1928,306 @@ int rockchip_set_intermediate_rate(struct device *dev,
} }
EXPORT_SYMBOL(rockchip_set_intermediate_rate); EXPORT_SYMBOL(rockchip_set_intermediate_rate);
int rockchip_init_opp_table(struct device *dev, struct rockchip_opp_info *info, static int rockchip_opp_set_volt(struct device *dev, struct regulator *reg,
char *lkg_name, char *reg_name) struct dev_pm_opp_supply *supply, char *reg_name)
{ {
struct device_node *np; int ret = 0;
int bin = -EINVAL, process = -EINVAL;
int scale = 0, volt_sel = -EINVAL;
int ret = 0, num_clks = 0, i;
u32 freq;
/* Get OPP descriptor node */ ret = regulator_set_voltage_triplet(reg, supply->u_volt_min,
np = of_parse_phandle(dev->of_node, "operating-points-v2", 0); supply->u_volt, supply->u_volt_max);
if (!np) { if (ret)
dev_dbg(dev, "Failed to find operating-points-v2\n"); dev_err(dev, "%s: failed to set voltage (%lu %lu %lu uV): %d\n",
return -ENOENT; reg_name, supply->u_volt_min, supply->u_volt,
} supply->u_volt_max, ret);
if (!info)
goto next;
info->dev = dev;
num_clks = of_clk_get_parent_count(np);
if (num_clks > 0) {
info->clks = devm_kcalloc(dev, num_clks, sizeof(*info->clks),
GFP_KERNEL);
if (!info->clks) {
ret = -ENOMEM;
goto out;
}
for (i = 0; i < num_clks; i++) {
info->clks[i].clk = of_clk_get(np, i);
if (IS_ERR(info->clks[i].clk)) {
ret = PTR_ERR(info->clks[i].clk);
dev_err(dev, "%s: failed to get clk %d\n",
np->name, i);
goto out;
}
}
info->num_clks = num_clks;
ret = clk_bulk_prepare_enable(info->num_clks, info->clks);
if (ret) {
dev_err(dev, "failed to enable opp clks\n");
goto out;
}
}
if (info->data && info->data->set_read_margin) {
info->current_rm = UINT_MAX;
info->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
if (IS_ERR(info->grf))
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;
rockchip_init_read_margin(dev, info, reg_name);
}
if (info->data && info->data->get_soc_info)
info->data->get_soc_info(dev, np, &bin, &process);
next:
rockchip_get_scale_volt_sel(dev, lkg_name, reg_name, bin, process,
&scale, &volt_sel);
if (info && info->data && info->data->set_soc_info)
info->data->set_soc_info(dev, np, bin, process, volt_sel);
rockchip_set_opp_prop_name(dev, process, volt_sel);
ret = dev_pm_opp_of_add_table(dev);
if (ret) {
dev_err(dev, "Invalid operating-points in device tree.\n");
goto dis_opp_clk;
}
rockchip_adjust_power_scale(dev, scale);
rockchip_pvtpll_calibrate_opp(info);
rockchip_pvtpll_add_length(info);
dis_opp_clk:
if (info && info->clks)
clk_bulk_disable_unprepare(info->num_clks, info->clks);
out:
of_node_put(np);
return ret; return ret;
} }
int rockchip_opp_config_regulators(struct device *dev,
struct dev_pm_opp *old_opp,
struct dev_pm_opp *new_opp,
struct regulator **regulators,
unsigned int count,
struct rockchip_opp_info *info)
{
struct regulator *vdd_reg = regulators[0];
struct regulator *mem_reg;
struct dev_pm_opp_supply old_supplies[2] = { 0 };
struct dev_pm_opp_supply new_supplies[2] = { 0 };
unsigned long old_freq, freq;
u32 target_rm = UINT_MAX;
int ret = 0;
if (count > 1)
mem_reg = regulators[1];
ret = dev_pm_opp_get_supplies(new_opp, new_supplies);
if (ret)
return ret;
ret = dev_pm_opp_get_supplies(old_opp, old_supplies);
if (ret)
return ret;
ret = clk_bulk_prepare_enable(info->nclocks, info->clocks);
if (ret) {
dev_err(dev, "failed to enable opp clks\n");
return ret;
}
rockchip_get_read_margin(dev, info, new_supplies[0].u_volt, &target_rm);
old_freq = dev_pm_opp_get_freq(old_opp);
freq = dev_pm_opp_get_freq(new_opp);
if (count > 1)
dev_dbg(dev, "%lu %lu -> %lu %lu (uV)\n",
old_supplies[0].u_volt, old_supplies[1].u_volt,
new_supplies[0].u_volt, new_supplies[1].u_volt);
else
dev_dbg(dev, "%lu -> %lu (uV)\n", old_supplies[0].u_volt,
new_supplies[0].u_volt);
if (freq > old_freq) {
if (count > 1) {
ret = rockchip_opp_set_volt(dev, mem_reg, &new_supplies[1], "mem");
if (ret)
goto restore_voltage;
}
ret = rockchip_opp_set_volt(dev, vdd_reg, &new_supplies[0], "vdd");
if (ret)
goto restore_voltage;
rockchip_set_read_margin(dev, info, target_rm, info->is_runtime_active);
} else {
rockchip_set_read_margin(dev, info, target_rm, info->is_runtime_active);
ret = rockchip_opp_set_volt(dev, vdd_reg, &new_supplies[0], "vdd");
if (ret)
goto restore_voltage;
if (count > 1) {
ret = rockchip_opp_set_volt(dev, mem_reg, &new_supplies[1], "mem");
if (ret)
goto restore_voltage;
}
}
clk_bulk_disable_unprepare(info->nclocks, info->clocks);
return 0;
restore_voltage:
rockchip_get_read_margin(dev, info, old_supplies[0].u_volt, &target_rm);
rockchip_set_read_margin(dev, info, target_rm, info->is_runtime_active);
if (old_supplies[0].u_volt) {
if (count > 1 && old_supplies[1].u_volt) {
ret = rockchip_opp_set_volt(dev, mem_reg, &old_supplies[1], "mem");
if (ret)
goto dis_clks;
}
ret = rockchip_opp_set_volt(dev, vdd_reg, &old_supplies[0], "vdd");
if (ret)
goto dis_clks;
}
dis_clks:
clk_bulk_disable_unprepare(info->nclocks, info->clocks);
return ret;
}
EXPORT_SYMBOL(rockchip_opp_config_regulators);
int rockchip_opp_config_clks(struct device *dev, struct opp_table *opp_table,
struct dev_pm_opp *opp, void *data,
bool scaling_down, struct rockchip_opp_info *info)
{
unsigned long *target = data;
int ret;
if (!info->is_runtime_active)
return 0;
dev_dbg(dev, "%lu -> %lu (Hz)\n", opp_table->rate_clk_single, *target);
ret = clk_set_rate(opp_table->clk, *target);
if (ret)
dev_err(dev, "failed to set clock rate: %lu\n", *target);
else
opp_table->rate_clk_single = *target;
return ret;
}
EXPORT_SYMBOL(rockchip_opp_config_clks);
int rockchip_opp_check_rate_volt(struct device *dev, struct rockchip_opp_info *info)
{
struct regulator *vdd_reg = NULL;
struct regulator *mem_reg = NULL;
struct dev_pm_opp *opp;
unsigned long old_rate = 0, new_rate = 0;
unsigned long new_volt = 0, new_volt_mem = 0;
int old_volt = 0, old_volt_mem = 0;
u32 target_rm = UINT_MAX;
bool is_set_clk = true;
bool is_set_rm = false;
int ret = 0;
if (!info->regulators || !info->clk)
return 0;
vdd_reg = info->regulators[0];
old_rate = clk_get_rate(info->clk);
old_volt = regulator_get_voltage(vdd_reg);
if (info->regulator_count > 1) {
mem_reg = info->regulators[1];
old_volt_mem = regulator_get_voltage(mem_reg);
}
if (info->init_freq) {
new_rate = info->init_freq * 1000;
info->init_freq = 0;
} else {
new_rate = old_rate;
}
opp = dev_pm_opp_find_freq_ceil(dev, &new_rate);
if (IS_ERR(opp)) {
opp = dev_pm_opp_find_freq_floor(dev, &new_rate);
if (IS_ERR(opp))
return PTR_ERR(opp);
}
new_volt = opp->supplies[0].u_volt;
if (info->regulator_count > 1)
new_volt_mem = opp->supplies[1].u_volt;
dev_pm_opp_put(opp);
if (old_rate == new_rate && info->is_rate_volt_checked) {
if (info->regulator_count > 1) {
if (old_volt == new_volt &&
new_volt_mem == old_volt_mem)
return 0;
} else if (old_volt == new_volt) {
return 0;
}
}
if (!new_volt || (info->regulator_count > 1 && !new_volt_mem))
return 0;
ret = clk_bulk_prepare_enable(info->nclocks, info->clocks);
if (ret) {
dev_err(dev, "failed to enable opp clks\n");
return ret;
}
if (info->is_scmi_clk && !info->is_runtime_active)
is_set_clk = false;
if (info->data && info->data->set_read_margin && info->is_runtime_active)
is_set_rm = true;
rockchip_get_read_margin(dev, info, new_volt, &target_rm);
dev_dbg(dev, "%s: %lu Hz --> %lu Hz, %lu %lu uV\n", __func__,
old_rate, new_rate, new_volt, new_volt_mem);
if (new_rate >= old_rate) {
if (info->regulator_count > 1) {
ret = regulator_set_voltage(mem_reg, new_volt_mem,
INT_MAX);
if (ret) {
dev_err(dev, "%s: failed to set volt: %lu\n",
__func__, new_volt_mem);
goto disable_clk;
}
}
ret = regulator_set_voltage(vdd_reg, new_volt, INT_MAX);
if (ret) {
dev_err(dev, "%s: failed to set volt: %lu\n",
__func__, new_volt);
goto restore_voltage;
}
rockchip_set_read_margin(dev, info, target_rm, is_set_rm);
if (new_rate == old_rate)
goto out;
}
if (is_set_clk) {
ret = clk_set_rate(info->clk, new_rate);
if (ret) {
dev_err(dev, "%s: failed to set clock rate: %lu\n",
__func__, new_rate);
goto restore_rm;
}
}
if (new_rate < old_rate) {
rockchip_set_read_margin(dev, info, target_rm, is_set_rm);
ret = regulator_set_voltage(vdd_reg, new_volt,
INT_MAX);
if (ret) {
dev_err(dev, "%s: failed to set volt: %lu\n",
__func__, new_volt);
goto restore_freq;
}
if (info->regulator_count > 1) {
ret = regulator_set_voltage(mem_reg, new_volt_mem,
INT_MAX);
if (ret) {
dev_err(dev, "%s: failed to set volt: %lu\n",
__func__, new_volt_mem);
goto restore_freq;
}
}
}
out:
clk_bulk_disable_unprepare(info->nclocks, info->clocks);
return 0;
restore_freq:
if (is_set_clk && clk_set_rate(info->clk, old_rate))
dev_err(dev, "%s: failed to restore old-freq (%lu Hz)\n",
__func__, old_rate);
restore_rm:
rockchip_get_read_margin(dev, info, old_volt, &target_rm);
rockchip_set_read_margin(dev, info, target_rm, is_set_rm);
restore_voltage:
if (info->regulator_count > 1)
regulator_set_voltage(mem_reg, old_volt_mem, INT_MAX);
regulator_set_voltage(vdd_reg, old_volt, INT_MAX);
disable_clk:
clk_bulk_disable_unprepare(info->nclocks, info->clocks);
return ret;
}
EXPORT_SYMBOL(rockchip_opp_check_rate_volt);
int rockchip_init_opp_table(struct device *dev, struct rockchip_opp_info *info,
char *clk_name, char *reg_name)
{
int ret = 0;
ret = rockchip_init_opp_info(dev, info, clk_name, reg_name);
if (ret) {
dev_err(dev, "failed to init opp info\n");
return ret;
}
ret = dev_pm_opp_of_add_table(dev);
if (ret) {
dev_err(dev, "failed to add opp table\n");
rockchip_uninit_opp_info(dev, info);
return ret;
}
rockchip_adjust_opp_table(dev, info);
return 0;
}
EXPORT_SYMBOL(rockchip_init_opp_table); EXPORT_SYMBOL(rockchip_init_opp_table);
void rockchip_uninit_opp_table(struct device *dev, struct rockchip_opp_info *info)
{
rockchip_uninit_opp_info(dev, info);
dev_pm_opp_of_remove_table(dev);
}
EXPORT_SYMBOL(rockchip_uninit_opp_table);
MODULE_DESCRIPTION("ROCKCHIP OPP Select"); MODULE_DESCRIPTION("ROCKCHIP OPP Select");
MODULE_AUTHOR("Finley Xiao <finley.xiao@rock-chips.com>, Liang Chen <cl@rock-chips.com>"); MODULE_AUTHOR("Finley Xiao <finley.xiao@rock-chips.com>, Liang Chen <cl@rock-chips.com>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");

View File

@@ -6,6 +6,8 @@
#ifndef __SOC_ROCKCHIP_OPP_SELECT_H #ifndef __SOC_ROCKCHIP_OPP_SELECT_H
#define __SOC_ROCKCHIP_OPP_SELECT_H #define __SOC_ROCKCHIP_OPP_SELECT_H
#include <linux/pm_opp.h>
#define VOLT_RM_TABLE_END ~1 #define VOLT_RM_TABLE_END ~1
/* /*
@@ -40,12 +42,15 @@ struct volt_rm_table {
}; };
struct rockchip_opp_data { struct rockchip_opp_data {
config_clks_t config_clks;
config_regulators_t config_regulators;
int (*get_soc_info)(struct device *dev, struct device_node *np, int (*get_soc_info)(struct device *dev, struct device_node *np,
int *bin, int *process); int *bin, int *process);
int (*set_soc_info)(struct device *dev, struct device_node *np, int (*set_soc_info)(struct device *dev, struct device_node *np,
int bin, int process, int volt_sel); struct rockchip_opp_info *info);
int (*set_read_margin)(struct device *dev, int (*set_read_margin)(struct device *dev,
struct rockchip_opp_info *opp_info, struct rockchip_opp_info *info,
u32 rm); u32 rm);
}; };
@@ -59,72 +64,112 @@ struct pvtpll_opp_table {
unsigned long u_volt_mem_max; unsigned long u_volt_mem_max;
}; };
/**
* struct rockchip_opp_info - Rockchip opp info structure
* @dev: The device.
* @dvfs_mutex: Mutex to protect changing volage and scmi clock rate.
* @data: Device-specific opp data.
* @opp_table: Temporary opp table only used when enable pvtpll calibration.
* @pvtpll_avg_offset: Register offset of pvtm value.
* @pvtpll_min_rate: Minimum frequency which needs calibration.
* @pvtpll_volt_step: Voltage step of pvtpll calibration.
* @volt_rm_tbl: Pointer to voltage to memory read margin conversion table.
* @grf: General Register Files regmap.
* @dsu_grf: DSU General Register Files regmap.
* @clocks: Pvtpll clocks.
* @nclocks: Number of pvtpll clock.
* @intermediate_threshold_freq: The frequency threshold of intermediate rate.
* @low_rm: The read margin threshold of intermediate rate.
* @current_rm: Current memory read margin.
* @target_rm: Target memory read margin.
* @is_runtime_active: Marks if device's pd is power on.
* @opp_token: Integer replacement for opp_table.
* @scale: Frequency scale.
* @bin: Soc version.
* @process: Process version.
* @volt_sel: Speed grade.
* @supported_hw: Array of version number to support.
* @clk: Device's clock handle.
* @is_scmi_clk: Marks if device's clock is scmi clock.
* @regulators: Supply regulators.
* @regulator_count: Number of power supply regulators.
* @init_freq: Set the initial frequency when init opp table.
* @is_rate_volt_checked: Marks if device has checked initial rate and voltage.
*/
struct rockchip_opp_info { struct rockchip_opp_info {
struct device *dev; struct device *dev;
struct pvtpll_opp_table *opp_table; struct mutex dvfs_mutex;
const struct rockchip_opp_data *data; const struct rockchip_opp_data *data;
struct volt_rm_table *volt_rm_tbl; struct pvtpll_opp_table *opp_table;
struct regmap *grf;
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;
unsigned int pvtpll_avg_offset; unsigned int pvtpll_avg_offset;
unsigned int pvtpll_min_rate; unsigned int pvtpll_min_rate;
unsigned int pvtpll_volt_step; unsigned int pvtpll_volt_step;
int num_clks;
/* The read margin for low voltage */ struct volt_rm_table *volt_rm_tbl;
struct regmap *grf;
struct regmap *dsu_grf;
struct clk_bulk_data *clocks;
int nclocks;
unsigned long intermediate_threshold_freq;
u32 low_rm; u32 low_rm;
u32 current_rm; u32 current_rm;
u32 target_rm; u32 target_rm;
bool is_runtime_active;
int opp_token;
int scale;
int bin;
int process;
int volt_sel;
u32 supported_hw[2];
struct clk *clk;
bool is_scmi_clk;
struct regulator **regulators;
int regulator_count;
unsigned int init_freq;
bool is_rate_volt_checked;
}; };
#if IS_ENABLED(CONFIG_ROCKCHIP_OPP) #if IS_ENABLED(CONFIG_ROCKCHIP_OPP)
int rockchip_of_get_leakage(struct device *dev, char *lkg_name, int *leakage); int rockchip_of_get_leakage(struct device *dev, char *lkg_name, int *leakage);
void rockchip_of_get_lkg_sel(struct device *dev, struct device_node *np,
char *lkg_name, int process,
int *volt_sel, int *scale_sel);
void rockchip_pvtpll_calibrate_opp(struct rockchip_opp_info *info);
void rockchip_pvtpll_add_length(struct rockchip_opp_info *info);
void rockchip_of_get_pvtm_sel(struct device *dev, struct device_node *np,
char *reg_name, int process,
int *volt_sel, int *scale_sel);
void rockchip_of_get_bin_sel(struct device *dev, struct device_node *np,
int bin, int *scale_sel);
void rockchip_of_get_bin_volt_sel(struct device *dev, struct device_node *np,
int bin, int *bin_volt_sel);
int rockchip_nvmem_cell_read_u8(struct device_node *np, const char *cell_id, int rockchip_nvmem_cell_read_u8(struct device_node *np, const char *cell_id,
u8 *val); u8 *val);
int rockchip_nvmem_cell_read_u16(struct device_node *np, const char *cell_id, int rockchip_nvmem_cell_read_u16(struct device_node *np, const char *cell_id,
u16 *val); u16 *val);
int rockchip_get_volt_rm_table(struct device *dev, struct device_node *np,
char *porp_name, struct volt_rm_table **table);
void rockchip_get_opp_data(const struct of_device_id *matches, void rockchip_get_opp_data(const struct of_device_id *matches,
struct rockchip_opp_info *info); struct rockchip_opp_info *info);
void rockchip_get_scale_volt_sel(struct device *dev, char *lkg_name, void rockchip_opp_dvfs_lock(struct rockchip_opp_info *info);
char *reg_name, int bin, int process, void rockchip_opp_dvfs_unlock(struct rockchip_opp_info *info);
int *scale, int *volt_sel); int rockchip_init_opp_info(struct device *dev, struct rockchip_opp_info *info,
struct opp_table *rockchip_set_opp_prop_name(struct device *dev, int process, char *clk_name, char *reg_name);
int volt_sel); void rockchip_uninit_opp_info(struct device *dev, struct rockchip_opp_info *info);
int rockchip_adjust_power_scale(struct device *dev, int scale); int rockchip_adjust_opp_table(struct device *dev, struct rockchip_opp_info *info);
int rockchip_get_read_margin(struct device *dev, int rockchip_get_read_margin(struct device *dev,
struct rockchip_opp_info *opp_info, struct rockchip_opp_info *info,
unsigned long volt, u32 *target_rm); unsigned long volt, u32 *target_rm);
int rockchip_set_read_margin(struct device *dev, int rockchip_set_read_margin(struct device *dev,
struct rockchip_opp_info *opp_info, u32 rm, struct rockchip_opp_info *info, u32 rm,
bool is_set_rm); bool is_set_rm);
int rockchip_init_read_margin(struct device *dev,
struct rockchip_opp_info *opp_info,
char *reg_name);
int rockchip_set_intermediate_rate(struct device *dev, int rockchip_set_intermediate_rate(struct device *dev,
struct rockchip_opp_info *opp_info, struct rockchip_opp_info *info,
struct clk *clk, unsigned long old_freq, struct clk *clk, unsigned long old_freq,
unsigned long new_freq, bool is_scaling_up, unsigned long new_freq, bool is_scaling_up,
bool is_set_clk); bool is_set_clk);
int rockchip_init_opp_table(struct device *dev, int rockchip_opp_config_regulators(struct device *dev,
struct rockchip_opp_info *info, struct dev_pm_opp *old_opp,
char *lkg_name, char *reg_name); struct dev_pm_opp *new_opp,
struct regulator **regulators,
unsigned int count,
struct rockchip_opp_info *info);
int rockchip_opp_config_clks(struct device *dev, struct opp_table *opp_table,
struct dev_pm_opp *opp, void *data,
bool scaling_down, struct rockchip_opp_info *info);
int rockchip_opp_check_rate_volt(struct device *dev, struct rockchip_opp_info *info);
int rockchip_init_opp_table(struct device *dev, struct rockchip_opp_info *info,
char *clk_name, char *reg_name);
void rockchip_uninit_opp_table(struct device *dev,
struct rockchip_opp_info *info);
#else #else
static inline int rockchip_of_get_leakage(struct device *dev, char *lkg_name, static inline int rockchip_of_get_leakage(struct device *dev, char *lkg_name,
int *leakage) int *leakage)
@@ -132,40 +177,6 @@ static inline int rockchip_of_get_leakage(struct device *dev, char *lkg_name,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static inline void rockchip_of_get_lkg_sel(struct device *dev,
struct device_node *np,
char *lkg_name, int process,
int *volt_sel, int *scale_sel)
{
}
static inline void rockchip_pvtpll_calibrate_opp(struct rockchip_opp_info *info)
{
}
static inline void rockchip_pvtpll_add_length(struct rockchip_opp_info *info)
{
}
static inline void rockchip_of_get_pvtm_sel(struct device *dev,
struct device_node *np,
char *reg_name, int process,
int *volt_sel, int *scale_sel)
{
}
static inline void rockchip_of_get_bin_sel(struct device *dev,
struct device_node *np, int bin,
int *scale_sel)
{
}
static inline void rockchip_of_get_bin_volt_sel(struct device *dev,
struct device_node *np,
int bin, int *bin_volt_sel)
{
}
static inline int rockchip_nvmem_cell_read_u8(struct device_node *np, static inline int rockchip_nvmem_cell_read_u8(struct device_node *np,
const char *cell_id, u8 *val) const char *cell_id, u8 *val)
{ {
@@ -178,59 +189,50 @@ static inline int rockchip_nvmem_cell_read_u16(struct device_node *np,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static inline int rockchip_get_volt_rm_table(struct device *dev,
struct device_node *np,
char *porp_name,
struct volt_rm_table **table)
{
return -EOPNOTSUPP;
}
static inline void rockchip_get_opp_data(const struct of_device_id *matches, static inline void rockchip_get_opp_data(const struct of_device_id *matches,
struct rockchip_opp_info *info) struct rockchip_opp_info *info)
{ {
} }
static inline void rockchip_get_scale_volt_sel(struct device *dev, static inline void rockchip_opp_dvfs_lock(struct rockchip_opp_info *info)
char *lkg_name, char *reg_name,
int bin, int process, int *scale,
int *volt_sel)
{ {
} }
static inline struct opp_table *rockchip_set_opp_prop_name(struct device *dev, static inline void rockchip_opp_dvfs_unlock(struct rockchip_opp_info *info)
int process,
int volt_sel)
{ {
return ERR_PTR(-EOPNOTSUPP);
} }
static inline int rockchip_adjust_power_scale(struct device *dev, int scale) static inline int
rockchip_init_opp_info(struct device *dev, struct rockchip_opp_info *info,
char *clk_name, char *reg_name)
{
return -EOPNOTSUPP;
}
static inline void
rockchip_uninit_opp_info(struct device *dev, struct rockchip_opp_info *info)
{
}
static inline int
rockchip_adjust_opp_table(struct device *dev, struct rockchip_opp_info *info)
{ {
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static inline int rockchip_get_read_margin(struct device *dev, static inline int rockchip_get_read_margin(struct device *dev,
struct rockchip_opp_info *opp_info, struct rockchip_opp_info *info,
unsigned long volt, u32 *target_rm) unsigned long volt, u32 *target_rm)
{ {
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static inline int rockchip_set_read_margin(struct device *dev, static inline int rockchip_set_read_margin(struct device *dev,
struct rockchip_opp_info *opp_info, struct rockchip_opp_info *info,
u32 rm, bool is_set_rm) u32 rm, bool is_set_rm)
{ {
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static inline int rockchip_init_read_margin(struct device *dev,
struct rockchip_opp_info *opp_info,
char *reg_name)
{
return -EOPNOTSUPP;
}
static inline int static inline int
rockchip_set_intermediate_rate(struct device *dev, rockchip_set_intermediate_rate(struct device *dev,
struct rockchip_opp_info *opp_info, struct rockchip_opp_info *opp_info,
@@ -241,13 +243,44 @@ rockchip_set_intermediate_rate(struct device *dev,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static inline int rockchip_init_opp_table(struct device *dev, static inline int
struct rockchip_opp_info *info, rockchip_opp_config_regulators(struct device *dev,
char *lkg_name, char *reg_name) struct dev_pm_opp *old_opp,
struct dev_pm_opp *new_opp,
struct regulator **regulators,
unsigned int count,
struct rockchip_opp_info *info)
{ {
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static inline int rockchip_opp_config_clks(struct device *dev,
struct opp_table *opp_table,
struct dev_pm_opp *opp, void *data,
bool scaling_down,
struct rockchip_opp_info *info)
{
return -EOPNOTSUPP;
}
static inline int rockchip_opp_check_rate_volt(struct device *dev,
struct rockchip_opp_info *info)
{
return -EOPNOTSUPP;
}
static inline int
rockchip_init_opp_table(struct device *dev, struct rockchip_opp_info *info,
char *clk_name, char *reg_name)
{
return -EOPNOTSUPP;
}
static inline void rockchip_uninit_opp_table(struct device *dev,
struct rockchip_opp_info *info)
{
}
#endif /* CONFIG_ROCKCHIP_OPP */ #endif /* CONFIG_ROCKCHIP_OPP */
#endif #endif