// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
 *
 * (C) COPYRIGHT 2016-2022 ARM Limited. All rights reserved.
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU license.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 *
 */

#include <linux/thermal.h>
#include <linux/devfreq_cooling.h>
#include <linux/of.h>
#include "mali_kbase.h"
#include "mali_kbase_ipa.h"
#include "mali_kbase_ipa_debugfs.h"
#include "mali_kbase_ipa_simple.h"
#include "backend/gpu/mali_kbase_pm_internal.h"
#include "backend/gpu/mali_kbase_devfreq.h"
#include <linux/pm_opp.h>

#define KBASE_IPA_FALLBACK_MODEL_NAME "mali-simple-power-model"

/* Polling by thermal governor starts when the temperature exceeds the certain
 * trip point. In order to have meaningful value for the counters, when the
 * polling starts and first call to kbase_get_real_power() is made, it is
 * required to reset the counter values every now and then.
 * It is reasonable to do the reset every second if no polling is being done,
 * the counter model implementation also assumes max sampling interval of 1 sec.
 */
#define RESET_INTERVAL_MS ((s64)1000)

int kbase_ipa_model_recalculate(struct kbase_ipa_model *model)
{
	int err = 0;

	lockdep_assert_held(&model->kbdev->ipa.lock);

	if (model->ops->recalculate) {
		err = model->ops->recalculate(model);
		if (err) {
			dev_err(model->kbdev->dev,
				"recalculation of power model %s returned error %d\n",
				model->ops->name, err);
		}
	}

	return err;
}

const struct kbase_ipa_model_ops *kbase_ipa_model_ops_find(struct kbase_device *kbdev,
							   const char *name)
{
	if (!strcmp(name, kbase_simple_ipa_model_ops.name))
		return &kbase_simple_ipa_model_ops;

	return kbase_ipa_counter_model_ops_find(kbdev, name);
}
KBASE_EXPORT_TEST_API(kbase_ipa_model_ops_find);

const char *kbase_ipa_model_name_from_id(u32 gpu_id)
{
	const char *model_name =
		kbase_ipa_counter_model_name_from_id(gpu_id);

	if (!model_name)
		return KBASE_IPA_FALLBACK_MODEL_NAME;
	else
		return model_name;
}
KBASE_EXPORT_TEST_API(kbase_ipa_model_name_from_id);

static struct device_node *get_model_dt_node(struct kbase_ipa_model *model,
					     bool dt_required)
{
	struct device_node *model_dt_node = NULL;
	char compat_string[64];

	if (unlikely(!scnprintf(compat_string, sizeof(compat_string), "arm,%s", model->ops->name)))
		return NULL;

	/* of_find_compatible_node() will call of_node_put() on the root node,
	 * so take a reference on it first.
	 */
	of_node_get(model->kbdev->dev->of_node);
	model_dt_node = of_find_compatible_node(model->kbdev->dev->of_node,
						NULL, compat_string);
	if (!model_dt_node && !model->missing_dt_node_warning) {
		if (dt_required)
			dev_warn(model->kbdev->dev,
			"Couldn't find power_model DT node matching \'%s\'\n",
			compat_string);
		model->missing_dt_node_warning = true;
	}

	return model_dt_node;
}

