.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | | - * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd. |
---|
3 | | - * Author: Lin Huang <hl@rock-chips.com> |
---|
| 3 | + * Rockchip Generic dmc support. |
---|
4 | 4 | * |
---|
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. |
---|
8 | | - * |
---|
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 |
---|
12 | | - * more details. |
---|
| 5 | + * Copyright (c) 2021 Rockchip Electronics Co. Ltd. |
---|
| 6 | + * Author: Finley Xiao <finley.xiao@rock-chips.com> |
---|
13 | 7 | */ |
---|
14 | 8 | |
---|
15 | 9 | #include <dt-bindings/clock/rockchip-ddr.h> |
---|
16 | 10 | #include <dt-bindings/soc/rockchip-system-status.h> |
---|
17 | | -#include <drm/drmP.h> |
---|
18 | 11 | #include <drm/drm_modeset_lock.h> |
---|
19 | 12 | #include <linux/arm-smccc.h> |
---|
20 | 13 | #include <linux/clk.h> |
---|
.. | .. |
---|
50 | 43 | #include <soc/rockchip/rockchip_system_monitor.h> |
---|
51 | 44 | #include <soc/rockchip/rockchip-system-status.h> |
---|
52 | 45 | #include <soc/rockchip/rockchip_opp_select.h> |
---|
53 | | -#include <soc/rockchip/scpi.h> |
---|
54 | 46 | #include <uapi/drm/drm_mode.h> |
---|
55 | 47 | |
---|
56 | 48 | #include "governor.h" |
---|
57 | 49 | #include "rockchip_dmc_timing.h" |
---|
| 50 | +#include "../clk/rockchip/clk.h" |
---|
| 51 | +#include "../gpu/drm/rockchip/rockchip_drm_drv.h" |
---|
| 52 | +#include "../opp/opp.h" |
---|
58 | 53 | |
---|
59 | 54 | #define system_status_to_dmcfreq(nb) container_of(nb, struct rockchip_dmcfreq, \ |
---|
60 | 55 | status_nb) |
---|
.. | .. |
---|
62 | 57 | reboot_nb) |
---|
63 | 58 | #define boost_to_dmcfreq(work) container_of(work, struct rockchip_dmcfreq, \ |
---|
64 | 59 | boost_work) |
---|
65 | | -#define msch_rl_to_dmcfreq(work) container_of(to_delayed_work(work), \ |
---|
66 | | - struct rockchip_dmcfreq, \ |
---|
67 | | - msch_rl_work) |
---|
68 | 60 | #define input_hd_to_dmcfreq(hd) container_of(hd, struct rockchip_dmcfreq, \ |
---|
69 | 61 | input_handler) |
---|
70 | 62 | |
---|
71 | 63 | #define VIDEO_1080P_SIZE (1920 * 1080) |
---|
72 | | -#define FIQ_INIT_HANDLER (0x1) |
---|
73 | | -#define FIQ_CPU_TGT_BOOT (0x0) /* to booting cpu */ |
---|
74 | | -#define FIQ_NUM_FOR_DCF (143) /* NA irq map to fiq for dcf */ |
---|
75 | 64 | #define DTS_PAR_OFFSET (4096) |
---|
76 | | -#define MSCH_RL_DELAY_TIME 50 /* ms */ |
---|
77 | 65 | |
---|
78 | 66 | #define FALLBACK_STATIC_TEMPERATURE 55000 |
---|
79 | 67 | |
---|
80 | | -struct freq_map_table { |
---|
81 | | - unsigned int min; |
---|
82 | | - unsigned int max; |
---|
83 | | - unsigned long freq; |
---|
84 | | -}; |
---|
85 | | - |
---|
86 | | -struct rl_map_table { |
---|
87 | | - unsigned int pn; /* panel number */ |
---|
88 | | - unsigned int rl; /* readlatency */ |
---|
89 | | -}; |
---|
90 | | - |
---|
91 | 68 | struct dmc_freq_table { |
---|
92 | 69 | unsigned long freq; |
---|
93 | | - unsigned long volt; |
---|
| 70 | + struct dev_pm_opp_supply supplies[2]; |
---|
94 | 71 | }; |
---|
95 | 72 | |
---|
96 | 73 | struct share_params { |
---|
.. | .. |
---|
116 | 93 | |
---|
117 | 94 | u32 freq_count; |
---|
118 | 95 | u32 freq_info_mhz[6]; |
---|
119 | | - /* if need, add parameter after */ |
---|
| 96 | + u32 wait_mode; |
---|
| 97 | + u32 vop_scan_line_time_ns; |
---|
| 98 | + /* if need, add parameter after */ |
---|
120 | 99 | }; |
---|
121 | 100 | |
---|
122 | 101 | static struct share_params *ddr_psci_param; |
---|
.. | .. |
---|
128 | 107 | |
---|
129 | 108 | struct rockchip_dmcfreq { |
---|
130 | 109 | struct device *dev; |
---|
131 | | - struct devfreq *devfreq; |
---|
| 110 | + struct dmcfreq_common_info info; |
---|
132 | 111 | struct rockchip_dmcfreq_ondemand_data ondemand_data; |
---|
133 | 112 | struct clk *dmc_clk; |
---|
134 | 113 | struct devfreq_event_dev **edev; |
---|
135 | 114 | struct mutex lock; /* serializes access to video_info_list */ |
---|
136 | 115 | struct dram_timing *timing; |
---|
137 | 116 | struct regulator *vdd_center; |
---|
| 117 | + struct regulator *mem_reg; |
---|
138 | 118 | struct notifier_block status_nb; |
---|
| 119 | + struct notifier_block panic_nb; |
---|
139 | 120 | struct list_head video_info_list; |
---|
140 | | - struct freq_map_table *vop_bw_tbl; |
---|
141 | | - struct freq_map_table *vop_frame_bw_tbl; |
---|
142 | 121 | struct freq_map_table *cpu_bw_tbl; |
---|
143 | 122 | struct work_struct boost_work; |
---|
144 | 123 | struct input_handler input_handler; |
---|
145 | 124 | struct monitor_dev_info *mdev_info; |
---|
146 | | - struct rl_map_table *vop_pn_rl_tbl; |
---|
147 | | - struct delayed_work msch_rl_work; |
---|
| 125 | + struct share_params *set_rate_params; |
---|
148 | 126 | |
---|
149 | 127 | unsigned long *nocp_bw; |
---|
150 | | - unsigned long rate, target_rate; |
---|
151 | | - unsigned long volt, target_volt; |
---|
152 | | - |
---|
| 128 | + unsigned long rate; |
---|
| 129 | + unsigned long volt, mem_volt; |
---|
| 130 | + unsigned long sleep_volt, sleep_mem_volt; |
---|
153 | 131 | unsigned long auto_min_rate; |
---|
154 | 132 | unsigned long status_rate; |
---|
155 | 133 | unsigned long normal_rate; |
---|
156 | 134 | unsigned long video_1080p_rate; |
---|
157 | 135 | unsigned long video_4k_rate; |
---|
158 | 136 | unsigned long video_4k_10b_rate; |
---|
| 137 | + unsigned long video_4k_60p_rate; |
---|
| 138 | + unsigned long video_svep_rate; |
---|
159 | 139 | unsigned long performance_rate; |
---|
160 | 140 | unsigned long hdmi_rate; |
---|
| 141 | + unsigned long hdmirx_rate; |
---|
161 | 142 | unsigned long idle_rate; |
---|
162 | 143 | unsigned long suspend_rate; |
---|
163 | 144 | unsigned long reboot_rate; |
---|
164 | 145 | unsigned long boost_rate; |
---|
165 | 146 | unsigned long fixed_rate; |
---|
166 | 147 | unsigned long low_power_rate; |
---|
167 | | - unsigned long vop_req_rate; |
---|
168 | 148 | |
---|
169 | 149 | unsigned long freq_count; |
---|
170 | 150 | unsigned long freq_info_rate[6]; |
---|
.. | .. |
---|
174 | 154 | unsigned long rate_high; |
---|
175 | 155 | |
---|
176 | 156 | unsigned int min_cpu_freq; |
---|
177 | | - unsigned int auto_freq_en; |
---|
178 | 157 | unsigned int system_status_en; |
---|
179 | 158 | unsigned int refresh; |
---|
180 | | - unsigned int last_refresh; |
---|
181 | | - unsigned int read_latency; |
---|
182 | 159 | int edev_count; |
---|
183 | 160 | int dfi_id; |
---|
184 | 161 | int nocp_cpu_id; |
---|
| 162 | + int regulator_count; |
---|
185 | 163 | |
---|
186 | 164 | bool is_fixed; |
---|
187 | | - bool is_msch_rl_work_started; |
---|
188 | 165 | bool is_set_rate_direct; |
---|
189 | 166 | |
---|
190 | 167 | struct thermal_cooling_device *devfreq_cooling; |
---|
.. | .. |
---|
196 | 173 | u64 touchboostpulse_endtime; |
---|
197 | 174 | |
---|
198 | 175 | int (*set_auto_self_refresh)(u32 en); |
---|
199 | | - int (*set_msch_readlatency)(unsigned int rl); |
---|
200 | 176 | }; |
---|
201 | 177 | |
---|
202 | 178 | static struct pm_qos_request pm_qos; |
---|
203 | 179 | |
---|
204 | | -static DECLARE_RWSEM(rockchip_dmcfreq_sem); |
---|
| 180 | +static int rockchip_dmcfreq_opp_helper(struct dev_pm_set_opp_data *data); |
---|
| 181 | + |
---|
| 182 | +static struct monitor_dev_profile dmc_mdevp = { |
---|
| 183 | + .type = MONITOR_TYPE_DEV, |
---|
| 184 | + .low_temp_adjust = rockchip_monitor_dev_low_temp_adjust, |
---|
| 185 | + .high_temp_adjust = rockchip_monitor_dev_high_temp_adjust, |
---|
| 186 | + .update_volt = rockchip_monitor_check_rate_volt, |
---|
| 187 | + .set_opp = rockchip_dmcfreq_opp_helper, |
---|
| 188 | +}; |
---|
205 | 189 | |
---|
206 | 190 | static inline unsigned long is_dualview(unsigned long status) |
---|
207 | 191 | { |
---|
.. | .. |
---|
214 | 198 | (status & SYS_STATUS_CIF0) || |
---|
215 | 199 | (status & SYS_STATUS_CIF1); |
---|
216 | 200 | } |
---|
217 | | - |
---|
218 | | -void rockchip_dmcfreq_lock(void) |
---|
219 | | -{ |
---|
220 | | - down_read(&rockchip_dmcfreq_sem); |
---|
221 | | -} |
---|
222 | | -EXPORT_SYMBOL(rockchip_dmcfreq_lock); |
---|
223 | | - |
---|
224 | | -void rockchip_dmcfreq_lock_nested(void) |
---|
225 | | -{ |
---|
226 | | - down_read_nested(&rockchip_dmcfreq_sem, SINGLE_DEPTH_NESTING); |
---|
227 | | -} |
---|
228 | | -EXPORT_SYMBOL(rockchip_dmcfreq_lock_nested); |
---|
229 | | - |
---|
230 | | -void rockchip_dmcfreq_unlock(void) |
---|
231 | | -{ |
---|
232 | | - up_read(&rockchip_dmcfreq_sem); |
---|
233 | | -} |
---|
234 | | -EXPORT_SYMBOL(rockchip_dmcfreq_unlock); |
---|
235 | 201 | |
---|
236 | 202 | /* |
---|
237 | 203 | * function: packaging de-skew setting to px30_ddr_dts_config_timing, |
---|
.. | .. |
---|
346 | 312 | |
---|
347 | 313 | static int rk_drm_get_lcdc_type(void) |
---|
348 | 314 | { |
---|
349 | | - struct drm_device *drm; |
---|
350 | | - u32 lcdc_type = 0; |
---|
| 315 | + u32 lcdc_type = rockchip_drm_get_sub_dev_type(); |
---|
351 | 316 | |
---|
352 | | - drm = drm_device_get_by_name("rockchip"); |
---|
353 | | - if (drm) { |
---|
354 | | - struct drm_connector *conn; |
---|
355 | | - |
---|
356 | | - list_for_each_entry(conn, &drm->mode_config.connector_list, |
---|
357 | | - head) { |
---|
358 | | - if (conn->encoder) { |
---|
359 | | - lcdc_type = conn->connector_type; |
---|
360 | | - break; |
---|
361 | | - } |
---|
362 | | - } |
---|
363 | | - } |
---|
364 | 317 | switch (lcdc_type) { |
---|
365 | 318 | case DRM_MODE_CONNECTOR_DPI: |
---|
366 | 319 | case DRM_MODE_CONNECTOR_LVDS: |
---|
.. | .. |
---|
396 | 349 | |
---|
397 | 350 | ddr_psci_param->hz = target_rate; |
---|
398 | 351 | ddr_psci_param->lcdc_type = rk_drm_get_lcdc_type(); |
---|
| 352 | + ddr_psci_param->vop_scan_line_time_ns = rockchip_drm_get_scan_line_time_ns(); |
---|
399 | 353 | ddr_psci_param->wait_flag1 = 1; |
---|
400 | 354 | ddr_psci_param->wait_flag0 = 1; |
---|
401 | 355 | |
---|
.. | .. |
---|
408 | 362 | return res.a0; |
---|
409 | 363 | } |
---|
410 | 364 | |
---|
411 | | -static int rockchip_dmcfreq_target(struct device *dev, unsigned long *freq, |
---|
412 | | - u32 flags) |
---|
| 365 | +static int rockchip_dmcfreq_set_volt(struct device *dev, struct regulator *reg, |
---|
| 366 | + struct dev_pm_opp_supply *supply, |
---|
| 367 | + char *reg_name) |
---|
413 | 368 | { |
---|
| 369 | + int ret; |
---|
| 370 | + |
---|
| 371 | + dev_dbg(dev, "%s: %s voltages (mV): %lu %lu %lu\n", __func__, reg_name, |
---|
| 372 | + supply->u_volt_min, supply->u_volt, supply->u_volt_max); |
---|
| 373 | + ret = regulator_set_voltage_triplet(reg, supply->u_volt_min, |
---|
| 374 | + supply->u_volt, INT_MAX); |
---|
| 375 | + if (ret) |
---|
| 376 | + dev_err(dev, "%s: failed to set voltage (%lu %lu %lu mV): %d\n", |
---|
| 377 | + __func__, supply->u_volt_min, supply->u_volt, |
---|
| 378 | + supply->u_volt_max, ret); |
---|
| 379 | + |
---|
| 380 | + return ret; |
---|
| 381 | +} |
---|
| 382 | + |
---|
| 383 | +static int rockchip_dmcfreq_opp_helper(struct dev_pm_set_opp_data *data) |
---|
| 384 | +{ |
---|
| 385 | + struct dev_pm_opp_supply *old_supply_vdd = &data->old_opp.supplies[0]; |
---|
| 386 | + struct dev_pm_opp_supply *new_supply_vdd = &data->new_opp.supplies[0]; |
---|
| 387 | + struct regulator *vdd_reg = data->regulators[0]; |
---|
| 388 | + struct dev_pm_opp_supply *old_supply_mem; |
---|
| 389 | + struct dev_pm_opp_supply *new_supply_mem; |
---|
| 390 | + struct regulator *mem_reg; |
---|
| 391 | + struct device *dev = data->dev; |
---|
| 392 | + struct clk *clk = data->clk; |
---|
414 | 393 | struct rockchip_dmcfreq *dmcfreq = dev_get_drvdata(dev); |
---|
415 | | - struct dev_pm_opp *opp; |
---|
416 | 394 | struct cpufreq_policy *policy; |
---|
417 | | - unsigned long old_clk_rate = dmcfreq->rate; |
---|
418 | | - unsigned long target_volt, target_rate; |
---|
419 | | - unsigned int cpu_cur, cpufreq_cur; |
---|
| 395 | + unsigned long old_freq = data->old_opp.rate; |
---|
| 396 | + unsigned long freq = data->new_opp.rate; |
---|
| 397 | + unsigned int reg_count = data->regulator_count; |
---|
420 | 398 | bool is_cpufreq_changed = false; |
---|
421 | | - int err = 0; |
---|
| 399 | + unsigned int cpu_cur, cpufreq_cur; |
---|
| 400 | + int ret = 0; |
---|
422 | 401 | |
---|
423 | | - opp = devfreq_recommended_opp(dev, freq, flags); |
---|
424 | | - if (IS_ERR(opp)) { |
---|
425 | | - dev_err(dev, "Failed to find opp for %lu Hz\n", *freq); |
---|
426 | | - return PTR_ERR(opp); |
---|
427 | | - } |
---|
428 | | - target_volt = dev_pm_opp_get_voltage(opp); |
---|
429 | | - dev_pm_opp_put(opp); |
---|
430 | | - |
---|
431 | | - if (dmcfreq->is_set_rate_direct) { |
---|
432 | | - target_rate = *freq; |
---|
433 | | - } else { |
---|
434 | | - target_rate = clk_round_rate(dmcfreq->dmc_clk, *freq); |
---|
435 | | - if ((long)target_rate <= 0) |
---|
436 | | - target_rate = *freq; |
---|
437 | | - } |
---|
438 | | - |
---|
439 | | - if (dmcfreq->rate == target_rate) { |
---|
440 | | - if (dmcfreq->volt == target_volt) |
---|
441 | | - return 0; |
---|
442 | | - err = regulator_set_voltage(dmcfreq->vdd_center, target_volt, |
---|
443 | | - INT_MAX); |
---|
444 | | - if (err) { |
---|
445 | | - dev_err(dev, "Cannot set voltage %lu uV\n", |
---|
446 | | - target_volt); |
---|
447 | | - return err; |
---|
448 | | - } |
---|
449 | | - dmcfreq->volt = target_volt; |
---|
450 | | - return 0; |
---|
451 | | - } else if (!dmcfreq->volt) { |
---|
452 | | - dmcfreq->volt = regulator_get_voltage(dmcfreq->vdd_center); |
---|
| 402 | + if (reg_count > 1) { |
---|
| 403 | + old_supply_mem = &data->old_opp.supplies[1]; |
---|
| 404 | + new_supply_mem = &data->new_opp.supplies[1]; |
---|
| 405 | + mem_reg = data->regulators[1]; |
---|
453 | 406 | } |
---|
454 | 407 | |
---|
455 | 408 | /* |
---|
.. | .. |
---|
459 | 412 | * Do this before taking the policy rwsem to avoid deadlocks between the |
---|
460 | 413 | * mutex that is locked/unlocked in cpu_hotplug_disable/enable. And it |
---|
461 | 414 | * can also avoid deadlocks between the mutex that is locked/unlocked |
---|
462 | | - * in get/put_online_cpus (such as store_scaling_max_freq()). |
---|
| 415 | + * in cpus_read_lock/unlock (such as store_scaling_max_freq()). |
---|
463 | 416 | */ |
---|
464 | | - get_online_cpus(); |
---|
| 417 | + cpus_read_lock(); |
---|
465 | 418 | |
---|
466 | | - /* |
---|
467 | | - * Go to specified cpufreq and block other cpufreq changes since |
---|
468 | | - * set_rate needs to complete during vblank. |
---|
469 | | - */ |
---|
470 | | - cpu_cur = raw_smp_processor_id(); |
---|
471 | | - policy = cpufreq_cpu_get(cpu_cur); |
---|
472 | | - if (!policy) { |
---|
473 | | - dev_err(dev, "cpu%d policy NULL\n", cpu_cur); |
---|
474 | | - goto cpufreq; |
---|
475 | | - } |
---|
476 | | - down_write(&policy->rwsem); |
---|
477 | | - cpufreq_cur = cpufreq_quick_get(cpu_cur); |
---|
| 419 | + if (dmcfreq->min_cpu_freq) { |
---|
| 420 | + /* |
---|
| 421 | + * Go to specified cpufreq and block other cpufreq changes since |
---|
| 422 | + * set_rate needs to complete during vblank. |
---|
| 423 | + */ |
---|
| 424 | + cpu_cur = raw_smp_processor_id(); |
---|
| 425 | + policy = cpufreq_cpu_get(cpu_cur); |
---|
| 426 | + if (!policy) { |
---|
| 427 | + dev_err(dev, "cpu%d policy NULL\n", cpu_cur); |
---|
| 428 | + ret = -EINVAL; |
---|
| 429 | + goto cpufreq; |
---|
| 430 | + } |
---|
| 431 | + down_write(&policy->rwsem); |
---|
| 432 | + cpufreq_cur = cpufreq_quick_get(cpu_cur); |
---|
478 | 433 | |
---|
479 | | - /* If we're thermally throttled; don't change; */ |
---|
480 | | - if (dmcfreq->min_cpu_freq && cpufreq_cur < dmcfreq->min_cpu_freq) { |
---|
481 | | - if (policy->max >= dmcfreq->min_cpu_freq) { |
---|
482 | | - __cpufreq_driver_target(policy, dmcfreq->min_cpu_freq, |
---|
483 | | - CPUFREQ_RELATION_L); |
---|
484 | | - is_cpufreq_changed = true; |
---|
485 | | - } else { |
---|
486 | | - dev_dbg(dev, "CPU may too slow for DMC (%d MHz)\n", |
---|
487 | | - policy->max); |
---|
| 434 | + /* If we're thermally throttled; don't change; */ |
---|
| 435 | + if (cpufreq_cur < dmcfreq->min_cpu_freq) { |
---|
| 436 | + if (policy->max >= dmcfreq->min_cpu_freq) { |
---|
| 437 | + __cpufreq_driver_target(policy, |
---|
| 438 | + dmcfreq->min_cpu_freq, |
---|
| 439 | + CPUFREQ_RELATION_L); |
---|
| 440 | + is_cpufreq_changed = true; |
---|
| 441 | + } else { |
---|
| 442 | + dev_dbg(dev, |
---|
| 443 | + "CPU may too slow for DMC (%d MHz)\n", |
---|
| 444 | + policy->max); |
---|
| 445 | + } |
---|
488 | 446 | } |
---|
489 | 447 | } |
---|
490 | 448 | |
---|
491 | | - /* |
---|
492 | | - * If frequency scaling from low to high, adjust voltage first. |
---|
493 | | - * If frequency scaling from high to low, adjust frequency first. |
---|
494 | | - */ |
---|
495 | | - if (old_clk_rate < target_rate) { |
---|
496 | | - err = regulator_set_voltage(dmcfreq->vdd_center, target_volt, |
---|
497 | | - INT_MAX); |
---|
498 | | - if (err) { |
---|
499 | | - dev_err(dev, "Cannot set voltage %lu uV\n", |
---|
500 | | - target_volt); |
---|
| 449 | + /* Scaling up? Scale voltage before frequency */ |
---|
| 450 | + if (freq >= old_freq) { |
---|
| 451 | + if (reg_count > 1) { |
---|
| 452 | + ret = rockchip_dmcfreq_set_volt(dev, mem_reg, |
---|
| 453 | + new_supply_mem, "mem"); |
---|
| 454 | + if (ret) |
---|
| 455 | + goto restore_voltage; |
---|
| 456 | + } |
---|
| 457 | + ret = rockchip_dmcfreq_set_volt(dev, vdd_reg, new_supply_vdd, |
---|
| 458 | + "vdd"); |
---|
| 459 | + if (ret) |
---|
| 460 | + goto restore_voltage; |
---|
| 461 | + if (freq == old_freq) |
---|
501 | 462 | goto out; |
---|
502 | | - } |
---|
503 | 463 | } |
---|
504 | 464 | |
---|
505 | 465 | /* |
---|
.. | .. |
---|
509 | 469 | * As a (suboptimal) workaround, let writer to spin until it gets the |
---|
510 | 470 | * lock. |
---|
511 | 471 | */ |
---|
512 | | - while (!down_write_trylock(&rockchip_dmcfreq_sem)) |
---|
| 472 | + while (!rockchip_dmcfreq_write_trylock()) |
---|
513 | 473 | cond_resched(); |
---|
514 | | - dev_dbg(dev, "%lu-->%lu\n", old_clk_rate, target_rate); |
---|
| 474 | + dev_dbg(dev, "%lu Hz --> %lu Hz\n", old_freq, freq); |
---|
| 475 | + |
---|
| 476 | + if (dmcfreq->set_rate_params) { |
---|
| 477 | + dmcfreq->set_rate_params->lcdc_type = rk_drm_get_lcdc_type(); |
---|
| 478 | + dmcfreq->set_rate_params->wait_flag1 = 1; |
---|
| 479 | + dmcfreq->set_rate_params->wait_flag0 = 1; |
---|
| 480 | + } |
---|
515 | 481 | |
---|
516 | 482 | if (dmcfreq->is_set_rate_direct) |
---|
517 | | - err = rockchip_ddr_set_rate(target_rate); |
---|
| 483 | + ret = rockchip_ddr_set_rate(freq); |
---|
518 | 484 | else |
---|
519 | | - err = clk_set_rate(dmcfreq->dmc_clk, target_rate); |
---|
| 485 | + ret = clk_set_rate(clk, freq); |
---|
520 | 486 | |
---|
521 | | - up_write(&rockchip_dmcfreq_sem); |
---|
522 | | - if (err) { |
---|
523 | | - dev_err(dev, "Cannot set frequency %lu (%d)\n", |
---|
524 | | - target_rate, err); |
---|
525 | | - regulator_set_voltage(dmcfreq->vdd_center, dmcfreq->volt, |
---|
526 | | - INT_MAX); |
---|
527 | | - goto out; |
---|
| 487 | + rockchip_dmcfreq_write_unlock(); |
---|
| 488 | + if (ret) { |
---|
| 489 | + dev_err(dev, "%s: failed to set clock rate: %d\n", __func__, |
---|
| 490 | + ret); |
---|
| 491 | + goto restore_voltage; |
---|
528 | 492 | } |
---|
529 | 493 | |
---|
530 | 494 | /* |
---|
531 | 495 | * Check the dpll rate, |
---|
532 | 496 | * There only two result we will get, |
---|
533 | 497 | * 1. Ddr frequency scaling fail, we still get the old rate. |
---|
534 | | - * 2. Ddr frequency scaling sucessful, we get the rate we set. |
---|
| 498 | + * 2. Ddr frequency scaling successful, we get the rate we set. |
---|
535 | 499 | */ |
---|
536 | | - dmcfreq->rate = clk_get_rate(dmcfreq->dmc_clk); |
---|
| 500 | + dmcfreq->rate = clk_get_rate(clk); |
---|
537 | 501 | |
---|
538 | 502 | /* If get the incorrect rate, set voltage to old value. */ |
---|
539 | | - if (dmcfreq->rate != target_rate) { |
---|
| 503 | + if (dmcfreq->rate != freq) { |
---|
540 | 504 | dev_err(dev, "Get wrong frequency, Request %lu, Current %lu\n", |
---|
541 | | - target_rate, dmcfreq->rate); |
---|
542 | | - regulator_set_voltage(dmcfreq->vdd_center, dmcfreq->volt, |
---|
543 | | - INT_MAX); |
---|
544 | | - goto out; |
---|
545 | | - } else if (old_clk_rate > target_rate) { |
---|
546 | | - err = regulator_set_voltage(dmcfreq->vdd_center, target_volt, |
---|
547 | | - INT_MAX); |
---|
548 | | - if (err) { |
---|
549 | | - dev_err(dev, "Cannot set vol %lu uV\n", target_volt); |
---|
550 | | - goto out; |
---|
551 | | - } |
---|
| 505 | + freq, dmcfreq->rate); |
---|
| 506 | + ret = -EINVAL; |
---|
| 507 | + goto restore_voltage; |
---|
552 | 508 | } |
---|
553 | 509 | |
---|
554 | | - if (dmcfreq->devfreq) |
---|
555 | | - dmcfreq->devfreq->last_status.current_frequency = *freq; |
---|
| 510 | + /* Scaling down? Scale voltage after frequency */ |
---|
| 511 | + if (freq < old_freq) { |
---|
| 512 | + ret = rockchip_dmcfreq_set_volt(dev, vdd_reg, new_supply_vdd, |
---|
| 513 | + "vdd"); |
---|
| 514 | + if (ret) |
---|
| 515 | + goto restore_freq; |
---|
| 516 | + if (reg_count > 1) { |
---|
| 517 | + ret = rockchip_dmcfreq_set_volt(dev, mem_reg, |
---|
| 518 | + new_supply_mem, "mem"); |
---|
| 519 | + if (ret) |
---|
| 520 | + goto restore_freq; |
---|
| 521 | + } |
---|
| 522 | + } |
---|
| 523 | + dmcfreq->volt = new_supply_vdd->u_volt; |
---|
| 524 | + if (reg_count > 1) |
---|
| 525 | + dmcfreq->mem_volt = new_supply_mem->u_volt; |
---|
556 | 526 | |
---|
557 | | - dmcfreq->volt = target_volt; |
---|
| 527 | + goto out; |
---|
| 528 | + |
---|
| 529 | +restore_freq: |
---|
| 530 | + if (dmcfreq->is_set_rate_direct) |
---|
| 531 | + ret = rockchip_ddr_set_rate(freq); |
---|
| 532 | + else |
---|
| 533 | + ret = clk_set_rate(clk, freq); |
---|
| 534 | + if (ret) |
---|
| 535 | + dev_err(dev, "%s: failed to restore old-freq (%lu Hz)\n", |
---|
| 536 | + __func__, old_freq); |
---|
| 537 | +restore_voltage: |
---|
| 538 | + if (reg_count > 1 && old_supply_mem->u_volt) |
---|
| 539 | + rockchip_dmcfreq_set_volt(dev, mem_reg, old_supply_mem, "mem"); |
---|
| 540 | + if (old_supply_vdd->u_volt) |
---|
| 541 | + rockchip_dmcfreq_set_volt(dev, vdd_reg, old_supply_vdd, "vdd"); |
---|
558 | 542 | out: |
---|
559 | | - if (is_cpufreq_changed) |
---|
560 | | - __cpufreq_driver_target(policy, cpufreq_cur, |
---|
561 | | - CPUFREQ_RELATION_L); |
---|
562 | | - up_write(&policy->rwsem); |
---|
563 | | - cpufreq_cpu_put(policy); |
---|
| 543 | + if (dmcfreq->min_cpu_freq) { |
---|
| 544 | + if (is_cpufreq_changed) |
---|
| 545 | + __cpufreq_driver_target(policy, cpufreq_cur, |
---|
| 546 | + CPUFREQ_RELATION_L); |
---|
| 547 | + up_write(&policy->rwsem); |
---|
| 548 | + cpufreq_cpu_put(policy); |
---|
| 549 | + } |
---|
564 | 550 | cpufreq: |
---|
565 | | - put_online_cpus(); |
---|
566 | | - return err; |
---|
| 551 | + cpus_read_unlock(); |
---|
| 552 | + |
---|
| 553 | + return ret; |
---|
| 554 | +} |
---|
| 555 | + |
---|
| 556 | +static int rockchip_dmcfreq_target(struct device *dev, unsigned long *freq, |
---|
| 557 | + u32 flags) |
---|
| 558 | +{ |
---|
| 559 | + struct rockchip_dmcfreq *dmcfreq = dev_get_drvdata(dev); |
---|
| 560 | + struct devfreq *devfreq; |
---|
| 561 | + struct dev_pm_opp *opp; |
---|
| 562 | + int ret = 0; |
---|
| 563 | + |
---|
| 564 | + if (!dmc_mdevp.is_checked) |
---|
| 565 | + return -EINVAL; |
---|
| 566 | + |
---|
| 567 | + opp = devfreq_recommended_opp(dev, freq, flags); |
---|
| 568 | + if (IS_ERR(opp)) { |
---|
| 569 | + dev_err(dev, "Failed to find opp for %lu Hz\n", *freq); |
---|
| 570 | + return PTR_ERR(opp); |
---|
| 571 | + } |
---|
| 572 | + dev_pm_opp_put(opp); |
---|
| 573 | + |
---|
| 574 | + rockchip_monitor_volt_adjust_lock(dmcfreq->mdev_info); |
---|
| 575 | + ret = dev_pm_opp_set_rate(dev, *freq); |
---|
| 576 | + if (!ret) { |
---|
| 577 | + if (dmcfreq->info.devfreq) { |
---|
| 578 | + devfreq = dmcfreq->info.devfreq; |
---|
| 579 | + devfreq->last_status.current_frequency = *freq; |
---|
| 580 | + } |
---|
| 581 | + } |
---|
| 582 | + rockchip_monitor_volt_adjust_unlock(dmcfreq->mdev_info); |
---|
| 583 | + |
---|
| 584 | + return ret; |
---|
567 | 585 | } |
---|
568 | 586 | |
---|
569 | 587 | static int rockchip_dmcfreq_get_dev_status(struct device *dev, |
---|
.. | .. |
---|
573 | 591 | struct devfreq_event_data edata; |
---|
574 | 592 | int i, ret = 0; |
---|
575 | 593 | |
---|
576 | | - if (!dmcfreq->auto_freq_en) |
---|
| 594 | + if (!dmcfreq->info.auto_freq_en) |
---|
577 | 595 | return -EINVAL; |
---|
578 | 596 | |
---|
| 597 | + /* |
---|
| 598 | + * RK3588 platform may crash if the CPU and MCU access the DFI/DMC |
---|
| 599 | + * registers at same time. |
---|
| 600 | + */ |
---|
| 601 | + rockchip_monitor_volt_adjust_lock(dmcfreq->mdev_info); |
---|
579 | 602 | for (i = 0; i < dmcfreq->edev_count; i++) { |
---|
580 | 603 | ret = devfreq_event_get_event(dmcfreq->edev[i], &edata); |
---|
581 | 604 | if (ret < 0) { |
---|
582 | 605 | dev_err(dev, "failed to get event %s\n", |
---|
583 | 606 | dmcfreq->edev[i]->desc->name); |
---|
584 | | - return ret; |
---|
| 607 | + goto out; |
---|
585 | 608 | } |
---|
586 | 609 | if (i == dmcfreq->dfi_id) { |
---|
587 | 610 | stat->busy_time = edata.load_count; |
---|
.. | .. |
---|
591 | 614 | } |
---|
592 | 615 | } |
---|
593 | 616 | |
---|
594 | | - return 0; |
---|
| 617 | +out: |
---|
| 618 | + rockchip_monitor_volt_adjust_unlock(dmcfreq->mdev_info); |
---|
| 619 | + |
---|
| 620 | + return ret; |
---|
595 | 621 | } |
---|
596 | 622 | |
---|
597 | 623 | static int rockchip_dmcfreq_get_cur_freq(struct device *dev, |
---|
.. | .. |
---|
962 | 988 | of_node_put(np_tim); |
---|
963 | 989 | } |
---|
964 | 990 | |
---|
965 | | -static struct rk3368_dram_timing *of_get_rk3368_timings(struct device *dev, |
---|
966 | | - struct device_node *np) |
---|
967 | | -{ |
---|
968 | | - struct rk3368_dram_timing *timing = NULL; |
---|
969 | | - struct device_node *np_tim; |
---|
970 | | - int ret = 0; |
---|
971 | | - |
---|
972 | | - np_tim = of_parse_phandle(np, "ddr_timing", 0); |
---|
973 | | - if (np_tim) { |
---|
974 | | - timing = devm_kzalloc(dev, sizeof(*timing), GFP_KERNEL); |
---|
975 | | - if (!timing) |
---|
976 | | - goto err; |
---|
977 | | - |
---|
978 | | - ret |= of_property_read_u32(np_tim, "dram_spd_bin", |
---|
979 | | - &timing->dram_spd_bin); |
---|
980 | | - ret |= of_property_read_u32(np_tim, "sr_idle", |
---|
981 | | - &timing->sr_idle); |
---|
982 | | - ret |= of_property_read_u32(np_tim, "pd_idle", |
---|
983 | | - &timing->pd_idle); |
---|
984 | | - ret |= of_property_read_u32(np_tim, "dram_dll_disb_freq", |
---|
985 | | - &timing->dram_dll_dis_freq); |
---|
986 | | - ret |= of_property_read_u32(np_tim, "phy_dll_disb_freq", |
---|
987 | | - &timing->phy_dll_dis_freq); |
---|
988 | | - ret |= of_property_read_u32(np_tim, "dram_odt_disb_freq", |
---|
989 | | - &timing->dram_odt_dis_freq); |
---|
990 | | - ret |= of_property_read_u32(np_tim, "phy_odt_disb_freq", |
---|
991 | | - &timing->phy_odt_dis_freq); |
---|
992 | | - ret |= of_property_read_u32(np_tim, "ddr3_drv", |
---|
993 | | - &timing->ddr3_drv); |
---|
994 | | - ret |= of_property_read_u32(np_tim, "ddr3_odt", |
---|
995 | | - &timing->ddr3_odt); |
---|
996 | | - ret |= of_property_read_u32(np_tim, "lpddr3_drv", |
---|
997 | | - &timing->lpddr3_drv); |
---|
998 | | - ret |= of_property_read_u32(np_tim, "lpddr3_odt", |
---|
999 | | - &timing->lpddr3_odt); |
---|
1000 | | - ret |= of_property_read_u32(np_tim, "lpddr2_drv", |
---|
1001 | | - &timing->lpddr2_drv); |
---|
1002 | | - ret |= of_property_read_u32(np_tim, "phy_clk_drv", |
---|
1003 | | - &timing->phy_clk_drv); |
---|
1004 | | - ret |= of_property_read_u32(np_tim, "phy_cmd_drv", |
---|
1005 | | - &timing->phy_cmd_drv); |
---|
1006 | | - ret |= of_property_read_u32(np_tim, "phy_dqs_drv", |
---|
1007 | | - &timing->phy_dqs_drv); |
---|
1008 | | - ret |= of_property_read_u32(np_tim, "phy_odt", |
---|
1009 | | - &timing->phy_odt); |
---|
1010 | | - ret |= of_property_read_u32(np_tim, "ddr_2t", |
---|
1011 | | - &timing->ddr_2t); |
---|
1012 | | - if (ret) { |
---|
1013 | | - devm_kfree(dev, timing); |
---|
1014 | | - goto err; |
---|
1015 | | - } |
---|
1016 | | - of_node_put(np_tim); |
---|
1017 | | - return timing; |
---|
1018 | | - } |
---|
1019 | | - |
---|
1020 | | -err: |
---|
1021 | | - if (timing) { |
---|
1022 | | - devm_kfree(dev, timing); |
---|
1023 | | - timing = NULL; |
---|
1024 | | - } |
---|
1025 | | - of_node_put(np_tim); |
---|
1026 | | - return timing; |
---|
1027 | | -} |
---|
1028 | | - |
---|
1029 | 991 | static struct rk3399_dram_timing *of_get_rk3399_timings(struct device *dev, |
---|
1030 | 992 | struct device_node *np) |
---|
1031 | 993 | { |
---|
.. | .. |
---|
1176 | 1138 | * CPUs only enter WFI when idle to make sure that |
---|
1177 | 1139 | * FIQn can quick response. |
---|
1178 | 1140 | */ |
---|
1179 | | - pm_qos_update_request(&pm_qos, 0); |
---|
| 1141 | + cpu_latency_qos_update_request(&pm_qos, 0); |
---|
1180 | 1142 | |
---|
1181 | 1143 | if (wait_ctrl.dcf_en == 1) { |
---|
1182 | 1144 | /* start dcf */ |
---|
.. | .. |
---|
1192 | 1154 | wait_event_timeout(wait_ctrl.wait_wq, (wait_ctrl.wait_flag == 0), |
---|
1193 | 1155 | msecs_to_jiffies(wait_ctrl.wait_time_out_ms)); |
---|
1194 | 1156 | |
---|
1195 | | - pm_qos_update_request(&pm_qos, PM_QOS_DEFAULT_VALUE); |
---|
| 1157 | + /* |
---|
| 1158 | + * If waiting for wait_ctrl.complt_irq times out, clear the IRQ and stop the MCU by |
---|
| 1159 | + * sip_smc_dram(DRAM_POST_SET_RATE). |
---|
| 1160 | + */ |
---|
| 1161 | + if (wait_ctrl.dcf_en == 2 && wait_ctrl.wait_flag != 0) { |
---|
| 1162 | + res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0, ROCKCHIP_SIP_CONFIG_DRAM_POST_SET_RATE); |
---|
| 1163 | + if (res.a0) |
---|
| 1164 | + pr_err("%s: dram post set rate error:%lx\n", __func__, res.a0); |
---|
| 1165 | + } |
---|
| 1166 | + |
---|
| 1167 | + cpu_latency_qos_update_request(&pm_qos, PM_QOS_DEFAULT_VALUE); |
---|
1196 | 1168 | disable_irq(wait_ctrl.complt_irq); |
---|
1197 | 1169 | |
---|
1198 | 1170 | return 0; |
---|
.. | .. |
---|
1230 | 1202 | return ret; |
---|
1231 | 1203 | } |
---|
1232 | 1204 | |
---|
1233 | | - freq_table = kmalloc(sizeof(struct dmc_freq_table) * count, GFP_KERNEL); |
---|
| 1205 | + freq_table = kzalloc(sizeof(*freq_table) * count, GFP_KERNEL); |
---|
1234 | 1206 | for (i = 0, rate = 0; i < count; i++, rate++) { |
---|
1235 | 1207 | /* find next rate */ |
---|
1236 | 1208 | opp = dev_pm_opp_find_freq_ceil(dmcfreq->dev, &rate); |
---|
.. | .. |
---|
1240 | 1212 | goto out; |
---|
1241 | 1213 | } |
---|
1242 | 1214 | freq_table[i].freq = rate; |
---|
1243 | | - freq_table[i].volt = dev_pm_opp_get_voltage(opp); |
---|
| 1215 | + freq_table[i].supplies[0].u_volt = dev_pm_opp_get_voltage(opp); |
---|
1244 | 1216 | dev_pm_opp_put(opp); |
---|
1245 | 1217 | |
---|
1246 | 1218 | for (j = 0; j < dmcfreq->freq_count; j++) { |
---|
.. | .. |
---|
1248 | 1220 | break; |
---|
1249 | 1221 | } |
---|
1250 | 1222 | if (j == dmcfreq->freq_count) |
---|
1251 | | - dev_pm_opp_remove(dmcfreq->dev, rate); |
---|
| 1223 | + dev_pm_opp_disable(dmcfreq->dev, rate); |
---|
1252 | 1224 | } |
---|
1253 | 1225 | |
---|
1254 | 1226 | for (i = 0; i < dmcfreq->freq_count; i++) { |
---|
.. | .. |
---|
1257 | 1229 | break; |
---|
1258 | 1230 | } else if (dmcfreq->freq_info_rate[i] < freq_table[j].freq) { |
---|
1259 | 1231 | dev_pm_opp_add(dmcfreq->dev, dmcfreq->freq_info_rate[i], |
---|
1260 | | - freq_table[j].volt); |
---|
| 1232 | + freq_table[j].supplies[0].u_volt); |
---|
1261 | 1233 | break; |
---|
1262 | 1234 | } |
---|
1263 | 1235 | } |
---|
.. | .. |
---|
1271 | 1243 | goto out; |
---|
1272 | 1244 | } |
---|
1273 | 1245 | } |
---|
| 1246 | + |
---|
| 1247 | +out: |
---|
| 1248 | + kfree(freq_table); |
---|
| 1249 | + return ret; |
---|
| 1250 | +} |
---|
| 1251 | + |
---|
| 1252 | +static __maybe_unused int |
---|
| 1253 | +rockchip_dmcfreq_adjust_opp_table(struct rockchip_dmcfreq *dmcfreq) |
---|
| 1254 | +{ |
---|
| 1255 | + struct device *dev = dmcfreq->dev; |
---|
| 1256 | + struct arm_smccc_res res; |
---|
| 1257 | + struct dev_pm_opp *opp; |
---|
| 1258 | + struct opp_table *opp_table; |
---|
| 1259 | + struct dmc_freq_table *freq_table; |
---|
| 1260 | + int i, j, count = 0, ret = 0; |
---|
| 1261 | + |
---|
| 1262 | + res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0, |
---|
| 1263 | + ROCKCHIP_SIP_CONFIG_DRAM_GET_FREQ_INFO); |
---|
| 1264 | + if (res.a0) { |
---|
| 1265 | + dev_err(dev, "rockchip_sip_config_dram_get_freq_info error:%lx\n", |
---|
| 1266 | + res.a0); |
---|
| 1267 | + return -ENOMEM; |
---|
| 1268 | + } |
---|
| 1269 | + |
---|
| 1270 | + if (ddr_psci_param->freq_count == 0 || ddr_psci_param->freq_count > 6) { |
---|
| 1271 | + dev_err(dev, "there is no available frequencies!\n"); |
---|
| 1272 | + return -EPERM; |
---|
| 1273 | + } |
---|
| 1274 | + |
---|
| 1275 | + for (i = 0; i < ddr_psci_param->freq_count; i++) |
---|
| 1276 | + dmcfreq->freq_info_rate[i] = ddr_psci_param->freq_info_mhz[i] * 1000000; |
---|
| 1277 | + dmcfreq->freq_count = ddr_psci_param->freq_count; |
---|
| 1278 | + |
---|
| 1279 | + count = dev_pm_opp_get_opp_count(dev); |
---|
| 1280 | + if (count <= 0) { |
---|
| 1281 | + dev_err(dev, "there is no available opp\n"); |
---|
| 1282 | + ret = count ? count : -ENODATA; |
---|
| 1283 | + return ret; |
---|
| 1284 | + } |
---|
| 1285 | + |
---|
| 1286 | + freq_table = kzalloc(sizeof(*freq_table) * count, GFP_KERNEL); |
---|
| 1287 | + opp_table = dev_pm_opp_get_opp_table(dev); |
---|
| 1288 | + if (!opp_table) { |
---|
| 1289 | + ret = -ENOMEM; |
---|
| 1290 | + goto out; |
---|
| 1291 | + } |
---|
| 1292 | + |
---|
| 1293 | + mutex_lock(&opp_table->lock); |
---|
| 1294 | + i = 0; |
---|
| 1295 | + list_for_each_entry(opp, &opp_table->opp_list, node) { |
---|
| 1296 | + if (!opp->available) |
---|
| 1297 | + continue; |
---|
| 1298 | + |
---|
| 1299 | + freq_table[i].freq = opp->rate; |
---|
| 1300 | + freq_table[i].supplies[0] = opp->supplies[0]; |
---|
| 1301 | + if (dmcfreq->regulator_count > 1) |
---|
| 1302 | + freq_table[i].supplies[1] = opp->supplies[1]; |
---|
| 1303 | + |
---|
| 1304 | + i++; |
---|
| 1305 | + } |
---|
| 1306 | + |
---|
| 1307 | + i = 0; |
---|
| 1308 | + list_for_each_entry(opp, &opp_table->opp_list, node) { |
---|
| 1309 | + if (!opp->available) |
---|
| 1310 | + continue; |
---|
| 1311 | + |
---|
| 1312 | + if (i >= dmcfreq->freq_count) { |
---|
| 1313 | + opp->available = false; |
---|
| 1314 | + continue; |
---|
| 1315 | + } |
---|
| 1316 | + |
---|
| 1317 | + for (j = 0; j < count; j++) { |
---|
| 1318 | + if (dmcfreq->freq_info_rate[i] <= freq_table[j].freq) { |
---|
| 1319 | + opp->rate = dmcfreq->freq_info_rate[i]; |
---|
| 1320 | + opp->supplies[0] = freq_table[j].supplies[0]; |
---|
| 1321 | + if (dmcfreq->regulator_count > 1) |
---|
| 1322 | + opp->supplies[1] = freq_table[j].supplies[1]; |
---|
| 1323 | + |
---|
| 1324 | + break; |
---|
| 1325 | + } |
---|
| 1326 | + } |
---|
| 1327 | + if (j == count) { |
---|
| 1328 | + dev_err(dmcfreq->dev, "failed to match dmc_opp_table for %ld\n", |
---|
| 1329 | + dmcfreq->freq_info_rate[i]); |
---|
| 1330 | + if (i == 0) { |
---|
| 1331 | + ret = -EPERM; |
---|
| 1332 | + goto out; |
---|
| 1333 | + } else { |
---|
| 1334 | + opp->available = false; |
---|
| 1335 | + dmcfreq->freq_count = i; |
---|
| 1336 | + } |
---|
| 1337 | + } |
---|
| 1338 | + i++; |
---|
| 1339 | + } |
---|
| 1340 | + |
---|
| 1341 | + mutex_unlock(&opp_table->lock); |
---|
| 1342 | + dev_pm_opp_put_opp_table(opp_table); |
---|
1274 | 1343 | |
---|
1275 | 1344 | out: |
---|
1276 | 1345 | kfree(freq_table); |
---|
.. | .. |
---|
1336 | 1405 | complt_irq_data = irq_get_irq_data(complt_irq); |
---|
1337 | 1406 | complt_hwirq = irqd_to_hwirq(complt_irq_data); |
---|
1338 | 1407 | ddr_psci_param->complt_hwirq = complt_hwirq; |
---|
| 1408 | + |
---|
| 1409 | + dmcfreq->set_rate_params = ddr_psci_param; |
---|
| 1410 | + rockchip_set_ddrclk_params(dmcfreq->set_rate_params); |
---|
| 1411 | + rockchip_set_ddrclk_dmcfreq_wait_complete(rockchip_dmcfreq_wait_complete); |
---|
1339 | 1412 | |
---|
1340 | 1413 | res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0, |
---|
1341 | 1414 | ROCKCHIP_SIP_CONFIG_DRAM_INIT); |
---|
.. | .. |
---|
1410 | 1483 | } |
---|
1411 | 1484 | disable_irq(complt_irq); |
---|
1412 | 1485 | |
---|
| 1486 | + dmcfreq->set_rate_params = ddr_psci_param; |
---|
| 1487 | + rockchip_set_ddrclk_params(dmcfreq->set_rate_params); |
---|
| 1488 | + rockchip_set_ddrclk_dmcfreq_wait_complete(rockchip_dmcfreq_wait_complete); |
---|
| 1489 | + |
---|
1413 | 1490 | res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0, |
---|
1414 | 1491 | ROCKCHIP_SIP_CONFIG_DRAM_INIT); |
---|
1415 | 1492 | if (res.a0) { |
---|
.. | .. |
---|
1427 | 1504 | struct rockchip_dmcfreq *dmcfreq) |
---|
1428 | 1505 | { |
---|
1429 | 1506 | struct arm_smccc_res res; |
---|
1430 | | - struct drm_device *drm = drm_device_get_by_name("rockchip"); |
---|
1431 | | - |
---|
1432 | | - if (!drm) { |
---|
1433 | | - dev_err(&pdev->dev, "Get drm_device fail\n"); |
---|
1434 | | - return -EPROBE_DEFER; |
---|
1435 | | - } |
---|
1436 | 1507 | |
---|
1437 | 1508 | res = sip_smc_request_share_mem(DIV_ROUND_UP(sizeof( |
---|
1438 | 1509 | struct rk3128_ddr_dts_config_timing), |
---|
.. | .. |
---|
1447 | 1518 | |
---|
1448 | 1519 | ddr_psci_param->hz = 0; |
---|
1449 | 1520 | ddr_psci_param->lcdc_type = rk_drm_get_lcdc_type(); |
---|
| 1521 | + |
---|
| 1522 | + dmcfreq->set_rate_params = ddr_psci_param; |
---|
| 1523 | + rockchip_set_ddrclk_params(dmcfreq->set_rate_params); |
---|
| 1524 | + |
---|
1450 | 1525 | res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0, |
---|
1451 | 1526 | ROCKCHIP_SIP_CONFIG_DRAM_INIT); |
---|
1452 | 1527 | |
---|
.. | .. |
---|
1480 | 1555 | return -ENOMEM; |
---|
1481 | 1556 | |
---|
1482 | 1557 | ddr_psci_param->hz = 0; |
---|
| 1558 | + |
---|
| 1559 | + dmcfreq->set_rate_params = ddr_psci_param; |
---|
| 1560 | + rockchip_set_ddrclk_params(dmcfreq->set_rate_params); |
---|
| 1561 | + |
---|
1483 | 1562 | res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0, |
---|
1484 | 1563 | ROCKCHIP_SIP_CONFIG_DRAM_INIT); |
---|
1485 | 1564 | |
---|
.. | .. |
---|
1500 | 1579 | struct device *dev = &pdev->dev; |
---|
1501 | 1580 | struct clk *pclk_phy, *pclk_upctl, *dmc_clk; |
---|
1502 | 1581 | struct arm_smccc_res res; |
---|
1503 | | - struct drm_device *drm = drm_device_get_by_name("rockchip"); |
---|
1504 | 1582 | int ret; |
---|
1505 | | - |
---|
1506 | | - if (!drm) { |
---|
1507 | | - dev_err(dev, "Get drm_device fail\n"); |
---|
1508 | | - return -EPROBE_DEFER; |
---|
1509 | | - } |
---|
1510 | 1583 | |
---|
1511 | 1584 | dmc_clk = devm_clk_get(dev, "dmc_clk"); |
---|
1512 | 1585 | if (IS_ERR(dmc_clk)) { |
---|
.. | .. |
---|
1575 | 1648 | |
---|
1576 | 1649 | ddr_psci_param->hz = 0; |
---|
1577 | 1650 | ddr_psci_param->lcdc_type = rk_drm_get_lcdc_type(); |
---|
| 1651 | + |
---|
| 1652 | + dmcfreq->set_rate_params = ddr_psci_param; |
---|
| 1653 | + rockchip_set_ddrclk_params(dmcfreq->set_rate_params); |
---|
| 1654 | + |
---|
1578 | 1655 | res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0, |
---|
1579 | 1656 | ROCKCHIP_SIP_CONFIG_DRAM_INIT); |
---|
1580 | 1657 | |
---|
.. | .. |
---|
1621 | 1698 | of_get_rk3328_timings(&pdev->dev, pdev->dev.of_node, |
---|
1622 | 1699 | (uint32_t *)ddr_psci_param); |
---|
1623 | 1700 | |
---|
| 1701 | + dmcfreq->set_rate_params = ddr_psci_param; |
---|
| 1702 | + rockchip_set_ddrclk_params(dmcfreq->set_rate_params); |
---|
| 1703 | + |
---|
1624 | 1704 | res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0, |
---|
1625 | 1705 | ROCKCHIP_SIP_CONFIG_DRAM_INIT); |
---|
1626 | 1706 | if (res.a0) { |
---|
.. | .. |
---|
1630 | 1710 | } |
---|
1631 | 1711 | |
---|
1632 | 1712 | dmcfreq->set_auto_self_refresh = rockchip_ddr_set_auto_self_refresh; |
---|
1633 | | - |
---|
1634 | | - return 0; |
---|
1635 | | -} |
---|
1636 | | - |
---|
1637 | | -static __maybe_unused int rk3368_dmc_init(struct platform_device *pdev, |
---|
1638 | | - struct rockchip_dmcfreq *dmcfreq) |
---|
1639 | | -{ |
---|
1640 | | - struct device *dev = &pdev->dev; |
---|
1641 | | - struct device_node *np = pdev->dev.of_node; |
---|
1642 | | - struct arm_smccc_res res; |
---|
1643 | | - struct rk3368_dram_timing *dram_timing; |
---|
1644 | | - struct clk *pclk_phy, *pclk_upctl; |
---|
1645 | | - struct drm_device *drm = drm_device_get_by_name("rockchip"); |
---|
1646 | | - int ret; |
---|
1647 | | - u32 dram_spd_bin; |
---|
1648 | | - u32 addr_mcu_el3; |
---|
1649 | | - u32 dclk_mode; |
---|
1650 | | - u32 lcdc_type; |
---|
1651 | | - |
---|
1652 | | - if (!drm) { |
---|
1653 | | - dev_err(dev, "Get drm_device fail\n"); |
---|
1654 | | - return -EPROBE_DEFER; |
---|
1655 | | - } |
---|
1656 | | - |
---|
1657 | | - pclk_phy = devm_clk_get(dev, "pclk_phy"); |
---|
1658 | | - if (IS_ERR(pclk_phy)) { |
---|
1659 | | - dev_err(dev, "Cannot get the clk pclk_phy\n"); |
---|
1660 | | - return PTR_ERR(pclk_phy); |
---|
1661 | | - } |
---|
1662 | | - ret = clk_prepare_enable(pclk_phy); |
---|
1663 | | - if (ret < 0) { |
---|
1664 | | - dev_err(dev, "failed to prepare/enable pclk_phy\n"); |
---|
1665 | | - return ret; |
---|
1666 | | - } |
---|
1667 | | - pclk_upctl = devm_clk_get(dev, "pclk_upctl"); |
---|
1668 | | - if (IS_ERR(pclk_upctl)) { |
---|
1669 | | - dev_err(dev, "Cannot get the clk pclk_upctl\n"); |
---|
1670 | | - return PTR_ERR(pclk_upctl); |
---|
1671 | | - } |
---|
1672 | | - ret = clk_prepare_enable(pclk_upctl); |
---|
1673 | | - if (ret < 0) { |
---|
1674 | | - dev_err(dev, "failed to prepare/enable pclk_upctl\n"); |
---|
1675 | | - return ret; |
---|
1676 | | - } |
---|
1677 | | - |
---|
1678 | | - /* |
---|
1679 | | - * Get dram timing and pass it to arm trust firmware, |
---|
1680 | | - * the dram drvier in arm trust firmware will get these |
---|
1681 | | - * timing and to do dram initial. |
---|
1682 | | - */ |
---|
1683 | | - dram_timing = of_get_rk3368_timings(dev, np); |
---|
1684 | | - if (dram_timing) { |
---|
1685 | | - dram_spd_bin = dram_timing->dram_spd_bin; |
---|
1686 | | - if (scpi_ddr_send_timing((u32 *)dram_timing, |
---|
1687 | | - sizeof(struct rk3368_dram_timing))) |
---|
1688 | | - dev_err(dev, "send ddr timing timeout\n"); |
---|
1689 | | - } else { |
---|
1690 | | - dev_err(dev, "get ddr timing from dts error\n"); |
---|
1691 | | - dram_spd_bin = DDR3_DEFAULT; |
---|
1692 | | - } |
---|
1693 | | - |
---|
1694 | | - res = sip_smc_mcu_el3fiq(FIQ_INIT_HANDLER, |
---|
1695 | | - FIQ_NUM_FOR_DCF, |
---|
1696 | | - FIQ_CPU_TGT_BOOT); |
---|
1697 | | - if ((res.a0) || (res.a1 == 0) || (res.a1 > 0x80000)) |
---|
1698 | | - dev_err(dev, "Trust version error, pls check trust version\n"); |
---|
1699 | | - addr_mcu_el3 = res.a1; |
---|
1700 | | - |
---|
1701 | | - if (of_property_read_u32(np, "vop-dclk-mode", &dclk_mode) == 0) |
---|
1702 | | - scpi_ddr_dclk_mode(dclk_mode); |
---|
1703 | | - |
---|
1704 | | - lcdc_type = rk_drm_get_lcdc_type(); |
---|
1705 | | - |
---|
1706 | | - if (scpi_ddr_init(dram_spd_bin, 0, lcdc_type, |
---|
1707 | | - addr_mcu_el3)) |
---|
1708 | | - dev_err(dev, "ddr init error\n"); |
---|
1709 | | - else |
---|
1710 | | - dev_dbg(dev, ("%s out\n"), __func__); |
---|
1711 | | - |
---|
1712 | | - dmcfreq->set_auto_self_refresh = scpi_ddr_set_auto_self_refresh; |
---|
1713 | 1713 | |
---|
1714 | 1714 | return 0; |
---|
1715 | 1715 | } |
---|
.. | .. |
---|
1756 | 1756 | } |
---|
1757 | 1757 | } |
---|
1758 | 1758 | |
---|
| 1759 | + dmcfreq->set_rate_params = |
---|
| 1760 | + devm_kzalloc(dev, sizeof(struct share_params), GFP_KERNEL); |
---|
| 1761 | + if (!dmcfreq->set_rate_params) |
---|
| 1762 | + return -ENOMEM; |
---|
| 1763 | + rockchip_set_ddrclk_params(dmcfreq->set_rate_params); |
---|
| 1764 | + |
---|
1759 | 1765 | arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0, |
---|
1760 | 1766 | ROCKCHIP_SIP_CONFIG_DRAM_INIT, |
---|
1761 | 1767 | 0, 0, 0, 0, &res); |
---|
1762 | 1768 | |
---|
1763 | | - dmcfreq->set_msch_readlatency = rk3399_set_msch_readlatency; |
---|
| 1769 | + dmcfreq->info.set_msch_readlatency = rk3399_set_msch_readlatency; |
---|
| 1770 | + |
---|
| 1771 | + return 0; |
---|
| 1772 | +} |
---|
| 1773 | + |
---|
| 1774 | +static __maybe_unused int rk3528_dmc_init(struct platform_device *pdev, |
---|
| 1775 | + struct rockchip_dmcfreq *dmcfreq) |
---|
| 1776 | +{ |
---|
| 1777 | + struct arm_smccc_res res; |
---|
| 1778 | + int ret; |
---|
| 1779 | + int complt_irq; |
---|
| 1780 | + u32 complt_hwirq; |
---|
| 1781 | + struct irq_data *complt_irq_data; |
---|
| 1782 | + |
---|
| 1783 | + res = sip_smc_dram(0, 0, ROCKCHIP_SIP_CONFIG_DRAM_GET_VERSION); |
---|
| 1784 | + dev_notice(&pdev->dev, "current ATF version 0x%lx\n", res.a1); |
---|
| 1785 | + if (res.a0 || res.a1 < 0x100) { |
---|
| 1786 | + dev_err(&pdev->dev, "trusted firmware need update to V1.00 and above.\n"); |
---|
| 1787 | + return -ENXIO; |
---|
| 1788 | + } |
---|
| 1789 | + |
---|
| 1790 | + /* |
---|
| 1791 | + * first 4KB is used for interface parameters |
---|
| 1792 | + * after 4KB is dts parameters |
---|
| 1793 | + * request share memory size 4KB * 2 |
---|
| 1794 | + */ |
---|
| 1795 | + res = sip_smc_request_share_mem(2, SHARE_PAGE_TYPE_DDR); |
---|
| 1796 | + if (res.a0 != 0) { |
---|
| 1797 | + dev_err(&pdev->dev, "no ATF memory for init\n"); |
---|
| 1798 | + return -ENOMEM; |
---|
| 1799 | + } |
---|
| 1800 | + ddr_psci_param = (struct share_params *)res.a1; |
---|
| 1801 | + /* Clear ddr_psci_param, size is 4KB * 2 */ |
---|
| 1802 | + memset_io(ddr_psci_param, 0x0, 4096 * 2); |
---|
| 1803 | + |
---|
| 1804 | + wait_ctrl.dcf_en = 0; |
---|
| 1805 | + |
---|
| 1806 | + init_waitqueue_head(&wait_ctrl.wait_wq); |
---|
| 1807 | + wait_ctrl.wait_en = 1; |
---|
| 1808 | + wait_ctrl.wait_time_out_ms = 17 * 5; |
---|
| 1809 | + |
---|
| 1810 | + complt_irq = platform_get_irq_byname(pdev, "complete"); |
---|
| 1811 | + if (complt_irq < 0) { |
---|
| 1812 | + dev_err(&pdev->dev, "no IRQ for complt_irq: %d\n", complt_irq); |
---|
| 1813 | + return complt_irq; |
---|
| 1814 | + } |
---|
| 1815 | + wait_ctrl.complt_irq = complt_irq; |
---|
| 1816 | + |
---|
| 1817 | + ret = devm_request_irq(&pdev->dev, complt_irq, wait_dcf_complete_irq, |
---|
| 1818 | + 0, dev_name(&pdev->dev), &wait_ctrl); |
---|
| 1819 | + if (ret < 0) { |
---|
| 1820 | + dev_err(&pdev->dev, "cannot request complt_irq\n"); |
---|
| 1821 | + return ret; |
---|
| 1822 | + } |
---|
| 1823 | + disable_irq(complt_irq); |
---|
| 1824 | + |
---|
| 1825 | + complt_irq_data = irq_get_irq_data(complt_irq); |
---|
| 1826 | + complt_hwirq = irqd_to_hwirq(complt_irq_data); |
---|
| 1827 | + ddr_psci_param->complt_hwirq = complt_hwirq; |
---|
| 1828 | + |
---|
| 1829 | + res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0, ROCKCHIP_SIP_CONFIG_DRAM_INIT); |
---|
| 1830 | + if (res.a0) { |
---|
| 1831 | + dev_err(&pdev->dev, "rockchip_sip_config_dram_init error:%lx\n", res.a0); |
---|
| 1832 | + return -ENOMEM; |
---|
| 1833 | + } |
---|
| 1834 | + |
---|
| 1835 | + ret = rockchip_get_freq_info(dmcfreq); |
---|
| 1836 | + if (ret < 0) { |
---|
| 1837 | + dev_err(&pdev->dev, "cannot get frequency info\n"); |
---|
| 1838 | + return ret; |
---|
| 1839 | + } |
---|
| 1840 | + dmcfreq->is_set_rate_direct = true; |
---|
| 1841 | + |
---|
| 1842 | + dmcfreq->set_auto_self_refresh = rockchip_ddr_set_auto_self_refresh; |
---|
1764 | 1843 | |
---|
1765 | 1844 | return 0; |
---|
1766 | 1845 | } |
---|
.. | .. |
---|
1837 | 1916 | return 0; |
---|
1838 | 1917 | } |
---|
1839 | 1918 | |
---|
| 1919 | +static __maybe_unused int rk3588_dmc_init(struct platform_device *pdev, |
---|
| 1920 | + struct rockchip_dmcfreq *dmcfreq) |
---|
| 1921 | +{ |
---|
| 1922 | + struct arm_smccc_res res; |
---|
| 1923 | + struct dev_pm_opp *opp; |
---|
| 1924 | + unsigned long opp_rate; |
---|
| 1925 | + int ret; |
---|
| 1926 | + int complt_irq; |
---|
| 1927 | + |
---|
| 1928 | + res = sip_smc_dram(0, 0, ROCKCHIP_SIP_CONFIG_DRAM_GET_VERSION); |
---|
| 1929 | + dev_notice(&pdev->dev, "current ATF version 0x%lx\n", res.a1); |
---|
| 1930 | + if (res.a0) { |
---|
| 1931 | + dev_err(&pdev->dev, "trusted firmware unsupported, please update.\n"); |
---|
| 1932 | + return -ENXIO; |
---|
| 1933 | + } |
---|
| 1934 | + |
---|
| 1935 | + /* |
---|
| 1936 | + * first 4KB is used for interface parameters |
---|
| 1937 | + * after 4KB is dts parameters |
---|
| 1938 | + * request share memory size 4KB * 2 |
---|
| 1939 | + */ |
---|
| 1940 | + res = sip_smc_request_share_mem(2, SHARE_PAGE_TYPE_DDR); |
---|
| 1941 | + if (res.a0 != 0) { |
---|
| 1942 | + dev_err(&pdev->dev, "no ATF memory for init\n"); |
---|
| 1943 | + return -ENOMEM; |
---|
| 1944 | + } |
---|
| 1945 | + ddr_psci_param = (struct share_params *)res.a1; |
---|
| 1946 | + /* Clear ddr_psci_param, size is 4KB * 2 */ |
---|
| 1947 | + memset_io(ddr_psci_param, 0x0, 4096 * 2); |
---|
| 1948 | + |
---|
| 1949 | + /* start mcu with sip_smc_dram */ |
---|
| 1950 | + wait_ctrl.dcf_en = 2; |
---|
| 1951 | + |
---|
| 1952 | + init_waitqueue_head(&wait_ctrl.wait_wq); |
---|
| 1953 | + wait_ctrl.wait_en = 1; |
---|
| 1954 | + wait_ctrl.wait_time_out_ms = 17 * 5; |
---|
| 1955 | + |
---|
| 1956 | + complt_irq = platform_get_irq_byname(pdev, "complete"); |
---|
| 1957 | + if (complt_irq < 0) { |
---|
| 1958 | + dev_err(&pdev->dev, "no IRQ for complt_irq: %d\n", complt_irq); |
---|
| 1959 | + return complt_irq; |
---|
| 1960 | + } |
---|
| 1961 | + wait_ctrl.complt_irq = complt_irq; |
---|
| 1962 | + |
---|
| 1963 | + ret = devm_request_irq(&pdev->dev, complt_irq, wait_dcf_complete_irq, |
---|
| 1964 | + 0, dev_name(&pdev->dev), &wait_ctrl); |
---|
| 1965 | + if (ret < 0) { |
---|
| 1966 | + dev_err(&pdev->dev, "cannot request complt_irq\n"); |
---|
| 1967 | + return ret; |
---|
| 1968 | + } |
---|
| 1969 | + disable_irq(complt_irq); |
---|
| 1970 | + |
---|
| 1971 | + res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0, ROCKCHIP_SIP_CONFIG_DRAM_INIT); |
---|
| 1972 | + if (res.a0) { |
---|
| 1973 | + dev_err(&pdev->dev, "rockchip_sip_config_dram_init error:%lx\n", res.a0); |
---|
| 1974 | + return -ENOMEM; |
---|
| 1975 | + } |
---|
| 1976 | + |
---|
| 1977 | + ret = rockchip_dmcfreq_adjust_opp_table(dmcfreq); |
---|
| 1978 | + if (ret < 0) { |
---|
| 1979 | + dev_err(&pdev->dev, "cannot get frequency info\n"); |
---|
| 1980 | + return ret; |
---|
| 1981 | + } |
---|
| 1982 | + dmcfreq->is_set_rate_direct = true; |
---|
| 1983 | + |
---|
| 1984 | + /* Config the dmcfreq->sleep_volt for deepsleep */ |
---|
| 1985 | + opp_rate = dmcfreq->freq_info_rate[dmcfreq->freq_count - 1]; |
---|
| 1986 | + opp = devfreq_recommended_opp(&pdev->dev, &opp_rate, 0); |
---|
| 1987 | + if (IS_ERR(opp)) { |
---|
| 1988 | + dev_err(&pdev->dev, "Failed to find opp for %lu Hz\n", opp_rate); |
---|
| 1989 | + return PTR_ERR(opp); |
---|
| 1990 | + } |
---|
| 1991 | + dmcfreq->sleep_volt = opp->supplies[0].u_volt; |
---|
| 1992 | + if (dmcfreq->regulator_count > 1) |
---|
| 1993 | + dmcfreq->sleep_mem_volt = opp->supplies[1].u_volt; |
---|
| 1994 | + dev_pm_opp_put(opp); |
---|
| 1995 | + |
---|
| 1996 | + if (of_property_read_u32(pdev->dev.of_node, "wait-mode", &ddr_psci_param->wait_mode)) |
---|
| 1997 | + ddr_psci_param->wait_mode = 0; |
---|
| 1998 | + |
---|
| 1999 | + dmcfreq->set_auto_self_refresh = rockchip_ddr_set_auto_self_refresh; |
---|
| 2000 | + |
---|
| 2001 | + return 0; |
---|
| 2002 | +} |
---|
| 2003 | + |
---|
1840 | 2004 | static __maybe_unused int rv1126_dmc_init(struct platform_device *pdev, |
---|
1841 | 2005 | struct rockchip_dmcfreq *dmcfreq) |
---|
1842 | 2006 | { |
---|
.. | .. |
---|
1905 | 2069 | &ddr_psci_param->update_deskew_cfg)) |
---|
1906 | 2070 | ddr_psci_param->update_deskew_cfg = 0; |
---|
1907 | 2071 | |
---|
| 2072 | + dmcfreq->set_rate_params = ddr_psci_param; |
---|
| 2073 | + rockchip_set_ddrclk_params(dmcfreq->set_rate_params); |
---|
| 2074 | + rockchip_set_ddrclk_dmcfreq_wait_complete(rockchip_dmcfreq_wait_complete); |
---|
| 2075 | + |
---|
1908 | 2076 | res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0, |
---|
1909 | 2077 | ROCKCHIP_SIP_CONFIG_DRAM_INIT); |
---|
1910 | 2078 | if (res.a0) { |
---|
.. | .. |
---|
1919 | 2087 | } |
---|
1920 | 2088 | |
---|
1921 | 2089 | static const struct of_device_id rockchip_dmcfreq_of_match[] = { |
---|
1922 | | -#ifdef CONFIG_CPU_PX30 |
---|
| 2090 | +#if IS_ENABLED(CONFIG_CPU_PX30) |
---|
1923 | 2091 | { .compatible = "rockchip,px30-dmc", .data = px30_dmc_init }, |
---|
1924 | 2092 | #endif |
---|
1925 | | -#ifdef CONFIG_CPU_RK1808 |
---|
| 2093 | +#if IS_ENABLED(CONFIG_CPU_RK1808) |
---|
1926 | 2094 | { .compatible = "rockchip,rk1808-dmc", .data = rk1808_dmc_init }, |
---|
1927 | 2095 | #endif |
---|
1928 | | -#ifdef CONFIG_CPU_RK312X |
---|
| 2096 | +#if IS_ENABLED(CONFIG_CPU_RK312X) |
---|
1929 | 2097 | { .compatible = "rockchip,rk3128-dmc", .data = rk3128_dmc_init }, |
---|
1930 | 2098 | #endif |
---|
1931 | | -#ifdef CONFIG_CPU_RK322X |
---|
| 2099 | +#if IS_ENABLED(CONFIG_CPU_RK322X) |
---|
1932 | 2100 | { .compatible = "rockchip,rk3228-dmc", .data = rk3228_dmc_init }, |
---|
1933 | 2101 | #endif |
---|
1934 | | -#ifdef CONFIG_CPU_RK3288 |
---|
| 2102 | +#if IS_ENABLED(CONFIG_CPU_RK3288) |
---|
1935 | 2103 | { .compatible = "rockchip,rk3288-dmc", .data = rk3288_dmc_init }, |
---|
1936 | 2104 | #endif |
---|
1937 | | -#ifdef CONFIG_CPU_RK3308 |
---|
| 2105 | +#if IS_ENABLED(CONFIG_CPU_RK3308) |
---|
1938 | 2106 | { .compatible = "rockchip,rk3308-dmc", .data = NULL }, |
---|
1939 | 2107 | #endif |
---|
1940 | | -#ifdef CONFIG_CPU_RK3328 |
---|
| 2108 | +#if IS_ENABLED(CONFIG_CPU_RK3328) |
---|
1941 | 2109 | { .compatible = "rockchip,rk3328-dmc", .data = rk3328_dmc_init }, |
---|
1942 | 2110 | #endif |
---|
1943 | | -#ifdef CONFIG_CPU_RK3368 |
---|
1944 | | - { .compatible = "rockchip,rk3368-dmc", .data = rk3368_dmc_init }, |
---|
1945 | | -#endif |
---|
1946 | | -#ifdef CONFIG_CPU_RK3399 |
---|
| 2111 | +#if IS_ENABLED(CONFIG_CPU_RK3399) |
---|
1947 | 2112 | { .compatible = "rockchip,rk3399-dmc", .data = rk3399_dmc_init }, |
---|
1948 | 2113 | #endif |
---|
1949 | | -#ifdef CONFIG_CPU_RK3568 |
---|
| 2114 | +#if IS_ENABLED(CONFIG_CPU_RK3528) |
---|
| 2115 | + { .compatible = "rockchip,rk3528-dmc", .data = rk3528_dmc_init }, |
---|
| 2116 | +#endif |
---|
| 2117 | +#if IS_ENABLED(CONFIG_CPU_RK3562) |
---|
| 2118 | + { .compatible = "rockchip,rk3562-dmc", .data = rk3568_dmc_init }, |
---|
| 2119 | +#endif |
---|
| 2120 | +#if IS_ENABLED(CONFIG_CPU_RK3568) |
---|
1950 | 2121 | { .compatible = "rockchip,rk3568-dmc", .data = rk3568_dmc_init }, |
---|
1951 | 2122 | #endif |
---|
1952 | | -#ifdef CONFIG_CPU_RV1126 |
---|
| 2123 | +#if IS_ENABLED(CONFIG_CPU_RK3588) |
---|
| 2124 | + { .compatible = "rockchip,rk3588-dmc", .data = rk3588_dmc_init }, |
---|
| 2125 | +#endif |
---|
| 2126 | +#if IS_ENABLED(CONFIG_CPU_RV1126) |
---|
1953 | 2127 | { .compatible = "rockchip,rv1126-dmc", .data = rv1126_dmc_init }, |
---|
1954 | 2128 | #endif |
---|
1955 | 2129 | { }, |
---|
.. | .. |
---|
1993 | 2167 | |
---|
1994 | 2168 | tbl[i].min = 0; |
---|
1995 | 2169 | tbl[i].max = 0; |
---|
1996 | | - tbl[i].freq = CPUFREQ_TABLE_END; |
---|
| 2170 | + tbl[i].freq = DMCFREQ_TABLE_END; |
---|
1997 | 2171 | |
---|
1998 | 2172 | *table = tbl; |
---|
1999 | 2173 | |
---|
.. | .. |
---|
2032 | 2206 | } |
---|
2033 | 2207 | |
---|
2034 | 2208 | tbl[i].pn = 0; |
---|
2035 | | - tbl[i].rl = CPUFREQ_TABLE_END; |
---|
| 2209 | + tbl[i].rl = DMCFREQ_TABLE_END; |
---|
2036 | 2210 | |
---|
2037 | 2211 | *table = tbl; |
---|
2038 | 2212 | |
---|
.. | .. |
---|
2083 | 2257 | case SYS_STATUS_VIDEO_4K_10B: |
---|
2084 | 2258 | dmcfreq->video_4k_10b_rate = freq * 1000; |
---|
2085 | 2259 | break; |
---|
| 2260 | + case SYS_STATUS_VIDEO_SVEP: |
---|
| 2261 | + dmcfreq->video_svep_rate = freq * 1000; |
---|
| 2262 | + break; |
---|
2086 | 2263 | case SYS_STATUS_PERFORMANCE: |
---|
2087 | 2264 | dmcfreq->performance_rate = freq * 1000; |
---|
2088 | 2265 | break; |
---|
2089 | 2266 | case SYS_STATUS_HDMI: |
---|
2090 | 2267 | dmcfreq->hdmi_rate = freq * 1000; |
---|
| 2268 | + break; |
---|
| 2269 | + case SYS_STATUS_HDMIRX: |
---|
| 2270 | + dmcfreq->hdmirx_rate = freq * 1000; |
---|
2091 | 2271 | break; |
---|
2092 | 2272 | case SYS_STATUS_IDLE: |
---|
2093 | 2273 | dmcfreq->idle_rate = freq * 1000; |
---|
.. | .. |
---|
2194 | 2374 | return -EINVAL; |
---|
2195 | 2375 | } |
---|
2196 | 2376 | |
---|
| 2377 | + dmcfreq->auto_min_rate = dmcfreq->rate_low; |
---|
| 2378 | + |
---|
2197 | 2379 | for (i = 0; i < count / 2; i++) { |
---|
2198 | 2380 | of_property_read_u32_index(np, porp_name, 2 * i, |
---|
2199 | 2381 | &status); |
---|
.. | .. |
---|
2222 | 2404 | dev_info(dmcfreq->dev, "video_4k_10b_rate = %ld\n", |
---|
2223 | 2405 | dmcfreq->video_4k_10b_rate); |
---|
2224 | 2406 | break; |
---|
| 2407 | + case SYS_STATUS_VIDEO_4K_60P: |
---|
| 2408 | + dmcfreq->video_4k_60p_rate = rockchip_freq_level_2_rate(dmcfreq, level); |
---|
| 2409 | + dev_info(dmcfreq->dev, "video_4k_60p_rate = %ld\n", |
---|
| 2410 | + dmcfreq->video_4k_60p_rate); |
---|
| 2411 | + break; |
---|
| 2412 | + case SYS_STATUS_VIDEO_SVEP: |
---|
| 2413 | + dmcfreq->video_svep_rate = rockchip_freq_level_2_rate(dmcfreq, level); |
---|
| 2414 | + dev_info(dmcfreq->dev, "video_svep_rate = %ld\n", |
---|
| 2415 | + dmcfreq->video_svep_rate); |
---|
| 2416 | + break; |
---|
2225 | 2417 | case SYS_STATUS_PERFORMANCE: |
---|
2226 | 2418 | dmcfreq->performance_rate = rockchip_freq_level_2_rate(dmcfreq, level); |
---|
2227 | 2419 | dev_info(dmcfreq->dev, "performance_rate = %ld\n", |
---|
.. | .. |
---|
2230 | 2422 | case SYS_STATUS_HDMI: |
---|
2231 | 2423 | dmcfreq->hdmi_rate = rockchip_freq_level_2_rate(dmcfreq, level); |
---|
2232 | 2424 | dev_info(dmcfreq->dev, "hdmi_rate = %ld\n", dmcfreq->hdmi_rate); |
---|
| 2425 | + break; |
---|
| 2426 | + case SYS_STATUS_HDMIRX: |
---|
| 2427 | + dmcfreq->hdmirx_rate = rockchip_freq_level_2_rate(dmcfreq, level); |
---|
| 2428 | + dev_info(dmcfreq->dev, "hdmirx_rate = %ld\n", dmcfreq->hdmirx_rate); |
---|
2233 | 2429 | break; |
---|
2234 | 2430 | case SYS_STATUS_IDLE: |
---|
2235 | 2431 | dmcfreq->idle_rate = rockchip_freq_level_2_rate(dmcfreq, level); |
---|
.. | .. |
---|
2269 | 2465 | |
---|
2270 | 2466 | static void rockchip_dmcfreq_update_target(struct rockchip_dmcfreq *dmcfreq) |
---|
2271 | 2467 | { |
---|
2272 | | - struct devfreq *df = dmcfreq->devfreq; |
---|
| 2468 | + struct devfreq *devfreq = dmcfreq->info.devfreq; |
---|
2273 | 2469 | |
---|
2274 | | - mutex_lock(&df->lock); |
---|
2275 | | - |
---|
2276 | | - if (dmcfreq->last_refresh != dmcfreq->refresh) { |
---|
2277 | | - if (dmcfreq->set_auto_self_refresh) |
---|
2278 | | - dmcfreq->set_auto_self_refresh(dmcfreq->refresh); |
---|
2279 | | - dmcfreq->last_refresh = dmcfreq->refresh; |
---|
2280 | | - } |
---|
2281 | | - |
---|
2282 | | - update_devfreq(df); |
---|
2283 | | - |
---|
2284 | | - mutex_unlock(&df->lock); |
---|
| 2470 | + mutex_lock(&devfreq->lock); |
---|
| 2471 | + update_devfreq(devfreq); |
---|
| 2472 | + mutex_unlock(&devfreq->lock); |
---|
2285 | 2473 | } |
---|
2286 | 2474 | |
---|
2287 | 2475 | static int rockchip_dmcfreq_system_status_notifier(struct notifier_block *nb, |
---|
.. | .. |
---|
2302 | 2490 | } |
---|
2303 | 2491 | |
---|
2304 | 2492 | if (dmcfreq->reboot_rate && (status & SYS_STATUS_REBOOT)) { |
---|
2305 | | - if (dmcfreq->auto_freq_en) |
---|
2306 | | - devfreq_monitor_stop(dmcfreq->devfreq); |
---|
| 2493 | + if (dmcfreq->info.auto_freq_en) |
---|
| 2494 | + devfreq_monitor_stop(dmcfreq->info.devfreq); |
---|
2307 | 2495 | target_rate = dmcfreq->reboot_rate; |
---|
2308 | 2496 | goto next; |
---|
2309 | 2497 | } |
---|
.. | .. |
---|
2329 | 2517 | target_rate = dmcfreq->hdmi_rate; |
---|
2330 | 2518 | } |
---|
2331 | 2519 | |
---|
| 2520 | + if (dmcfreq->hdmirx_rate && (status & SYS_STATUS_HDMIRX)) { |
---|
| 2521 | + if (dmcfreq->hdmirx_rate > target_rate) |
---|
| 2522 | + target_rate = dmcfreq->hdmirx_rate; |
---|
| 2523 | + } |
---|
| 2524 | + |
---|
2332 | 2525 | if (dmcfreq->video_4k_rate && (status & SYS_STATUS_VIDEO_4K)) { |
---|
2333 | 2526 | if (dmcfreq->video_4k_rate > target_rate) |
---|
2334 | 2527 | target_rate = dmcfreq->video_4k_rate; |
---|
.. | .. |
---|
2339 | 2532 | target_rate = dmcfreq->video_4k_10b_rate; |
---|
2340 | 2533 | } |
---|
2341 | 2534 | |
---|
| 2535 | + if (dmcfreq->video_4k_60p_rate && (status & SYS_STATUS_VIDEO_4K_60P)) { |
---|
| 2536 | + if (dmcfreq->video_4k_60p_rate > target_rate) |
---|
| 2537 | + target_rate = dmcfreq->video_4k_60p_rate; |
---|
| 2538 | + } |
---|
| 2539 | + |
---|
2342 | 2540 | if (dmcfreq->video_1080p_rate && (status & SYS_STATUS_VIDEO_1080P)) { |
---|
2343 | 2541 | if (dmcfreq->video_1080p_rate > target_rate) |
---|
2344 | 2542 | target_rate = dmcfreq->video_1080p_rate; |
---|
2345 | 2543 | } |
---|
2346 | 2544 | |
---|
| 2545 | + if (dmcfreq->video_svep_rate && (status & SYS_STATUS_VIDEO_SVEP)) { |
---|
| 2546 | + if (dmcfreq->video_svep_rate > target_rate) |
---|
| 2547 | + target_rate = dmcfreq->video_svep_rate; |
---|
| 2548 | + } |
---|
| 2549 | + |
---|
2347 | 2550 | next: |
---|
2348 | 2551 | |
---|
2349 | | - dev_dbg(&dmcfreq->devfreq->dev, "status=0x%x\n", (unsigned int)status); |
---|
2350 | | - dmcfreq->refresh = refresh; |
---|
| 2552 | + dev_dbg(dmcfreq->dev, "status=0x%x\n", (unsigned int)status); |
---|
2351 | 2553 | dmcfreq->is_fixed = is_fixed; |
---|
2352 | 2554 | dmcfreq->status_rate = target_rate; |
---|
| 2555 | + if (dmcfreq->refresh != refresh) { |
---|
| 2556 | + if (dmcfreq->set_auto_self_refresh) |
---|
| 2557 | + dmcfreq->set_auto_self_refresh(refresh); |
---|
| 2558 | + dmcfreq->refresh = refresh; |
---|
| 2559 | + } |
---|
2353 | 2560 | rockchip_dmcfreq_update_target(dmcfreq); |
---|
2354 | 2561 | |
---|
2355 | 2562 | return NOTIFY_OK; |
---|
| 2563 | +} |
---|
| 2564 | + |
---|
| 2565 | +static int rockchip_dmcfreq_panic_notifier(struct notifier_block *nb, |
---|
| 2566 | + unsigned long v, void *p) |
---|
| 2567 | +{ |
---|
| 2568 | + struct rockchip_dmcfreq *dmcfreq = |
---|
| 2569 | + container_of(nb, struct rockchip_dmcfreq, panic_nb); |
---|
| 2570 | + struct device *dev = dmcfreq->dev; |
---|
| 2571 | + |
---|
| 2572 | + if (dmcfreq->regulator_count == 1) |
---|
| 2573 | + dev_info(dev, "cur_freq: %lu Hz, volt: %lu uV\n", |
---|
| 2574 | + dmcfreq->rate, dmcfreq->volt); |
---|
| 2575 | + else |
---|
| 2576 | + dev_info(dev, "cur_freq: %lu Hz, volt_vdd: %lu uV, volt_mem: %lu uV\n", |
---|
| 2577 | + dmcfreq->rate, dmcfreq->volt, dmcfreq->mem_volt); |
---|
| 2578 | + |
---|
| 2579 | + return 0; |
---|
2356 | 2580 | } |
---|
2357 | 2581 | |
---|
2358 | 2582 | static ssize_t rockchip_dmcfreq_status_show(struct device *dev, |
---|
.. | .. |
---|
2438 | 2662 | |
---|
2439 | 2663 | static DEVICE_ATTR_RW(downdifferential); |
---|
2440 | 2664 | |
---|
2441 | | -static void rockchip_dmcfreq_set_msch_rl(struct rockchip_dmcfreq *dmcfreq, |
---|
2442 | | - unsigned int readlatency) |
---|
2443 | | - |
---|
2444 | | -{ |
---|
2445 | | - down_read(&rockchip_dmcfreq_sem); |
---|
2446 | | - dev_dbg(dmcfreq->dev, "rl 0x%x -> 0x%x\n", |
---|
2447 | | - dmcfreq->read_latency, readlatency); |
---|
2448 | | - if (!dmcfreq->set_msch_readlatency(readlatency)) |
---|
2449 | | - dmcfreq->read_latency = readlatency; |
---|
2450 | | - else |
---|
2451 | | - dev_err(dmcfreq->dev, "failed to set msch rl\n"); |
---|
2452 | | - up_read(&rockchip_dmcfreq_sem); |
---|
2453 | | -} |
---|
2454 | | - |
---|
2455 | | -static void rockchip_dmcfreq_set_msch_rl_work(struct work_struct *work) |
---|
2456 | | -{ |
---|
2457 | | - struct rockchip_dmcfreq *dmcfreq = msch_rl_to_dmcfreq(work); |
---|
2458 | | - |
---|
2459 | | - rockchip_dmcfreq_set_msch_rl(dmcfreq, 0); |
---|
2460 | | - dmcfreq->is_msch_rl_work_started = false; |
---|
2461 | | -} |
---|
2462 | | - |
---|
2463 | | -static void rockchip_dmcfreq_msch_rl_init(struct rockchip_dmcfreq *dmcfreq) |
---|
2464 | | -{ |
---|
2465 | | - if (!dmcfreq->set_msch_readlatency) |
---|
2466 | | - return; |
---|
2467 | | - INIT_DELAYED_WORK(&dmcfreq->msch_rl_work, |
---|
2468 | | - rockchip_dmcfreq_set_msch_rl_work); |
---|
2469 | | -} |
---|
2470 | | - |
---|
2471 | | -void rockchip_dmcfreq_vop_bandwidth_update(struct devfreq *devfreq, |
---|
2472 | | - unsigned int line_bw_mbyte, |
---|
2473 | | - unsigned int frame_bw_mbyte, |
---|
2474 | | - unsigned int plane_num) |
---|
2475 | | -{ |
---|
2476 | | - struct device *dev; |
---|
2477 | | - struct rockchip_dmcfreq *dmcfreq; |
---|
2478 | | - unsigned long vop_last_rate, target = 0; |
---|
2479 | | - unsigned int readlatency = 0; |
---|
2480 | | - int i; |
---|
2481 | | - |
---|
2482 | | - if (!devfreq) |
---|
2483 | | - return; |
---|
2484 | | - |
---|
2485 | | - dev = devfreq->dev.parent; |
---|
2486 | | - dmcfreq = dev_get_drvdata(dev); |
---|
2487 | | - if (!dmcfreq) |
---|
2488 | | - return; |
---|
2489 | | - |
---|
2490 | | - dev_dbg(dmcfreq->dev, "line bw=%u, frame bw=%u, pn=%u\n", |
---|
2491 | | - line_bw_mbyte, frame_bw_mbyte, plane_num); |
---|
2492 | | - |
---|
2493 | | - if (!dmcfreq->vop_pn_rl_tbl || !dmcfreq->set_msch_readlatency) |
---|
2494 | | - goto vop_bw_tbl; |
---|
2495 | | - for (i = 0; dmcfreq->vop_pn_rl_tbl[i].rl != CPUFREQ_TABLE_END; i++) { |
---|
2496 | | - if (plane_num >= dmcfreq->vop_pn_rl_tbl[i].pn) |
---|
2497 | | - readlatency = dmcfreq->vop_pn_rl_tbl[i].rl; |
---|
2498 | | - } |
---|
2499 | | - if (readlatency) { |
---|
2500 | | - cancel_delayed_work_sync(&dmcfreq->msch_rl_work); |
---|
2501 | | - dmcfreq->is_msch_rl_work_started = false; |
---|
2502 | | - if (dmcfreq->read_latency != readlatency) |
---|
2503 | | - rockchip_dmcfreq_set_msch_rl(dmcfreq, readlatency); |
---|
2504 | | - } else if (dmcfreq->read_latency && |
---|
2505 | | - !dmcfreq->is_msch_rl_work_started) { |
---|
2506 | | - dmcfreq->is_msch_rl_work_started = true; |
---|
2507 | | - schedule_delayed_work(&dmcfreq->msch_rl_work, |
---|
2508 | | - msecs_to_jiffies(MSCH_RL_DELAY_TIME)); |
---|
2509 | | - } |
---|
2510 | | - |
---|
2511 | | -vop_bw_tbl: |
---|
2512 | | - if (!dmcfreq->auto_freq_en || !dmcfreq->vop_bw_tbl) |
---|
2513 | | - goto vop_frame_bw_tbl; |
---|
2514 | | - for (i = 0; dmcfreq->vop_bw_tbl[i].freq != CPUFREQ_TABLE_END; i++) { |
---|
2515 | | - if (line_bw_mbyte >= dmcfreq->vop_bw_tbl[i].min) |
---|
2516 | | - target = dmcfreq->vop_bw_tbl[i].freq; |
---|
2517 | | - } |
---|
2518 | | - |
---|
2519 | | -vop_frame_bw_tbl: |
---|
2520 | | - if (!dmcfreq->auto_freq_en || !dmcfreq->vop_frame_bw_tbl) |
---|
2521 | | - goto next; |
---|
2522 | | - for (i = 0; dmcfreq->vop_frame_bw_tbl[i].freq != CPUFREQ_TABLE_END; |
---|
2523 | | - i++) { |
---|
2524 | | - if (frame_bw_mbyte >= dmcfreq->vop_frame_bw_tbl[i].min) { |
---|
2525 | | - if (target < dmcfreq->vop_frame_bw_tbl[i].freq) |
---|
2526 | | - target = dmcfreq->vop_frame_bw_tbl[i].freq; |
---|
2527 | | - } |
---|
2528 | | - } |
---|
2529 | | - |
---|
2530 | | -next: |
---|
2531 | | - vop_last_rate = dmcfreq->vop_req_rate; |
---|
2532 | | - dmcfreq->vop_req_rate = target; |
---|
2533 | | - if (target > vop_last_rate) |
---|
2534 | | - rockchip_dmcfreq_update_target(dmcfreq); |
---|
2535 | | -} |
---|
2536 | | -EXPORT_SYMBOL(rockchip_dmcfreq_vop_bandwidth_update); |
---|
2537 | | - |
---|
2538 | | -int rockchip_dmcfreq_vop_bandwidth_request(struct devfreq *devfreq, |
---|
2539 | | - unsigned int bw_mbyte) |
---|
2540 | | -{ |
---|
2541 | | - struct device *dev; |
---|
2542 | | - struct rockchip_dmcfreq *dmcfreq; |
---|
2543 | | - unsigned long target = 0; |
---|
2544 | | - int i; |
---|
2545 | | - |
---|
2546 | | - if (!devfreq) |
---|
2547 | | - return 0; |
---|
2548 | | - |
---|
2549 | | - dev = devfreq->dev.parent; |
---|
2550 | | - dmcfreq = dev_get_drvdata(dev); |
---|
2551 | | - |
---|
2552 | | - if (!dmcfreq || !dmcfreq->auto_freq_en || !dmcfreq->vop_bw_tbl) |
---|
2553 | | - return 0; |
---|
2554 | | - |
---|
2555 | | - for (i = 0; dmcfreq->vop_bw_tbl[i].freq != CPUFREQ_TABLE_END; i++) { |
---|
2556 | | - if (bw_mbyte <= dmcfreq->vop_bw_tbl[i].max) { |
---|
2557 | | - target = dmcfreq->vop_bw_tbl[i].freq; |
---|
2558 | | - break; |
---|
2559 | | - } |
---|
2560 | | - } |
---|
2561 | | - if (target) |
---|
2562 | | - return 0; |
---|
2563 | | - else |
---|
2564 | | - return -EINVAL; |
---|
2565 | | -} |
---|
2566 | | -EXPORT_SYMBOL(rockchip_dmcfreq_vop_bandwidth_request); |
---|
2567 | | - |
---|
2568 | 2665 | static unsigned long get_nocp_req_rate(struct rockchip_dmcfreq *dmcfreq) |
---|
2569 | 2666 | { |
---|
2570 | 2667 | unsigned long target = 0, cpu_bw = 0; |
---|
.. | .. |
---|
2597 | 2694 | unsigned long target_freq = 0, nocp_req_rate = 0; |
---|
2598 | 2695 | u64 now; |
---|
2599 | 2696 | |
---|
2600 | | - if (dmcfreq->auto_freq_en && !dmcfreq->is_fixed) { |
---|
| 2697 | + if (dmcfreq->info.auto_freq_en && !dmcfreq->is_fixed) { |
---|
2601 | 2698 | if (dmcfreq->status_rate) |
---|
2602 | 2699 | target_freq = dmcfreq->status_rate; |
---|
2603 | 2700 | else if (dmcfreq->auto_min_rate) |
---|
2604 | 2701 | target_freq = dmcfreq->auto_min_rate; |
---|
2605 | 2702 | nocp_req_rate = get_nocp_req_rate(dmcfreq); |
---|
2606 | 2703 | target_freq = max3(target_freq, nocp_req_rate, |
---|
2607 | | - dmcfreq->vop_req_rate); |
---|
| 2704 | + dmcfreq->info.vop_req_rate); |
---|
2608 | 2705 | now = ktime_to_us(ktime_get()); |
---|
2609 | 2706 | if (now < dmcfreq->touchboostpulse_endtime) |
---|
2610 | 2707 | target_freq = max(target_freq, dmcfreq->boost_rate); |
---|
.. | .. |
---|
2615 | 2712 | target_freq = dmcfreq->normal_rate; |
---|
2616 | 2713 | if (target_freq) |
---|
2617 | 2714 | *freq = target_freq; |
---|
2618 | | - if (dmcfreq->auto_freq_en && !devfreq_update_stats(df)) |
---|
| 2715 | + if (dmcfreq->info.auto_freq_en && !devfreq_update_stats(df)) |
---|
2619 | 2716 | return 0; |
---|
2620 | 2717 | goto reset_last_status; |
---|
2621 | 2718 | } |
---|
.. | .. |
---|
2686 | 2783 | { |
---|
2687 | 2784 | struct rockchip_dmcfreq *dmcfreq = dev_get_drvdata(devfreq->dev.parent); |
---|
2688 | 2785 | |
---|
2689 | | - if (!dmcfreq->auto_freq_en) |
---|
| 2786 | + if (!dmcfreq->info.auto_freq_en) |
---|
2690 | 2787 | return 0; |
---|
2691 | 2788 | |
---|
2692 | 2789 | switch (event) { |
---|
.. | .. |
---|
2698 | 2795 | devfreq_monitor_stop(devfreq); |
---|
2699 | 2796 | break; |
---|
2700 | 2797 | |
---|
2701 | | - case DEVFREQ_GOV_INTERVAL: |
---|
2702 | | - devfreq_interval_update(devfreq, (unsigned int *)data); |
---|
| 2798 | + case DEVFREQ_GOV_UPDATE_INTERVAL: |
---|
| 2799 | + devfreq_update_interval(devfreq, (unsigned int *)data); |
---|
2703 | 2800 | break; |
---|
2704 | 2801 | |
---|
2705 | 2802 | case DEVFREQ_GOV_SUSPEND: |
---|
.. | .. |
---|
2727 | 2824 | { |
---|
2728 | 2825 | int i, ret; |
---|
2729 | 2826 | |
---|
2730 | | - if (!dmcfreq->auto_freq_en) |
---|
| 2827 | + if (!dmcfreq->info.auto_freq_en) |
---|
2731 | 2828 | return 0; |
---|
2732 | 2829 | |
---|
2733 | 2830 | for (i = 0; i < dmcfreq->edev_count; i++) { |
---|
.. | .. |
---|
2746 | 2843 | { |
---|
2747 | 2844 | int i, ret; |
---|
2748 | 2845 | |
---|
2749 | | - if (!dmcfreq->auto_freq_en) |
---|
| 2846 | + if (!dmcfreq->info.auto_freq_en) |
---|
2750 | 2847 | return 0; |
---|
2751 | 2848 | |
---|
2752 | 2849 | for (i = 0; i < dmcfreq->edev_count; i++) { |
---|
.. | .. |
---|
2782 | 2879 | struct device_node *events_np, *np = dev->of_node; |
---|
2783 | 2880 | int i, j, count, available_count = 0; |
---|
2784 | 2881 | |
---|
2785 | | - count = devfreq_event_get_edev_count(dev); |
---|
| 2882 | + count = devfreq_event_get_edev_count(dev, "devfreq-events"); |
---|
2786 | 2883 | if (count < 0) { |
---|
2787 | 2884 | dev_dbg(dev, "failed to get count of devfreq-event dev\n"); |
---|
2788 | 2885 | return 0; |
---|
.. | .. |
---|
2817 | 2914 | return -EINVAL; |
---|
2818 | 2915 | } |
---|
2819 | 2916 | dmcfreq->edev[j] = |
---|
2820 | | - devfreq_event_get_edev_by_phandle(dev, i); |
---|
| 2917 | + devfreq_event_get_edev_by_phandle(dev, "devfreq-events", i); |
---|
2821 | 2918 | if (IS_ERR(dmcfreq->edev[j])) |
---|
2822 | 2919 | return -EPROBE_DEFER; |
---|
2823 | 2920 | j++; |
---|
.. | .. |
---|
2825 | 2922 | of_node_put(events_np); |
---|
2826 | 2923 | } |
---|
2827 | 2924 | } |
---|
2828 | | - dmcfreq->auto_freq_en = true; |
---|
| 2925 | + dmcfreq->info.auto_freq_en = true; |
---|
2829 | 2926 | dmcfreq->dfi_id = rockchip_get_edev_id(dmcfreq, "dfi"); |
---|
2830 | 2927 | dmcfreq->nocp_cpu_id = rockchip_get_edev_id(dmcfreq, "nocp-cpu"); |
---|
2831 | 2928 | dmcfreq->nocp_bw = |
---|
.. | .. |
---|
2840 | 2937 | static int rockchip_dmcfreq_power_control(struct rockchip_dmcfreq *dmcfreq) |
---|
2841 | 2938 | { |
---|
2842 | 2939 | struct device *dev = dmcfreq->dev; |
---|
| 2940 | + struct device_node *np = dev->of_node; |
---|
| 2941 | + struct opp_table *opp_table = NULL, *reg_opp_table = NULL; |
---|
| 2942 | + const char * const reg_names[] = {"center", "mem"}; |
---|
| 2943 | + int ret = 0; |
---|
| 2944 | + |
---|
| 2945 | + if (of_find_property(np, "mem-supply", NULL)) |
---|
| 2946 | + dmcfreq->regulator_count = 2; |
---|
| 2947 | + else |
---|
| 2948 | + dmcfreq->regulator_count = 1; |
---|
| 2949 | + reg_opp_table = dev_pm_opp_set_regulators(dev, reg_names, |
---|
| 2950 | + dmcfreq->regulator_count); |
---|
| 2951 | + if (IS_ERR(reg_opp_table)) { |
---|
| 2952 | + dev_err(dev, "failed to set regulators\n"); |
---|
| 2953 | + return PTR_ERR(reg_opp_table); |
---|
| 2954 | + } |
---|
| 2955 | + opp_table = dev_pm_opp_register_set_opp_helper(dev, rockchip_dmcfreq_opp_helper); |
---|
| 2956 | + if (IS_ERR(opp_table)) { |
---|
| 2957 | + dev_err(dev, "failed to set opp helper\n"); |
---|
| 2958 | + ret = PTR_ERR(opp_table); |
---|
| 2959 | + goto reg_opp_table; |
---|
| 2960 | + } |
---|
2843 | 2961 | |
---|
2844 | 2962 | dmcfreq->vdd_center = devm_regulator_get_optional(dev, "center"); |
---|
2845 | 2963 | if (IS_ERR(dmcfreq->vdd_center)) { |
---|
2846 | 2964 | dev_err(dev, "Cannot get the regulator \"center\"\n"); |
---|
2847 | | - return PTR_ERR(dmcfreq->vdd_center); |
---|
| 2965 | + ret = PTR_ERR(dmcfreq->vdd_center); |
---|
| 2966 | + goto opp_table; |
---|
| 2967 | + } |
---|
| 2968 | + if (dmcfreq->regulator_count > 1) { |
---|
| 2969 | + dmcfreq->mem_reg = devm_regulator_get_optional(dev, "mem"); |
---|
| 2970 | + if (IS_ERR(dmcfreq->mem_reg)) { |
---|
| 2971 | + dev_err(dev, "Cannot get the regulator \"mem\"\n"); |
---|
| 2972 | + ret = PTR_ERR(dmcfreq->mem_reg); |
---|
| 2973 | + goto opp_table; |
---|
| 2974 | + } |
---|
2848 | 2975 | } |
---|
2849 | 2976 | |
---|
2850 | 2977 | dmcfreq->dmc_clk = devm_clk_get(dev, "dmc_clk"); |
---|
2851 | 2978 | if (IS_ERR(dmcfreq->dmc_clk)) { |
---|
2852 | 2979 | dev_err(dev, "Cannot get the clk dmc_clk. If using SCMI, trusted firmware need update to V1.01 and above.\n"); |
---|
2853 | | - return PTR_ERR(dmcfreq->dmc_clk); |
---|
| 2980 | + ret = PTR_ERR(dmcfreq->dmc_clk); |
---|
| 2981 | + goto opp_table; |
---|
2854 | 2982 | } |
---|
2855 | 2983 | dmcfreq->rate = clk_get_rate(dmcfreq->dmc_clk); |
---|
2856 | 2984 | |
---|
2857 | 2985 | return 0; |
---|
| 2986 | + |
---|
| 2987 | +opp_table: |
---|
| 2988 | + if (opp_table) |
---|
| 2989 | + dev_pm_opp_unregister_set_opp_helper(opp_table); |
---|
| 2990 | +reg_opp_table: |
---|
| 2991 | + if (reg_opp_table) |
---|
| 2992 | + dev_pm_opp_put_regulators(reg_opp_table); |
---|
| 2993 | + |
---|
| 2994 | + return ret; |
---|
2858 | 2995 | } |
---|
2859 | 2996 | |
---|
2860 | 2997 | static int rockchip_dmcfreq_dmc_init(struct platform_device *pdev, |
---|
.. | .. |
---|
2894 | 3031 | &dmcfreq->ondemand_data.upthreshold); |
---|
2895 | 3032 | of_property_read_u32(np, "downdifferential", |
---|
2896 | 3033 | &dmcfreq->ondemand_data.downdifferential); |
---|
2897 | | - if (dmcfreq->auto_freq_en) |
---|
| 3034 | + if (dmcfreq->info.auto_freq_en) |
---|
2898 | 3035 | of_property_read_u32(np, "auto-freq-en", |
---|
2899 | | - &dmcfreq->auto_freq_en); |
---|
2900 | | - of_property_read_u32(np, "auto-min-freq", |
---|
2901 | | - (u32 *)&dmcfreq->auto_min_rate); |
---|
2902 | | - dmcfreq->auto_min_rate *= 1000; |
---|
| 3036 | + &dmcfreq->info.auto_freq_en); |
---|
| 3037 | + if (!dmcfreq->auto_min_rate) { |
---|
| 3038 | + of_property_read_u32(np, "auto-min-freq", |
---|
| 3039 | + (u32 *)&dmcfreq->auto_min_rate); |
---|
| 3040 | + dmcfreq->auto_min_rate *= 1000; |
---|
| 3041 | + } |
---|
2903 | 3042 | |
---|
2904 | 3043 | if (rockchip_get_freq_map_talbe(np, "cpu-bw-dmc-freq", |
---|
2905 | 3044 | &dmcfreq->cpu_bw_tbl)) |
---|
2906 | 3045 | dev_dbg(dev, "failed to get cpu bandwidth to dmc rate\n"); |
---|
2907 | 3046 | if (rockchip_get_freq_map_talbe(np, "vop-frame-bw-dmc-freq", |
---|
2908 | | - &dmcfreq->vop_frame_bw_tbl)) |
---|
| 3047 | + &dmcfreq->info.vop_frame_bw_tbl)) |
---|
2909 | 3048 | dev_dbg(dev, "failed to get vop frame bandwidth to dmc rate\n"); |
---|
2910 | 3049 | if (rockchip_get_freq_map_talbe(np, "vop-bw-dmc-freq", |
---|
2911 | | - &dmcfreq->vop_bw_tbl)) |
---|
| 3050 | + &dmcfreq->info.vop_bw_tbl)) |
---|
2912 | 3051 | dev_err(dev, "failed to get vop bandwidth to dmc rate\n"); |
---|
2913 | 3052 | if (rockchip_get_rl_map_talbe(np, "vop-pn-msch-readlatency", |
---|
2914 | | - &dmcfreq->vop_pn_rl_tbl)) |
---|
| 3053 | + &dmcfreq->info.vop_pn_rl_tbl)) |
---|
2915 | 3054 | dev_err(dev, "failed to get vop pn to msch rl\n"); |
---|
2916 | 3055 | |
---|
2917 | 3056 | of_property_read_u32(np, "touchboost_duration", |
---|
.. | .. |
---|
2922 | 3061 | dmcfreq->touchboostpulse_duration_val = 500 * USEC_PER_MSEC; |
---|
2923 | 3062 | } |
---|
2924 | 3063 | |
---|
2925 | | -static int rockchip_dmcfreq_set_volt_only(struct rockchip_dmcfreq *dmcfreq) |
---|
2926 | | -{ |
---|
2927 | | - struct device *dev = dmcfreq->dev; |
---|
2928 | | - struct dev_pm_opp *opp; |
---|
2929 | | - unsigned long opp_volt, opp_rate = dmcfreq->rate; |
---|
2930 | | - int ret; |
---|
2931 | | - |
---|
2932 | | - opp = devfreq_recommended_opp(dev, &opp_rate, 0); |
---|
2933 | | - if (IS_ERR(opp)) { |
---|
2934 | | - dev_err(dev, "Failed to find opp for %lu Hz\n", opp_rate); |
---|
2935 | | - return PTR_ERR(opp); |
---|
2936 | | - } |
---|
2937 | | - opp_volt = dev_pm_opp_get_voltage(opp); |
---|
2938 | | - dev_pm_opp_put(opp); |
---|
2939 | | - |
---|
2940 | | - ret = regulator_set_voltage(dmcfreq->vdd_center, opp_volt, INT_MAX); |
---|
2941 | | - if (ret) { |
---|
2942 | | - dev_err(dev, "Cannot set voltage %lu uV\n", opp_volt); |
---|
2943 | | - return ret; |
---|
2944 | | - } |
---|
2945 | | - |
---|
2946 | | - return 0; |
---|
2947 | | -} |
---|
2948 | | - |
---|
2949 | 3064 | static int rockchip_dmcfreq_add_devfreq(struct rockchip_dmcfreq *dmcfreq) |
---|
2950 | 3065 | { |
---|
2951 | 3066 | struct devfreq_dev_profile *devp = &rockchip_devfreq_dmc_profile; |
---|
2952 | 3067 | struct device *dev = dmcfreq->dev; |
---|
2953 | 3068 | struct dev_pm_opp *opp; |
---|
| 3069 | + struct devfreq *devfreq; |
---|
2954 | 3070 | unsigned long opp_rate = dmcfreq->rate; |
---|
2955 | 3071 | |
---|
2956 | 3072 | opp = devfreq_recommended_opp(dev, &opp_rate, 0); |
---|
.. | .. |
---|
2961 | 3077 | dev_pm_opp_put(opp); |
---|
2962 | 3078 | |
---|
2963 | 3079 | devp->initial_freq = dmcfreq->rate; |
---|
2964 | | - dmcfreq->devfreq = devm_devfreq_add_device(dev, devp, |
---|
2965 | | - "dmc_ondemand", |
---|
2966 | | - &dmcfreq->ondemand_data); |
---|
2967 | | - if (IS_ERR(dmcfreq->devfreq)) { |
---|
| 3080 | + devfreq = devm_devfreq_add_device(dev, devp, "dmc_ondemand", |
---|
| 3081 | + &dmcfreq->ondemand_data); |
---|
| 3082 | + if (IS_ERR(devfreq)) { |
---|
2968 | 3083 | dev_err(dev, "failed to add devfreq\n"); |
---|
2969 | | - return PTR_ERR(dmcfreq->devfreq); |
---|
| 3084 | + return PTR_ERR(devfreq); |
---|
2970 | 3085 | } |
---|
2971 | 3086 | |
---|
2972 | | - devm_devfreq_register_opp_notifier(dev, dmcfreq->devfreq); |
---|
| 3087 | + devm_devfreq_register_opp_notifier(dev, devfreq); |
---|
2973 | 3088 | |
---|
2974 | | - dmcfreq->devfreq->last_status.current_frequency = opp_rate; |
---|
| 3089 | + devfreq->last_status.current_frequency = opp_rate; |
---|
2975 | 3090 | |
---|
2976 | | - reset_last_status(dmcfreq->devfreq); |
---|
| 3091 | + reset_last_status(devfreq); |
---|
| 3092 | + |
---|
| 3093 | + dmcfreq->info.devfreq = devfreq; |
---|
2977 | 3094 | |
---|
2978 | 3095 | return 0; |
---|
2979 | 3096 | } |
---|
2980 | | - |
---|
2981 | | -static struct monitor_dev_profile dmc_mdevp = { |
---|
2982 | | - .type = MONITOR_TPYE_DEV, |
---|
2983 | | - .low_temp_adjust = rockchip_monitor_dev_low_temp_adjust, |
---|
2984 | | - .high_temp_adjust = rockchip_monitor_dev_high_temp_adjust, |
---|
2985 | | -}; |
---|
2986 | 3097 | |
---|
2987 | 3098 | static void rockchip_dmcfreq_register_notifier(struct rockchip_dmcfreq *dmcfreq) |
---|
2988 | 3099 | { |
---|
2989 | 3100 | int ret; |
---|
2990 | 3101 | |
---|
2991 | | - if (vop_register_dmc()) |
---|
2992 | | - dev_err(dmcfreq->dev, "fail to register notify to vop.\n"); |
---|
| 3102 | + if (dmcfreq->system_status_en || dmcfreq->info.auto_freq_en) { |
---|
| 3103 | + if (vop_register_dmc()) |
---|
| 3104 | + dev_err(dmcfreq->dev, "fail to register notify to vop.\n"); |
---|
2993 | 3105 | |
---|
2994 | | - dmcfreq->status_nb.notifier_call = |
---|
2995 | | - rockchip_dmcfreq_system_status_notifier; |
---|
2996 | | - ret = rockchip_register_system_status_notifier(&dmcfreq->status_nb); |
---|
| 3106 | + dmcfreq->status_nb.notifier_call = |
---|
| 3107 | + rockchip_dmcfreq_system_status_notifier; |
---|
| 3108 | + ret = rockchip_register_system_status_notifier(&dmcfreq->status_nb); |
---|
| 3109 | + if (ret) |
---|
| 3110 | + dev_err(dmcfreq->dev, "failed to register system_status nb\n"); |
---|
| 3111 | + } |
---|
| 3112 | + |
---|
| 3113 | + dmcfreq->panic_nb.notifier_call = rockchip_dmcfreq_panic_notifier; |
---|
| 3114 | + ret = atomic_notifier_chain_register(&panic_notifier_list, |
---|
| 3115 | + &dmcfreq->panic_nb); |
---|
2997 | 3116 | if (ret) |
---|
2998 | | - dev_err(dmcfreq->dev, "failed to register system_status nb\n"); |
---|
| 3117 | + dev_err(dmcfreq->dev, "failed to register panic nb\n"); |
---|
2999 | 3118 | |
---|
3000 | | - dmc_mdevp.data = dmcfreq->devfreq; |
---|
| 3119 | + dmc_mdevp.data = dmcfreq->info.devfreq; |
---|
3001 | 3120 | dmcfreq->mdev_info = rockchip_system_monitor_register(dmcfreq->dev, |
---|
3002 | 3121 | &dmc_mdevp); |
---|
3003 | 3122 | if (IS_ERR(dmcfreq->mdev_info)) { |
---|
.. | .. |
---|
3008 | 3127 | |
---|
3009 | 3128 | static void rockchip_dmcfreq_add_interface(struct rockchip_dmcfreq *dmcfreq) |
---|
3010 | 3129 | { |
---|
3011 | | - if (sysfs_create_file(&dmcfreq->devfreq->dev.kobj, |
---|
3012 | | - &dev_attr_upthreshold.attr)) |
---|
| 3130 | + struct devfreq *devfreq = dmcfreq->info.devfreq; |
---|
| 3131 | + |
---|
| 3132 | + if (sysfs_create_file(&devfreq->dev.kobj, &dev_attr_upthreshold.attr)) |
---|
3013 | 3133 | dev_err(dmcfreq->dev, |
---|
3014 | 3134 | "failed to register upthreshold sysfs file\n"); |
---|
3015 | | - if (sysfs_create_file(&dmcfreq->devfreq->dev.kobj, |
---|
| 3135 | + if (sysfs_create_file(&devfreq->dev.kobj, |
---|
3016 | 3136 | &dev_attr_downdifferential.attr)) |
---|
3017 | 3137 | dev_err(dmcfreq->dev, |
---|
3018 | 3138 | "failed to register downdifferential sysfs file\n"); |
---|
3019 | 3139 | |
---|
3020 | | - if (!rockchip_add_system_status_interface(&dmcfreq->devfreq->dev)) |
---|
| 3140 | + if (!rockchip_add_system_status_interface(&devfreq->dev)) |
---|
3021 | 3141 | return; |
---|
3022 | | - if (sysfs_create_file(&dmcfreq->devfreq->dev.kobj, |
---|
| 3142 | + if (sysfs_create_file(&devfreq->dev.kobj, |
---|
3023 | 3143 | &dev_attr_system_status.attr)) |
---|
3024 | 3144 | dev_err(dmcfreq->dev, |
---|
3025 | 3145 | "failed to register system_status sysfs file\n"); |
---|
.. | .. |
---|
3049 | 3169 | return; |
---|
3050 | 3170 | dmcfreq->touchboostpulse_endtime = endtime; |
---|
3051 | 3171 | |
---|
3052 | | - schedule_work(&dmcfreq->boost_work); |
---|
| 3172 | + queue_work(system_freezable_wq, &dmcfreq->boost_work); |
---|
3053 | 3173 | } |
---|
3054 | 3174 | |
---|
3055 | 3175 | static int rockchip_dmcfreq_input_connect(struct input_handler *handler, |
---|
.. | .. |
---|
3238 | 3358 | return; |
---|
3239 | 3359 | dmcfreq->devfreq_cooling = |
---|
3240 | 3360 | of_devfreq_cooling_register_power(dmcfreq->dev->of_node, |
---|
3241 | | - dmcfreq->devfreq, |
---|
| 3361 | + dmcfreq->info.devfreq, |
---|
3242 | 3362 | &ddr_cooling_power_data); |
---|
3243 | 3363 | if (IS_ERR(dmcfreq->devfreq_cooling)) { |
---|
3244 | 3364 | ret = PTR_ERR(dmcfreq->devfreq_cooling); |
---|
.. | .. |
---|
3259 | 3379 | return -ENOMEM; |
---|
3260 | 3380 | |
---|
3261 | 3381 | data->dev = dev; |
---|
| 3382 | + data->info.dev = dev; |
---|
3262 | 3383 | mutex_init(&data->lock); |
---|
3263 | 3384 | INIT_LIST_HEAD(&data->video_info_list); |
---|
3264 | 3385 | |
---|
.. | .. |
---|
3279 | 3400 | return ret; |
---|
3280 | 3401 | |
---|
3281 | 3402 | rockchip_dmcfreq_parse_dt(data); |
---|
3282 | | - if (!data->system_status_en && !data->auto_freq_en) { |
---|
| 3403 | + |
---|
| 3404 | + platform_set_drvdata(pdev, data); |
---|
| 3405 | + |
---|
| 3406 | + if (!data->system_status_en && !data->info.auto_freq_en) { |
---|
3283 | 3407 | dev_info(dev, "don't add devfreq feature\n"); |
---|
3284 | | - return rockchip_dmcfreq_set_volt_only(data); |
---|
| 3408 | + rockchip_dmcfreq_register_notifier(data); |
---|
| 3409 | + return 0; |
---|
3285 | 3410 | } |
---|
3286 | 3411 | |
---|
3287 | | - pm_qos_add_request(&pm_qos, PM_QOS_CPU_DMA_LATENCY, |
---|
3288 | | - PM_QOS_DEFAULT_VALUE); |
---|
3289 | | - platform_set_drvdata(pdev, data); |
---|
| 3412 | + cpu_latency_qos_add_request(&pm_qos, PM_QOS_DEFAULT_VALUE); |
---|
3290 | 3413 | |
---|
3291 | 3414 | ret = devfreq_add_governor(&devfreq_dmc_ondemand); |
---|
3292 | 3415 | if (ret) |
---|
.. | .. |
---|
3303 | 3426 | rockchip_dmcfreq_register_notifier(data); |
---|
3304 | 3427 | rockchip_dmcfreq_add_interface(data); |
---|
3305 | 3428 | rockchip_dmcfreq_boost_init(data); |
---|
3306 | | - rockchip_dmcfreq_msch_rl_init(data); |
---|
| 3429 | + rockchip_dmcfreq_vop_bandwidth_init(&data->info); |
---|
3307 | 3430 | rockchip_dmcfreq_register_cooling_device(data); |
---|
3308 | 3431 | |
---|
3309 | 3432 | rockchip_set_system_status(SYS_STATUS_NORMAL); |
---|
.. | .. |
---|
3323 | 3446 | if (ret) |
---|
3324 | 3447 | return ret; |
---|
3325 | 3448 | |
---|
3326 | | - ret = devfreq_suspend_device(dmcfreq->devfreq); |
---|
3327 | | - if (ret < 0) { |
---|
3328 | | - dev_err(dev, "failed to suspend the devfreq devices\n"); |
---|
3329 | | - return ret; |
---|
| 3449 | + if (dmcfreq->info.devfreq) { |
---|
| 3450 | + ret = devfreq_suspend_device(dmcfreq->info.devfreq); |
---|
| 3451 | + if (ret < 0) { |
---|
| 3452 | + dev_err(dev, "failed to suspend the devfreq devices\n"); |
---|
| 3453 | + return ret; |
---|
| 3454 | + } |
---|
| 3455 | + } |
---|
| 3456 | + |
---|
| 3457 | + /* set voltage to sleep_volt if need */ |
---|
| 3458 | + if (dmcfreq->sleep_volt && dmcfreq->sleep_volt != dmcfreq->volt) { |
---|
| 3459 | + ret = regulator_set_voltage(dmcfreq->vdd_center, |
---|
| 3460 | + dmcfreq->sleep_volt, INT_MAX); |
---|
| 3461 | + if (ret) { |
---|
| 3462 | + dev_err(dev, "Cannot set vdd voltage %lu uV\n", |
---|
| 3463 | + dmcfreq->sleep_volt); |
---|
| 3464 | + return ret; |
---|
| 3465 | + } |
---|
| 3466 | + } |
---|
| 3467 | + if (dmcfreq->sleep_mem_volt && |
---|
| 3468 | + dmcfreq->sleep_mem_volt != dmcfreq->mem_volt) { |
---|
| 3469 | + ret = regulator_set_voltage(dmcfreq->mem_reg, |
---|
| 3470 | + dmcfreq->sleep_mem_volt, INT_MAX); |
---|
| 3471 | + if (ret) { |
---|
| 3472 | + dev_err(dev, "Cannot set mem voltage %lu uV\n", |
---|
| 3473 | + dmcfreq->sleep_mem_volt); |
---|
| 3474 | + return ret; |
---|
| 3475 | + } |
---|
3330 | 3476 | } |
---|
3331 | 3477 | |
---|
3332 | 3478 | return 0; |
---|
.. | .. |
---|
3340 | 3486 | if (!dmcfreq) |
---|
3341 | 3487 | return 0; |
---|
3342 | 3488 | |
---|
| 3489 | + /* restore voltage if it is sleep_volt */ |
---|
| 3490 | + if (dmcfreq->sleep_volt && dmcfreq->sleep_volt != dmcfreq->volt) { |
---|
| 3491 | + ret = regulator_set_voltage(dmcfreq->vdd_center, dmcfreq->volt, |
---|
| 3492 | + INT_MAX); |
---|
| 3493 | + if (ret) { |
---|
| 3494 | + dev_err(dev, "Cannot set vdd voltage %lu uV\n", |
---|
| 3495 | + dmcfreq->volt); |
---|
| 3496 | + return ret; |
---|
| 3497 | + } |
---|
| 3498 | + } |
---|
| 3499 | + if (dmcfreq->sleep_mem_volt && |
---|
| 3500 | + dmcfreq->sleep_mem_volt != dmcfreq->mem_volt) { |
---|
| 3501 | + ret = regulator_set_voltage(dmcfreq->mem_reg, dmcfreq->mem_volt, |
---|
| 3502 | + INT_MAX); |
---|
| 3503 | + if (ret) { |
---|
| 3504 | + dev_err(dev, "Cannot set mem voltage %lu uV\n", |
---|
| 3505 | + dmcfreq->mem_volt); |
---|
| 3506 | + return ret; |
---|
| 3507 | + } |
---|
| 3508 | + } |
---|
| 3509 | + |
---|
3343 | 3510 | ret = rockchip_dmcfreq_enable_event(dmcfreq); |
---|
3344 | 3511 | if (ret) |
---|
3345 | 3512 | return ret; |
---|
3346 | 3513 | |
---|
3347 | | - ret = devfreq_resume_device(dmcfreq->devfreq); |
---|
3348 | | - if (ret < 0) { |
---|
3349 | | - dev_err(dev, "failed to resume the devfreq devices\n"); |
---|
3350 | | - return ret; |
---|
| 3514 | + if (dmcfreq->info.devfreq) { |
---|
| 3515 | + ret = devfreq_resume_device(dmcfreq->info.devfreq); |
---|
| 3516 | + if (ret < 0) { |
---|
| 3517 | + dev_err(dev, "failed to resume the devfreq devices\n"); |
---|
| 3518 | + return ret; |
---|
| 3519 | + } |
---|
3351 | 3520 | } |
---|
| 3521 | + |
---|
3352 | 3522 | return ret; |
---|
3353 | 3523 | } |
---|
3354 | 3524 | |
---|
.. | .. |
---|
3364 | 3534 | }; |
---|
3365 | 3535 | module_platform_driver(rockchip_dmcfreq_driver); |
---|
3366 | 3536 | |
---|
3367 | | -MODULE_LICENSE("GPL v2"); |
---|
3368 | | -MODULE_AUTHOR("Lin Huang <hl@rock-chips.com>"); |
---|
| 3537 | +MODULE_AUTHOR("Finley Xiao <finley.xiao@rock-chips.com>"); |
---|
3369 | 3538 | MODULE_DESCRIPTION("rockchip dmcfreq driver with devfreq framework"); |
---|
| 3539 | +MODULE_LICENSE("GPL v2"); |
---|