Skip to content

Commit 4b52958

Browse files
committed
[DM/FEATURE] Support thermal
Thermal drivers offer a generic mechanism for thermal management. Usually it's made up of one or more thermal zones and cooling devices. Each thermal zone contains its own temperature, trip points, and cooling devices. All platforms with ACPI or OFW thermal support can use this driver. Signed-off-by: GuEe-GUI <[email protected]>
1 parent d025072 commit 4b52958

File tree

9 files changed

+1274
-0
lines changed

9 files changed

+1274
-0
lines changed

components/drivers/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ rsource "block/Kconfig"
2828
rsource "nvme/Kconfig"
2929
rsource "scsi/Kconfig"
3030
rsource "reset/Kconfig"
31+
rsource "thermal/Kconfig"
3132
rsource "virtio/Kconfig"
3233
rsource "dma/Kconfig"
3334
rsource "mfd/Kconfig"
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
/*
2+
* Copyright (c) 2006-2022, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2022-3-08 GuEe-GUI the first version
9+
*/
10+
11+
#ifndef __THERMAL_H__
12+
#define __THERMAL_H__
13+
14+
#include <rtdef.h>
15+
#include <dt-bindings/thermal/thermal.h>
16+
17+
/* No upper/lower limit requirement */
18+
#define RT_THERMAL_NO_LIMIT ((rt_uint32_t)THERMAL_NO_LIMIT)
19+
#define RT_THERMAL_TEMP_INVALID (-274000)
20+
21+
struct rt_thermal_zone_ops;
22+
struct rt_thermal_cooling_device;
23+
struct rt_thermal_cooling_device_ops;
24+
struct rt_thermal_cooling_governor;
25+
26+
enum rt_thermal_trip_type
27+
{
28+
RT_THERMAL_TRIP_ACTIVE = 0,
29+
RT_THERMAL_TRIP_PASSIVE,
30+
RT_THERMAL_TRIP_HOT,
31+
RT_THERMAL_TRIP_CRITICAL,
32+
33+
RT_THERMAL_TRIP_TYPE_MAX,
34+
};
35+
36+
struct rt_thermal_trip
37+
{
38+
/* Temperature value in millidegree celsius */
39+
int temperature;
40+
/* Relative hysteresis in millidegree celsius */
41+
int hysteresis;
42+
enum rt_thermal_trip_type type;
43+
44+
void *priv;
45+
};
46+
47+
struct rt_thermal_zone_params
48+
{
49+
/* Sustainable power (heat) that this thermal zone can dissipate in mW */
50+
int sustainable_power;
51+
/* Slope of a linear temperature adjustment curve */
52+
int slope;
53+
/* Offset of a linear temperature adjustment curve */
54+
int offset;
55+
};
56+
57+
struct rt_thermal_cooling_cell
58+
{
59+
struct rt_thermal_cooling_device *cooling_devices;
60+
61+
rt_uint32_t level_range[2];
62+
};
63+
64+
struct rt_thermal_cooling_map
65+
{
66+
rt_uint32_t contribution;
67+
68+
rt_size_t cells_nr;
69+
struct rt_thermal_cooling_cell *cells;
70+
struct rt_thermal_trip *trips;
71+
};
72+
73+
struct rt_thermal_zone_device
74+
{
75+
struct rt_device parent;
76+
77+
int zone_id;
78+
const struct rt_thermal_zone_ops *ops;
79+
80+
rt_bool_t trips_free;
81+
rt_size_t trips_nr;
82+
struct rt_thermal_trip *trips;
83+
struct rt_thermal_zone_params params;
84+
85+
rt_bool_t enabled;
86+
rt_bool_t cooling;
87+
int temperature;
88+
int last_temperature;
89+
int prev_low_trip;
90+
int prev_high_trip;
91+
92+
rt_list_t notifier_nodes;
93+
struct rt_spinlock nodes_lock;
94+
95+
rt_size_t cooling_maps_nr;
96+
struct rt_thermal_cooling_map *cooling_maps;
97+
98+
rt_tick_t passive_delay, polling_delay;
99+
struct rt_work poller;
100+
101+
struct rt_mutex mutex;
102+
103+
void *priv;
104+
};
105+
106+
struct rt_thermal_zone_ops
107+
{
108+
rt_err_t (*get_temp)(struct rt_thermal_zone_device *zdev, int *out_temp);
109+
rt_err_t (*set_trips)(struct rt_thermal_zone_device *zdev, int low_temp, int high_temp);
110+
rt_err_t (*set_trip_temp)(struct rt_thermal_zone_device *zdev, int trip_id, int temp);
111+
rt_err_t (*set_trip_hyst)(struct rt_thermal_zone_device *zdev, int trip_id, int hyst);
112+
void (*hot)(struct rt_thermal_zone_device *zdev);
113+
void (*critical)(struct rt_thermal_zone_device *zdev);
114+
};
115+
116+
/*
117+
* We don't want to make a temperature control system
118+
* that is finer than an air conditioner's temperature control,
119+
* just ensure get a reliable heat dissipation under high-load task
120+
* or when the SoC temperature is too high.
121+
*/
122+
struct rt_thermal_cooling_device
123+
{
124+
struct rt_device parent;
125+
126+
const struct rt_thermal_cooling_device_ops *ops;
127+
128+
/* The cooling capacity indicator */
129+
rt_ubase_t max_level;
130+
rt_list_t governor_node;
131+
struct rt_thermal_cooling_governor *gov;
132+
133+
void *priv;
134+
};
135+
136+
struct rt_thermal_cooling_device_ops
137+
{
138+
rt_err_t (*bind)(struct rt_thermal_cooling_device *cdev, struct rt_thermal_zone_device *zdev);
139+
rt_err_t (*unbind)(struct rt_thermal_cooling_device *cdev, struct rt_thermal_zone_device *zdev);
140+
rt_err_t (*get_max_level)(struct rt_thermal_cooling_device *cdev, rt_ubase_t *out_level);
141+
rt_err_t (*get_cur_level)(struct rt_thermal_cooling_device *cdev, rt_ubase_t *out_level);
142+
rt_err_t (*set_cur_level)(struct rt_thermal_cooling_device *cdev, rt_ubase_t level);
143+
};
144+
145+
struct rt_thermal_cooling_governor
146+
{
147+
rt_list_t list;
148+
149+
const char *name;
150+
rt_list_t cdev_nodes;
151+
152+
void (*tuning)(struct rt_thermal_zone_device *zdev,
153+
int map_idx, int cell_idx, rt_ubase_t *level);
154+
};
155+
156+
struct rt_thermal_notifier;
157+
158+
#define RT_THERMAL_MSG_EVENT_UNSPECIFIED RT_BIT(0) /* Unspecified event */
159+
#define RT_THERMAL_MSG_EVENT_TEMP_SAMPLE RT_BIT(1) /* New Temperature sample */
160+
#define RT_THERMAL_MSG_TRIP_VIOLATED RT_BIT(2) /* TRIP Point violation */
161+
#define RT_THERMAL_MSG_TRIP_CHANGED RT_BIT(3) /* TRIP Point temperature changed */
162+
#define RT_THERMAL_MSG_DEVICE_DOWN RT_BIT(4) /* Thermal device is down */
163+
#define RT_THERMAL_MSG_DEVICE_UP RT_BIT(5) /* Thermal device is up after a down event */
164+
#define RT_THERMAL_MSG_DEVICE_POWER_CAPABILITY_CHANGED RT_BIT(6) /* Power capability changed */
165+
#define RT_THERMAL_MSG_TABLE_CHANGED RT_BIT(7) /* Thermal table(s) changed */
166+
#define RT_THERMAL_MSG_EVENT_KEEP_ALIVE RT_BIT(8) /* Request for user space handler to respond */
167+
168+
typedef rt_err_t (*rt_thermal_notifier_callback)(struct rt_thermal_notifier *notifier,
169+
rt_ubase_t msg);
170+
171+
struct rt_thermal_notifier
172+
{
173+
rt_list_t list;
174+
175+
struct rt_thermal_zone_device *zdev;
176+
rt_thermal_notifier_callback callback;
177+
void *priv;
178+
};
179+
180+
rt_err_t rt_thermal_zone_device_register(struct rt_thermal_zone_device *zdev);
181+
rt_err_t rt_thermal_zone_device_unregister(struct rt_thermal_zone_device *zdev);
182+
183+
rt_err_t rt_thermal_cooling_device_register(struct rt_thermal_cooling_device *cdev);
184+
rt_err_t rt_thermal_cooling_device_unregister(struct rt_thermal_cooling_device *cdev);
185+
186+
rt_err_t rt_thermal_cooling_governor_register(struct rt_thermal_cooling_governor *gov);
187+
rt_err_t rt_thermal_cooling_governor_unregister(struct rt_thermal_cooling_governor *gov);
188+
189+
rt_err_t rt_thermal_cooling_device_change_governor(struct rt_thermal_cooling_device *cdev,
190+
const char *name);
191+
192+
rt_err_t rt_thermal_zone_notifier_register(struct rt_thermal_zone_device *zdev,
193+
struct rt_thermal_notifier *notifier);
194+
rt_err_t rt_thermal_zone_notifier_unregister(struct rt_thermal_zone_device *zdev,
195+
struct rt_thermal_notifier *notifier);
196+
197+
void rt_thermal_zone_device_update(struct rt_thermal_zone_device *zdev, rt_ubase_t msg);
198+
void rt_thermal_cooling_device_kick(struct rt_thermal_zone_device *zdev);
199+
200+
rt_err_t rt_thermal_zone_set_trip(struct rt_thermal_zone_device *zdev, int trip_id,
201+
const struct rt_thermal_trip *trip);
202+
rt_err_t rt_thermal_zone_get_trip(struct rt_thermal_zone_device *zdev, int trip_id,
203+
struct rt_thermal_trip *out_trip);
204+
205+
#endif /* __THERMAL_H__ */
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/*
2+
* Copyright (c) 2006-2022, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef __DT_BINDINGS_THERMAL_THERMAL_H__
8+
#define __DT_BINDINGS_THERMAL_THERMAL_H__
9+
10+
/* On cooling devices upper and lower limits */
11+
#define THERMAL_NO_LIMIT (~0)
12+
13+
#endif /* __DT_BINDINGS_THERMAL_THERMAL_H__ */

