2 * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd.
3 * Author: Lin Huang <hl@rock-chips.com>
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 #include <linux/arm-smccc.h>
16 #include <linux/clk.h>
17 #include <linux/delay.h>
18 #include <linux/devfreq.h>
19 #include <linux/devfreq-event.h>
20 #include <linux/interrupt.h>
21 #include <linux/module.h>
23 #include <linux/platform_device.h>
24 #include <linux/pm_opp.h>
25 #include <linux/regulator/consumer.h>
26 #include <linux/rwsem.h>
27 #include <linux/suspend.h>
29 #include <soc/rockchip/rockchip_sip.h>
32 unsigned int ddr3_speed_bin
;
35 unsigned int sr_mc_gate_idle
;
36 unsigned int srpd_lite_idle
;
37 unsigned int standby_idle
;
38 unsigned int auto_pd_dis_freq
;
39 unsigned int dram_dll_dis_freq
;
40 unsigned int phy_dll_dis_freq
;
41 unsigned int ddr3_odt_dis_freq
;
42 unsigned int ddr3_drv
;
43 unsigned int ddr3_odt
;
44 unsigned int phy_ddr3_ca_drv
;
45 unsigned int phy_ddr3_dq_drv
;
46 unsigned int phy_ddr3_odt
;
47 unsigned int lpddr3_odt_dis_freq
;
48 unsigned int lpddr3_drv
;
49 unsigned int lpddr3_odt
;
50 unsigned int phy_lpddr3_ca_drv
;
51 unsigned int phy_lpddr3_dq_drv
;
52 unsigned int phy_lpddr3_odt
;
53 unsigned int lpddr4_odt_dis_freq
;
54 unsigned int lpddr4_drv
;
55 unsigned int lpddr4_dq_odt
;
56 unsigned int lpddr4_ca_odt
;
57 unsigned int phy_lpddr4_ca_drv
;
58 unsigned int phy_lpddr4_ck_cs_drv
;
59 unsigned int phy_lpddr4_dq_drv
;
60 unsigned int phy_lpddr4_odt
;
63 struct rk3399_dmcfreq
{
65 struct devfreq
*devfreq
;
66 struct devfreq_simple_ondemand_data ondemand_data
;
68 struct devfreq_event_dev
*edev
;
70 struct dram_timing timing
;
71 struct regulator
*vdd_center
;
72 unsigned long rate
, target_rate
;
73 unsigned long volt
, target_volt
;
76 static int rk3399_dmcfreq_target(struct device
*dev
, unsigned long *freq
,
79 struct rk3399_dmcfreq
*dmcfreq
= dev_get_drvdata(dev
);
80 struct dev_pm_opp
*opp
;
81 unsigned long old_clk_rate
= dmcfreq
->rate
;
82 unsigned long target_volt
, target_rate
;
85 opp
= devfreq_recommended_opp(dev
, freq
, flags
);
89 target_rate
= dev_pm_opp_get_freq(opp
);
90 target_volt
= dev_pm_opp_get_voltage(opp
);
93 if (dmcfreq
->rate
== target_rate
)
96 mutex_lock(&dmcfreq
->lock
);
99 * If frequency scaling from low to high, adjust voltage first.
100 * If frequency scaling from high to low, adjust frequency first.
102 if (old_clk_rate
< target_rate
) {
103 err
= regulator_set_voltage(dmcfreq
->vdd_center
, target_volt
,
106 dev_err(dev
, "Cannot set voltage %lu uV\n",
112 err
= clk_set_rate(dmcfreq
->dmc_clk
, target_rate
);
114 dev_err(dev
, "Cannot set frequency %lu (%d)\n", target_rate
,
116 regulator_set_voltage(dmcfreq
->vdd_center
, dmcfreq
->volt
,
122 * Check the dpll rate,
123 * There only two result we will get,
124 * 1. Ddr frequency scaling fail, we still get the old rate.
125 * 2. Ddr frequency scaling sucessful, we get the rate we set.
127 dmcfreq
->rate
= clk_get_rate(dmcfreq
->dmc_clk
);
129 /* If get the incorrect rate, set voltage to old value. */
130 if (dmcfreq
->rate
!= target_rate
) {
131 dev_err(dev
, "Got wrong frequency, Request %lu, Current %lu\n",
132 target_rate
, dmcfreq
->rate
);
133 regulator_set_voltage(dmcfreq
->vdd_center
, dmcfreq
->volt
,
136 } else if (old_clk_rate
> target_rate
)
137 err
= regulator_set_voltage(dmcfreq
->vdd_center
, target_volt
,
140 dev_err(dev
, "Cannot set voltage %lu uV\n", target_volt
);
142 dmcfreq
->rate
= target_rate
;
143 dmcfreq
->volt
= target_volt
;
146 mutex_unlock(&dmcfreq
->lock
);
150 static int rk3399_dmcfreq_get_dev_status(struct device
*dev
,
151 struct devfreq_dev_status
*stat
)
153 struct rk3399_dmcfreq
*dmcfreq
= dev_get_drvdata(dev
);
154 struct devfreq_event_data edata
;
157 ret
= devfreq_event_get_event(dmcfreq
->edev
, &edata
);
161 stat
->current_frequency
= dmcfreq
->rate
;
162 stat
->busy_time
= edata
.load_count
;
163 stat
->total_time
= edata
.total_count
;
168 static int rk3399_dmcfreq_get_cur_freq(struct device
*dev
, unsigned long *freq
)
170 struct rk3399_dmcfreq
*dmcfreq
= dev_get_drvdata(dev
);
172 *freq
= dmcfreq
->rate
;
177 static struct devfreq_dev_profile rk3399_devfreq_dmc_profile
= {
179 .target
= rk3399_dmcfreq_target
,
180 .get_dev_status
= rk3399_dmcfreq_get_dev_status
,
181 .get_cur_freq
= rk3399_dmcfreq_get_cur_freq
,
184 static __maybe_unused
int rk3399_dmcfreq_suspend(struct device
*dev
)
186 struct rk3399_dmcfreq
*dmcfreq
= dev_get_drvdata(dev
);
189 ret
= devfreq_event_disable_edev(dmcfreq
->edev
);
191 dev_err(dev
, "failed to disable the devfreq-event devices\n");
195 ret
= devfreq_suspend_device(dmcfreq
->devfreq
);
197 dev_err(dev
, "failed to suspend the devfreq devices\n");
204 static __maybe_unused
int rk3399_dmcfreq_resume(struct device
*dev
)
206 struct rk3399_dmcfreq
*dmcfreq
= dev_get_drvdata(dev
);
209 ret
= devfreq_event_enable_edev(dmcfreq
->edev
);
211 dev_err(dev
, "failed to enable the devfreq-event devices\n");
215 ret
= devfreq_resume_device(dmcfreq
->devfreq
);
217 dev_err(dev
, "failed to resume the devfreq devices\n");
223 static SIMPLE_DEV_PM_OPS(rk3399_dmcfreq_pm
, rk3399_dmcfreq_suspend
,
224 rk3399_dmcfreq_resume
);
226 static int of_get_ddr_timings(struct dram_timing
*timing
,
227 struct device_node
*np
)
231 ret
= of_property_read_u32(np
, "rockchip,ddr3_speed_bin",
232 &timing
->ddr3_speed_bin
);
233 ret
|= of_property_read_u32(np
, "rockchip,pd_idle",
235 ret
|= of_property_read_u32(np
, "rockchip,sr_idle",
237 ret
|= of_property_read_u32(np
, "rockchip,sr_mc_gate_idle",
238 &timing
->sr_mc_gate_idle
);
239 ret
|= of_property_read_u32(np
, "rockchip,srpd_lite_idle",
240 &timing
->srpd_lite_idle
);
241 ret
|= of_property_read_u32(np
, "rockchip,standby_idle",
242 &timing
->standby_idle
);
243 ret
|= of_property_read_u32(np
, "rockchip,auto_pd_dis_freq",
244 &timing
->auto_pd_dis_freq
);
245 ret
|= of_property_read_u32(np
, "rockchip,dram_dll_dis_freq",
246 &timing
->dram_dll_dis_freq
);
247 ret
|= of_property_read_u32(np
, "rockchip,phy_dll_dis_freq",
248 &timing
->phy_dll_dis_freq
);
249 ret
|= of_property_read_u32(np
, "rockchip,ddr3_odt_dis_freq",
250 &timing
->ddr3_odt_dis_freq
);
251 ret
|= of_property_read_u32(np
, "rockchip,ddr3_drv",
253 ret
|= of_property_read_u32(np
, "rockchip,ddr3_odt",
255 ret
|= of_property_read_u32(np
, "rockchip,phy_ddr3_ca_drv",
256 &timing
->phy_ddr3_ca_drv
);
257 ret
|= of_property_read_u32(np
, "rockchip,phy_ddr3_dq_drv",
258 &timing
->phy_ddr3_dq_drv
);
259 ret
|= of_property_read_u32(np
, "rockchip,phy_ddr3_odt",
260 &timing
->phy_ddr3_odt
);
261 ret
|= of_property_read_u32(np
, "rockchip,lpddr3_odt_dis_freq",
262 &timing
->lpddr3_odt_dis_freq
);
263 ret
|= of_property_read_u32(np
, "rockchip,lpddr3_drv",
264 &timing
->lpddr3_drv
);
265 ret
|= of_property_read_u32(np
, "rockchip,lpddr3_odt",
266 &timing
->lpddr3_odt
);
267 ret
|= of_property_read_u32(np
, "rockchip,phy_lpddr3_ca_drv",
268 &timing
->phy_lpddr3_ca_drv
);
269 ret
|= of_property_read_u32(np
, "rockchip,phy_lpddr3_dq_drv",
270 &timing
->phy_lpddr3_dq_drv
);
271 ret
|= of_property_read_u32(np
, "rockchip,phy_lpddr3_odt",
272 &timing
->phy_lpddr3_odt
);
273 ret
|= of_property_read_u32(np
, "rockchip,lpddr4_odt_dis_freq",
274 &timing
->lpddr4_odt_dis_freq
);
275 ret
|= of_property_read_u32(np
, "rockchip,lpddr4_drv",
276 &timing
->lpddr4_drv
);
277 ret
|= of_property_read_u32(np
, "rockchip,lpddr4_dq_odt",
278 &timing
->lpddr4_dq_odt
);
279 ret
|= of_property_read_u32(np
, "rockchip,lpddr4_ca_odt",
280 &timing
->lpddr4_ca_odt
);
281 ret
|= of_property_read_u32(np
, "rockchip,phy_lpddr4_ca_drv",
282 &timing
->phy_lpddr4_ca_drv
);
283 ret
|= of_property_read_u32(np
, "rockchip,phy_lpddr4_ck_cs_drv",
284 &timing
->phy_lpddr4_ck_cs_drv
);
285 ret
|= of_property_read_u32(np
, "rockchip,phy_lpddr4_dq_drv",
286 &timing
->phy_lpddr4_dq_drv
);
287 ret
|= of_property_read_u32(np
, "rockchip,phy_lpddr4_odt",
288 &timing
->phy_lpddr4_odt
);
293 static int rk3399_dmcfreq_probe(struct platform_device
*pdev
)
295 struct arm_smccc_res res
;
296 struct device
*dev
= &pdev
->dev
;
297 struct device_node
*np
= pdev
->dev
.of_node
;
298 struct rk3399_dmcfreq
*data
;
299 int ret
, index
, size
;
301 struct dev_pm_opp
*opp
;
303 data
= devm_kzalloc(dev
, sizeof(struct rk3399_dmcfreq
), GFP_KERNEL
);
307 mutex_init(&data
->lock
);
309 data
->vdd_center
= devm_regulator_get(dev
, "center");
310 if (IS_ERR(data
->vdd_center
)) {
311 if (PTR_ERR(data
->vdd_center
) == -EPROBE_DEFER
)
312 return -EPROBE_DEFER
;
314 dev_err(dev
, "Cannot get the regulator \"center\"\n");
315 return PTR_ERR(data
->vdd_center
);
318 data
->dmc_clk
= devm_clk_get(dev
, "dmc_clk");
319 if (IS_ERR(data
->dmc_clk
)) {
320 if (PTR_ERR(data
->dmc_clk
) == -EPROBE_DEFER
)
321 return -EPROBE_DEFER
;
323 dev_err(dev
, "Cannot get the clk dmc_clk\n");
324 return PTR_ERR(data
->dmc_clk
);
327 data
->edev
= devfreq_event_get_edev_by_phandle(dev
, 0);
328 if (IS_ERR(data
->edev
))
329 return -EPROBE_DEFER
;
331 ret
= devfreq_event_enable_edev(data
->edev
);
333 dev_err(dev
, "failed to enable devfreq-event devices\n");
338 * Get dram timing and pass it to arm trust firmware,
339 * the dram drvier in arm trust firmware will get these
340 * timing and to do dram initial.
342 if (!of_get_ddr_timings(&data
->timing
, np
)) {
343 timing
= &data
->timing
.ddr3_speed_bin
;
344 size
= sizeof(struct dram_timing
) / 4;
345 for (index
= 0; index
< size
; index
++) {
346 arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ
, *timing
++, index
,
347 ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM
,
350 dev_err(dev
, "Failed to set dram param: %ld\n",
357 arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ
, 0, 0,
358 ROCKCHIP_SIP_CONFIG_DRAM_INIT
,
362 * We add a devfreq driver to our parent since it has a device tree node
363 * with operating points.
365 if (dev_pm_opp_of_add_table(dev
)) {
366 dev_err(dev
, "Invalid operating-points in device tree.\n");
370 of_property_read_u32(np
, "upthreshold",
371 &data
->ondemand_data
.upthreshold
);
372 of_property_read_u32(np
, "downdifferential",
373 &data
->ondemand_data
.downdifferential
);
375 data
->rate
= clk_get_rate(data
->dmc_clk
);
377 opp
= devfreq_recommended_opp(dev
, &data
->rate
, 0);
383 data
->rate
= dev_pm_opp_get_freq(opp
);
384 data
->volt
= dev_pm_opp_get_voltage(opp
);
387 rk3399_devfreq_dmc_profile
.initial_freq
= data
->rate
;
389 data
->devfreq
= devm_devfreq_add_device(dev
,
390 &rk3399_devfreq_dmc_profile
,
391 DEVFREQ_GOV_SIMPLE_ONDEMAND
,
392 &data
->ondemand_data
);
393 if (IS_ERR(data
->devfreq
)) {
394 ret
= PTR_ERR(data
->devfreq
);
398 devm_devfreq_register_opp_notifier(dev
, data
->devfreq
);
401 platform_set_drvdata(pdev
, data
);
406 dev_pm_opp_of_remove_table(&pdev
->dev
);
410 static int rk3399_dmcfreq_remove(struct platform_device
*pdev
)
412 struct rk3399_dmcfreq
*dmcfreq
= dev_get_drvdata(&pdev
->dev
);
415 * Before remove the opp table we need to unregister the opp notifier.
417 devm_devfreq_unregister_opp_notifier(dmcfreq
->dev
, dmcfreq
->devfreq
);
418 dev_pm_opp_of_remove_table(dmcfreq
->dev
);
423 static const struct of_device_id rk3399dmc_devfreq_of_match
[] = {
424 { .compatible
= "rockchip,rk3399-dmc" },
427 MODULE_DEVICE_TABLE(of
, rk3399dmc_devfreq_of_match
);
429 static struct platform_driver rk3399_dmcfreq_driver
= {
430 .probe
= rk3399_dmcfreq_probe
,
431 .remove
= rk3399_dmcfreq_remove
,
433 .name
= "rk3399-dmc-freq",
434 .pm
= &rk3399_dmcfreq_pm
,
435 .of_match_table
= rk3399dmc_devfreq_of_match
,
438 module_platform_driver(rk3399_dmcfreq_driver
);
440 MODULE_LICENSE("GPL v2");
441 MODULE_AUTHOR("Lin Huang <hl@rock-chips.com>");
442 MODULE_DESCRIPTION("RK3399 dmcfreq driver with devfreq framework");