int kbase_ipa_model_add_param_s32(struct kbase_ipa_model *model,
				  const char *name, s32 *addr,
				  size_t num_elems, bool dt_required)
{
	int err = -EINVAL, i;
	struct device_node *model_dt_node = get_model_dt_node(model,
								dt_required);
	char *origin;

	err = of_property_read_u32_array(model_dt_node, name, (u32 *)addr, num_elems);
	/* We're done with model_dt_node now, so drop the reference taken in
	 * get_model_dt_node()/of_find_compatible_node().
	 */
	of_node_put(model_dt_node);

	if (err && dt_required) {
		memset(addr, 0, sizeof(s32) * num_elems);
		dev_warn(model->kbdev->dev,
			 "Error %d, no DT entry: %s.%s = %zu*[0]\n",
			 err, model->ops->name, name, num_elems);
		origin = "zero";
	} else if (err && !dt_required) {
		origin = "default";
	} else /* !err */ {
		origin = "DT";
	}

	/* Create a unique debugfs entry for each element */
	for (i = 0; i < num_elems; ++i) {
		char elem_name[32];

		if (num_elems == 1) {
			if (unlikely(!scnprintf(elem_name, sizeof(elem_name), "%s", name))) {
				err = -ENOMEM;
				goto exit;
			}
		} else {
			if (unlikely(!scnprintf(elem_name, sizeof(elem_name), "%s.%d", name, i))) {
				err = -ENOMEM;
				goto exit;
			}
		}

		dev_dbg(model->kbdev->dev, "%s.%s = %d (%s)\n",
			model->ops->name, elem_name, addr[i], origin);

		err = kbase_ipa_model_param_add(model, elem_name,
						&addr[i], sizeof(s32),
						PARAM_TYPE_S32);
		if (err)
			goto exit;
	}
exit:
	return err;
}

int kbase_ipa_model_add_param_string(struct kbase_ipa_model *model,
				     const char *name, char *addr,
				     size_t size, bool dt_required)
{
	int err;
	struct device_node *model_dt_node = get_model_dt_node(model,
								dt_required);
	const char *string_prop_value = "";
	char *origin;

	err = of_property_read_string(model_dt_node, name,
				      &string_prop_value);

	/* We're done with model_dt_node now, so drop the reference taken in
	 * get_model_dt_node()/of_find_compatible_node().
	 */
	of_node_put(model_dt_node);

	if (err && dt_required) {
		strncpy(addr, "", size - 1);
		dev_warn(model->kbdev->dev,
			 "Error %d, no DT entry: %s.%s = \'%s\'\n",
			 err, model->ops->name, name, addr);
		err = 0;
		origin = "zero";
	} else if (err && !dt_required) {
		origin = "default";
	} else /* !err */ {
		strncpy(addr, string_prop_value, size - 1);
		origin = "DT";
	}

	addr[size - 1] = '\0';

	dev_dbg(model->kbdev->dev, "%s.%s = \'%s\' (%s)\n",
		model->ops->name, name, string_prop_value, origin);

	err = kbase_ipa_model_param_add(model, name, addr, size,
					PARAM_TYPE_STRING);
	return err;
}

void kbase_ipa_term_model(struct kbase_ipa_model *model)
{
	if (!model)
		return;

	lockdep_assert_held(&model->kbdev->ipa.lock);

	if (model->ops->term)
		model->ops->term(model);

	kbase_ipa_model_param_free_all(model);

	kfree(model);
}
KBASE_EXPORT_TEST_API(kbase_ipa_term_model);

struct kbase_ipa_model *kbase_ipa_init_model(struct kbase_device *kbdev,
					     const struct kbase_ipa_model_ops *ops)
{
	struct kbase_ipa_model *model;
	int err;

	lockdep_assert_held(&kbdev->ipa.lock);

	if (!ops || !ops->name)
		return NULL;

	model = kzalloc(sizeof(struct kbase_ipa_model), GFP_KERNEL);
	if (!model)
		return NULL;

	model->kbdev = kbdev;
	model->ops = ops;
	INIT_LIST_HEAD(&model->params);

	err = model->ops->init(model);
	if (err) {
		dev_err(kbdev->dev,
			"init of power model \'%s\' returned error %d\n",
			ops->name, err);
		kfree(model);
		return NULL;
	}

	err = kbase_ipa_model_recalculate(model);
	if (err) {
		kbase_ipa_term_model(model);
		return NULL;
	}

	return model;
}
KBASE_EXPORT_TEST_API(kbase_ipa_init_model);

