Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

PM / devfreq: rk3399_dmc: Support new *-ns properties

We want to keep the idle time fixed, so compute based on the current DDR
frequency.

The old properties were deprecated and never used, so we can safely drop
them from the driver.

This is a rewritten version of work by Lin Huang <hl@rock-chips.com>.

Signed-off-by: Brian Norris <briannorris@chromium.org>
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>

authored by

Brian Norris and committed by
Chanwoo Choi
fd5b8479 e4421721

+50 -35
+50 -35
drivers/devfreq/rk3399_dmc.c
··· 24 24 #include <soc/rockchip/rk3399_grf.h> 25 25 #include <soc/rockchip/rockchip_sip.h> 26 26 27 + #define NS_TO_CYCLE(NS, MHz) (((NS) * (MHz)) / NSEC_PER_USEC) 28 + 27 29 #define RK3399_SET_ODT_PD_0_SR_IDLE GENMASK(7, 0) 28 30 #define RK3399_SET_ODT_PD_0_SR_MC_GATE_IDLE GENMASK(15, 8) 29 31 #define RK3399_SET_ODT_PD_0_STANDBY_IDLE GENMASK(31, 16) ··· 47 45 unsigned long rate, target_rate; 48 46 unsigned long volt, target_volt; 49 47 unsigned int odt_dis_freq; 50 - int odt_pd_arg0, odt_pd_arg1; 51 48 52 - unsigned int pd_idle; 53 - unsigned int sr_idle; 54 - unsigned int sr_mc_gate_idle; 55 - unsigned int srpd_lite_idle; 56 - unsigned int standby_idle; 49 + unsigned int pd_idle_ns; 50 + unsigned int sr_idle_ns; 51 + unsigned int sr_mc_gate_idle_ns; 52 + unsigned int srpd_lite_idle_ns; 53 + unsigned int standby_idle_ns; 57 54 unsigned int ddr3_odt_dis_freq; 58 55 unsigned int lpddr3_odt_dis_freq; 59 56 unsigned int lpddr4_odt_dis_freq; ··· 71 70 struct dev_pm_opp *opp; 72 71 unsigned long old_clk_rate = dmcfreq->rate; 73 72 unsigned long target_volt, target_rate; 73 + unsigned int ddrcon_mhz; 74 74 struct arm_smccc_res res; 75 75 int err; 76 + 77 + u32 odt_pd_arg0 = 0; 78 + u32 odt_pd_arg1 = 0; 79 + u32 odt_pd_arg2 = 0; 76 80 77 81 opp = devfreq_recommended_opp(dev, freq, flags); 78 82 if (IS_ERR(opp)) ··· 92 86 93 87 mutex_lock(&dmcfreq->lock); 94 88 95 - if (dmcfreq->regmap_pmu) { 96 - unsigned int odt_pd_arg0 = dmcfreq->odt_pd_arg0; 97 - unsigned int odt_pd_arg1 = dmcfreq->odt_pd_arg1; 98 - unsigned int odt_pd_arg2 = 0; 89 + /* 90 + * Some idle parameters may be based on the DDR controller clock, which 91 + * is half of the DDR frequency. 92 + * pd_idle and standby_idle are based on the controller clock cycle. 93 + * sr_idle_cycle, sr_mc_gate_idle_cycle, and srpd_lite_idle_cycle 94 + * are based on the 1024 controller clock cycle 95 + */ 96 + ddrcon_mhz = target_rate / USEC_PER_SEC / 2; 99 97 98 + u32p_replace_bits(&odt_pd_arg1, 99 + NS_TO_CYCLE(dmcfreq->pd_idle_ns, ddrcon_mhz), 100 + RK3399_SET_ODT_PD_1_PD_IDLE); 101 + u32p_replace_bits(&odt_pd_arg0, 102 + NS_TO_CYCLE(dmcfreq->standby_idle_ns, ddrcon_mhz), 103 + RK3399_SET_ODT_PD_0_STANDBY_IDLE); 104 + u32p_replace_bits(&odt_pd_arg0, 105 + DIV_ROUND_UP(NS_TO_CYCLE(dmcfreq->sr_idle_ns, 106 + ddrcon_mhz), 1024), 107 + RK3399_SET_ODT_PD_0_SR_IDLE); 108 + u32p_replace_bits(&odt_pd_arg0, 109 + DIV_ROUND_UP(NS_TO_CYCLE(dmcfreq->sr_mc_gate_idle_ns, 110 + ddrcon_mhz), 1024), 111 + RK3399_SET_ODT_PD_0_SR_MC_GATE_IDLE); 112 + u32p_replace_bits(&odt_pd_arg1, 113 + DIV_ROUND_UP(NS_TO_CYCLE(dmcfreq->srpd_lite_idle_ns, 114 + ddrcon_mhz), 1024), 115 + RK3399_SET_ODT_PD_1_SRPD_LITE_IDLE); 116 + 117 + if (dmcfreq->regmap_pmu) { 100 118 if (target_rate >= dmcfreq->sr_idle_dis_freq) 101 119 odt_pd_arg0 &= ~RK3399_SET_ODT_PD_0_SR_IDLE; 102 120 ··· 292 262 data->srpd_lite_idle_dis_freq = 293 263 data->standby_idle_dis_freq = UINT_MAX; 294 264 295 - ret |= of_property_read_u32(np, "rockchip,pd_idle", 296 - &data->pd_idle); 297 - ret |= of_property_read_u32(np, "rockchip,sr_idle", 298 - &data->sr_idle); 299 - ret |= of_property_read_u32(np, "rockchip,sr_mc_gate_idle", 300 - &data->sr_mc_gate_idle); 301 - ret |= of_property_read_u32(np, "rockchip,srpd_lite_idle", 302 - &data->srpd_lite_idle); 303 - ret |= of_property_read_u32(np, "rockchip,standby_idle", 304 - &data->standby_idle); 265 + ret |= of_property_read_u32(np, "rockchip,pd-idle-ns", 266 + &data->pd_idle_ns); 267 + ret |= of_property_read_u32(np, "rockchip,sr-idle-ns", 268 + &data->sr_idle_ns); 269 + ret |= of_property_read_u32(np, "rockchip,sr-mc-gate-idle-ns", 270 + &data->sr_mc_gate_idle_ns); 271 + ret |= of_property_read_u32(np, "rockchip,srpd-lite-idle-ns", 272 + &data->srpd_lite_idle_ns); 273 + ret |= of_property_read_u32(np, "rockchip,standby-idle-ns", 274 + &data->standby_idle_ns); 305 275 ret |= of_property_read_u32(np, "rockchip,ddr3_odt_dis_freq", 306 276 &data->ddr3_odt_dis_freq); 307 277 ret |= of_property_read_u32(np, "rockchip,lpddr3_odt_dis_freq", ··· 396 366 arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0, 397 367 ROCKCHIP_SIP_CONFIG_DRAM_INIT, 398 368 0, 0, 0, 0, &res); 399 - 400 - /* 401 - * In TF-A there is a platform SIP call to set the PD (power-down) 402 - * timings and to enable or disable the ODT (on-die termination). 403 - */ 404 - data->odt_pd_arg0 = 405 - FIELD_PREP(RK3399_SET_ODT_PD_0_SR_IDLE, data->sr_idle) | 406 - FIELD_PREP(RK3399_SET_ODT_PD_0_SR_MC_GATE_IDLE, 407 - data->sr_mc_gate_idle) | 408 - FIELD_PREP(RK3399_SET_ODT_PD_0_STANDBY_IDLE, 409 - data->standby_idle); 410 - data->odt_pd_arg1 = 411 - FIELD_PREP(RK3399_SET_ODT_PD_1_PD_IDLE, data->pd_idle) | 412 - FIELD_PREP(RK3399_SET_ODT_PD_1_SRPD_LITE_IDLE, 413 - data->srpd_lite_idle); 414 369 415 370 /* 416 371 * We add a devfreq driver to our parent since it has a device tree node