Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DM/FEATURE] Support thermal #9711

Merged
merged 2 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions components/drivers/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ rsource "block/Kconfig"
rsource "nvme/Kconfig"
rsource "scsi/Kconfig"
rsource "reset/Kconfig"
rsource "thermal/Kconfig"
rsource "virtio/Kconfig"
rsource "dma/Kconfig"
rsource "mfd/Kconfig"
Expand Down
205 changes: 205 additions & 0 deletions components/drivers/include/drivers/thermal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-3-08 GuEe-GUI the first version
*/

#ifndef __THERMAL_H__
#define __THERMAL_H__

#include <rtdef.h>
#include <dt-bindings/thermal/thermal.h>

/* No upper/lower limit requirement */
#define RT_THERMAL_NO_LIMIT ((rt_uint32_t)THERMAL_NO_LIMIT)
#define RT_THERMAL_TEMP_INVALID (-274000)

struct rt_thermal_zone_ops;
struct rt_thermal_cooling_device;
struct rt_thermal_cooling_device_ops;
struct rt_thermal_cooling_governor;

enum rt_thermal_trip_type
{
RT_THERMAL_TRIP_ACTIVE = 0,
RT_THERMAL_TRIP_PASSIVE,
RT_THERMAL_TRIP_HOT,
RT_THERMAL_TRIP_CRITICAL,

RT_THERMAL_TRIP_TYPE_MAX,
};

struct rt_thermal_trip
{
/* Temperature value in millidegree celsius */
int temperature;
/* Relative hysteresis in millidegree celsius */
int hysteresis;
enum rt_thermal_trip_type type;

void *priv;
};

struct rt_thermal_zone_params
{
/* Sustainable power (heat) that this thermal zone can dissipate in mW */
int sustainable_power;
/* Slope of a linear temperature adjustment curve */
int slope;
/* Offset of a linear temperature adjustment curve */
int offset;
};

struct rt_thermal_cooling_cell
{
struct rt_thermal_cooling_device *cooling_devices;

rt_uint32_t level_range[2];
};

struct rt_thermal_cooling_map
{
rt_uint32_t contribution;

rt_size_t cells_nr;
struct rt_thermal_cooling_cell *cells;
struct rt_thermal_trip *trips;
};

struct rt_thermal_zone_device
{
struct rt_device parent;

int zone_id;
const struct rt_thermal_zone_ops *ops;

rt_bool_t trips_free;
rt_size_t trips_nr;
struct rt_thermal_trip *trips;
struct rt_thermal_zone_params params;

rt_bool_t enabled;
rt_bool_t cooling;
int temperature;
int last_temperature;
int prev_low_trip;
int prev_high_trip;

rt_list_t notifier_nodes;
struct rt_spinlock nodes_lock;

rt_size_t cooling_maps_nr;
struct rt_thermal_cooling_map *cooling_maps;

rt_tick_t passive_delay, polling_delay;
struct rt_work poller;

struct rt_mutex mutex;

void *priv;
};

struct rt_thermal_zone_ops
{
rt_err_t (*get_temp)(struct rt_thermal_zone_device *zdev, int *out_temp);
rt_err_t (*set_trips)(struct rt_thermal_zone_device *zdev, int low_temp, int high_temp);
rt_err_t (*set_trip_temp)(struct rt_thermal_zone_device *zdev, int trip_id, int temp);
rt_err_t (*set_trip_hyst)(struct rt_thermal_zone_device *zdev, int trip_id, int hyst);
void (*hot)(struct rt_thermal_zone_device *zdev);
void (*critical)(struct rt_thermal_zone_device *zdev);
};

/*
* We don't want to make a temperature control system
* that is finer than an air conditioner's temperature control,
* just ensure get a reliable heat dissipation under high-load task
* or when the SoC temperature is too high.
*/
struct rt_thermal_cooling_device
{
struct rt_device parent;

const struct rt_thermal_cooling_device_ops *ops;

/* The cooling capacity indicator */
rt_ubase_t max_level;
rt_list_t governor_node;
struct rt_thermal_cooling_governor *gov;

void *priv;
};

struct rt_thermal_cooling_device_ops
{
rt_err_t (*bind)(struct rt_thermal_cooling_device *cdev, struct rt_thermal_zone_device *zdev);
rt_err_t (*unbind)(struct rt_thermal_cooling_device *cdev, struct rt_thermal_zone_device *zdev);
rt_err_t (*get_max_level)(struct rt_thermal_cooling_device *cdev, rt_ubase_t *out_level);
rt_err_t (*get_cur_level)(struct rt_thermal_cooling_device *cdev, rt_ubase_t *out_level);
rt_err_t (*set_cur_level)(struct rt_thermal_cooling_device *cdev, rt_ubase_t level);
};

struct rt_thermal_cooling_governor
{
rt_list_t list;

const char *name;
rt_list_t cdev_nodes;

void (*tuning)(struct rt_thermal_zone_device *zdev,
int map_idx, int cell_idx, rt_ubase_t *level);
};

struct rt_thermal_notifier;