static void kbase_ipa_term_locked(struct kbase_device *kbdev)
{
	lockdep_assert_held(&kbdev->ipa.lock);

	/* Clean up the models */
	if (kbdev->ipa.configured_model != kbdev->ipa.fallback_model)
		kbase_ipa_term_model(kbdev->ipa.configured_model);
	kbase_ipa_term_model(kbdev->ipa.fallback_model);

	kbdev->ipa.configured_model = NULL;
	kbdev->ipa.fallback_model = NULL;
}

int kbase_ipa_init(struct kbase_device *kbdev)
{

	const char *model_name;
	const struct kbase_ipa_model_ops *ops;
	struct kbase_ipa_model *default_model = NULL;
	int err;

	mutex_init(&kbdev->ipa.lock);
	/*
	 * Lock during init to avoid warnings from lockdep_assert_held (there
	 * shouldn't be any concurrent access yet).
	 */
	mutex_lock(&kbdev->ipa.lock);

	/* The simple IPA model must *always* be present.*/
	ops = kbase_ipa_model_ops_find(kbdev, KBASE_IPA_FALLBACK_MODEL_NAME);

	default_model = kbase_ipa_init_model(kbdev, ops);
	if (!default_model) {
		err = -EINVAL;
		goto end;
	}

	kbdev->ipa.fallback_model = default_model;
	err = of_property_read_string(kbdev->dev->of_node,
				      "ipa-model",
				      &model_name);
	if (err) {
		/* Attempt to load a match from GPU-ID */
		u32 gpu_id;

		gpu_id = kbdev->gpu_props.props.raw_props.gpu_id;
		model_name = kbase_ipa_model_name_from_id(gpu_id);
		dev_dbg(kbdev->dev,
			"Inferring model from GPU ID 0x%x: \'%s\'\n",
			gpu_id, model_name);
		err = 0;
	} else {
		dev_dbg(kbdev->dev,
			"Using ipa-model parameter from DT: \'%s\'\n",
			model_name);
	}

	if (strcmp(KBASE_IPA_FALLBACK_MODEL_NAME, model_name) != 0) {
		ops = kbase_ipa_model_ops_find(kbdev, model_name);
		kbdev->ipa.configured_model = kbase_ipa_init_model(kbdev, ops);
		if (!kbdev->ipa.configured_model) {
			dev_warn(kbdev->dev,
				"Failed to initialize ipa-model: \'%s\'\n"
				"Falling back on default model\n",
				model_name);
			kbdev->ipa.configured_model = default_model;
		}
	} else {
		kbdev->ipa.configured_model = default_model;
	}

	kbdev->ipa.last_sample_time = ktime_get_raw();

end:
	if (err)
		kbase_ipa_term_locked(kbdev);
	else
		dev_info(kbdev->dev,
			 "Using configured power model %s, and fallback %s\n",
			 kbdev->ipa.configured_model->ops->name,
			 kbdev->ipa.fallback_model->ops->name);

	mutex_unlock(&kbdev->ipa.lock);
	return err;
}
KBASE_EXPORT_TEST_API(kbase_ipa_init);

void kbase_ipa_term(struct kbase_device *kbdev)
{
	mutex_lock(&kbdev->ipa.lock);
	kbase_ipa_term_locked(kbdev);
	mutex_unlock(&kbdev->ipa.lock);

	mutex_destroy(&kbdev->ipa.lock);
}
KBASE_EXPORT_TEST_API(kbase_ipa_term);

/**
 * kbase_scale_dynamic_power() - Scale a dynamic power coefficient to an OPP
 * @c:		Dynamic model coefficient, in pW/(Hz V^2). Should be in range
 *		0 < c < 2^26 to prevent overflow.
 * @freq:	Frequency, in Hz. Range: 2^23 < freq < 2^30 (~8MHz to ~1GHz)
 * @voltage:	Voltage, in mV. Range: 2^9 < voltage < 2^13 (~0.5V to ~8V)
 *
 * Keep a record of the approximate range of each value at every stage of the
 * calculation, to ensure we don't overflow. This makes heavy use of the
 * approximations 1000 = 2^10 and 1000000 = 2^20, but does the actual
 * calculations in decimal for increased accuracy.
 *
 * Return: Power consumption, in mW. Range: 0 < p < 2^13 (0W to ~8W)
 */
