• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
4  * Author: Finley Xiao <finley.xiao@rock-chips.com>
5  */
6 
7 #include <dt-bindings/soc/rockchip-system-status.h>
8 #include <linux/clk-provider.h>
9 #include <linux/cpu.h>
10 #include <linux/cpufreq.h>
11 #include <linux/devfreq.h>
12 #include <linux/device.h>
13 #include <linux/fb.h>
14 #include <linux/module.h>
15 #include <linux/mutex.h>
16 #include <linux/notifier.h>
17 #include <linux/of.h>
18 #include <linux/platform_device.h>
19 #include <linux/pm_opp.h>
20 #include <linux/pm_qos.h>
21 #include <linux/pm_runtime.h>
22 #include <linux/regulator/consumer.h>
23 #include <linux/regulator/coupler.h>
24 #include <linux/regulator/driver.h>
25 #include <linux/regulator/machine.h>
26 #include <linux/reboot.h>
27 #include <linux/slab.h>
28 #include <linux/suspend.h>
29 #include <linux/thermal.h>
30 #include <linux/uaccess.h>
31 #include <linux/version.h>
32 #include <linux/delay.h>
33 #include <soc/rockchip/rockchip_opp_select.h>
34 #include <soc/rockchip/rockchip_system_monitor.h>
35 #include <soc/rockchip/rockchip-system-status.h>
36 
37 #include "../../gpu/drm/rockchip/ebc_dev.h"
38 #include "../../opp/opp.h"
39 #include "../../regulator/internal.h"
40 #include "../../thermal/thermal_core.h"
41 
42 #define CPU_REBOOT_FREQ		816000 /* kHz */
43 #define VIDEO_1080P_SIZE	(1920 * 1080)
44 #define THERMAL_POLLING_DELAY	200 /* milliseconds */
45 
46 struct video_info {
47 	unsigned int width;
48 	unsigned int height;
49 	unsigned int ishevc;
50 	unsigned int videoFramerate;
51 	unsigned int streamBitrate;
52 	struct list_head node;
53 };
54 
55 struct system_monitor_attr {
56 	struct attribute attr;
57 	ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,
58 			char *buf);
59 	ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,
60 			 const char *buf, size_t n);
61 };
62 
63 struct system_monitor {
64 	struct device *dev;
65 	struct cpumask video_4k_offline_cpus;
66 	struct cpumask status_offline_cpus;
67 	struct cpumask temp_offline_cpus;
68 	struct cpumask offline_cpus;
69 	struct notifier_block status_nb;
70 	struct kobject *kobj;
71 
72 	struct thermal_zone_device *tz;
73 	struct delayed_work thermal_work;
74 	int offline_cpus_temp;
75 	int temp_hysteresis;
76 	unsigned int delay;
77 	bool is_temp_offline;
78 };
79 
80 static unsigned long system_status;
81 static unsigned long ref_count[32] = {0};
82 
83 static DEFINE_MUTEX(system_status_mutex);
84 static DEFINE_MUTEX(video_info_mutex);
85 static DEFINE_MUTEX(cpu_on_off_mutex);
86 
87 static DECLARE_RWSEM(mdev_list_sem);
88 
89 static LIST_HEAD(video_info_list);
90 static LIST_HEAD(monitor_dev_list);
91 static struct system_monitor *system_monitor;
92 static atomic_t monitor_in_suspend;
93 
94 static BLOCKING_NOTIFIER_HEAD(system_status_notifier_list);
95 
rockchip_register_system_status_notifier(struct notifier_block * nb)96 int rockchip_register_system_status_notifier(struct notifier_block *nb)
97 {
98 	return blocking_notifier_chain_register(&system_status_notifier_list,
99 						nb);
100 }
101 EXPORT_SYMBOL(rockchip_register_system_status_notifier);
102 
rockchip_unregister_system_status_notifier(struct notifier_block * nb)103 int rockchip_unregister_system_status_notifier(struct notifier_block *nb)
104 {
105 	return blocking_notifier_chain_unregister(&system_status_notifier_list,
106 						  nb);
107 }
108 EXPORT_SYMBOL(rockchip_unregister_system_status_notifier);
109 
rockchip_system_status_notifier_call_chain(unsigned long val)110 static int rockchip_system_status_notifier_call_chain(unsigned long val)
111 {
112 	int ret = blocking_notifier_call_chain(&system_status_notifier_list,
113 					       val, NULL);
114 
115 	return notifier_to_errno(ret);
116 }
117 
rockchip_set_system_status(unsigned long status)118 void rockchip_set_system_status(unsigned long status)
119 {
120 	unsigned long old_system_status;
121 	unsigned int single_status_offset;
122 
123 	mutex_lock(&system_status_mutex);
124 
125 	old_system_status = system_status;
126 
127 	while (status) {
128 		single_status_offset = fls(status) - 1;
129 		status &= ~(1 << single_status_offset);
130 		if (ref_count[single_status_offset] == 0)
131 			system_status |= 1 << single_status_offset;
132 		ref_count[single_status_offset]++;
133 	}
134 
135 	if (old_system_status != system_status)
136 		rockchip_system_status_notifier_call_chain(system_status);
137 
138 	mutex_unlock(&system_status_mutex);
139 }
140 EXPORT_SYMBOL(rockchip_set_system_status);
141 
rockchip_clear_system_status(unsigned long status)142 void rockchip_clear_system_status(unsigned long status)
143 {
144 	unsigned long old_system_status;
145 	unsigned int single_status_offset;
146 
147 	mutex_lock(&system_status_mutex);
148 
149 	old_system_status = system_status;
150 
151 	while (status) {
152 		single_status_offset = fls(status) - 1;
153 		status &= ~(1 << single_status_offset);
154 		if (ref_count[single_status_offset] == 0) {
155 			continue;
156 		} else {
157 			if (ref_count[single_status_offset] == 1)
158 				system_status &= ~(1 << single_status_offset);
159 			ref_count[single_status_offset]--;
160 		}
161 	}
162 
163 	if (old_system_status != system_status)
164 		rockchip_system_status_notifier_call_chain(system_status);
165 
166 	mutex_unlock(&system_status_mutex);
167 }
168 EXPORT_SYMBOL(rockchip_clear_system_status);
169 
rockchip_get_system_status(void)170 unsigned long rockchip_get_system_status(void)
171 {
172 	return system_status;
173 }
174 EXPORT_SYMBOL(rockchip_get_system_status);
175 
rockchip_add_system_status_interface(struct device * dev)176 int rockchip_add_system_status_interface(struct device *dev)
177 {
178 	if (!system_monitor || !system_monitor->kobj) {
179 		pr_err("failed to get system status kobj\n");
180 		return -EINVAL;
181 	}
182 
183 	return compat_only_sysfs_link_entry_to_kobj(&dev->kobj,
184 						    system_monitor->kobj,
185 						    "system_status", NULL);
186 }
187 EXPORT_SYMBOL(rockchip_add_system_status_interface);
188 
rockchip_get_video_param(char ** str)189 static unsigned long rockchip_get_video_param(char **str)
190 {
191 	char *p;
192 	unsigned long val = 0;
193 
194 	strsep(str, "=");
195 	p = strsep(str, ",");
196 	if (p) {
197 		if (kstrtoul(p, 10, &val))
198 			return 0;
199 	}
200 
201 	return val;
202 }
203 
204 /*
205  * format:
206  * 0,width=val,height=val,ishevc=val,videoFramerate=val,streamBitrate=val
207  * 1,width=val,height=val,ishevc=val,videoFramerate=val,streamBitrate=val
208  */
rockchip_parse_video_info(const char * buf)209 static struct video_info *rockchip_parse_video_info(const char *buf)
210 {
211 	struct video_info *video_info;
212 	const char *cp = buf;
213 	char *str, *p;
214 	int ntokens = 0;
215 
216 	while ((cp = strpbrk(cp + 1, ",")))
217 		ntokens++;
218 	if (ntokens != 5)
219 		return NULL;
220 
221 	video_info = kzalloc(sizeof(*video_info), GFP_KERNEL);
222 	if (!video_info)
223 		return NULL;
224 
225 	INIT_LIST_HEAD(&video_info->node);
226 
227 	str = kstrdup(buf, GFP_KERNEL);
228 	p = str;
229 	strsep(&p, ",");
230 	video_info->width = rockchip_get_video_param(&p);
231 	video_info->height = rockchip_get_video_param(&p);
232 	video_info->ishevc = rockchip_get_video_param(&p);
233 	video_info->videoFramerate = rockchip_get_video_param(&p);
234 	video_info->streamBitrate = rockchip_get_video_param(&p);
235 	pr_debug("%c,width=%d,height=%d,ishevc=%d,videoFramerate=%d,streamBitrate=%d\n",
236 		 buf[0],
237 		 video_info->width,
238 		 video_info->height,
239 		 video_info->ishevc,
240 		 video_info->videoFramerate,
241 		 video_info->streamBitrate);
242 	kfree(str);
243 
244 	return video_info;
245 }
246 
rockchip_find_video_info(const char * buf)247 static struct video_info *rockchip_find_video_info(const char *buf)
248 {
249 	struct video_info *info, *video_info;
250 
251 	video_info = rockchip_parse_video_info(buf);
252 
253 	if (!video_info)
254 		return NULL;
255 
256 	mutex_lock(&video_info_mutex);
257 	list_for_each_entry(info, &video_info_list, node) {
258 		if (info->width == video_info->width &&
259 		    info->height == video_info->height &&
260 		    info->ishevc == video_info->ishevc &&
261 		    info->videoFramerate == video_info->videoFramerate &&
262 		    info->streamBitrate == video_info->streamBitrate) {
263 			mutex_unlock(&video_info_mutex);
264 			kfree(video_info);
265 			return info;
266 		}
267 	}
268 
269 	mutex_unlock(&video_info_mutex);
270 	kfree(video_info);
271 
272 	return NULL;
273 }
274 
rockchip_add_video_info(struct video_info * video_info)275 static void rockchip_add_video_info(struct video_info *video_info)
276 {
277 	if (video_info) {
278 		mutex_lock(&video_info_mutex);
279 		list_add(&video_info->node, &video_info_list);
280 		mutex_unlock(&video_info_mutex);
281 	}
282 }
283 
rockchip_del_video_info(struct video_info * video_info)284 static void rockchip_del_video_info(struct video_info *video_info)
285 {
286 	if (video_info) {
287 		mutex_lock(&video_info_mutex);
288 		list_del(&video_info->node);
289 		mutex_unlock(&video_info_mutex);
290 		kfree(video_info);
291 	}
292 }
293 
rockchip_update_video_info(void)294 static void rockchip_update_video_info(void)
295 {
296 	struct video_info *video_info;
297 	unsigned int max_res = 0, max_stream_bitrate = 0, res = 0;
298 
299 	mutex_lock(&video_info_mutex);
300 	if (list_empty(&video_info_list)) {
301 		mutex_unlock(&video_info_mutex);
302 		rockchip_clear_system_status(SYS_STATUS_VIDEO);
303 		return;
304 	}
305 
306 	list_for_each_entry(video_info, &video_info_list, node) {
307 		res = video_info->width * video_info->height;
308 		if (res > max_res)
309 			max_res = res;
310 		if (video_info->streamBitrate > max_stream_bitrate)
311 			max_stream_bitrate = video_info->streamBitrate;
312 	}
313 	mutex_unlock(&video_info_mutex);
314 
315 	if (max_res <= VIDEO_1080P_SIZE) {
316 		rockchip_set_system_status(SYS_STATUS_VIDEO_1080P);
317 	} else {
318 		if (max_stream_bitrate == 10)
319 			rockchip_set_system_status(SYS_STATUS_VIDEO_4K_10B);
320 		else
321 			rockchip_set_system_status(SYS_STATUS_VIDEO_4K);
322 	}
323 }
324 
rockchip_update_system_status(const char * buf)325 void rockchip_update_system_status(const char *buf)
326 {
327 	struct video_info *video_info;
328 
329 	if (!buf)
330 		return;
331 
332 	switch (buf[0]) {
333 	case '0':
334 		/* clear video flag */
335 		video_info = rockchip_find_video_info(buf);
336 		if (video_info) {
337 			rockchip_del_video_info(video_info);
338 			rockchip_update_video_info();
339 		}
340 		break;
341 	case '1':
342 		/* set video flag */
343 		video_info = rockchip_parse_video_info(buf);
344 		if (video_info) {
345 			rockchip_add_video_info(video_info);
346 			rockchip_update_video_info();
347 		}
348 		break;
349 	case 'L':
350 		/* clear low power flag */
351 		rockchip_clear_system_status(SYS_STATUS_LOW_POWER);
352 		break;
353 	case 'l':
354 		/* set low power flag */
355 		rockchip_set_system_status(SYS_STATUS_LOW_POWER);
356 		break;
357 	case 'p':
358 		/* set performance flag */
359 		rockchip_set_system_status(SYS_STATUS_PERFORMANCE);
360 		break;
361 	case 'n':
362 		/* clear performance flag */
363 		rockchip_clear_system_status(SYS_STATUS_PERFORMANCE);
364 		break;
365 	default:
366 		break;
367 	}
368 }
369 EXPORT_SYMBOL(rockchip_update_system_status);
370 
status_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)371 static ssize_t status_show(struct kobject *kobj, struct kobj_attribute *attr,
372 			   char *buf)
373 {
374 	unsigned int status = rockchip_get_system_status();
375 
376 	return sprintf(buf, "0x%x\n", status);
377 }
378 
status_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t n)379 static ssize_t status_store(struct kobject *kobj, struct kobj_attribute *attr,
380 			    const char *buf, size_t n)
381 {
382 	if (!n)
383 		return -EINVAL;
384 
385 	rockchip_update_system_status(buf);
386 
387 	return n;
388 }
389 
390 static struct system_monitor_attr status =
391 	__ATTR(system_status, 0644, status_show, status_store);
392 
rockchip_get_temp_freq_table(struct device_node * np,char * porp_name,struct temp_freq_table ** freq_table)393 static int rockchip_get_temp_freq_table(struct device_node *np,
394 					char *porp_name,
395 					struct temp_freq_table **freq_table)
396 {
397 	struct temp_freq_table *table;
398 	const struct property *prop;
399 	int count, i;
400 
401 	prop = of_find_property(np, porp_name, NULL);
402 	if (!prop)
403 		return -EINVAL;
404 
405 	if (!prop->value)
406 		return -ENODATA;
407 
408 	count = of_property_count_u32_elems(np, porp_name);
409 	if (count < 0)
410 		return -EINVAL;
411 
412 	if (count % 2)
413 		return -EINVAL;
414 
415 	table = kzalloc(sizeof(*table) * (count / 2 + 1), GFP_KERNEL);
416 	if (!table)
417 		return -ENOMEM;
418 
419 	for (i = 0; i < count / 2; i++) {
420 		of_property_read_u32_index(np, porp_name, 2 * i,
421 					   &table[i].temp);
422 		of_property_read_u32_index(np, porp_name, 2 * i + 1,
423 					   &table[i].freq);
424 	}
425 	table[i].freq = UINT_MAX;
426 	*freq_table = table;
427 
428 	return 0;
429 }
430 
rockchip_get_adjust_volt_table(struct device_node * np,char * porp_name,struct volt_adjust_table ** table)431 static int rockchip_get_adjust_volt_table(struct device_node *np,
432 					  char *porp_name,
433 					  struct volt_adjust_table **table)
434 {
435 	struct volt_adjust_table *volt_table;
436 	const struct property *prop;
437 	int count, i;
438 
439 	prop = of_find_property(np, porp_name, NULL);
440 	if (!prop)
441 		return -EINVAL;
442 
443 	if (!prop->value)
444 		return -ENODATA;
445 
446 	count = of_property_count_u32_elems(np, porp_name);
447 	if (count < 0)
448 		return -EINVAL;
449 
450 	if (count % 3)
451 		return -EINVAL;
452 
453 	volt_table = kzalloc(sizeof(*volt_table) * (count / 3 + 1), GFP_KERNEL);
454 	if (!volt_table)
455 		return -ENOMEM;
456 
457 	for (i = 0; i < count / 3; i++) {
458 		of_property_read_u32_index(np, porp_name, 3 * i,
459 					   &volt_table[i].min);
460 		of_property_read_u32_index(np, porp_name, 3 * i + 1,
461 					   &volt_table[i].max);
462 		of_property_read_u32_index(np, porp_name, 3 * i + 2,
463 					   &volt_table[i].volt);
464 	}
465 	volt_table[i].min = 0;
466 	volt_table[i].max = 0;
467 	volt_table[i].volt = INT_MAX;
468 
469 	*table = volt_table;
470 
471 	return 0;
472 }
473 
rockchip_get_low_temp_volt(struct monitor_dev_info * info,unsigned long rate,int * delta_volt)474 static int rockchip_get_low_temp_volt(struct monitor_dev_info *info,
475 				      unsigned long rate, int *delta_volt)
476 {
477 	int i, ret = -EINVAL;
478 	unsigned int _rate = (unsigned int)(rate / 1000000);
479 
480 	if (!info->low_temp_adjust_table)
481 		return ret;
482 
483 	for (i = 0; info->low_temp_adjust_table[i].volt != INT_MAX; i++) {
484 		if (_rate >= info->low_temp_adjust_table[i].min &&
485 		    _rate <= info->low_temp_adjust_table[i].max) {
486 			*delta_volt = info->low_temp_adjust_table[i].volt;
487 			ret = 0;
488 		}
489 	}
490 
491 	return ret;
492 }
493 
rockchip_init_temp_opp_table(struct monitor_dev_info * info)494 static int rockchip_init_temp_opp_table(struct monitor_dev_info *info)
495 {
496 	struct device *dev = info->dev;
497 	struct opp_table *opp_table;
498 	struct dev_pm_opp *opp;
499 	int delta_volt = 0;
500 	int i = 0, max_count;
501 	unsigned long low_limit = 0, high_limit = 0;
502 	bool reach_max_volt = false;
503 	bool reach_high_temp_max_volt = false;
504 
505 	max_count = dev_pm_opp_get_opp_count(dev);
506 	if (max_count <= 0)
507 		return max_count ? max_count : -ENODATA;
508 	info->opp_table = kzalloc(sizeof(*info->opp_table) * max_count,
509 				  GFP_KERNEL);
510 	if (!info->opp_table)
511 		return -ENOMEM;
512 
513 	opp_table = dev_pm_opp_get_opp_table(dev);
514 	if (!opp_table) {
515 		kfree(info->opp_table);
516 		info->opp_table = NULL;
517 		return -ENOMEM;
518 	}
519 	mutex_lock(&opp_table->lock);
520 	list_for_each_entry(opp, &opp_table->opp_list, node) {
521 		info->opp_table[i].rate = opp->rate;
522 		info->opp_table[i].volt = opp->supplies[0].u_volt;
523 		info->opp_table[i].max_volt = opp->supplies[0].u_volt_max;
524 
525 		if (opp->supplies[0].u_volt <= info->high_temp_max_volt) {
526 			if (!reach_high_temp_max_volt)
527 				high_limit = opp->rate;
528 			if (opp->supplies[0].u_volt == info->high_temp_max_volt)
529 				reach_high_temp_max_volt = true;
530 		}
531 
532 		if (rockchip_get_low_temp_volt(info, opp->rate, &delta_volt))
533 			delta_volt = 0;
534 		if ((opp->supplies[0].u_volt + delta_volt) <= info->max_volt) {
535 			info->opp_table[i].low_temp_volt =
536 				opp->supplies[0].u_volt + delta_volt;
537 			if (info->opp_table[i].low_temp_volt <
538 			    info->low_temp_min_volt)
539 				info->opp_table[i].low_temp_volt =
540 					info->low_temp_min_volt;
541 			if (!reach_max_volt)
542 				low_limit = opp->rate;
543 			if (info->opp_table[i].low_temp_volt == info->max_volt)
544 				reach_max_volt = true;
545 		} else {
546 			info->opp_table[i].low_temp_volt = info->max_volt;
547 		}
548 		if (low_limit && low_limit != opp->rate)
549 			info->low_limit = low_limit;
550 		if (high_limit && high_limit != opp->rate)
551 			info->high_limit = high_limit;
552 		dev_dbg(dev, "rate=%lu, volt=%lu, low_temp_volt=%lu\n",
553 			info->opp_table[i].rate, info->opp_table[i].volt,
554 			info->opp_table[i].low_temp_volt);
555 		i++;
556 	}
557 	mutex_unlock(&opp_table->lock);
558 
559 	dev_pm_opp_put_opp_table(opp_table);
560 
561 	return 0;
562 }
563 
monitor_device_parse_wide_temp_config(struct device_node * np,struct monitor_dev_info * info)564 static int monitor_device_parse_wide_temp_config(struct device_node *np,
565 						 struct monitor_dev_info *info)
566 {
567 	struct device *dev = info->dev;
568 	unsigned long high_temp_max_freq;
569 	int ret = 0;
570 	u32 value;
571 
572 	np = of_parse_phandle(dev->of_node, "operating-points-v2", 0);
573 	if (!np)
574 		return -EINVAL;
575 
576 	if (of_property_read_u32(np, "rockchip,max-volt", &value))
577 		info->max_volt = ULONG_MAX;
578 	else
579 		info->max_volt = value;
580 	of_property_read_u32(np, "rockchip,temp-hysteresis",
581 			     &info->temp_hysteresis);
582 	if (of_property_read_u32(np, "rockchip,low-temp", &info->low_temp))
583 		info->low_temp = INT_MIN;
584 	rockchip_get_adjust_volt_table(np, "rockchip,low-temp-adjust-volt",
585 				       &info->low_temp_adjust_table);
586 	if (!of_property_read_u32(np, "rockchip,low-temp-min-volt", &value))
587 		info->low_temp_min_volt = value;
588 	if (of_property_read_u32(np, "rockchip,high-temp", &info->high_temp))
589 		info->high_temp = INT_MAX;
590 	if (of_property_read_u32(np, "rockchip,high-temp-max-volt",
591 				 &value))
592 		info->high_temp_max_volt = ULONG_MAX;
593 	else
594 		info->high_temp_max_volt = value;
595 	rockchip_init_temp_opp_table(info);
596 	rockchip_get_temp_freq_table(np, "rockchip,temp-freq-table",
597 				     &info->high_limit_table);
598 	if (!info->high_limit_table)
599 		rockchip_get_temp_freq_table(np, "rockchip,high-temp-limit-table",
600 					     &info->high_limit_table);
601 	if (!info->high_limit_table) {
602 		if (!of_property_read_u32(np, "rockchip,high-temp-max-freq",
603 					  &value)) {
604 			high_temp_max_freq = value * 1000;
605 			if (info->high_limit)
606 				info->high_limit = min(high_temp_max_freq,
607 						       info->high_limit);
608 			else
609 				info->high_limit = high_temp_max_freq;
610 		}
611 	} else {
612 		info->high_limit = 0;
613 	}
614 	dev_info(dev, "l=%d h=%d hyst=%d l_limit=%lu h_limit=%lu h_table=%d\n",
615 		 info->low_temp, info->high_temp, info->temp_hysteresis,
616 		 info->low_limit, info->high_limit,
617 		 info->high_limit_table ? true : false);
618 
619 	if ((info->low_temp + info->temp_hysteresis) > info->high_temp) {
620 		dev_err(dev, "Invalid temperature, low=%d high=%d hyst=%d\n",
621 			info->low_temp, info->high_temp,
622 			info->temp_hysteresis);
623 		ret = -EINVAL;
624 		goto err;
625 	}
626 	if (!info->low_temp_adjust_table && !info->low_temp_min_volt &&
627 	    !info->low_limit && !info->high_limit && !info->high_limit_table) {
628 		ret = -EINVAL;
629 		goto err;
630 	}
631 	if (info->low_temp_adjust_table || info->low_temp_min_volt)
632 		info->is_low_temp_enabled = true;
633 
634 	return 0;
635 err:
636 	kfree(info->low_temp_adjust_table);
637 	info->low_temp_adjust_table = NULL;
638 	kfree(info->opp_table);
639 	info->opp_table = NULL;
640 
641 	return ret;
642 }
643 
monitor_device_parse_status_config(struct device_node * np,struct monitor_dev_info * info)644 static int monitor_device_parse_status_config(struct device_node *np,
645 					      struct monitor_dev_info *info)
646 {
647 	int ret;
648 
649 	ret = of_property_read_u32(np, "rockchip,video-4k-freq",
650 				   &info->video_4k_freq);
651 	ret &= of_property_read_u32(np, "rockchip,reboot-freq",
652 				    &info->reboot_freq);
653 	if (info->devp->type == MONITOR_TPYE_CPU) {
654 		if (!info->reboot_freq) {
655 			info->reboot_freq = CPU_REBOOT_FREQ;
656 			ret = 0;
657 		}
658 	}
659 
660 	return ret;
661 }
662 
monitor_device_parse_early_min_volt(struct device_node * np,struct monitor_dev_info * info)663 static int monitor_device_parse_early_min_volt(struct device_node *np,
664 					       struct monitor_dev_info *info)
665 {
666 	return of_property_read_u32(np, "rockchip,early-min-microvolt",
667 				    &info->early_min_volt);
668 }
669 
monitor_device_parse_read_margin(struct device_node * np,struct monitor_dev_info * info)670 static int monitor_device_parse_read_margin(struct device_node *np,
671 					    struct monitor_dev_info *info)
672 {
673 	if (of_property_read_bool(np, "volt-mem-read-margin"))
674 		return 0;
675 	return -EINVAL;
676 }
677 
monitor_device_parse_scmi_clk(struct device_node * np,struct monitor_dev_info * info)678 static int monitor_device_parse_scmi_clk(struct device_node *np,
679 					 struct monitor_dev_info *info)
680 {
681 	struct clk *clk;
682 
683 	clk = clk_get(info->dev, NULL);
684 	if (strstr(__clk_get_name(clk), "scmi"))
685 		return 0;
686 	return -EINVAL;
687 }
688 
monitor_device_parse_dt(struct device * dev,struct monitor_dev_info * info)689 static int monitor_device_parse_dt(struct device *dev,
690 				   struct monitor_dev_info *info)
691 {
692 	struct device_node *np;
693 	int ret;
694 
695 	np = of_parse_phandle(dev->of_node, "operating-points-v2", 0);
696 	if (!np)
697 		return -EINVAL;
698 
699 	of_property_read_u32(np, "rockchip,init-freq", &info->init_freq);
700 
701 	ret = monitor_device_parse_wide_temp_config(np, info);
702 	ret &= monitor_device_parse_status_config(np, info);
703 	ret &= monitor_device_parse_early_min_volt(np, info);
704 	ret &= monitor_device_parse_read_margin(np, info);
705 	ret &= monitor_device_parse_scmi_clk(np, info);
706 
707 	of_node_put(np);
708 
709 	return ret;
710 }
711 
rockchip_monitor_cpu_low_temp_adjust(struct monitor_dev_info * info,bool is_low)712 int rockchip_monitor_cpu_low_temp_adjust(struct monitor_dev_info *info,
713 					 bool is_low)
714 {
715 	if (info->low_limit) {
716 		if (is_low)
717 			freq_qos_update_request(&info->max_temp_freq_req,
718 						info->low_limit / 1000);
719 		else
720 			freq_qos_update_request(&info->max_temp_freq_req,
721 						FREQ_QOS_MAX_DEFAULT_VALUE);
722 	}
723 
724 	return 0;
725 }
726 EXPORT_SYMBOL(rockchip_monitor_cpu_low_temp_adjust);
727 
rockchip_monitor_cpu_high_temp_adjust(struct monitor_dev_info * info,bool is_high)728 int rockchip_monitor_cpu_high_temp_adjust(struct monitor_dev_info *info,
729 					  bool is_high)
730 {
731 	if (!info->high_limit)
732 		return 0;
733 
734 	if (info->high_limit_table) {
735 		freq_qos_update_request(&info->max_temp_freq_req,
736 					info->high_limit / 1000);
737 		return 0;
738 	}
739 
740 	if (is_high)
741 		freq_qos_update_request(&info->max_temp_freq_req,
742 					info->high_limit / 1000);
743 	else
744 		freq_qos_update_request(&info->max_temp_freq_req,
745 					FREQ_QOS_MAX_DEFAULT_VALUE);
746 
747 	return 0;
748 }
749 EXPORT_SYMBOL(rockchip_monitor_cpu_high_temp_adjust);
750 
rockchip_monitor_dev_low_temp_adjust(struct monitor_dev_info * info,bool is_low)751 int rockchip_monitor_dev_low_temp_adjust(struct monitor_dev_info *info,
752 					 bool is_low)
753 {
754 	if (!info->low_limit)
755 		return 0;
756 
757 	if (is_low)
758 		dev_pm_qos_update_request(&info->dev_max_freq_req,
759 					  info->low_limit / 1000);
760 	else
761 		dev_pm_qos_update_request(&info->dev_max_freq_req,
762 					  PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
763 
764 	return 0;
765 }
766 EXPORT_SYMBOL(rockchip_monitor_dev_low_temp_adjust);
767 
rockchip_monitor_dev_high_temp_adjust(struct monitor_dev_info * info,bool is_high)768 int rockchip_monitor_dev_high_temp_adjust(struct monitor_dev_info *info,
769 					  bool is_high)
770 {
771 	if (!info->high_limit)
772 		return 0;
773 
774 	if (info->high_limit_table) {
775 		dev_pm_qos_update_request(&info->dev_max_freq_req,
776 					  info->high_limit / 1000);
777 		return 0;
778 	}
779 
780 	if (is_high)
781 		dev_pm_qos_update_request(&info->dev_max_freq_req,
782 					  info->high_limit / 1000);
783 	else
784 		dev_pm_qos_update_request(&info->dev_max_freq_req,
785 					  PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
786 
787 	return 0;
788 }
789 EXPORT_SYMBOL(rockchip_monitor_dev_high_temp_adjust);
790 
rockchip_adjust_low_temp_opp_volt(struct monitor_dev_info * info,bool is_low_temp)791 static int rockchip_adjust_low_temp_opp_volt(struct monitor_dev_info *info,
792 					     bool is_low_temp)
793 {
794 	struct device *dev = info->dev;
795 	struct opp_table *opp_table;
796 	struct dev_pm_opp *opp;
797 	int i = 0;
798 
799 	opp_table = dev_pm_opp_get_opp_table(dev);
800 	if (!opp_table)
801 		return -ENOMEM;
802 
803 	mutex_lock(&opp_table->lock);
804 	list_for_each_entry(opp, &opp_table->opp_list, node) {
805 		if (is_low_temp) {
806 			if (opp->supplies[0].u_volt_max <
807 			    info->opp_table[i].low_temp_volt)
808 				opp->supplies[0].u_volt_max =
809 					info->opp_table[i].low_temp_volt;
810 			opp->supplies[0].u_volt =
811 				info->opp_table[i].low_temp_volt;
812 			opp->supplies[0].u_volt_min = opp->supplies[0].u_volt;
813 		} else {
814 			opp->supplies[0].u_volt_min = info->opp_table[i].volt;
815 			opp->supplies[0].u_volt = opp->supplies[0].u_volt_min;
816 			opp->supplies[0].u_volt_max =
817 				info->opp_table[i].max_volt;
818 		}
819 		i++;
820 	}
821 	mutex_unlock(&opp_table->lock);
822 
823 	dev_pm_opp_put_opp_table(opp_table);
824 
825 	return 0;
826 }
827 
rockchip_low_temp_adjust(struct monitor_dev_info * info,bool is_low)828 static void rockchip_low_temp_adjust(struct monitor_dev_info *info,
829 				     bool is_low)
830 {
831 	struct monitor_dev_profile *devp = info->devp;
832 	int ret = 0;
833 
834 	dev_dbg(info->dev, "low_temp %d\n", is_low);
835 
836 	if (info->opp_table)
837 		rockchip_adjust_low_temp_opp_volt(info, is_low);
838 
839 	if (devp->low_temp_adjust)
840 		ret = devp->low_temp_adjust(info, is_low);
841 	if (!ret)
842 		info->is_low_temp = is_low;
843 
844 	if (devp->update_volt)
845 		devp->update_volt(info, false);
846 }
847 
rockchip_high_temp_adjust(struct monitor_dev_info * info,bool is_high)848 static void rockchip_high_temp_adjust(struct monitor_dev_info *info,
849 				      bool is_high)
850 {
851 	struct monitor_dev_profile *devp = info->devp;
852 	int ret = 0;
853 
854 	if (!devp->high_temp_adjust)
855 		return;
856 
857 	if (info->high_limit_table) {
858 		devp->high_temp_adjust(info, is_high);
859 	} else {
860 		dev_dbg(info->dev, "high_temp %d\n", is_high);
861 		ret = devp->high_temp_adjust(info, is_high);
862 		if (!ret)
863 			info->is_high_temp = is_high;
864 	}
865 }
866 
rockchip_monitor_suspend_low_temp_adjust(int cpu)867 int rockchip_monitor_suspend_low_temp_adjust(int cpu)
868 {
869 	struct monitor_dev_info *info = NULL, *tmp;
870 
871 	list_for_each_entry(tmp, &monitor_dev_list, node) {
872 		if (tmp->devp->type != MONITOR_TPYE_CPU)
873 			continue;
874 		if (cpumask_test_cpu(cpu, &tmp->devp->allowed_cpus)) {
875 			info = tmp;
876 			break;
877 		}
878 	}
879 
880 	if (!info || !info->is_low_temp_enabled)
881 		return 0;
882 
883 	if (info->high_limit_table) {
884 		info->high_limit = 0;
885 		rockchip_high_temp_adjust(info, true);
886 	} else if (info->is_high_temp) {
887 		rockchip_high_temp_adjust(info, false);
888 	}
889 	if (!info->is_low_temp)
890 		rockchip_low_temp_adjust(info, true);
891 
892 	return 0;
893 }
894 EXPORT_SYMBOL(rockchip_monitor_suspend_low_temp_adjust);
895 
896 static int
rockchip_system_monitor_wide_temp_adjust(struct monitor_dev_info * info,int temp)897 rockchip_system_monitor_wide_temp_adjust(struct monitor_dev_info *info,
898 					 int temp)
899 {
900 	unsigned long target_freq = 0;
901 	int i;
902 
903 	if (temp < info->low_temp) {
904 		if (!info->is_low_temp)
905 			rockchip_low_temp_adjust(info, true);
906 	} else if (temp > (info->low_temp + info->temp_hysteresis)) {
907 		if (info->is_low_temp)
908 			rockchip_low_temp_adjust(info, false);
909 	}
910 
911 	if (info->high_limit_table) {
912 		for (i = 0; info->high_limit_table[i].freq != UINT_MAX; i++) {
913 			if (temp > info->high_limit_table[i].temp)
914 				target_freq =
915 					info->high_limit_table[i].freq * 1000;
916 		}
917 		if (target_freq != info->high_limit) {
918 			info->high_limit = target_freq;
919 			rockchip_high_temp_adjust(info, true);
920 		}
921 	} else {
922 		if (temp > info->high_temp) {
923 			if (!info->is_high_temp)
924 				rockchip_high_temp_adjust(info, true);
925 		} else if (temp < (info->high_temp - info->temp_hysteresis)) {
926 			if (info->is_high_temp)
927 				rockchip_high_temp_adjust(info, false);
928 		}
929 	}
930 
931 	return 0;
932 }
933 
934 static void
rockchip_system_monitor_wide_temp_init(struct monitor_dev_info * info)935 rockchip_system_monitor_wide_temp_init(struct monitor_dev_info *info)
936 {
937 	int ret, temp;
938 
939 	if (!info->opp_table)
940 		return;
941 
942 	/*
943 	 * set the init state to low temperature that the voltage will be enough
944 	 * when cpu up at low temperature.
945 	 */
946 	if (!info->is_low_temp) {
947 		if (info->opp_table)
948 			rockchip_adjust_low_temp_opp_volt(info, true);
949 		info->is_low_temp = true;
950 	}
951 
952 	ret = thermal_zone_get_temp(system_monitor->tz, &temp);
953 	if (ret || temp == THERMAL_TEMP_INVALID) {
954 		dev_err(info->dev,
955 			"failed to read out thermal zone (%d)\n", ret);
956 		return;
957 	}
958 
959 	if (temp > info->high_temp) {
960 		if (info->opp_table)
961 			rockchip_adjust_low_temp_opp_volt(info, false);
962 		info->is_low_temp = false;
963 		info->is_high_temp = true;
964 	} else if (temp > (info->low_temp + info->temp_hysteresis)) {
965 		if (info->opp_table)
966 			rockchip_adjust_low_temp_opp_volt(info, false);
967 		info->is_low_temp = false;
968 	}
969 }
970 
get_rdev_name(struct regulator_dev * rdev)971 static const char *get_rdev_name(struct regulator_dev *rdev)
972 {
973 	if (rdev->constraints && rdev->constraints->name)
974 		return rdev->constraints->name;
975 	else if (rdev->desc->name)
976 		return rdev->desc->name;
977 	else
978 		return "";
979 }
980 
981 static void
rockchip_system_monitor_early_regulator_init(struct monitor_dev_info * info)982 rockchip_system_monitor_early_regulator_init(struct monitor_dev_info *info)
983 {
984 	struct regulator *reg;
985 	struct regulator_dev *rdev;
986 
987 	if (!info->early_min_volt || !info->regulators)
988 		return;
989 
990 	rdev = info->regulators[0]->rdev;
991 	reg = regulator_get(NULL, get_rdev_name(rdev));
992 	if (!IS_ERR_OR_NULL(reg)) {
993 		info->early_reg = reg;
994 		reg->voltage[PM_SUSPEND_ON].min_uV = info->early_min_volt;
995 		reg->voltage[PM_SUSPEND_ON].max_uV = rdev->constraints->max_uV;
996 	}
997 }
998 
999 static int
rockchip_system_monitor_freq_qos_requset(struct monitor_dev_info * info)1000 rockchip_system_monitor_freq_qos_requset(struct monitor_dev_info *info)
1001 {
1002 	struct devfreq *devfreq;
1003 	struct cpufreq_policy *policy;
1004 	int max_default_value = FREQ_QOS_MAX_DEFAULT_VALUE;
1005 	int ret;
1006 
1007 	if (info->is_low_temp && info->low_limit)
1008 		max_default_value = info->low_limit / 1000;
1009 	else if (info->is_high_temp && info->high_limit)
1010 		max_default_value = info->high_limit / 1000;
1011 
1012 	if (info->devp->type == MONITOR_TPYE_CPU) {
1013 		policy = (struct cpufreq_policy *)info->devp->data;
1014 		ret = freq_qos_add_request(&policy->constraints,
1015 					   &info->max_temp_freq_req,
1016 					   FREQ_QOS_MAX,
1017 					   max_default_value);
1018 		if (ret < 0) {
1019 			dev_info(info->dev,
1020 				 "failed to add temp freq constraint\n");
1021 			return ret;
1022 		}
1023 		ret = freq_qos_add_request(&policy->constraints,
1024 					   &info->min_sta_freq_req,
1025 					   FREQ_QOS_MIN,
1026 					   FREQ_QOS_MIN_DEFAULT_VALUE);
1027 		if (ret < 0) {
1028 			dev_info(info->dev,
1029 				 "failed to add sta freq constraint\n");
1030 			freq_qos_remove_request(&info->max_temp_freq_req);
1031 			return ret;
1032 		}
1033 		ret = freq_qos_add_request(&policy->constraints,
1034 					   &info->max_sta_freq_req,
1035 					   FREQ_QOS_MAX,
1036 					   FREQ_QOS_MAX_DEFAULT_VALUE);
1037 		if (ret < 0) {
1038 			dev_info(info->dev,
1039 				 "failed to add sta freq constraint\n");
1040 			freq_qos_remove_request(&info->max_temp_freq_req);
1041 			freq_qos_remove_request(&info->min_sta_freq_req);
1042 			return ret;
1043 		}
1044 	} else if (info->devp->type == MONITOR_TPYE_DEV) {
1045 		devfreq = (struct devfreq *)info->devp->data;
1046 		ret = dev_pm_qos_add_request(devfreq->dev.parent,
1047 					     &info->dev_max_freq_req,
1048 					     DEV_PM_QOS_MAX_FREQUENCY,
1049 					     max_default_value);
1050 		if (ret < 0) {
1051 			dev_info(info->dev, "failed to add freq constraint\n");
1052 			return ret;
1053 		}
1054 	}
1055 
1056 	return 0;
1057 }
1058 
rockchip_system_monitor_parse_supplies(struct device * dev,struct monitor_dev_info * info)1059 static int rockchip_system_monitor_parse_supplies(struct device *dev,
1060 						  struct monitor_dev_info *info)
1061 {
1062 	struct opp_table *opp_table;
1063 
1064 	opp_table = dev_pm_opp_get_opp_table(dev);
1065 	if (IS_ERR(opp_table))
1066 		return PTR_ERR(opp_table);
1067 
1068 	if (opp_table->clk)
1069 		info->clk = opp_table->clk;
1070 	if (opp_table->regulators)
1071 		info->regulators = opp_table->regulators;
1072 	info->regulator_count = opp_table->regulator_count;
1073 
1074 	dev_pm_opp_put_opp_table(opp_table);
1075 
1076 	return 0;
1077 }
1078 
rockchip_monitor_volt_adjust_lock(struct monitor_dev_info * info)1079 void rockchip_monitor_volt_adjust_lock(struct monitor_dev_info *info)
1080 {
1081 	if (info)
1082 		mutex_lock(&info->volt_adjust_mutex);
1083 }
1084 EXPORT_SYMBOL(rockchip_monitor_volt_adjust_lock);
1085 
rockchip_monitor_volt_adjust_unlock(struct monitor_dev_info * info)1086 void rockchip_monitor_volt_adjust_unlock(struct monitor_dev_info *info)
1087 {
1088 	if (info)
1089 		mutex_unlock(&info->volt_adjust_mutex);
1090 }
1091 EXPORT_SYMBOL(rockchip_monitor_volt_adjust_unlock);
1092 
rockchip_monitor_set_read_margin(struct device * dev,struct rockchip_opp_info * opp_info,unsigned long volt)1093 static int rockchip_monitor_set_read_margin(struct device *dev,
1094 					    struct rockchip_opp_info *opp_info,
1095 					    unsigned long volt)
1096 {
1097 
1098 	if (opp_info && opp_info->data && opp_info->data->set_read_margin) {
1099 		if (pm_runtime_active(dev))
1100 			opp_info->data->set_read_margin(dev, opp_info, volt);
1101 		opp_info->volt_rm = volt;
1102 	}
1103 
1104 	return 0;
1105 }
1106 
rockchip_monitor_check_rate_volt(struct monitor_dev_info * info,bool is_set_clk)1107 int rockchip_monitor_check_rate_volt(struct monitor_dev_info *info,
1108 				     bool is_set_clk)
1109 {
1110 	struct device *dev = info->dev;
1111 	struct regulator *vdd_reg = NULL;
1112 	struct regulator *mem_reg = NULL;
1113 	struct rockchip_opp_info *opp_info = info->devp->opp_info;
1114 	struct dev_pm_opp *opp;
1115 	unsigned long old_rate, new_rate, new_volt, new_mem_volt;
1116 	int old_volt, old_mem_volt;
1117 	int ret = 0;
1118 
1119 	if (!info->regulators || !info->clk)
1120 		return 0;
1121 
1122 	mutex_lock(&info->volt_adjust_mutex);
1123 	if (opp_info) {
1124 		ret = clk_bulk_prepare_enable(opp_info->num_clks,
1125 					      opp_info->clks);
1126 		if (ret) {
1127 			dev_err(dev, "failed to enable opp clks\n");
1128 			goto unlock;
1129 		}
1130 	}
1131 
1132 	vdd_reg = info->regulators[0];
1133 	old_rate = clk_get_rate(info->clk);
1134 	old_volt = regulator_get_voltage(vdd_reg);
1135 	if (info->regulator_count > 1) {
1136 		mem_reg = info->regulators[1];
1137 		old_mem_volt = regulator_get_voltage(mem_reg);
1138 	}
1139 
1140 	if (info->init_freq) {
1141 		new_rate = info->init_freq * 1000;
1142 		info->init_freq = 0;
1143 	} else {
1144 		new_rate = old_rate;
1145 	}
1146 	opp = dev_pm_opp_find_freq_ceil(dev, &new_rate);
1147 	if (IS_ERR(opp)) {
1148 		opp = dev_pm_opp_find_freq_floor(dev, &new_rate);
1149 		if (IS_ERR(opp)) {
1150 			ret = PTR_ERR(opp);
1151 			goto unlock;
1152 		}
1153 	}
1154 	new_volt = opp->supplies[0].u_volt;
1155 	if (info->regulator_count > 1)
1156 		new_mem_volt = opp->supplies[1].u_volt;
1157 	dev_pm_opp_put(opp);
1158 
1159 	if (old_rate == new_rate) {
1160 		if (info->regulator_count > 1) {
1161 			if (old_volt == new_volt &&
1162 			    new_mem_volt == old_mem_volt)
1163 				goto unlock;
1164 		} else if (old_volt == new_volt) {
1165 			goto unlock;
1166 		}
1167 	}
1168 	if (!new_volt || (info->regulator_count > 1 && !new_mem_volt))
1169 		goto unlock;
1170 
1171 	dev_dbg(dev, "%s: %lu Hz --> %lu Hz\n", __func__, old_rate, new_rate);
1172 	if (new_rate >= old_rate) {
1173 		if (info->regulator_count > 1) {
1174 			ret = regulator_set_voltage(mem_reg, new_mem_volt,
1175 						    INT_MAX);
1176 			if (ret) {
1177 				dev_err(dev, "%s: failed to set volt: %lu\n",
1178 					__func__, new_mem_volt);
1179 				goto restore_voltage;
1180 			}
1181 		}
1182 		ret = regulator_set_voltage(vdd_reg, new_volt, INT_MAX);
1183 		if (ret) {
1184 			dev_err(dev, "%s: failed to set volt: %lu\n",
1185 				__func__, new_volt);
1186 			goto restore_voltage;
1187 		}
1188 		rockchip_monitor_set_read_margin(dev, opp_info, new_volt);
1189 		if (new_rate == old_rate)
1190 			goto unlock;
1191 	}
1192 
1193 	if (is_set_clk && clk_set_rate(info->clk, new_rate)) {
1194 		dev_err(dev, "%s: failed to set clock rate: %lu\n",
1195 			__func__, new_rate);
1196 		goto restore_rm;
1197 	}
1198 
1199 	if (new_rate < old_rate) {
1200 		rockchip_monitor_set_read_margin(dev, opp_info, new_volt);
1201 		ret = regulator_set_voltage(vdd_reg, new_volt,
1202 					    INT_MAX);
1203 		if (ret) {
1204 			dev_err(dev, "%s: failed to set volt: %lu\n",
1205 				__func__, new_volt);
1206 			goto restore_freq;
1207 		}
1208 		if (info->regulator_count > 1) {
1209 			ret = regulator_set_voltage(mem_reg, new_mem_volt,
1210 						    INT_MAX);
1211 			if (ret) {
1212 				dev_err(dev, "%s: failed to set volt: %lu\n",
1213 					__func__, new_mem_volt);
1214 				goto restore_freq;
1215 			}
1216 		}
1217 	}
1218 	goto disable_clk;
1219 
1220 restore_freq:
1221 	if (is_set_clk && clk_set_rate(info->clk, old_rate))
1222 		dev_err(dev, "%s: failed to restore old-freq (%lu Hz)\n",
1223 			__func__, old_rate);
1224 restore_rm:
1225 	rockchip_monitor_set_read_margin(dev, opp_info, old_volt);
1226 restore_voltage:
1227 	if (info->regulator_count > 1)
1228 		regulator_set_voltage(mem_reg, old_mem_volt, INT_MAX);
1229 	regulator_set_voltage(vdd_reg, old_volt, INT_MAX);
1230 disable_clk:
1231 	if (opp_info)
1232 		clk_bulk_disable_unprepare(opp_info->num_clks, opp_info->clks);
1233 unlock:
1234 	mutex_unlock(&info->volt_adjust_mutex);
1235 
1236 	return ret;
1237 }
1238 EXPORT_SYMBOL(rockchip_monitor_check_rate_volt);
1239 
1240 struct monitor_dev_info *
rockchip_system_monitor_register(struct device * dev,struct monitor_dev_profile * devp)1241 rockchip_system_monitor_register(struct device *dev,
1242 				 struct monitor_dev_profile *devp)
1243 {
1244 	struct monitor_dev_info *info;
1245 
1246 	if (!system_monitor)
1247 		return ERR_PTR(-ENOMEM);
1248 
1249 	info = kzalloc(sizeof(*info), GFP_KERNEL);
1250 	if (!info)
1251 		return ERR_PTR(-ENOMEM);
1252 	info->dev = dev;
1253 	info->devp = devp;
1254 
1255 	mutex_init(&info->volt_adjust_mutex);
1256 
1257 	rockchip_system_monitor_parse_supplies(dev, info);
1258 	if (monitor_device_parse_dt(dev, info)) {
1259 		rockchip_monitor_check_rate_volt(info, true);
1260 		kfree(info);
1261 		return ERR_PTR(-EINVAL);
1262 	}
1263 
1264 	rockchip_system_monitor_early_regulator_init(info);
1265 	rockchip_system_monitor_wide_temp_init(info);
1266 	rockchip_monitor_check_rate_volt(info, true);
1267 	devp->is_checked = true;
1268 	rockchip_system_monitor_freq_qos_requset(info);
1269 
1270 	down_write(&mdev_list_sem);
1271 	list_add(&info->node, &monitor_dev_list);
1272 	up_write(&mdev_list_sem);
1273 
1274 	return info;
1275 }
1276 EXPORT_SYMBOL(rockchip_system_monitor_register);
1277 
rockchip_system_monitor_unregister(struct monitor_dev_info * info)1278 void rockchip_system_monitor_unregister(struct monitor_dev_info *info)
1279 {
1280 	if (!info)
1281 		return;
1282 
1283 	down_write(&mdev_list_sem);
1284 	list_del(&info->node);
1285 	up_write(&mdev_list_sem);
1286 
1287 	if (info->devp->type == MONITOR_TPYE_CPU) {
1288 		freq_qos_remove_request(&info->max_temp_freq_req);
1289 		freq_qos_remove_request(&info->min_sta_freq_req);
1290 		freq_qos_remove_request(&info->max_sta_freq_req);
1291 	} else {
1292 		dev_pm_qos_remove_request(&info->dev_max_freq_req);
1293 	}
1294 
1295 	kfree(info->low_temp_adjust_table);
1296 	kfree(info->opp_table);
1297 	kfree(info);
1298 }
1299 EXPORT_SYMBOL(rockchip_system_monitor_unregister);
1300 
notify_dummy(struct thermal_zone_device * tz,int trip)1301 static int notify_dummy(struct thermal_zone_device *tz, int trip)
1302 {
1303 	return 0;
1304 }
1305 
1306 static struct thermal_governor thermal_gov_dummy = {
1307 	.name		= "dummy",
1308 	.throttle	= notify_dummy,
1309 };
1310 
rockchip_system_monitor_parse_dt(struct system_monitor * monitor)1311 static int rockchip_system_monitor_parse_dt(struct system_monitor *monitor)
1312 {
1313 	struct device_node *np = monitor->dev->of_node;
1314 	const char *tz_name, *buf = NULL;
1315 
1316 	if (of_property_read_string(np, "rockchip,video-4k-offline-cpus", &buf))
1317 		cpumask_clear(&system_monitor->video_4k_offline_cpus);
1318 	else
1319 		cpulist_parse(buf, &monitor->video_4k_offline_cpus);
1320 
1321 	if (of_property_read_string(np, "rockchip,thermal-zone", &tz_name))
1322 		goto out;
1323 	monitor->tz = thermal_zone_get_zone_by_name(tz_name);
1324 	if (IS_ERR(monitor->tz)) {
1325 		monitor->tz = NULL;
1326 		goto out;
1327 	}
1328 	if (of_property_read_u32(np, "rockchip,polling-delay",
1329 				 &monitor->delay))
1330 		monitor->delay = THERMAL_POLLING_DELAY;
1331 
1332 	if (of_property_read_string(np, "rockchip,temp-offline-cpus",
1333 				    &buf))
1334 		cpumask_clear(&system_monitor->temp_offline_cpus);
1335 	else
1336 		cpulist_parse(buf, &system_monitor->temp_offline_cpus);
1337 
1338 	if (of_property_read_u32(np, "rockchip,offline-cpu-temp",
1339 				 &system_monitor->offline_cpus_temp))
1340 		system_monitor->offline_cpus_temp = INT_MAX;
1341 	of_property_read_u32(np, "rockchip,temp-hysteresis",
1342 			     &system_monitor->temp_hysteresis);
1343 
1344 	if (of_find_property(np, "rockchip,thermal-governor-dummy", NULL)) {
1345 		if (monitor->tz->governor->unbind_from_tz)
1346 			monitor->tz->governor->unbind_from_tz(monitor->tz);
1347 		monitor->tz->governor = &thermal_gov_dummy;
1348 	}
1349 
1350 out:
1351 	return 0;
1352 }
1353 
rockchip_system_monitor_cpu_on_off(void)1354 static void rockchip_system_monitor_cpu_on_off(void)
1355 {
1356 #ifdef CONFIG_HOTPLUG_CPU
1357 	struct cpumask online_cpus, offline_cpus;
1358 	unsigned int cpu;
1359 
1360 	mutex_lock(&cpu_on_off_mutex);
1361 
1362 	cpumask_clear(&offline_cpus);
1363 	if (system_monitor->is_temp_offline) {
1364 		cpumask_or(&offline_cpus, &system_monitor->status_offline_cpus,
1365 			   &system_monitor->temp_offline_cpus);
1366 	} else {
1367 		cpumask_copy(&offline_cpus,
1368 			     &system_monitor->status_offline_cpus);
1369 	}
1370 	if (cpumask_equal(&offline_cpus, &system_monitor->offline_cpus))
1371 		goto out;
1372 	cpumask_copy(&system_monitor->offline_cpus, &offline_cpus);
1373 	for_each_cpu(cpu, &system_monitor->offline_cpus) {
1374 		if (cpu_online(cpu))
1375 			remove_cpu(cpu);
1376 	}
1377 
1378 	cpumask_clear(&online_cpus);
1379 	cpumask_andnot(&online_cpus, cpu_possible_mask,
1380 		       &system_monitor->offline_cpus);
1381 	cpumask_xor(&online_cpus, cpu_online_mask, &online_cpus);
1382 	if (cpumask_empty(&online_cpus))
1383 		goto out;
1384 	for_each_cpu(cpu, &online_cpus)
1385 		add_cpu(cpu);
1386 
1387 out:
1388 	mutex_unlock(&cpu_on_off_mutex);
1389 #endif
1390 }
1391 
rockchip_system_monitor_temp_cpu_on_off(int temp)1392 static void rockchip_system_monitor_temp_cpu_on_off(int temp)
1393 {
1394 	bool is_temp_offline;
1395 
1396 	if (cpumask_empty(&system_monitor->temp_offline_cpus))
1397 		return;
1398 
1399 	if (temp > system_monitor->offline_cpus_temp)
1400 		is_temp_offline = true;
1401 	else if (temp < system_monitor->offline_cpus_temp -
1402 		 system_monitor->temp_hysteresis)
1403 		is_temp_offline = false;
1404 	else
1405 		return;
1406 
1407 	if (system_monitor->is_temp_offline == is_temp_offline)
1408 		return;
1409 	system_monitor->is_temp_offline = is_temp_offline;
1410 	rockchip_system_monitor_cpu_on_off();
1411 }
1412 
rockchip_system_monitor_thermal_update(void)1413 static void rockchip_system_monitor_thermal_update(void)
1414 {
1415 	int temp, ret;
1416 	struct monitor_dev_info *info;
1417 	static int last_temp = INT_MAX;
1418 
1419 	ret = thermal_zone_get_temp(system_monitor->tz, &temp);
1420 	if (ret || temp == THERMAL_TEMP_INVALID)
1421 		goto out;
1422 
1423 	dev_dbg(system_monitor->dev, "temperature=%d\n", temp);
1424 
1425 	if (temp < last_temp && last_temp - temp <= 2000)
1426 		goto out;
1427 	last_temp = temp;
1428 
1429 	down_read(&mdev_list_sem);
1430 	list_for_each_entry(info, &monitor_dev_list, node)
1431 		rockchip_system_monitor_wide_temp_adjust(info, temp);
1432 	up_read(&mdev_list_sem);
1433 
1434 	rockchip_system_monitor_temp_cpu_on_off(temp);
1435 
1436 out:
1437 	mod_delayed_work(system_freezable_wq, &system_monitor->thermal_work,
1438 			 msecs_to_jiffies(system_monitor->delay));
1439 }
1440 
rockchip_system_monitor_thermal_check(struct work_struct * work)1441 static void rockchip_system_monitor_thermal_check(struct work_struct *work)
1442 {
1443 	if (atomic_read(&monitor_in_suspend))
1444 		return;
1445 
1446 	rockchip_system_monitor_thermal_update();
1447 }
1448 
rockchip_system_status_cpu_limit_freq(struct monitor_dev_info * info,unsigned long status)1449 static void rockchip_system_status_cpu_limit_freq(struct monitor_dev_info *info,
1450 						  unsigned long status)
1451 {
1452 	unsigned int target_freq = 0;
1453 
1454 	if (status & SYS_STATUS_REBOOT) {
1455 		freq_qos_update_request(&info->max_sta_freq_req,
1456 					info->reboot_freq);
1457 		freq_qos_update_request(&info->min_sta_freq_req,
1458 					info->reboot_freq);
1459 		return;
1460 	}
1461 
1462 	if (info->video_4k_freq && (status & SYS_STATUS_VIDEO_4K))
1463 		target_freq = info->video_4k_freq;
1464 
1465 	if (target_freq == info->status_max_limit)
1466 		return;
1467 	info->status_max_limit = target_freq;
1468 	if (info->status_max_limit)
1469 		freq_qos_update_request(&info->max_sta_freq_req,
1470 					info->status_max_limit);
1471 	else
1472 		freq_qos_update_request(&info->max_sta_freq_req,
1473 					FREQ_QOS_MAX_DEFAULT_VALUE);
1474 }
1475 
rockchip_system_status_limit_freq(unsigned long status)1476 static void rockchip_system_status_limit_freq(unsigned long status)
1477 {
1478 	struct monitor_dev_info *info;
1479 
1480 	down_read(&mdev_list_sem);
1481 	list_for_each_entry(info, &monitor_dev_list, node) {
1482 		if (info->devp->type == MONITOR_TPYE_CPU)
1483 			rockchip_system_status_cpu_limit_freq(info, status);
1484 	}
1485 	up_read(&mdev_list_sem);
1486 }
1487 
rockchip_system_status_cpu_on_off(unsigned long status)1488 static void rockchip_system_status_cpu_on_off(unsigned long status)
1489 {
1490 	struct cpumask offline_cpus;
1491 
1492 	if (cpumask_empty(&system_monitor->video_4k_offline_cpus))
1493 		return;
1494 
1495 	cpumask_clear(&offline_cpus);
1496 	if (status & SYS_STATUS_VIDEO_4K)
1497 		cpumask_copy(&offline_cpus,
1498 			     &system_monitor->video_4k_offline_cpus);
1499 	if (cpumask_equal(&offline_cpus, &system_monitor->status_offline_cpus))
1500 		return;
1501 	cpumask_copy(&system_monitor->status_offline_cpus, &offline_cpus);
1502 	rockchip_system_monitor_cpu_on_off();
1503 }
1504 
rockchip_system_status_notifier(struct notifier_block * nb,unsigned long status,void * ptr)1505 static int rockchip_system_status_notifier(struct notifier_block *nb,
1506 					   unsigned long status,
1507 					   void *ptr)
1508 {
1509 	rockchip_system_status_limit_freq(status);
1510 
1511 	rockchip_system_status_cpu_on_off(status);
1512 
1513 	return NOTIFY_OK;
1514 }
1515 
monitor_pm_notify(struct notifier_block * nb,unsigned long mode,void * _unused)1516 static int monitor_pm_notify(struct notifier_block *nb,
1517 			     unsigned long mode, void *_unused)
1518 {
1519 	switch (mode) {
1520 	case PM_HIBERNATION_PREPARE:
1521 	case PM_RESTORE_PREPARE:
1522 	case PM_SUSPEND_PREPARE:
1523 		atomic_set(&monitor_in_suspend, 1);
1524 		break;
1525 	case PM_POST_HIBERNATION:
1526 	case PM_POST_RESTORE:
1527 	case PM_POST_SUSPEND:
1528 		if (system_monitor->tz)
1529 			rockchip_system_monitor_thermal_update();
1530 		atomic_set(&monitor_in_suspend, 0);
1531 		break;
1532 	default:
1533 		break;
1534 	}
1535 	return 0;
1536 }
1537 
1538 static struct notifier_block monitor_pm_nb = {
1539 	.notifier_call = monitor_pm_notify,
1540 };
1541 
rockchip_monitor_reboot_notifier(struct notifier_block * nb,unsigned long action,void * ptr)1542 static int rockchip_monitor_reboot_notifier(struct notifier_block *nb,
1543 					     unsigned long action, void *ptr)
1544 {
1545 	rockchip_set_system_status(SYS_STATUS_REBOOT);
1546 	if (system_monitor->tz)
1547 		cancel_delayed_work_sync(&system_monitor->thermal_work);
1548 
1549 	return NOTIFY_OK;
1550 }
1551 
1552 static struct notifier_block rockchip_monitor_reboot_nb = {
1553 	.notifier_call = rockchip_monitor_reboot_notifier,
1554 };
1555 
rockchip_monitor_fb_notifier(struct notifier_block * nb,unsigned long action,void * ptr)1556 static int rockchip_monitor_fb_notifier(struct notifier_block *nb,
1557 					unsigned long action, void *ptr)
1558 {
1559 	struct fb_event *event = ptr;
1560 
1561 	if (action != FB_EVENT_BLANK)
1562 		return NOTIFY_OK;
1563 
1564 	switch (*((int *)event->data)) {
1565 	case FB_BLANK_UNBLANK:
1566 		rockchip_clear_system_status(SYS_STATUS_SUSPEND);
1567 		break;
1568 	case FB_BLANK_POWERDOWN:
1569 		rockchip_set_system_status(SYS_STATUS_SUSPEND);
1570 		break;
1571 	default:
1572 		break;
1573 	}
1574 
1575 	return NOTIFY_OK;
1576 }
1577 
1578 static struct notifier_block rockchip_monitor_fb_nb = {
1579 	.notifier_call = rockchip_monitor_fb_notifier,
1580 };
1581 
rockchip_eink_devfs_notifier(struct notifier_block * nb,unsigned long action,void * ptr)1582 static int rockchip_eink_devfs_notifier(struct notifier_block *nb,
1583 					unsigned long action, void *ptr)
1584 {
1585 	switch (action) {
1586 	case EBC_ON:
1587 		rockchip_clear_system_status(SYS_STATUS_LOW_POWER);
1588 		break;
1589 	case EBC_OFF:
1590 		rockchip_set_system_status(SYS_STATUS_LOW_POWER);
1591 		break;
1592 	default:
1593 		break;
1594 	}
1595 
1596 	return NOTIFY_OK;
1597 }
1598 
1599 static struct notifier_block rockchip_monitor_ebc_nb = {
1600 	.notifier_call = rockchip_eink_devfs_notifier,
1601 };
1602 
system_monitor_early_min_volt_function(struct work_struct * work)1603 static void system_monitor_early_min_volt_function(struct work_struct *work)
1604 {
1605 	struct monitor_dev_info *info;
1606 	struct regulator_dev *rdev;
1607 	int min_uV, max_uV;
1608 	int ret;
1609 
1610 	down_read(&mdev_list_sem);
1611 	list_for_each_entry(info, &monitor_dev_list, node) {
1612 		if (!info->early_min_volt || !info->early_reg)
1613 			continue;
1614 		rdev = info->early_reg->rdev;
1615 		min_uV = rdev->constraints->min_uV;
1616 		max_uV = rdev->constraints->max_uV;
1617 		ret = regulator_set_voltage(info->early_reg, min_uV, max_uV);
1618 		if (ret)
1619 			dev_err(&rdev->dev,
1620 				"%s: failed to set volt\n", __func__);
1621 		regulator_put(info->early_reg);
1622 	}
1623 	up_read(&mdev_list_sem);
1624 }
1625 
1626 static DECLARE_DELAYED_WORK(system_monitor_early_min_volt_work,
1627 			    system_monitor_early_min_volt_function);
1628 
rockchip_system_monitor_probe(struct platform_device * pdev)1629 static int rockchip_system_monitor_probe(struct platform_device *pdev)
1630 {
1631 	struct device *dev = &pdev->dev;
1632 
1633 	system_monitor = devm_kzalloc(dev, sizeof(struct system_monitor),
1634 				      GFP_KERNEL);
1635 	if (!system_monitor)
1636 		return -ENOMEM;
1637 	system_monitor->dev = dev;
1638 
1639 	system_monitor->kobj = kobject_create_and_add("system_monitor", NULL);
1640 	if (!system_monitor->kobj)
1641 		return -ENOMEM;
1642 	if (sysfs_create_file(system_monitor->kobj, &status.attr))
1643 		dev_err(dev, "failed to create system status sysfs\n");
1644 
1645 	cpumask_clear(&system_monitor->status_offline_cpus);
1646 	cpumask_clear(&system_monitor->offline_cpus);
1647 
1648 	rockchip_system_monitor_parse_dt(system_monitor);
1649 	if (system_monitor->tz) {
1650 		INIT_DELAYED_WORK(&system_monitor->thermal_work,
1651 				  rockchip_system_monitor_thermal_check);
1652 		mod_delayed_work(system_freezable_wq,
1653 				 &system_monitor->thermal_work,
1654 				 msecs_to_jiffies(system_monitor->delay));
1655 	}
1656 
1657 	system_monitor->status_nb.notifier_call =
1658 		rockchip_system_status_notifier;
1659 	rockchip_register_system_status_notifier(&system_monitor->status_nb);
1660 
1661 	if (register_pm_notifier(&monitor_pm_nb))
1662 		dev_err(dev, "failed to register suspend notifier\n");
1663 
1664 	register_reboot_notifier(&rockchip_monitor_reboot_nb);
1665 
1666 	if (fb_register_client(&rockchip_monitor_fb_nb))
1667 		dev_err(dev, "failed to register fb nb\n");
1668 
1669 	ebc_register_notifier(&rockchip_monitor_ebc_nb);
1670 
1671 	schedule_delayed_work(&system_monitor_early_min_volt_work,
1672 			      msecs_to_jiffies(30000));
1673 
1674 	dev_info(dev, "system monitor probe\n");
1675 
1676 	return 0;
1677 }
1678 
1679 static const struct of_device_id rockchip_system_monitor_of_match[] = {
1680 	{
1681 		.compatible = "rockchip,system-monitor",
1682 	},
1683 	{ /* sentinel */ },
1684 };
1685 MODULE_DEVICE_TABLE(of, rockchip_system_monitor_of_match);
1686 
1687 static struct platform_driver rockchip_system_monitor_driver = {
1688 	.probe	= rockchip_system_monitor_probe,
1689 	.driver = {
1690 		.name	= "rockchip-system-monitor",
1691 		.of_match_table = rockchip_system_monitor_of_match,
1692 	},
1693 };
1694 module_platform_driver(rockchip_system_monitor_driver);
1695 
1696 MODULE_LICENSE("GPL v2");
1697 MODULE_AUTHOR("Finley Xiao <finley.xiao@rock-chips.com>");
1698 MODULE_DESCRIPTION("rockchip system monitor driver");
1699