#define RT_THERMAL_MSG_EVENT_UNSPECIFIED RT_BIT(0) /* Unspecified event */
#define RT_THERMAL_MSG_EVENT_TEMP_SAMPLE RT_BIT(1) /* New Temperature sample */
#define RT_THERMAL_MSG_TRIP_VIOLATED RT_BIT(2) /* TRIP Point violation */
#define RT_THERMAL_MSG_TRIP_CHANGED RT_BIT(3) /* TRIP Point temperature changed */
#define RT_THERMAL_MSG_DEVICE_DOWN RT_BIT(4) /* Thermal device is down */
#define RT_THERMAL_MSG_DEVICE_UP RT_BIT(5) /* Thermal device is up after a down event */
#define RT_THERMAL_MSG_DEVICE_POWER_CAPABILITY_CHANGED RT_BIT(6) /* Power capability changed */
#define RT_THERMAL_MSG_TABLE_CHANGED RT_BIT(7) /* Thermal table(s) changed */
#define RT_THERMAL_MSG_EVENT_KEEP_ALIVE RT_BIT(8) /* Request for user space handler to respond */

typedef rt_err_t (*rt_thermal_notifier_callback)(struct rt_thermal_notifier *notifier,
rt_ubase_t msg);

struct rt_thermal_notifier
{
rt_list_t list;

struct rt_thermal_zone_device *zdev;
rt_thermal_notifier_callback callback;
void *priv;
};

rt_err_t rt_thermal_zone_device_register(struct rt_thermal_zone_device *zdev);
rt_err_t rt_thermal_zone_device_unregister(struct rt_thermal_zone_device *zdev);

rt_err_t rt_thermal_cooling_device_register(struct rt_thermal_cooling_device *cdev);
rt_err_t rt_thermal_cooling_device_unregister(struct rt_thermal_cooling_device *cdev);

rt_err_t rt_thermal_cooling_governor_register(struct rt_thermal_cooling_governor *gov);
rt_err_t rt_thermal_cooling_governor_unregister(struct rt_thermal_cooling_governor *gov);

rt_err_t rt_thermal_cooling_device_change_governor(struct rt_thermal_cooling_device *cdev,
const char *name);

rt_err_t rt_thermal_zone_notifier_register(struct rt_thermal_zone_device *zdev,
struct rt_thermal_notifier *notifier);
rt_err_t rt_thermal_zone_notifier_unregister(struct rt_thermal_zone_device *zdev,
struct rt_thermal_notifier *notifier);

void rt_thermal_zone_device_update(struct rt_thermal_zone_device *zdev, rt_ubase_t msg);
void rt_thermal_cooling_device_kick(struct rt_thermal_zone_device *zdev);

rt_err_t rt_thermal_zone_set_trip(struct rt_thermal_zone_device *zdev, int trip_id,
const struct rt_thermal_trip *trip);
rt_err_t rt_thermal_zone_get_trip(struct rt_thermal_zone_device *zdev, int trip_id,
struct rt_thermal_trip *out_trip);

#endif /* __THERMAL_H__ */
13 changes: 13 additions & 0 deletions components/drivers/include/dt-bindings/thermal/thermal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

加上日期,作者信息吧

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

目前dts绑定头文件的默认都是不加这些信息的

* SPDX-License-Identifier: Apache-2.0
*/

#ifndef __DT_BINDINGS_THERMAL_THERMAL_H__
#define __DT_BINDINGS_THERMAL_THERMAL_H__

/* On cooling devices upper and lower limits */
#define THERMAL_NO_LIMIT (~0)

#endif /* __DT_BINDINGS_THERMAL_THERMAL_H__ */
4 changes: 4 additions & 0 deletions components/drivers/include/rtdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ extern "C" {
#ifdef RT_MFD_SYSCON
#include "drivers/syscon.h"
#endif /* RT_MFD_SYSCON */

#ifdef RT_USING_THERMAL
#include "drivers/thermal.h"
#endif /* RT_USING_THERMAL */
#endif /* RT_USING_DM */

#ifdef RT_USING_RTC
Expand Down
28 changes: 28 additions & 0 deletions components/drivers/thermal/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
menuconfig RT_USING_THERMAL
bool "Using Thermal Management device drivers"
depends on RT_USING_DM
default n

if RT_USING_THERMAL
comment "Thermal Sensors Drivers"
endif

if RT_USING_THERMAL
osource "$(SOC_DM_THERMAL_DIR)/Kconfig"
endif

if RT_USING_THERMAL
comment "Thermal Cool Drivers"
endif

config RT_THERMAL_COOL_PWM_FAN
bool "PWM Fan"
depends on RT_USING_THERMAL
depends on RT_USING_PWM
depends on RT_USING_REGULATOR
depends on RT_USING_OFW
default n

if RT_USING_THERMAL
osource "$(SOC_DM_THERMAL_COOL_DIR)/Kconfig"
endif
18 changes: 18 additions & 0 deletions components/drivers/thermal/SConscript
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from building import *

group = []

if not GetDepend(['RT_USING_THERMAL']):
Return('group')

cwd = GetCurrentDir()
CPPPATH = [cwd + '/../include']

src = ['thermal.c', 'thermal_dm.c']

if GetDepend(['RT_THERMAL_COOL_PWM_FAN']):
src += ['thermal-cool-pwm-fan.c']

group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)

Return('group')
Loading
Loading