static u32 kbase_scale_dynamic_power(const u32 c, const u32 freq,
				     const u32 voltage)
{
	/* Range: 2^8 < v2 < 2^16 m(V^2) */
	const u32 v2 = (voltage * voltage) / 1000;

	/* Range: 2^3 < f_MHz < 2^10 MHz */
	const u32 f_MHz = freq / 1000000;

	/* Range: 2^11 < v2f_big < 2^26 kHz V^2 */
	const u32 v2f_big = v2 * f_MHz;

	/* Range: 2^1 < v2f < 2^16 MHz V^2 */
	const u32 v2f = v2f_big / 1000;

	/* Range (working backwards from next line): 0 < v2fc < 2^23 uW.
	 * Must be < 2^42 to avoid overflowing the return value.
	 */
	const u64 v2fc = (u64) c * (u64) v2f;

	/* Range: 0 < v2fc / 1000 < 2^13 mW */
	return div_u64(v2fc, 1000);
}

/**
 * kbase_scale_static_power() - Scale a static power coefficient to an OPP
 * @c:		Static model coefficient, in uW/V^3. Should be in range
 *		0 < c < 2^32 to prevent overflow.
 * @voltage:	Voltage, in mV. Range: 2^9 < voltage < 2^13 (~0.5V to ~8V)
 *
 * Return: Power consumption, in mW. Range: 0 < p < 2^13 (0W to ~8W)
 */
static u32 kbase_scale_static_power(const u32 c, const u32 voltage)
{
	/* Range: 2^8 < v2 < 2^16 m(V^2) */
	const u32 v2 = (voltage * voltage) / 1000;

	/* Range: 2^17 < v3_big < 2^29 m(V^2) mV */
	const u32 v3_big = v2 * voltage;

	/* Range: 2^7 < v3 < 2^19 m(V^3) */
	const u32 v3 = v3_big / 1000;

	/*
	 * Range (working backwards from next line): 0 < v3c_big < 2^33 nW.
	 * The result should be < 2^52 to avoid overflowing the return value.
	 */
	const u64 v3c_big = (u64) c * (u64) v3;

	/* Range: 0 < v3c_big / 1000000 < 2^13 mW */
	return div_u64(v3c_big, 1000000);
}

void kbase_ipa_protection_mode_switch_event(struct kbase_device *kbdev)
{
	lockdep_assert_held(&kbdev->hwaccess_lock);

	/* Record the event of GPU entering protected mode. */
	kbdev->ipa_protection_mode_switched = true;
}

static struct kbase_ipa_model *get_current_model(struct kbase_device *kbdev)
{
	struct kbase_ipa_model *model;
	unsigned long flags;

	lockdep_assert_held(&kbdev->ipa.lock);

	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);

	if (kbdev->ipa_protection_mode_switched ||
			kbdev->ipa.force_fallback_model)
		model = kbdev->ipa.fallback_model;
	else
		model = kbdev->ipa.configured_model;

	/*
	 * Having taken cognizance of the fact that whether GPU earlier
	 * protected mode or not, the event can be now reset (if GPU is not
	 * currently in protected mode) so that configured model is used
	 * for the next sample.
	 */
	if (!kbdev->protected_mode)
		kbdev->ipa_protection_mode_switched = false;

	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);

	return model;
}

