489 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd.4 * Author: Lin Huang <hl@rock-chips.com>5 */6 7#include <linux/arm-smccc.h>8#include <linux/bitfield.h>9#include <linux/clk.h>10#include <linux/delay.h>11#include <linux/devfreq.h>12#include <linux/devfreq-event.h>13#include <linux/interrupt.h>14#include <linux/mfd/syscon.h>15#include <linux/module.h>16#include <linux/of.h>17#include <linux/platform_device.h>18#include <linux/pm_opp.h>19#include <linux/regmap.h>20#include <linux/regulator/consumer.h>21#include <linux/rwsem.h>22#include <linux/suspend.h>23 24#include <soc/rockchip/pm_domains.h>25#include <soc/rockchip/rockchip_grf.h>26#include <soc/rockchip/rk3399_grf.h>27#include <soc/rockchip/rockchip_sip.h>28 29#define NS_TO_CYCLE(NS, MHz) (((NS) * (MHz)) / NSEC_PER_USEC)30 31#define RK3399_SET_ODT_PD_0_SR_IDLE GENMASK(7, 0)32#define RK3399_SET_ODT_PD_0_SR_MC_GATE_IDLE GENMASK(15, 8)33#define RK3399_SET_ODT_PD_0_STANDBY_IDLE GENMASK(31, 16)34 35#define RK3399_SET_ODT_PD_1_PD_IDLE GENMASK(11, 0)36#define RK3399_SET_ODT_PD_1_SRPD_LITE_IDLE GENMASK(27, 16)37 38#define RK3399_SET_ODT_PD_2_ODT_ENABLE BIT(0)39 40struct rk3399_dmcfreq {41 struct device *dev;42 struct devfreq *devfreq;43 struct devfreq_dev_profile profile;44 struct devfreq_simple_ondemand_data ondemand_data;45 struct clk *dmc_clk;46 struct devfreq_event_dev *edev;47 struct mutex lock;48 struct regulator *vdd_center;49 struct regmap *regmap_pmu;50 unsigned long rate, target_rate;51 unsigned long volt, target_volt;52 unsigned int odt_dis_freq;53 54 unsigned int pd_idle_ns;55 unsigned int sr_idle_ns;56 unsigned int sr_mc_gate_idle_ns;57 unsigned int srpd_lite_idle_ns;58 unsigned int standby_idle_ns;59 unsigned int ddr3_odt_dis_freq;60 unsigned int lpddr3_odt_dis_freq;61 unsigned int lpddr4_odt_dis_freq;62 63 unsigned int pd_idle_dis_freq;64 unsigned int sr_idle_dis_freq;65 unsigned int sr_mc_gate_idle_dis_freq;66 unsigned int srpd_lite_idle_dis_freq;67 unsigned int standby_idle_dis_freq;68};69 70static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,71 u32 flags)72{73 struct rk3399_dmcfreq *dmcfreq = dev_get_drvdata(dev);74 struct dev_pm_opp *opp;75 unsigned long old_clk_rate = dmcfreq->rate;76 unsigned long target_volt, target_rate;77 unsigned int ddrcon_mhz;78 struct arm_smccc_res res;79 int err;80 81 u32 odt_pd_arg0 = 0;82 u32 odt_pd_arg1 = 0;83 u32 odt_pd_arg2 = 0;84 85 opp = devfreq_recommended_opp(dev, freq, flags);86 if (IS_ERR(opp))87 return PTR_ERR(opp);88 89 target_rate = dev_pm_opp_get_freq(opp);90 target_volt = dev_pm_opp_get_voltage(opp);91 dev_pm_opp_put(opp);92 93 if (dmcfreq->rate == target_rate)94 return 0;95 96 mutex_lock(&dmcfreq->lock);97 98 /*99 * Ensure power-domain transitions don't interfere with ARM Trusted100 * Firmware power-domain idling.101 */102 err = rockchip_pmu_block();103 if (err) {104 dev_err(dev, "Failed to block PMU: %d\n", err);105 goto out_unlock;106 }107 108 /*109 * Some idle parameters may be based on the DDR controller clock, which110 * is half of the DDR frequency.111 * pd_idle and standby_idle are based on the controller clock cycle.112 * sr_idle_cycle, sr_mc_gate_idle_cycle, and srpd_lite_idle_cycle113 * are based on the 1024 controller clock cycle114 */115 ddrcon_mhz = target_rate / USEC_PER_SEC / 2;116 117 u32p_replace_bits(&odt_pd_arg1,118 NS_TO_CYCLE(dmcfreq->pd_idle_ns, ddrcon_mhz),119 RK3399_SET_ODT_PD_1_PD_IDLE);120 u32p_replace_bits(&odt_pd_arg0,121 NS_TO_CYCLE(dmcfreq->standby_idle_ns, ddrcon_mhz),122 RK3399_SET_ODT_PD_0_STANDBY_IDLE);123 u32p_replace_bits(&odt_pd_arg0,124 DIV_ROUND_UP(NS_TO_CYCLE(dmcfreq->sr_idle_ns,125 ddrcon_mhz), 1024),126 RK3399_SET_ODT_PD_0_SR_IDLE);127 u32p_replace_bits(&odt_pd_arg0,128 DIV_ROUND_UP(NS_TO_CYCLE(dmcfreq->sr_mc_gate_idle_ns,129 ddrcon_mhz), 1024),130 RK3399_SET_ODT_PD_0_SR_MC_GATE_IDLE);131 u32p_replace_bits(&odt_pd_arg1,132 DIV_ROUND_UP(NS_TO_CYCLE(dmcfreq->srpd_lite_idle_ns,133 ddrcon_mhz), 1024),134 RK3399_SET_ODT_PD_1_SRPD_LITE_IDLE);135 136 if (dmcfreq->regmap_pmu) {137 if (target_rate >= dmcfreq->sr_idle_dis_freq)138 odt_pd_arg0 &= ~RK3399_SET_ODT_PD_0_SR_IDLE;139 140 if (target_rate >= dmcfreq->sr_mc_gate_idle_dis_freq)141 odt_pd_arg0 &= ~RK3399_SET_ODT_PD_0_SR_MC_GATE_IDLE;142 143 if (target_rate >= dmcfreq->standby_idle_dis_freq)144 odt_pd_arg0 &= ~RK3399_SET_ODT_PD_0_STANDBY_IDLE;145 146 if (target_rate >= dmcfreq->pd_idle_dis_freq)147 odt_pd_arg1 &= ~RK3399_SET_ODT_PD_1_PD_IDLE;148 149 if (target_rate >= dmcfreq->srpd_lite_idle_dis_freq)150 odt_pd_arg1 &= ~RK3399_SET_ODT_PD_1_SRPD_LITE_IDLE;151 152 if (target_rate >= dmcfreq->odt_dis_freq)153 odt_pd_arg2 |= RK3399_SET_ODT_PD_2_ODT_ENABLE;154 155 /*156 * This makes a SMC call to the TF-A to set the DDR PD157 * (power-down) timings and to enable or disable the158 * ODT (on-die termination) resistors.159 */160 arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, odt_pd_arg0, odt_pd_arg1,161 ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD, odt_pd_arg2,162 0, 0, 0, &res);163 }164 165 /*166 * If frequency scaling from low to high, adjust voltage first.167 * If frequency scaling from high to low, adjust frequency first.168 */169 if (old_clk_rate < target_rate) {170 err = regulator_set_voltage(dmcfreq->vdd_center, target_volt,171 target_volt);172 if (err) {173 dev_err(dev, "Cannot set voltage %lu uV\n",174 target_volt);175 goto out;176 }177 }178 179 err = clk_set_rate(dmcfreq->dmc_clk, target_rate);180 if (err) {181 dev_err(dev, "Cannot set frequency %lu (%d)\n", target_rate,182 err);183 regulator_set_voltage(dmcfreq->vdd_center, dmcfreq->volt,184 dmcfreq->volt);185 goto out;186 }187 188 /*189 * Check the dpll rate,190 * There only two result we will get,191 * 1. Ddr frequency scaling fail, we still get the old rate.192 * 2. Ddr frequency scaling sucessful, we get the rate we set.193 */194 dmcfreq->rate = clk_get_rate(dmcfreq->dmc_clk);195 196 /* If get the incorrect rate, set voltage to old value. */197 if (dmcfreq->rate != target_rate) {198 dev_err(dev, "Got wrong frequency, Request %lu, Current %lu\n",199 target_rate, dmcfreq->rate);200 regulator_set_voltage(dmcfreq->vdd_center, dmcfreq->volt,201 dmcfreq->volt);202 goto out;203 } else if (old_clk_rate > target_rate)204 err = regulator_set_voltage(dmcfreq->vdd_center, target_volt,205 target_volt);206 if (err)207 dev_err(dev, "Cannot set voltage %lu uV\n", target_volt);208 209 dmcfreq->rate = target_rate;210 dmcfreq->volt = target_volt;211 212out:213 rockchip_pmu_unblock();214out_unlock:215 mutex_unlock(&dmcfreq->lock);216 return err;217}218 219static int rk3399_dmcfreq_get_dev_status(struct device *dev,220 struct devfreq_dev_status *stat)221{222 struct rk3399_dmcfreq *dmcfreq = dev_get_drvdata(dev);223 struct devfreq_event_data edata;224 int ret = 0;225 226 ret = devfreq_event_get_event(dmcfreq->edev, &edata);227 if (ret < 0)228 return ret;229 230 stat->current_frequency = dmcfreq->rate;231 stat->busy_time = edata.load_count;232 stat->total_time = edata.total_count;233 234 return ret;235}236 237static int rk3399_dmcfreq_get_cur_freq(struct device *dev, unsigned long *freq)238{239 struct rk3399_dmcfreq *dmcfreq = dev_get_drvdata(dev);240 241 *freq = dmcfreq->rate;242 243 return 0;244}245 246static __maybe_unused int rk3399_dmcfreq_suspend(struct device *dev)247{248 struct rk3399_dmcfreq *dmcfreq = dev_get_drvdata(dev);249 int ret = 0;250 251 ret = devfreq_event_disable_edev(dmcfreq->edev);252 if (ret < 0) {253 dev_err(dev, "failed to disable the devfreq-event devices\n");254 return ret;255 }256 257 ret = devfreq_suspend_device(dmcfreq->devfreq);258 if (ret < 0) {259 dev_err(dev, "failed to suspend the devfreq devices\n");260 return ret;261 }262 263 return 0;264}265 266static __maybe_unused int rk3399_dmcfreq_resume(struct device *dev)267{268 struct rk3399_dmcfreq *dmcfreq = dev_get_drvdata(dev);269 int ret = 0;270 271 ret = devfreq_event_enable_edev(dmcfreq->edev);272 if (ret < 0) {273 dev_err(dev, "failed to enable the devfreq-event devices\n");274 return ret;275 }276 277 ret = devfreq_resume_device(dmcfreq->devfreq);278 if (ret < 0) {279 dev_err(dev, "failed to resume the devfreq devices\n");280 return ret;281 }282 return ret;283}284 285static SIMPLE_DEV_PM_OPS(rk3399_dmcfreq_pm, rk3399_dmcfreq_suspend,286 rk3399_dmcfreq_resume);287 288static int rk3399_dmcfreq_of_props(struct rk3399_dmcfreq *data,289 struct device_node *np)290{291 int ret = 0;292 293 /*294 * These are all optional, and serve as minimum bounds. Give them large295 * (i.e., never "disabled") values if the DT doesn't specify one.296 */297 data->pd_idle_dis_freq =298 data->sr_idle_dis_freq =299 data->sr_mc_gate_idle_dis_freq =300 data->srpd_lite_idle_dis_freq =301 data->standby_idle_dis_freq = UINT_MAX;302 303 ret |= of_property_read_u32(np, "rockchip,pd-idle-ns",304 &data->pd_idle_ns);305 ret |= of_property_read_u32(np, "rockchip,sr-idle-ns",306 &data->sr_idle_ns);307 ret |= of_property_read_u32(np, "rockchip,sr-mc-gate-idle-ns",308 &data->sr_mc_gate_idle_ns);309 ret |= of_property_read_u32(np, "rockchip,srpd-lite-idle-ns",310 &data->srpd_lite_idle_ns);311 ret |= of_property_read_u32(np, "rockchip,standby-idle-ns",312 &data->standby_idle_ns);313 ret |= of_property_read_u32(np, "rockchip,ddr3_odt_dis_freq",314 &data->ddr3_odt_dis_freq);315 ret |= of_property_read_u32(np, "rockchip,lpddr3_odt_dis_freq",316 &data->lpddr3_odt_dis_freq);317 ret |= of_property_read_u32(np, "rockchip,lpddr4_odt_dis_freq",318 &data->lpddr4_odt_dis_freq);319 320 ret |= of_property_read_u32(np, "rockchip,pd-idle-dis-freq-hz",321 &data->pd_idle_dis_freq);322 ret |= of_property_read_u32(np, "rockchip,sr-idle-dis-freq-hz",323 &data->sr_idle_dis_freq);324 ret |= of_property_read_u32(np, "rockchip,sr-mc-gate-idle-dis-freq-hz",325 &data->sr_mc_gate_idle_dis_freq);326 ret |= of_property_read_u32(np, "rockchip,srpd-lite-idle-dis-freq-hz",327 &data->srpd_lite_idle_dis_freq);328 ret |= of_property_read_u32(np, "rockchip,standby-idle-dis-freq-hz",329 &data->standby_idle_dis_freq);330 331 return ret;332}333 334static int rk3399_dmcfreq_probe(struct platform_device *pdev)335{336 struct arm_smccc_res res;337 struct device *dev = &pdev->dev;338 struct device_node *np = pdev->dev.of_node, *node;339 struct rk3399_dmcfreq *data;340 int ret;341 struct dev_pm_opp *opp;342 u32 ddr_type;343 u32 val;344 345 data = devm_kzalloc(dev, sizeof(struct rk3399_dmcfreq), GFP_KERNEL);346 if (!data)347 return -ENOMEM;348 349 mutex_init(&data->lock);350 351 data->vdd_center = devm_regulator_get(dev, "center");352 if (IS_ERR(data->vdd_center))353 return dev_err_probe(dev, PTR_ERR(data->vdd_center),354 "Cannot get the regulator \"center\"\n");355 356 data->dmc_clk = devm_clk_get(dev, "dmc_clk");357 if (IS_ERR(data->dmc_clk))358 return dev_err_probe(dev, PTR_ERR(data->dmc_clk),359 "Cannot get the clk dmc_clk\n");360 361 data->edev = devfreq_event_get_edev_by_phandle(dev, "devfreq-events", 0);362 if (IS_ERR(data->edev))363 return -EPROBE_DEFER;364 365 ret = devfreq_event_enable_edev(data->edev);366 if (ret < 0) {367 dev_err(dev, "failed to enable devfreq-event devices\n");368 return ret;369 }370 371 rk3399_dmcfreq_of_props(data, np);372 373 node = of_parse_phandle(np, "rockchip,pmu", 0);374 if (!node)375 goto no_pmu;376 377 data->regmap_pmu = syscon_node_to_regmap(node);378 of_node_put(node);379 if (IS_ERR(data->regmap_pmu)) {380 ret = PTR_ERR(data->regmap_pmu);381 goto err_edev;382 }383 384 regmap_read(data->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val);385 ddr_type = FIELD_GET(RK3399_PMUGRF_OS_REG2_DDRTYPE, val);386 387 switch (ddr_type) {388 case ROCKCHIP_DDRTYPE_DDR3:389 data->odt_dis_freq = data->ddr3_odt_dis_freq;390 break;391 case ROCKCHIP_DDRTYPE_LPDDR3:392 data->odt_dis_freq = data->lpddr3_odt_dis_freq;393 break;394 case ROCKCHIP_DDRTYPE_LPDDR4:395 data->odt_dis_freq = data->lpddr4_odt_dis_freq;396 break;397 default:398 ret = -EINVAL;399 goto err_edev;400 }401 402no_pmu:403 arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0,404 ROCKCHIP_SIP_CONFIG_DRAM_INIT,405 0, 0, 0, 0, &res);406 407 /*408 * We add a devfreq driver to our parent since it has a device tree node409 * with operating points.410 */411 if (devm_pm_opp_of_add_table(dev)) {412 dev_err(dev, "Invalid operating-points in device tree.\n");413 ret = -EINVAL;414 goto err_edev;415 }416 417 data->ondemand_data.upthreshold = 25;418 data->ondemand_data.downdifferential = 15;419 420 data->rate = clk_get_rate(data->dmc_clk);421 422 opp = devfreq_recommended_opp(dev, &data->rate, 0);423 if (IS_ERR(opp)) {424 ret = PTR_ERR(opp);425 goto err_edev;426 }427 428 data->rate = dev_pm_opp_get_freq(opp);429 data->volt = dev_pm_opp_get_voltage(opp);430 dev_pm_opp_put(opp);431 432 data->profile = (struct devfreq_dev_profile) {433 .polling_ms = 200,434 .target = rk3399_dmcfreq_target,435 .get_dev_status = rk3399_dmcfreq_get_dev_status,436 .get_cur_freq = rk3399_dmcfreq_get_cur_freq,437 .initial_freq = data->rate,438 };439 440 data->devfreq = devm_devfreq_add_device(dev,441 &data->profile,442 DEVFREQ_GOV_SIMPLE_ONDEMAND,443 &data->ondemand_data);444 if (IS_ERR(data->devfreq)) {445 ret = PTR_ERR(data->devfreq);446 goto err_edev;447 }448 449 devm_devfreq_register_opp_notifier(dev, data->devfreq);450 451 data->dev = dev;452 platform_set_drvdata(pdev, data);453 454 return 0;455 456err_edev:457 devfreq_event_disable_edev(data->edev);458 459 return ret;460}461 462static void rk3399_dmcfreq_remove(struct platform_device *pdev)463{464 struct rk3399_dmcfreq *dmcfreq = dev_get_drvdata(&pdev->dev);465 466 devfreq_event_disable_edev(dmcfreq->edev);467}468 469static const struct of_device_id rk3399dmc_devfreq_of_match[] = {470 { .compatible = "rockchip,rk3399-dmc" },471 { },472};473MODULE_DEVICE_TABLE(of, rk3399dmc_devfreq_of_match);474 475static struct platform_driver rk3399_dmcfreq_driver = {476 .probe = rk3399_dmcfreq_probe,477 .remove_new = rk3399_dmcfreq_remove,478 .driver = {479 .name = "rk3399-dmc-freq",480 .pm = &rk3399_dmcfreq_pm,481 .of_match_table = rk3399dmc_devfreq_of_match,482 },483};484module_platform_driver(rk3399_dmcfreq_driver);485 486MODULE_LICENSE("GPL v2");487MODULE_AUTHOR("Lin Huang <hl@rock-chips.com>");488MODULE_DESCRIPTION("RK3399 dmcfreq driver with devfreq framework");489