tegrakernel/kernel/nvidia/include/linux/therm_est.h

274 lines
6.8 KiB
C

/*
* include/linux/therm_est.h
*
* Copyright (c) 2010-2021, NVIDIA CORPORATION. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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 _LINUX_THERM_EST_H
#define _LINUX_THERM_EST_H
#include <linux/workqueue.h>
#include <linux/thermal.h>
#include <linux/pwm.h>
#define HIST_LEN (20)
#define MAX_ACTIVE_STATES 10
#define MAX_TIMER_TRIPS 10
#define MAX_SUBDEVICE_GROUP 2
struct therm_est_sub_thz {
struct thermal_zone_device *thz;
long hist[HIST_LEN];
};
struct therm_est_coeffs {
long toffset;
s32 (*coeffs)[HIST_LEN];
};
struct therm_est_subdevice {
struct therm_est_sub_thz *sub_thz;
struct therm_est_coeffs *coeffs_set;
int num_devs;
int num_coeffs;
int active_coeffs;
int ntemp;
};
/*
* Timer trip provides a way to change trip temp dynamically based on timestamp
* when the trip is enabled.
* - Timer trip can be various numbers on a trip.
* - If the trip is enabled, then timer will be started with time_after delay
* in the corresponding timer trip. After the timer expires, trip_temp and
* hysteresis in the corresponding timer trip will be used to trip_temp for
* the trip.
* - When the timer has expired, index of timer trip will be increased a step
* and then start the timer with time_after delay in newly indexed timer trip.
* - When temp is below trip temp, index of timer trip will be decreased a step
* and then stop the timer and start the timer with time_after delay in newly
* indexed timer trip.
* - The timer will be stopped if there is no more next timer trip on the trip,
* or the trip is disabled.
*/
struct therm_est_timer_trip {
long time_after; /* in msec */
long trip_temp;
long hysteresis;
};
struct therm_est_timer_trip_info {
int trip; /* trip point on thermal zone to apply timer trip */
int num_timers;
struct therm_est_timer_trip timers[MAX_TIMER_TRIPS];
int cur; /* index of current timer trip */
s64 last_tripped; /* timestamp when the trip is enabled, in msec */
};
struct therm_est_data {
/* trip point info */
int num_trips;
struct thermal_trip_info *trips;
/* timer trip info */
int num_timer_trips;
struct therm_est_timer_trip_info *timer_trips;
/* zone parameters */
struct thermal_zone_params *tzp;
long polling_period;
int passive_delay;
int tc1;
int tc2;
struct therm_est_subdevice subdevice;
int use_activator;
};
struct therm_fan_est_subdevice {
const char *dev_data;
int (*get_temp)(const char *, int *);
int group;
/*
* as we read coeffs array from the device tree,
* specify type that has known width - 32 bits
*
* 'long' does not work, as its size if arch-dependent
*/
s32 coeffs[HIST_LEN];
int hist[HIST_LEN];
};
struct therm_fan_est_data {
long toffset;
long polling_period;
int ndevs;
char *cdev_type;
int active_trip_temps[MAX_ACTIVE_STATES];
int active_hysteresis[MAX_ACTIVE_STATES];
struct thermal_zone_params *tzp;
struct therm_fan_est_subdevice devs[];
};
struct fan_dev_data {
int next_state;
int active_steps;
int *fan_rpm;
int *fan_pwm;
int *fan_rru;
int *fan_rrd;
int *fan_state_cap_lookup;
int num_profiles;
int current_profile;
const char **fan_profile_names;
int **fan_profile_pwms;
int *fan_profile_caps;
struct workqueue_struct *workqueue;
int fan_temp_control_flag;
struct pwm_device *pwm_dev;
bool pwm_legacy_api;
int fan_cap_pwm;
int fan_cur_pwm;
int next_target_pwm;
struct thermal_cooling_device *cdev;
struct delayed_work fan_ramp_work;
struct delayed_work fan_hyst_work;
int step_time;
long long precision_multiplier;
struct mutex fan_state_lock;
int pwm_period;
int fan_pwm_max;
struct device *dev;
int tach_gpio;
int tach_irq;
atomic_t tach_enabled;
int fan_state_cap;
int pwm_gpio;
int pwm_id;
int fan_startup_pwm;
int fan_startup_time;
bool fan_kickstart; /*flag to check if fan is kickstart*/
bool kickstart_en; /*flag to check if kickstart feature is enabled*/
enum pwm_polarity fan_pwm_polarity;
int suspend_state;
const char *name;
const char *regulator_name;
struct regulator *fan_reg;
bool is_fan_reg_enabled;
struct dentry *debugfs_root;
/* for tach feedback */
atomic64_t rpm_measured;
struct delayed_work fan_tach_work;
struct workqueue_struct *tach_workqueue;
int tach_period;
spinlock_t irq_lock;
int irq_count;
u64 first_irq;
u64 last_irq;
u64 old_irq;
struct device_node *of_node_tach;
bool use_tach_feedback;
int rpm_diff_tolerance;
int fan_rpm_target_hit_count;
int fan_rpm_ramp_index;
int next_target_rpm;
int fan_ramp_time_ms;
struct delayed_work fan_ramp_pwm_work;
struct delayed_work fan_ramp_rpm_work;
struct device *pwm_tach_dev;
struct completion pwm_set;
bool fan_rpm_in_limits;
int rpm_valid_retry_delay;
int rpm_invalid_retry_delay;
int rpm_valid_retry_count;
bool continuous_gov;
bool is_tmargin;
bool is_always_on;
};
#define DEBUG 0
#define MULTIQP (100)
#define DEFERRED_RESUME_TIME 3000
#define THERMAL_GOV_PID "pid_thermal_gov"
#define THERMAL_CONTINUOUS_GOV "continuous_therm_gov"
struct therm_fan_estimator {
long cur_temp;
long pre_temp;
#if DEBUG
long cur_temp_debug;
#endif
long polling_period;
struct workqueue_struct *workqueue;
struct delayed_work therm_fan_est_work;
long toffset;
int ntemp;
int ndevs;
struct therm_fan_est_subdevice *devs;
struct thermal_zone_device *thz;
int current_trip_level;
const char *cdev_type;
rwlock_t state_lock;
int num_profiles;
int current_profile;
const char **fan_profile_names;
s32 **fan_profile_trip_temps;
s32 **fan_profile_trip_hysteresis;
s32 active_trip_temps[MAX_ACTIVE_STATES];
s32 active_hysteresis[MAX_ACTIVE_STATES];
struct thermal_zone_params *tzp;
int num_resources;
int trip_length;
const char *name;
bool is_pid_gov;
bool reset_trip_index;
/* allow cooling device to turn off at higher temperature if sleep */
bool sleep_mode;
int nonsleep_hyst;
bool use_tmargin;
long crit_temp[MAX_SUBDEVICE_GROUP];
bool is_continuous_gov;
};
#if IS_ENABLED(CONFIG_GENERIC_PWM_TACHOMETER)
int pwm_tach_capture_rpm(struct device *dev);
struct device *pwm_get_tach_dev(void);
#else
static inline int pwm_tach_capture_rpm(struct device *dev)
{
return 0;
}
static inline struct device *pwm_get_tach_dev(void)
{
return NULL;
}
#endif
#if IS_ENABLED(CONFIG_THERMAL_GOV_CONTINUOUS)
int continuous_thermal_gov_update_params(struct thermal_zone_params *tzp,
struct device_node *np);
#else
static inline int continuous_thermal_gov_update_params(
struct thermal_zone_params *tzp, struct device_node *np)
{
return 0;
}
#endif
#endif /* _LINUX_THERM_EST_H */