static u32 get_static_power_locked(struct kbase_device *kbdev,
				   struct kbase_ipa_model *model,
				   unsigned long voltage)
{
	u32 power = 0;
	int err;
	u32 power_coeff;

	lockdep_assert_held(&model->kbdev->ipa.lock);

	if (!model->ops->get_static_coeff)
		model = kbdev->ipa.fallback_model;

	if (model->ops->get_static_coeff) {
		err = model->ops->get_static_coeff(model, &power_coeff);
		if (!err)
			power = kbase_scale_static_power(power_coeff,
							 (u32) voltage);
	}

	return power;
}

#if KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE
#if defined(CONFIG_MALI_PWRSOFT_765) ||                                        \
	KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE
static unsigned long kbase_get_static_power(struct devfreq *df,
					    unsigned long voltage)
#else
static unsigned long kbase_get_static_power(unsigned long voltage)
#endif
{
	struct kbase_ipa_model *model;
	u32 power = 0;
#if defined(CONFIG_MALI_PWRSOFT_765) ||                                        \
	KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE
	struct kbase_device *kbdev = dev_get_drvdata(&df->dev);
#else
	struct kbase_device *kbdev = kbase_find_device(-1);
#endif

	if (!kbdev)
		return 0ul;

	mutex_lock(&kbdev->ipa.lock);

	model = get_current_model(kbdev);
	power = get_static_power_locked(kbdev, model, voltage);

	mutex_unlock(&kbdev->ipa.lock);

#if !(defined(CONFIG_MALI_PWRSOFT_765) ||                                      \
	KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE)
	kbase_release_device(kbdev);
#endif

	return power;
}
#endif /* KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE */

/**
 * opp_translate_freq_voltage() - Translate nominal OPP frequency from
 *                                devicetree into the real frequency for
 *                                top-level and shader cores.
 * @kbdev:            Device pointer
 * @nominal_freq:     Nominal frequency in Hz.
 * @nominal_voltage:  Nominal voltage, in mV.
 * @freqs:            Pointer to array of real frequency values.
 * @volts:            Pointer to array of voltages.
 *
 * If there are 2 clock domains, then top-level and shader cores can operate
 * at different frequency and voltage level. The nominal frequency ("opp-hz")
 * used by devfreq from the devicetree may not be same as the real frequency
 * at which top-level and shader cores are operating, so a translation is
 * needed.
 * Nominal voltage shall always be same as the real voltage for top-level.
 */
static void opp_translate_freq_voltage(struct kbase_device *kbdev,
				       unsigned long nominal_freq,
				       unsigned long nominal_voltage,
				       unsigned long *freqs,
				       unsigned long *volts)
{
#if IS_ENABLED(CONFIG_MALI_NO_MALI)
	/* An arbitrary voltage and frequency value can be chosen for testing
	 * in no mali configuration which may not match with any OPP level.
	 */
	freqs[KBASE_IPA_BLOCK_TYPE_TOP_LEVEL] = nominal_freq;
	volts[KBASE_IPA_BLOCK_TYPE_TOP_LEVEL] = nominal_voltage;

	freqs[KBASE_IPA_BLOCK_TYPE_SHADER_CORES] = nominal_freq;
	volts[KBASE_IPA_BLOCK_TYPE_SHADER_CORES] = nominal_voltage;
#else
	u64 core_mask;
	unsigned int i;

	kbase_devfreq_opp_translate(kbdev, nominal_freq, &core_mask,
				    freqs, volts);
	CSTD_UNUSED(core_mask);

	/* Convert micro volts to milli volts */
	for (i = 0; i < kbdev->nr_clocks; i++)
		volts[i] /= 1000;

	if (kbdev->nr_clocks == 1) {
		freqs[KBASE_IPA_BLOCK_TYPE_SHADER_CORES] =
			freqs[KBASE_IPA_BLOCK_TYPE_TOP_LEVEL];
		volts[KBASE_IPA_BLOCK_TYPE_SHADER_CORES] =
			volts[KBASE_IPA_BLOCK_TYPE_TOP_LEVEL];
	}
#endif
}

#if KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE
#if defined(CONFIG_MALI_PWRSOFT_765) ||                                        \
	KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE
static unsigned long kbase_get_dynamic_power(struct devfreq *df,
					     unsigned long freq,
					     unsigned long voltage)
#else
static unsigned long kbase_get_dynamic_power(unsigned long freq,
					     unsigned long voltage)
#endif
{
	struct kbase_ipa_model *model;
	unsigned long freqs[KBASE_IPA_BLOCK_TYPE_NUM] = {0};
	unsigned long volts[KBASE_IPA_BLOCK_TYPE_NUM] = {0};
	u32 power_coeffs[KBASE_IPA_BLOCK_TYPE_NUM] = {0};
	u32 power = 0;
	int err = 0;
#if defined(CONFIG_MALI_PWRSOFT_765) ||                                        \
	KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE
	struct kbase_device *kbdev = dev_get_drvdata(&df->dev);
#else
	struct kbase_device *kbdev = kbase_find_device(-1);
#endif

	if (!kbdev)
		return 0ul;

	mutex_lock(&kbdev->ipa.lock);

	model = kbdev->ipa.fallback_model;

	err = model->ops->get_dynamic_coeff(model, power_coeffs);

	if (!err) {
		opp_translate_freq_voltage(kbdev, freq, voltage, freqs, volts);

		power = kbase_scale_dynamic_power(
			power_coeffs[KBASE_IPA_BLOCK_TYPE_TOP_LEVEL],
			freqs[KBASE_IPA_BLOCK_TYPE_TOP_LEVEL],
			volts[KBASE_IPA_BLOCK_TYPE_TOP_LEVEL]);

		/* Here unlike kbase_get_real_power(), shader core frequency is
		 * used for the scaling as simple power model is used to obtain
		 * the value of dynamic coefficient (which is a fixed value
		 * retrieved from the device tree).
		 */
		power += kbase_scale_dynamic_power(
			 power_coeffs[KBASE_IPA_BLOCK_TYPE_SHADER_CORES],
			 freqs[KBASE_IPA_BLOCK_TYPE_SHADER_CORES],
			 volts[KBASE_IPA_BLOCK_TYPE_SHADER_CORES]);
	} else
		dev_err_ratelimited(kbdev->dev,
				    "Model %s returned error code %d\n",
				    model->ops->name, err);

	mutex_unlock(&kbdev->ipa.lock);

#if !(defined(CONFIG_MALI_PWRSOFT_765) ||                                      \
	KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE)
	kbase_release_device(kbdev);
#endif

	return power;
}
#endif /* KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE */

