summaryrefslogtreecommitdiff
path: root/include/soc/rockchip/rockchip_system_monitor.h
blob: 07f3a48ec0b152fde76f8ae33b7c848a49efda3e (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
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
 * Copyright (C) 2019, Fuzhou Rockchip Electronics Co., Ltd
 */

#ifndef __SOC_ROCKCHIP_SYSTEM_MONITOR_H
#define __SOC_ROCKCHIP_SYSTEM_MONITOR_H

enum monitor_dev_type {
	MONITOR_TPYE_CPU = 0,	/* CPU */
	MONITOR_TPYE_DEV,	/* GPU, NPU, DMC, and so on */
};

struct volt_adjust_table {
	unsigned int min;	/* Minimum frequency in MHz */
	unsigned int max;	/* Maximum frequency in MHz */
	int volt;		/* Voltage in microvolt */
};

struct temp_freq_table {
	int temp;		/* millicelsius */
	unsigned int freq;	/* KHz */
};

/**
 * struct temp_opp_table - System monitor device OPP description structure
 * @rate:		Frequency in hertz
 * @volt:		Target voltage in microvolt
 * @low_temp_volt:	Target voltage when low temperature, in microvolt
 * @max_volt:		Maximum voltage in microvolt
 */
struct temp_opp_table {
	unsigned long rate;
	unsigned long volt;
	unsigned long low_temp_volt;
	unsigned long max_volt;
};

/**
 * struct monitor_dev_info - structure for a system monitor device
 * @dev:		Device registered by system monitor
 * @devfreq_nb:		Notifier block used to notify devfreq object
 *			that it should reevaluate operable frequencies
 * @low_temp_adjust_table:	Voltage margin for different OPPs when lowe
 *				temperature
 * @opp_table:		Frequency and voltage information of device
 * @devp:		Device-specific system monitor profile
 * @node:		Node in monitor_dev_list
 * @temp_freq_table:	Maximum frequency at different temperature
 * @low_limit:		Limit maximum frequency when low temperature, in Hz
 * @high_limit:		Limit maximum frequency when high temperature, in Hz
 * @max_volt:		Maximum voltage in microvolt
 * @low_temp_min_volt:	Minimum voltage of OPPs when low temperature, in
 *			microvolt
 * @high_temp_max_volt:	Maximum voltage when high temperature, in microvolt
 * @wide_temp_limit:	Target maximum frequency when low or high temperature,
 *			in Hz
 * @video_4k_freq:	Maximum frequency when paly 4k video, in KHz
 * @status_limit:	Minimum frequency of all status frequency, in KHz
 * @freq_table:		Optional list of frequencies in descending order
 * @max_state:		The size of freq_table
 * @low_temp:		Low temperature trip point, in millicelsius
 * @high_temp:		High temperature trip point, in millicelsius
 * @temp_hysteresis:	A low hysteresis value on low_temp, in millicelsius
 * @is_low_temp:	True if current temperature less than low_temp
 * @is_high_temp:	True if current temperature greater than high_temp
 * @is_low_temp_enabled:	True if device node contains low temperature
 *				configuration
 */
struct monitor_dev_info {
	struct device *dev;
	struct notifier_block devfreq_nb;
	struct volt_adjust_table *low_temp_adjust_table;
	struct temp_opp_table *opp_table;
	struct monitor_dev_profile *devp;
	struct list_head node;
	struct temp_freq_table *temp_freq_table;
	unsigned long low_limit;
	unsigned long high_limit;
	unsigned long max_volt;
	unsigned long low_temp_min_volt;
	unsigned long high_temp_max_volt;
	unsigned long wide_temp_limit;
	unsigned int video_4k_freq;
	unsigned int status_limit;
	unsigned long *freq_table;
	unsigned int max_state;
	int low_temp;
	int high_temp;
	int temp_hysteresis;
	bool is_low_temp;
	bool is_high_temp;
	bool is_low_temp_enabled;
};

struct monitor_dev_profile {
	enum monitor_dev_type type;
	void *data;
	int (*low_temp_adjust)(struct monitor_dev_info *info, bool is_low);
	int (*high_temp_adjust)(struct monitor_dev_info *info, bool is_low);
	struct cpumask allowed_cpus;
};

#ifdef CONFIG_ROCKCHIP_SYSTEM_MONITOR
struct monitor_dev_info *
rockchip_system_monitor_register(struct device *dev,
				 struct monitor_dev_profile *devp);
void rockchip_system_monitor_unregister(struct monitor_dev_info *info);
int rockchip_monitor_cpu_low_temp_adjust(struct monitor_dev_info *info,
					 bool is_low);
int rockchip_monitor_cpu_high_temp_adjust(struct monitor_dev_info *info,
					  bool is_high);
int rockchip_monitor_dev_low_temp_adjust(struct monitor_dev_info *info,
					 bool is_low);
int rockchip_monitor_dev_high_temp_adjust(struct monitor_dev_info *info,
					  bool is_high);
int rockchip_monitor_suspend_low_temp_adjust(struct monitor_dev_info *info);
int
rockchip_system_monitor_adjust_cdev_state(struct thermal_cooling_device *cdev,
					  int temp, unsigned long *state);
#else
static inline struct monitor_dev_info *
rockchip_system_monitor_register(struct device *dev,
				 struct monitor_dev_profile *devp)
{
	return ERR_PTR(-ENOTSUPP);
};

static inline void
rockchip_system_monitor_unregister(struct monitor_dev_info *info)
{
}

static inline int
rockchip_monitor_cpu_low_temp_adjust(struct monitor_dev_info *info, bool is_low)
{
	return 0;
};

static inline int
rockchip_monitor_cpu_high_temp_adjust(struct monitor_dev_info *info,
				      bool is_high)
{
	return 0;
};

static inline int
rockchip_monitor_dev_low_temp_adjust(struct monitor_dev_info *info, bool is_low)
{
	return 0;
};

static inline int
rockchip_monitor_dev_high_temp_adjust(struct monitor_dev_info *info,
				      bool is_high)
{
	return 0;
};

static inline int
rockchip_monitor_suspend_low_temp_adjust(struct monitor_dev_info *info)
{
	return 0;
};

static inline int
rockchip_system_monitor_adjust_cdev_state(struct thermal_cooling_device *cdev,
					  int temp, unsigned long *state)
{
	return 0;
}

#endif /* CONFIG_ROCKCHIP_SYSTEM_MONITOR */

#endif