// SPDX-License-Identifier: GPL-2.0-only
/*
 *  step_wise.c - A step-by-step Thermal throttling governor
 *
 *  Copyright (C) 2012 Intel Corp
 *  Copyright (C) 2012 Durgadoss R <durgadoss.r@intel.com>
 *
 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */

#include <linux/thermal.h>
#include <linux/minmax.h>
#include "thermal_trace.h"

#include "thermal_core.h"

/*
 * If the temperature is higher than a trip point,
 *    a. if the trend is THERMAL_TREND_RAISING, use higher cooling
 *       state for this trip point
 *    b. if the trend is THERMAL_TREND_DROPPING, do nothing
 * If the temperature is lower than a trip point,
 *    a. if the trend is THERMAL_TREND_RAISING, do nothing
 *    b. if the trend is THERMAL_TREND_DROPPING, use lower cooling
 *       state for this trip point, if the cooling state already
 *       equals lower limit, deactivate the thermal instance
 */
static unsigned long get_target_state(struct thermal_instance *instance,
				enum thermal_trend trend, bool throttle)
{
	struct thermal_cooling_device *cdev = instance->cdev;
	unsigned long cur_state;

	/*
	 * We keep this instance the way it is by default.
	 * Otherwise, we use the current state of the
	 * cdev in use to determine the next_target.
	 */
	cdev->ops->get_cur_state(cdev, &cur_state);
	dev_dbg(&cdev->device, "cur_state=%ld\n", cur_state);

	if (!instance->initialized) {
		if (throttle)
			return clamp(cur_state + 1, instance->lower, instance->upper);

		return THERMAL_NO_TARGET;
	}

	if (throttle) {
		if (trend == THERMAL_TREND_RAISING)
			return clamp(cur_state + 1, instance->lower, instance->upper);
	} else if (trend == THERMAL_TREND_DROPPING) {
		if (cur_state <= instance->lower)
			return THERMAL_NO_TARGET;

		/*
		 * If 'throttle' is false, no mitigation is necessary, so
		 * request the lower state for this instance.
		 */
		return instance->lower;
	}

	return instance->target;
}

static void thermal_zone_trip_update(struct thermal_zone_device *tz,
				     const struct thermal_trip_desc *td,
				     int trip_threshold)
{
	const struct thermal_trip *trip = &td->trip;
	enum thermal_trend trend = get_tz_trend(tz, trip);
	int trip_id = thermal_zone_trip_id(tz, trip);
	struct thermal_instance *instance;
	bool throttle = false;

	if (tz->temperature >= trip_threshold) {
		throttle = true;
		trace_thermal_zone_trip(tz, trip_id, trip->type);
	}

	dev_dbg(&tz->device, "Trip%d[type=%d,temp=%d]:trend=%d,throttle=%d\n",
		trip_id, trip->type, trip_threshold, trend, throttle);

	list_for_each_entry(instance, &td->thermal_instances, trip_node) {
		int old_target;

		old_target = instance->target;
		instance->target = get_target_state(instance, trend, throttle);

		dev_dbg(&instance->cdev->device, "old_target=%d, target=%ld\n",
			old_target, instance->target);

		if (instance->initialized && old_target == instance->target)
			continue;

		instance->initialized = true;

		scoped_guard(cooling_dev, instance->cdev) {
			instance->cdev->updated = false; /* cdev needs update */
		}
	}
}

static void step_wise_manage(struct thermal_zone_device *tz)
{
	const struct thermal_trip_desc *td;
	struct thermal_instance *instance;

	lockdep_assert_held(&tz->lock);

	/*
	 * Throttling Logic: Use the trend of the thermal zone to throttle.
	 * If the thermal zone is 'heating up', throttle all of the cooling
	 * devices associated with each trip point by one step. If the zone
	 * is 'cooling down', it brings back the performance of the devices
	 * by one step.
	 */
	for_each_trip_desc(tz, td) {
		const struct thermal_trip *trip = &td->trip;

		if (trip->temperature == THERMAL_TEMP_INVALID ||
		    trip->type == THERMAL_TRIP_CRITICAL ||
		    trip->type == THERMAL_TRIP_HOT)
			continue;

		thermal_zone_trip_update(tz, td, td->threshold);
	}

	for_each_trip_desc(tz, td) {
		list_for_each_entry(instance, &td->thermal_instances, trip_node)
			thermal_cdev_update(instance->cdev);
	}
}

static struct thermal_governor thermal_gov_step_wise = {
	.name	= "step_wise",
	.manage	= step_wise_manage,
};
THERMAL_GOVERNOR_DECLARE(thermal_gov_step_wise);
