.. | .. |
---|
4 | 4 | * Author: Finley Xiao <finley.xiao@rock-chips.com> |
---|
5 | 5 | */ |
---|
6 | 6 | |
---|
7 | | -#include <dt-bindings/soc/rockchip-system-status.h> |
---|
8 | 7 | #include <linux/clk-provider.h> |
---|
9 | 8 | #include <linux/cpu.h> |
---|
10 | 9 | #include <linux/cpufreq.h> |
---|
.. | .. |
---|
24 | 23 | #include <linux/regulator/driver.h> |
---|
25 | 24 | #include <linux/regulator/machine.h> |
---|
26 | 25 | #include <linux/reboot.h> |
---|
| 26 | +#include <linux/rockchip/rockchip_sip.h> |
---|
27 | 27 | #include <linux/slab.h> |
---|
28 | 28 | #include <linux/suspend.h> |
---|
29 | 29 | #include <linux/thermal.h> |
---|
.. | .. |
---|
246 | 246 | return video_info; |
---|
247 | 247 | } |
---|
248 | 248 | |
---|
249 | | -static struct video_info *rockchip_find_video_info(const char *buf) |
---|
250 | | -{ |
---|
251 | | - struct video_info *info, *video_info; |
---|
252 | | - |
---|
253 | | - video_info = rockchip_parse_video_info(buf); |
---|
254 | | - |
---|
255 | | - if (!video_info) |
---|
256 | | - return NULL; |
---|
257 | | - |
---|
258 | | - mutex_lock(&video_info_mutex); |
---|
259 | | - list_for_each_entry(info, &video_info_list, node) { |
---|
260 | | - if (info->width == video_info->width && |
---|
261 | | - info->height == video_info->height && |
---|
262 | | - info->ishevc == video_info->ishevc && |
---|
263 | | - info->videoFramerate == video_info->videoFramerate && |
---|
264 | | - info->streamBitrate == video_info->streamBitrate) { |
---|
265 | | - mutex_unlock(&video_info_mutex); |
---|
266 | | - kfree(video_info); |
---|
267 | | - return info; |
---|
268 | | - } |
---|
269 | | - } |
---|
270 | | - |
---|
271 | | - mutex_unlock(&video_info_mutex); |
---|
272 | | - kfree(video_info); |
---|
273 | | - |
---|
274 | | - return NULL; |
---|
275 | | -} |
---|
276 | | - |
---|
277 | 249 | static void rockchip_add_video_info(struct video_info *video_info) |
---|
278 | 250 | { |
---|
279 | 251 | if (video_info) { |
---|
.. | .. |
---|
285 | 257 | |
---|
286 | 258 | static void rockchip_del_video_info(struct video_info *video_info) |
---|
287 | 259 | { |
---|
288 | | - if (video_info) { |
---|
289 | | - mutex_lock(&video_info_mutex); |
---|
290 | | - list_del(&video_info->node); |
---|
291 | | - mutex_unlock(&video_info_mutex); |
---|
292 | | - kfree(video_info); |
---|
| 260 | + struct video_info *info, *tmp; |
---|
| 261 | + |
---|
| 262 | + if (!video_info) |
---|
| 263 | + return; |
---|
| 264 | + |
---|
| 265 | + mutex_lock(&video_info_mutex); |
---|
| 266 | + list_for_each_entry_safe(info, tmp, &video_info_list, node) { |
---|
| 267 | + if (info->width == video_info->width && |
---|
| 268 | + info->height == video_info->height && |
---|
| 269 | + info->ishevc == video_info->ishevc && |
---|
| 270 | + info->videoFramerate == video_info->videoFramerate && |
---|
| 271 | + info->streamBitrate == video_info->streamBitrate) { |
---|
| 272 | + list_del(&info->node); |
---|
| 273 | + kfree(info); |
---|
| 274 | + break; |
---|
| 275 | + } |
---|
293 | 276 | } |
---|
| 277 | + kfree(video_info); |
---|
| 278 | + mutex_unlock(&video_info_mutex); |
---|
294 | 279 | } |
---|
295 | 280 | |
---|
296 | 281 | static void rockchip_update_video_info(void) |
---|
.. | .. |
---|
338 | 323 | switch (buf[0]) { |
---|
339 | 324 | case '0': |
---|
340 | 325 | /* clear video flag */ |
---|
341 | | - video_info = rockchip_find_video_info(buf); |
---|
| 326 | + video_info = rockchip_parse_video_info(buf); |
---|
342 | 327 | if (video_info) { |
---|
343 | 328 | rockchip_del_video_info(video_info); |
---|
344 | 329 | rockchip_update_video_info(); |
---|
.. | .. |
---|
920 | 905 | bool is_low) |
---|
921 | 906 | { |
---|
922 | 907 | struct monitor_dev_profile *devp = info->devp; |
---|
| 908 | + struct arm_smccc_res res; |
---|
923 | 909 | int ret = 0; |
---|
924 | 910 | |
---|
925 | 911 | dev_dbg(info->dev, "low_temp %d\n", is_low); |
---|
.. | .. |
---|
934 | 920 | |
---|
935 | 921 | if (devp->update_volt) |
---|
936 | 922 | devp->update_volt(info); |
---|
| 923 | + |
---|
| 924 | + if (devp->opp_info && devp->opp_info->pvtpll_low_temp) { |
---|
| 925 | + res = sip_smc_pvtpll_config(PVTPLL_LOW_TEMP, |
---|
| 926 | + devp->opp_info->pvtpll_clk_id, |
---|
| 927 | + is_low, 0, 0, 0, 0); |
---|
| 928 | + if (res.a0) |
---|
| 929 | + dev_err(info->dev, |
---|
| 930 | + "%s: error cfg id=%u low temp %d (%d)\n", |
---|
| 931 | + __func__, devp->opp_info->pvtpll_clk_id, |
---|
| 932 | + is_low, (int)res.a0); |
---|
| 933 | + } |
---|
937 | 934 | } |
---|
938 | 935 | |
---|
939 | 936 | static void rockchip_high_temp_adjust(struct monitor_dev_info *info, |
---|
.. | .. |
---|
1338 | 1335 | rockchip_set_intermediate_rate(dev, opp_info, info->clk, |
---|
1339 | 1336 | old_rate, new_rate, |
---|
1340 | 1337 | true, is_set_clk); |
---|
| 1338 | + |
---|
| 1339 | + if (old_volt > new_volt) { |
---|
| 1340 | + ret = regulator_set_voltage(vdd_reg, new_volt, INT_MAX); |
---|
| 1341 | + if (ret) { |
---|
| 1342 | + dev_err(dev, "%s: failed to set volt: %lu\n", |
---|
| 1343 | + __func__, new_volt); |
---|
| 1344 | + goto restore_voltage; |
---|
| 1345 | + } |
---|
| 1346 | + } |
---|
1341 | 1347 | if (info->regulator_count > 1) { |
---|
1342 | 1348 | ret = regulator_set_voltage(mem_reg, new_mem_volt, |
---|
1343 | 1349 | INT_MAX); |
---|
.. | .. |
---|
1347 | 1353 | goto restore_voltage; |
---|
1348 | 1354 | } |
---|
1349 | 1355 | } |
---|
1350 | | - ret = regulator_set_voltage(vdd_reg, new_volt, INT_MAX); |
---|
1351 | | - if (ret) { |
---|
1352 | | - dev_err(dev, "%s: failed to set volt: %lu\n", |
---|
1353 | | - __func__, new_volt); |
---|
1354 | | - goto restore_voltage; |
---|
| 1356 | + if (old_volt <= new_volt) { |
---|
| 1357 | + ret = regulator_set_voltage(vdd_reg, new_volt, INT_MAX); |
---|
| 1358 | + if (ret) { |
---|
| 1359 | + dev_err(dev, "%s: failed to set volt: %lu\n", |
---|
| 1360 | + __func__, new_volt); |
---|
| 1361 | + goto restore_voltage; |
---|
| 1362 | + } |
---|
1355 | 1363 | } |
---|
1356 | 1364 | rockchip_set_read_margin(dev, opp_info, target_rm, is_set_rm); |
---|
1357 | 1365 | if (is_set_clk && clk_set_rate(info->clk, new_rate)) { |
---|
.. | .. |
---|
1396 | 1404 | rockchip_get_read_margin(dev, opp_info, old_volt, &target_rm); |
---|
1397 | 1405 | rockchip_set_read_margin(dev, opp_info, target_rm, is_set_rm); |
---|
1398 | 1406 | restore_voltage: |
---|
| 1407 | + if (old_volt <= new_volt) |
---|
| 1408 | + regulator_set_voltage(vdd_reg, old_volt, INT_MAX); |
---|
1399 | 1409 | if (info->regulator_count > 1) |
---|
1400 | 1410 | regulator_set_voltage(mem_reg, old_mem_volt, INT_MAX); |
---|
1401 | | - regulator_set_voltage(vdd_reg, old_volt, INT_MAX); |
---|
| 1411 | + if (old_volt > new_volt) |
---|
| 1412 | + regulator_set_voltage(vdd_reg, old_volt, INT_MAX); |
---|
1402 | 1413 | disable_clk: |
---|
1403 | 1414 | rockchip_monitor_disable_opp_clk(dev, opp_info); |
---|
1404 | 1415 | unlock: |
---|