summaryrefslogtreecommitdiff
path: root/include/linux/msm_thermal.h
blob: 1098a0c9afaaf8bf869a66c0984320c6512d70ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
/*
 * Copyright (c) 2012-2016,2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#ifndef __MSM_THERMAL_H
#define __MSM_THERMAL_H

#include <linux/thermal.h>

#define MAX_THRESHOLD  2
#define TSENS_NAME_MAX 20
#define MONITOR_ALL_TSENS -1
#define HOTPLUG_DEVICE "hotplug"
#define CPU0_DEVICE     "cpu0"
#define CPU1_DEVICE     "cpu1"
#define CPU2_DEVICE     "cpu2"
#define CPU3_DEVICE     "cpu3"
#define CPU4_DEVICE     "cpu4"
#define CPU5_DEVICE     "cpu5"
#define CPU6_DEVICE     "cpu6"
#define CPU7_DEVICE     "cpu7"
#define CPUFREQ_MAX_NO_MITIGATION     UINT_MAX
#define CPUFREQ_MIN_NO_MITIGATION     0
#define HOTPLUG_NO_MITIGATION(_mask)  cpumask_clear(_mask)

#define IS_HI_THRESHOLD_SET(_val) (_val & 1)
#define IS_LOW_THRESHOLD_SET(_val) (_val & 2)

struct msm_thermal_data {
	struct platform_device *pdev;
	uint32_t sensor_id;
	uint32_t poll_ms;
	int32_t limit_temp_degC;
	int32_t temp_hysteresis_degC;
	uint32_t bootup_freq_step;
	uint32_t bootup_freq_control_mask;
	int32_t core_limit_temp_degC;
	int32_t core_temp_hysteresis_degC;
	int32_t hotplug_temp_degC;
	int32_t hotplug_temp_hysteresis_degC;
	uint32_t core_control_mask;
	uint32_t freq_mitig_temp_degc;
	uint32_t freq_mitig_temp_hysteresis_degc;
	uint32_t freq_mitig_control_mask;
	uint32_t freq_limit;
	int32_t vdd_rstr_temp_degC;
	int32_t vdd_rstr_temp_hyst_degC;
	int32_t vdd_rstr_sensor_id;
	int32_t vdd_mx_min;
	int32_t vdd_cx_min;
	int32_t psm_temp_degC;
	int32_t psm_temp_hyst_degC;
	int32_t ocr_temp_degC;
	int32_t ocr_temp_hyst_degC;
	uint32_t ocr_sensor_id;
	int32_t phase_rpm_resource_type;
	int32_t phase_rpm_resource_id;
	int32_t gfx_phase_warm_temp_degC;
	int32_t gfx_phase_warm_temp_hyst_degC;
	int32_t gfx_phase_hot_temp_degC;
	int32_t gfx_phase_hot_temp_hyst_degC;
	int32_t gfx_sensor;
	int32_t gfx_phase_request_key;
	int32_t cx_phase_hot_temp_degC;
	int32_t cx_phase_hot_temp_hyst_degC;
	int32_t cx_phase_request_key;
	int32_t vdd_mx_temp_degC;
	int32_t vdd_mx_temp_hyst_degC;
	int32_t vdd_mx_sensor_id;
	int32_t therm_reset_temp_degC;
};

enum sensor_id_type {
	THERM_ZONE_ID,
	THERM_TSENS_ID,
	THERM_ID_MAX_NR,
};

struct threshold_info;
struct therm_threshold {
	int32_t                     sensor_id;
	enum sensor_id_type         id_type;
	struct sensor_threshold     threshold[MAX_THRESHOLD];
	int32_t                     trip_triggered;
	void (*notify)(struct therm_threshold *);
	struct threshold_info       *parent;
	int32_t                     cur_state;
};

struct threshold_info {
	uint32_t                     thresh_ct;
	bool                         thresh_triggered;
	struct list_head             list_ptr;
	struct therm_threshold       *thresh_list;
};

enum device_req_type {
	DEVICE_REQ_NONE = -1,
	HOTPLUG_MITIGATION_REQ,
	CPUFREQ_MITIGATION_REQ,
	DEVICE_REQ_MAX,
};

/**
 * For frequency mitigation request, if client is interested
 * only in one, either max_freq or min_freq, update default
 * value for other one also for mitigation request.
 * Default value for request structure variables:
 *   max_freq = UINT_MAX;
 *   min_freq = 0;
 *   offline_mask =  CPU_MASK_NONE;
 */
