From e87424342decc18db1c923ec2b49208a337e22d6 Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Tue, 11 Jan 2022 12:45:40 +0800 Subject: [PATCH] cpufreq: rockchip: Add support to change read margin for dsu Signed-off-by: Finley Xiao Change-Id: I6bb6bcdf2ac169deb668e004d823b9dc1fdc4033 --- drivers/cpufreq/rockchip-cpufreq.c | 57 ++++++++++++++++------ include/soc/rockchip/rockchip_opp_select.h | 1 + 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/drivers/cpufreq/rockchip-cpufreq.c b/drivers/cpufreq/rockchip-cpufreq.c index 1a0e960870c1..dc10a6894684 100644 --- a/drivers/cpufreq/rockchip-cpufreq.c +++ b/drivers/cpufreq/rockchip-cpufreq.c @@ -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); } diff --git a/include/soc/rockchip/rockchip_opp_select.h b/include/soc/rockchip/rockchip_opp_select.h index 69f4b9707d66..379a088510cc 100644 --- a/include/soc/rockchip/rockchip_opp_select.h +++ b/include/soc/rockchip/rockchip_opp_select.h @@ -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;