xref: /OK3568_Linux_fs/kernel/include/soc/rockchip/rockchip_system_monitor.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2019, Fuzhou Rockchip Electronics Co., Ltd
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #ifndef __SOC_ROCKCHIP_SYSTEM_MONITOR_H
7*4882a593Smuzhiyun #define __SOC_ROCKCHIP_SYSTEM_MONITOR_H
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/pm_opp.h>
10*4882a593Smuzhiyun #include <linux/pm_qos.h>
11*4882a593Smuzhiyun #include <linux/regulator/consumer.h>
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun enum monitor_dev_type {
14*4882a593Smuzhiyun 	MONITOR_TYPE_CPU = 0,	/* CPU */
15*4882a593Smuzhiyun 	MONITOR_TYPE_DEV,	/* GPU, NPU, DMC, and so on */
16*4882a593Smuzhiyun };
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun enum system_monitor_event_type {
19*4882a593Smuzhiyun 	SYSTEM_MONITOR_CHANGE_TEMP = 0,
20*4882a593Smuzhiyun };
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun struct system_monitor_event_data {
23*4882a593Smuzhiyun 	int temp;
24*4882a593Smuzhiyun };
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun struct volt_adjust_table {
27*4882a593Smuzhiyun 	unsigned int min;	/* Minimum frequency in MHz */
28*4882a593Smuzhiyun 	unsigned int max;	/* Maximum frequency in MHz */
29*4882a593Smuzhiyun 	int volt;		/* Voltage in microvolt */
30*4882a593Smuzhiyun };
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun struct temp_freq_table {
33*4882a593Smuzhiyun 	int temp;		/* millicelsius */
34*4882a593Smuzhiyun 	unsigned int freq;	/* KHz */
35*4882a593Smuzhiyun };
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun /**
38*4882a593Smuzhiyun  * struct temp_opp_table - System monitor device OPP description structure
39*4882a593Smuzhiyun  * @rate:		Frequency in hertz
40*4882a593Smuzhiyun  * @volt:		Target voltage in microvolt
41*4882a593Smuzhiyun  * @mem_volt:		Target voltage for memory in microvolt
42*4882a593Smuzhiyun  * @low_temp_volt:	Target voltage when low temperature, in microvolt
43*4882a593Smuzhiyun  * @low_temp_mem_volt:	Target voltage for memory when low temperature,
44*4882a593Smuzhiyun  *			in microvolt
45*4882a593Smuzhiyun  * @max_volt:		Maximum voltage in microvolt
46*4882a593Smuzhiyun  * @max_mem_volt:	Maximum voltage for memory in microvolt
47*4882a593Smuzhiyun  */
48*4882a593Smuzhiyun struct temp_opp_table {
49*4882a593Smuzhiyun 	unsigned long rate;
50*4882a593Smuzhiyun 	unsigned long volt;
51*4882a593Smuzhiyun 	unsigned long mem_volt;
52*4882a593Smuzhiyun 	unsigned long low_temp_volt;
53*4882a593Smuzhiyun 	unsigned long low_temp_mem_volt;
54*4882a593Smuzhiyun 	unsigned long max_volt;
55*4882a593Smuzhiyun 	unsigned long max_mem_volt;
56*4882a593Smuzhiyun };
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun /**
59*4882a593Smuzhiyun  * struct monitor_dev_info - structure for a system monitor device
60*4882a593Smuzhiyun  * @dev:		Device registered by system monitor
61*4882a593Smuzhiyun  * @low_temp_adjust_table:	Voltage margin for different OPPs when lowe
62*4882a593Smuzhiyun  *				temperature
63*4882a593Smuzhiyun  * @opp_table:		Frequency and voltage information of device
64*4882a593Smuzhiyun  * @devp:		Device-specific system monitor profile
65*4882a593Smuzhiyun  * @node:		Node in monitor_dev_list
66*4882a593Smuzhiyun  * @high_limit_table:	Limit maximum frequency at different temperature,
67*4882a593Smuzhiyun  *			but the frequency is also changed by thermal framework.
68*4882a593Smuzhiyun  * @volt_adjust_mutex:	A mutex to protect changing voltage.
69*4882a593Smuzhiyun  * @max_temp_freq_req:	CPU maximum frequency constraint changed according
70*4882a593Smuzhiyun  *			to temperature.
71*4882a593Smuzhiyun  * @min_sta_freq_req:   CPU minimum frequency constraint changed according
72*4882a593Smuzhiyun  *			to system status.
73*4882a593Smuzhiyun  * @max_sta_freq_req:   CPU maximum frequency constraint changed according
74*4882a593Smuzhiyun  *			to system status.
75*4882a593Smuzhiyun  * @dev_max_freq_req:	Devices maximum frequency constraint changed according
76*4882a593Smuzhiyun  *			to temperature.
77*4882a593Smuzhiyun  * @low_limit:		Limit maximum frequency when low temperature, in Hz
78*4882a593Smuzhiyun  * @high_limit:		Limit maximum frequency when high temperature, in Hz
79*4882a593Smuzhiyun  * @max_volt:		Maximum voltage in microvolt
80*4882a593Smuzhiyun  * @low_temp_min_volt:	Minimum voltage of OPPs when low temperature, in
81*4882a593Smuzhiyun  *			microvolt
82*4882a593Smuzhiyun  * @high_temp_max_volt:	Maximum voltage when high temperature, in microvolt
83*4882a593Smuzhiyun  * @wide_temp_limit:	Target maximum frequency when low or high temperature,
84*4882a593Smuzhiyun  *			in Hz
85*4882a593Smuzhiyun  * @video_4k_freq:	Maximum frequency when paly 4k video, in KHz
86*4882a593Smuzhiyun  * @reboot_freq:	Limit maximum and minimum frequency when reboot, in KHz
87*4882a593Smuzhiyun  * @status_min_limit:	Minimum frequency of some status frequency, in KHz
88*4882a593Smuzhiyun  * @status_max_limit:	Minimum frequency of all status frequency, in KHz
89*4882a593Smuzhiyun  * @low_temp:		Low temperature trip point, in millicelsius
90*4882a593Smuzhiyun  * @high_temp:		High temperature trip point, in millicelsius
91*4882a593Smuzhiyun  * @temp_hysteresis:	A low hysteresis value on low_temp, in millicelsius
92*4882a593Smuzhiyun  * @is_low_temp:	True if current temperature less than low_temp
93*4882a593Smuzhiyun  * @is_high_temp:	True if current temperature greater than high_temp
94*4882a593Smuzhiyun  * @is_low_temp_enabled:	True if device node contains low temperature
95*4882a593Smuzhiyun  *				configuration
96*4882a593Smuzhiyun  * @is_status_freq_fixed:	True if enter into some status
97*4882a593Smuzhiyun  */
98*4882a593Smuzhiyun struct monitor_dev_info {
99*4882a593Smuzhiyun 	struct device *dev;
100*4882a593Smuzhiyun 	struct volt_adjust_table *low_temp_adjust_table;
101*4882a593Smuzhiyun 	struct temp_opp_table *opp_table;
102*4882a593Smuzhiyun 	struct monitor_dev_profile *devp;
103*4882a593Smuzhiyun 	struct list_head node;
104*4882a593Smuzhiyun 	struct temp_freq_table *high_limit_table;
105*4882a593Smuzhiyun 	struct mutex volt_adjust_mutex;
106*4882a593Smuzhiyun 	struct freq_qos_request max_temp_freq_req;
107*4882a593Smuzhiyun 	struct freq_qos_request min_sta_freq_req;
108*4882a593Smuzhiyun 	struct freq_qos_request max_sta_freq_req;
109*4882a593Smuzhiyun 	struct dev_pm_qos_request dev_max_freq_req;
110*4882a593Smuzhiyun 	struct regulator *early_reg;
111*4882a593Smuzhiyun 	struct regulator **regulators;
112*4882a593Smuzhiyun 	struct dev_pm_set_opp_data *set_opp_data;
113*4882a593Smuzhiyun 	struct clk *clk;
114*4882a593Smuzhiyun 	unsigned long low_limit;
115*4882a593Smuzhiyun 	unsigned long high_limit;
116*4882a593Smuzhiyun 	unsigned long max_volt;
117*4882a593Smuzhiyun 	unsigned long low_temp_min_volt;
118*4882a593Smuzhiyun 	unsigned long high_temp_max_volt;
119*4882a593Smuzhiyun 	unsigned int video_4k_freq;
120*4882a593Smuzhiyun 	unsigned int reboot_freq;
121*4882a593Smuzhiyun 	unsigned int init_freq;
122*4882a593Smuzhiyun 	unsigned int status_min_limit;
123*4882a593Smuzhiyun 	unsigned int status_max_limit;
124*4882a593Smuzhiyun 	unsigned int early_min_volt;
125*4882a593Smuzhiyun 	unsigned int regulator_count;
126*4882a593Smuzhiyun 	int low_temp;
127*4882a593Smuzhiyun 	int high_temp;
128*4882a593Smuzhiyun 	int temp_hysteresis;
129*4882a593Smuzhiyun 	bool is_low_temp;
130*4882a593Smuzhiyun 	bool is_high_temp;
131*4882a593Smuzhiyun 	bool is_low_temp_enabled;
132*4882a593Smuzhiyun };
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun struct monitor_dev_profile {
135*4882a593Smuzhiyun 	enum monitor_dev_type type;
136*4882a593Smuzhiyun 	void *data;
137*4882a593Smuzhiyun 	bool is_checked;
138*4882a593Smuzhiyun 	int (*low_temp_adjust)(struct monitor_dev_info *info, bool is_low);
139*4882a593Smuzhiyun 	int (*high_temp_adjust)(struct monitor_dev_info *info, bool is_low);
140*4882a593Smuzhiyun 	int (*update_volt)(struct monitor_dev_info *info);
141*4882a593Smuzhiyun 	int (*set_opp)(struct dev_pm_set_opp_data *data);
142*4882a593Smuzhiyun 	struct cpumask allowed_cpus;
143*4882a593Smuzhiyun 	struct rockchip_opp_info *opp_info;
144*4882a593Smuzhiyun };
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun #if IS_REACHABLE(CONFIG_ROCKCHIP_SYSTEM_MONITOR)
147*4882a593Smuzhiyun struct monitor_dev_info *
148*4882a593Smuzhiyun rockchip_system_monitor_register(struct device *dev,
149*4882a593Smuzhiyun 				 struct monitor_dev_profile *devp);
150*4882a593Smuzhiyun void rockchip_system_monitor_unregister(struct monitor_dev_info *info);
151*4882a593Smuzhiyun int rockchip_monitor_cpu_low_temp_adjust(struct monitor_dev_info *info,
152*4882a593Smuzhiyun 					 bool is_low);
153*4882a593Smuzhiyun int rockchip_monitor_cpu_high_temp_adjust(struct monitor_dev_info *info,
154*4882a593Smuzhiyun 					  bool is_high);
155*4882a593Smuzhiyun void rockchip_monitor_volt_adjust_lock(struct monitor_dev_info *info);
156*4882a593Smuzhiyun void rockchip_monitor_volt_adjust_unlock(struct monitor_dev_info *info);
157*4882a593Smuzhiyun int rockchip_monitor_check_rate_volt(struct monitor_dev_info *info);
158*4882a593Smuzhiyun int rockchip_monitor_dev_low_temp_adjust(struct monitor_dev_info *info,
159*4882a593Smuzhiyun 					 bool is_low);
160*4882a593Smuzhiyun int rockchip_monitor_dev_high_temp_adjust(struct monitor_dev_info *info,
161*4882a593Smuzhiyun 					  bool is_high);
162*4882a593Smuzhiyun int rockchip_monitor_suspend_low_temp_adjust(int cpu);
163*4882a593Smuzhiyun int rockchip_system_monitor_register_notifier(struct notifier_block *nb);
164*4882a593Smuzhiyun void rockchip_system_monitor_unregister_notifier(struct notifier_block *nb);
165*4882a593Smuzhiyun #else
166*4882a593Smuzhiyun static inline struct monitor_dev_info *
rockchip_system_monitor_register(struct device * dev,struct monitor_dev_profile * devp)167*4882a593Smuzhiyun rockchip_system_monitor_register(struct device *dev,
168*4882a593Smuzhiyun 				 struct monitor_dev_profile *devp)
169*4882a593Smuzhiyun {
170*4882a593Smuzhiyun 	return ERR_PTR(-ENOTSUPP);
171*4882a593Smuzhiyun };
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun static inline void
rockchip_system_monitor_unregister(struct monitor_dev_info * info)174*4882a593Smuzhiyun rockchip_system_monitor_unregister(struct monitor_dev_info *info)
175*4882a593Smuzhiyun {
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun static inline int
rockchip_monitor_cpu_low_temp_adjust(struct monitor_dev_info * info,bool is_low)179*4882a593Smuzhiyun rockchip_monitor_cpu_low_temp_adjust(struct monitor_dev_info *info, bool is_low)
180*4882a593Smuzhiyun {
181*4882a593Smuzhiyun 	return 0;
182*4882a593Smuzhiyun };
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun static inline int
rockchip_monitor_cpu_high_temp_adjust(struct monitor_dev_info * info,bool is_high)185*4882a593Smuzhiyun rockchip_monitor_cpu_high_temp_adjust(struct monitor_dev_info *info,
186*4882a593Smuzhiyun 				      bool is_high)
187*4882a593Smuzhiyun {
188*4882a593Smuzhiyun 	return 0;
189*4882a593Smuzhiyun };
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun static inline void
rockchip_monitor_volt_adjust_lock(struct monitor_dev_info * info)192*4882a593Smuzhiyun rockchip_monitor_volt_adjust_lock(struct monitor_dev_info *info)
193*4882a593Smuzhiyun {
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun static inline void
rockchip_monitor_volt_adjust_unlock(struct monitor_dev_info * info)197*4882a593Smuzhiyun rockchip_monitor_volt_adjust_unlock(struct monitor_dev_info *info)
198*4882a593Smuzhiyun {
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun static inline int
rockchip_monitor_check_rate_volt(struct monitor_dev_info * info)202*4882a593Smuzhiyun rockchip_monitor_check_rate_volt(struct monitor_dev_info *info)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun 	return 0;
205*4882a593Smuzhiyun }
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun static inline int
rockchip_monitor_dev_low_temp_adjust(struct monitor_dev_info * info,bool is_low)208*4882a593Smuzhiyun rockchip_monitor_dev_low_temp_adjust(struct monitor_dev_info *info, bool is_low)
209*4882a593Smuzhiyun {
210*4882a593Smuzhiyun 	return 0;
211*4882a593Smuzhiyun };
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun static inline int
rockchip_monitor_dev_high_temp_adjust(struct monitor_dev_info * info,bool is_high)214*4882a593Smuzhiyun rockchip_monitor_dev_high_temp_adjust(struct monitor_dev_info *info,
215*4882a593Smuzhiyun 				      bool is_high)
216*4882a593Smuzhiyun {
217*4882a593Smuzhiyun 	return 0;
218*4882a593Smuzhiyun };
219*4882a593Smuzhiyun 
rockchip_monitor_suspend_low_temp_adjust(int cpu)220*4882a593Smuzhiyun static inline int rockchip_monitor_suspend_low_temp_adjust(int cpu)
221*4882a593Smuzhiyun {
222*4882a593Smuzhiyun 	return 0;
223*4882a593Smuzhiyun };
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun static inline int
rockchip_system_monitor_register_notifier(struct notifier_block * nb)226*4882a593Smuzhiyun rockchip_system_monitor_register_notifier(struct notifier_block *nb)
227*4882a593Smuzhiyun {
228*4882a593Smuzhiyun 	return 0;
229*4882a593Smuzhiyun };
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun static inline void
rockchip_system_monitor_unregister_notifier(struct notifier_block * nb)232*4882a593Smuzhiyun rockchip_system_monitor_unregister_notifier(struct notifier_block *nb)
233*4882a593Smuzhiyun {
234*4882a593Smuzhiyun };
235*4882a593Smuzhiyun #endif /* CONFIG_ROCKCHIP_SYSTEM_MONITOR */
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun #endif
238