cpufreq: rockchip: Add support to change read margin for dsu

Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
Change-Id: I6bb6bcdf2ac169deb668e004d823b9dc1fdc4033
This commit is contained in:
Finley Xiao
2022-01-11 12:45:40 +08:00
committed by Tao Huang
parent 83654bf74e
commit e87424342d
2 changed files with 42 additions and 16 deletions

View File

@@ -186,7 +186,7 @@ static int rk3588_cpu_set_read_margin(struct device *dev,
u32 rm;
int i;
if (!opp_info->grf || !opp_info->volt_rm_tbl)
if (!opp_info->volt_rm_tbl)
return 0;
for (i = 0; opp_info->volt_rm_tbl[i].rm != VOLT_RM_TABLE_END; i++) {
@@ -203,12 +203,24 @@ static int rk3588_cpu_set_read_margin(struct device *dev,
return 0;
dev_dbg(dev, "set rm to %d\n", rm);
regmap_write(opp_info->grf, 0x20, 0x001c0000 | (rm << 2));
regmap_write(opp_info->grf, 0x28, 0x003c0000 | (rm << 2));
regmap_write(opp_info->grf, 0x2c, 0x003c0000 | (rm << 2));
regmap_write(opp_info->grf, 0x30, 0x00200020);
udelay(1);
regmap_write(opp_info->grf, 0x30, 0x00200000);
if (opp_info->grf) {
regmap_write(opp_info->grf, 0x20, 0x001c0000 | (rm << 2));
regmap_write(opp_info->grf, 0x28, 0x003c0000 | (rm << 2));
regmap_write(opp_info->grf, 0x2c, 0x003c0000 | (rm << 2));
regmap_write(opp_info->grf, 0x30, 0x00200020);
udelay(1);
regmap_write(opp_info->grf, 0x30, 0x00200000);
}
if (opp_info->dsu_grf) {
regmap_write(opp_info->dsu_grf, 0x20, 0x001c0000 | (rm << 2));
regmap_write(opp_info->dsu_grf, 0x28, 0x003c0000 | (rm << 2));
regmap_write(opp_info->dsu_grf, 0x2c, 0x003c0000 | (rm << 2));
regmap_write(opp_info->dsu_grf, 0x30, 0x001c0000 | (rm << 2));
regmap_write(opp_info->dsu_grf, 0x38, 0x001c0000 | (rm << 2));
regmap_write(opp_info->dsu_grf, 0x18, 0x40004000);
udelay(1);
regmap_write(opp_info->dsu_grf, 0x18, 0x40000000);
}
opp_info->current_rm = rm;
@@ -326,6 +338,18 @@ static int rockchip_cpufreq_set_volt(struct device *dev,
return ret;
}
static int rockchip_cpufreq_set_read_margin(struct device *dev,
struct rockchip_opp_info *opp_info,
unsigned long volt)
{
if (opp_info->data && opp_info->data->set_read_margin) {
opp_info->data->set_read_margin(dev, opp_info, volt);
opp_info->volt_rm = volt;
}
return 0;
}
static int cpu_opp_helper(struct dev_pm_set_opp_data *data)
{
struct dev_pm_opp_supply *old_supply_vdd = &data->old_opp.supplies[0];
@@ -357,9 +381,8 @@ static int cpu_opp_helper(struct dev_pm_set_opp_data *data)
"vdd");
if (ret)
goto restore_voltage;
if (opp_info->data->set_read_margin)
opp_info->data->set_read_margin(dev, opp_info,
new_supply_vdd->u_volt);
rockchip_cpufreq_set_read_margin(dev, opp_info,
new_supply_vdd->u_volt);
}
/* Change frequency */
@@ -373,9 +396,8 @@ static int cpu_opp_helper(struct dev_pm_set_opp_data *data)
/* Scaling down? Scale voltage after frequency */
if (new_freq < old_freq) {
if (opp_info->data->set_read_margin)
opp_info->data->set_read_margin(dev, opp_info,
new_supply_vdd->u_volt);
rockchip_cpufreq_set_read_margin(dev, opp_info,
new_supply_vdd->u_volt);
ret = rockchip_cpufreq_set_volt(dev, vdd_reg, new_supply_vdd,
"vdd");
if (ret)
@@ -393,9 +415,8 @@ restore_freq:
dev_err(dev, "%s: failed to restore old-freq (%lu Hz)\n",
__func__, old_freq);
restore_rm:
if (opp_info->data->set_read_margin)
opp_info->data->set_read_margin(dev, opp_info,
old_supply_vdd->u_volt);
rockchip_cpufreq_set_read_margin(dev, opp_info,
old_supply_vdd->u_volt);
restore_voltage:
rockchip_cpufreq_set_volt(dev, mem_reg, old_supply_mem, "mem");
rockchip_cpufreq_set_volt(dev, vdd_reg, old_supply_vdd, "vdd");
@@ -448,6 +469,10 @@ static int rockchip_cpufreq_cluster_init(int cpu, struct cluster_info *cluster)
"rockchip,grf");
if (IS_ERR(opp_info->grf))
opp_info->grf = NULL;
opp_info->dsu_grf =
syscon_regmap_lookup_by_phandle(np, "rockchip,dsu-grf");
if (IS_ERR(opp_info->dsu_grf))
opp_info->dsu_grf = NULL;
rockchip_get_volt_rm_table(dev, np, "volt-mem-read-margin",
&opp_info->volt_rm_tbl);
}

View File

@@ -27,6 +27,7 @@ struct rockchip_opp_info {
const struct rockchip_opp_data *data;
struct volt_rm_table *volt_rm_tbl;
struct regmap *grf;
struct regmap *dsu_grf;
struct clk_bulk_data *clks;
int num_clks;
unsigned long volt_rm;