struct cpufreq_request {
	uint32_t                     max_freq;
	uint32_t                     min_freq;
};

union device_request {
	struct cpufreq_request       freq;
	cpumask_t                    offline_mask;
};

struct device_clnt_data;
struct device_manager_data {
	char                         device_name[TSENS_NAME_MAX];
	union device_request         active_req;
	struct list_head             client_list;
	struct list_head             dev_ptr;
	struct mutex                 clnt_lock;
	int (*request_validate)(struct device_clnt_data *,
			union device_request *,
			enum device_req_type);
	int (*update)(struct device_manager_data *);
	void                         *data;
};

struct device_clnt_data {
	struct device_manager_data   *dev_mgr;
	bool                         req_active;
	union device_request         request;
	struct list_head             clnt_ptr;
	void (*callback)(struct device_clnt_data *,
			union device_request *req, void *);
	void                         *usr_data;
};

#ifdef CONFIG_THERMAL_MONITOR
extern int msm_thermal_ioctl_init(void);
extern void msm_thermal_ioctl_cleanup(void);
extern int msm_thermal_init(struct msm_thermal_data *pdata);
extern int msm_thermal_device_init(void);
extern int msm_thermal_set_frequency(uint32_t cpu, uint32_t freq,
	bool is_max);
extern int msm_thermal_set_cluster_freq(uint32_t cluster, uint32_t freq,
	bool is_max);
extern int msm_thermal_get_freq_plan_size(uint32_t cluster,
	unsigned int *table_len);
extern int msm_thermal_get_cluster_freq_plan(uint32_t cluster,
	unsigned int *table_ptr);
extern int msm_thermal_get_cluster_voltage_plan(uint32_t cluster,
	uint32_t *table_ptr);
/**
 * sensor_mgr_init_threshold - Initialize thresholds data structure for
 *                             sensor(s) with high and low thresholds and
 *                             threshold callback.
 *
 * @thresh_inp: Client threshold data structure.
 * @sensor_id: Sensor h/w ID to be monitored. Use MONITOR_ALL_TSENS
 *             to monitor all temperature sensors.
 *
 * @high_temp: Trigger threshold value for sensor_id or all sensors.
 * @low_temp: Clear threshold value for sensor_id or all sensors.
 * @callback: Callback pointer for threshold notification.
 *
 * Returns which threshold is set on success, negative error number
 * on failure. MACRO IS_HI_THRESHOLD_SET/IS_LOW_THRESHOLD_SET can be used
 * to decipher which threshold being set.
 */
extern int sensor_mgr_init_threshold(struct threshold_info *thresh_inp,
				int sensor_id, int32_t high_temp,
				int32_t low_temp,
				void (*callback)(struct therm_threshold *));
/**
 * sensor_mgr_convert_id_and_set_threshold - It accepts sensor h/w ID, converts
 *                                           it to sensor zone id and sets
 *                                           thermal threshold for those
 *                                           sensors listed in threshold info.
 *
 * @thresh_inp: Client threshold data structure.
 *
 * Returns zero on success, negative error number on failure.
 */
extern int sensor_mgr_convert_id_and_set_threshold(
				struct threshold_info *thresh_inp);
/**
 * sensor_mgr_set_threshold- It sets thermal threshold trips for a sensor.
 *
 * @zone_id: Thermal zone ID for the sensor.
 * @threshold: threshold info for the sensor.
 *
 * Returns zero on success, negative error number on failure.
 */
extern int sensor_mgr_set_threshold(uint32_t zone_id,
				struct sensor_threshold *threshold);
/**
 * sensor_mgr_remove_threshold- It cancels threshold notification and
 *                              removes threshold from sensor manager
 *                              threshold list.
 *
 * @thresh_inp: The threshold info which needs to be removed.
 */
