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