int kbase_get_real_power_locked(struct kbase_device *kbdev, u32 *power,
				unsigned long freq,
				unsigned long voltage)
{
	struct kbase_ipa_model *model;
	unsigned long freqs[KBASE_IPA_BLOCK_TYPE_NUM] = {0};
	unsigned long volts[KBASE_IPA_BLOCK_TYPE_NUM] = {0};
	u32 power_coeffs[KBASE_IPA_BLOCK_TYPE_NUM] = {0};
	struct kbasep_pm_metrics diff;
	u64 total_time;
	bool skip_utilization_scaling = false;
	int err = 0;

	lockdep_assert_held(&kbdev->ipa.lock);

	kbase_pm_get_dvfs_metrics(kbdev, &kbdev->ipa.last_metrics, &diff);

	model = get_current_model(kbdev);

	err = model->ops->get_dynamic_coeff(model, power_coeffs);

	/* If the counter model returns an error (e.g. switching back to
	 * protected mode and failing to read counters, or a counter sample
	 * with too few cycles), revert to the fallback model.
	 */
	if (err && model != kbdev->ipa.fallback_model) {
		/* No meaningful scaling for GPU utilization can be done if
		 * the sampling interval was too long. This is equivalent to
		 * assuming GPU was busy throughout (similar to what is done
		 * during protected mode).
		 */
		if (err == -EOVERFLOW)
			skip_utilization_scaling = true;

		model = kbdev->ipa.fallback_model;
		err = model->ops->get_dynamic_coeff(model, power_coeffs);
	}

	if (WARN_ON(err))
		return err;

	opp_translate_freq_voltage(kbdev, freq, voltage, freqs, volts);

	*power = kbase_scale_dynamic_power(
			power_coeffs[KBASE_IPA_BLOCK_TYPE_TOP_LEVEL],
			freqs[KBASE_IPA_BLOCK_TYPE_TOP_LEVEL],
			volts[KBASE_IPA_BLOCK_TYPE_TOP_LEVEL]);

	if (power_coeffs[KBASE_IPA_BLOCK_TYPE_SHADER_CORES]) {
		unsigned long freq = freqs[KBASE_IPA_BLOCK_TYPE_SHADER_CORES];

		/* As per the HW team, the top-level frequency needs to be used
		 * for the scaling if the counter based model was used as
		 * counter values are normalized with the GPU_ACTIVE counter
		 * value, which increments at the rate of top-level frequency.
		 */
		if (model != kbdev->ipa.fallback_model)
			freq = freqs[KBASE_IPA_BLOCK_TYPE_TOP_LEVEL];

		*power += kbase_scale_dynamic_power(
				power_coeffs[KBASE_IPA_BLOCK_TYPE_SHADER_CORES],
				freq, volts[KBASE_IPA_BLOCK_TYPE_SHADER_CORES]);
	}

	if (!skip_utilization_scaling) {
		/* time_busy / total_time cannot be >1, so assigning the 64-bit
		 * result of div_u64 to *power cannot overflow.
		 */
		total_time = diff.time_busy + (u64) diff.time_idle;
		*power = div_u64(*power * (u64) diff.time_busy,
				 max(total_time, 1ull));
	}

	*power += get_static_power_locked(kbdev, model,
				volts[KBASE_IPA_BLOCK_TYPE_TOP_LEVEL]);

	return err;
}
KBASE_EXPORT_TEST_API(kbase_get_real_power_locked);

int kbase_get_real_power(struct devfreq *df, u32 *power,
				unsigned long freq,
				unsigned long voltage)
{
	int ret;
	struct kbase_device *kbdev = dev_get_drvdata(&df->dev);

	if (!kbdev)
		return -ENODEV;

	mutex_lock(&kbdev->ipa.lock);
	ret = kbase_get_real_power_locked(kbdev, power, freq, voltage);
	mutex_unlock(&kbdev->ipa.lock);

	return ret;
}
KBASE_EXPORT_TEST_API(kbase_get_real_power);

struct devfreq_cooling_power kbase_ipa_power_model_ops = {
#if KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE
	.get_static_power = &kbase_get_static_power,
	.get_dynamic_power = &kbase_get_dynamic_power,
#endif /* KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE */
#if defined(CONFIG_MALI_PWRSOFT_765) ||                                        \
	KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE
	.get_real_power = &kbase_get_real_power,
#endif
};
KBASE_EXPORT_TEST_API(kbase_ipa_power_model_ops);

void kbase_ipa_reset_data(struct kbase_device *kbdev)
{
	ktime_t now, diff;
	s64 elapsed_time;

	mutex_lock(&kbdev->ipa.lock);

	now = ktime_get_raw();
	diff = ktime_sub(now, kbdev->ipa.last_sample_time);
	elapsed_time = ktime_to_ms(diff);

	if (elapsed_time > RESET_INTERVAL_MS) {
		struct kbasep_pm_metrics diff;
		struct kbase_ipa_model *model;

		kbase_pm_get_dvfs_metrics(
			kbdev, &kbdev->ipa.last_metrics, &diff);

		model = get_current_model(kbdev);
		if (model != kbdev->ipa.fallback_model)
			model->ops->reset_counter_data(model);

		kbdev->ipa.last_sample_time = ktime_get_raw();
	}

	mutex_unlock(&kbdev->ipa.lock);
}