extern void sensor_mgr_remove_threshold(struct threshold_info *thresh_inp);
/**
 * devmgr_register_mitigation_client - Register for a device and
 *                                     gets a handle for mitigation.
 * @dev: Client device structure.
 * @device_name: Mitgation device name which the client is interested
 *               to mitigate.
 * @callback: Optional callback pointer for device change notification,
 *            otherwise pass NULL.
 *
 * Returns client handle structure for that device on success, or NULL
 * with IS_ERR() condition containing error number.
 */
extern struct device_clnt_data *devmgr_register_mitigation_client(
				struct device *dev,
				const char *device_name,
				void (*callback)(struct device_clnt_data *,
				union device_request *, void *));
/**
 * devmgr_client_request_mitigation -  Set a valid mitigation for
 *                                     registered device.
 * @clnt: Client handle for device.
 * @type: Type of device request populated above.
 * @req:  Valid mitigation request.
 *
 * Returns zero on successful mitigation update, or negative error number.
 */
extern int devmgr_client_request_mitigation(struct device_clnt_data *clnt,
						enum device_req_type type,
						union device_request *req);
/**
 * devmgr_unregister_mitigation_client - Unregister mitigation device
 * @dev: Client device structure.
 * @clnt: Client handle for device.
 */
extern void devmgr_unregister_mitigation_client(
					struct device *dev,
					struct device_clnt_data *clnt);
#ifdef CONFIG_QCOM_THERMAL_LIMITS_DCVS
extern int msm_lmh_dcvsh_sw_notify(int cpu);
#else
static inline int msm_lmh_dcvsh_sw_notify(int cpu)
{
	return -ENODEV;
}
#endif

#else
static inline int msm_thermal_init(struct msm_thermal_data *pdata)
{
	return -ENOSYS;
}
static inline int msm_thermal_device_init(void)
{
	return -ENOSYS;
}
static inline int msm_thermal_set_frequency(uint32_t cpu, uint32_t freq,
	bool is_max)
{
	return -ENOSYS;
}
static inline int msm_thermal_set_cluster_freq(uint32_t cluster, uint32_t freq,
	bool is_max)
{
	return -ENOSYS;
}
static inline int msm_thermal_get_freq_plan_size(uint32_t cluster,
	unsigned int *table_len)
{
	return -ENOSYS;
}
static inline int msm_thermal_get_cluster_freq_plan(uint32_t cluster,
	unsigned int *table_ptr)
{
	return -ENOSYS;
}
static inline int msm_thermal_get_cluster_voltage_plan(uint32_t cluster,
	uint32_t *table_ptr)
{
	return -ENOSYS;
}
static inline int sensor_mgr_init_threshold(struct threshold_info *thresh_inp,
				int sensor_id, int32_t high_temp,
				int32_t low_temp,
				void (*callback)(struct therm_threshold *))
{
	return -ENOSYS;
}
static inline int sensor_mgr_convert_id_and_set_threshold(
			struct threshold_info *thresh_inp)
{
	return -ENOSYS;
}
static inline int sensor_mgr_set_threshold(uint32_t zone_id,
			struct sensor_threshold *threshold)
{
	return -ENOSYS;
}
static inline void sensor_mgr_remove_threshold(
				struct threshold_info *thresh_inp)
{
}
static inline struct device_clnt_data *devmgr_register_mitigation_client(
				struct device *dev,
				const char *device_name,
				void (*callback)(struct device_clnt_data *,
				union device_request *, void *))
{
	return NULL;
}
static inline int devmgr_client_request_mitigation(
					struct device_clnt_data *clnt,
					enum device_req_type type,
					union device_request *req)
{
	return -ENOSYS;
}
static inline void devmgr_unregister_mitigation_client(
					struct device *dev,
					struct device_clnt_data *clnt)
{
}
static inline int msm_lmh_dcvsh_sw_notify(int cpu)
{
	return -ENODEV;
}
#endif

#endif /*__MSM_THERMAL_H*/