components/drivers/include/rtdevice.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ extern "C" {
9696
#ifdef RT_MFD_SYSCON
9797
#include "drivers/syscon.h"
9898
#endif /* RT_MFD_SYSCON */
99+
100+
#ifdef RT_USING_THERMAL
101+
#include "drivers/thermal.h"
102+
#endif /* RT_USING_THERMAL */
99103
#endif /* RT_USING_DM */
100104

101105
#ifdef RT_USING_RTC

components/drivers/thermal/Kconfig

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
menuconfig RT_USING_THERMAL
2+
bool "Using Thermal Management device drivers"
3+
depends on RT_USING_DM
4+
default n
5+
6+
if RT_USING_THERMAL
7+
comment "Thermal Sensors Drivers"
8+
endif
9+
10+
if RT_USING_THERMAL
11+
osource "$(SOC_DM_THERMAL_DIR)/Kconfig"
12+
endif
13+
14+
if RT_USING_THERMAL
15+
comment "Thermal Cool Drivers"
16+
endif
17+
18+
if RT_USING_THERMAL
19+
osource "$(SOC_DM_THERMAL_COOL_DIR)/Kconfig"
20+
endif

components/drivers/thermal/SConscript

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from building import *
2+
3+
group = []
4+
objs = []
5+
6+
if not GetDepend(['RT_USING_THERMAL']):
7+
Return('group')
8+
9+
cwd = GetCurrentDir()
10+
list = os.listdir(cwd)
11+
CPPPATH = [cwd + '/../include']
12+
13+
src = ['thermal.c', 'thermal_dm.c']
14+
15+
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
16+
17+
for d in list:
18+
path = os.path.join(cwd, d)
19+
if os.path.isfile(os.path.join(path, 'SConscript')):
20+
objs = objs + SConscript(os.path.join(d, 'SConscript'))
21+
objs = objs + group
22+
23+
Return('objs')

0 commit comments

Comments
 (0)