301 lines
11 KiB
C
301 lines
11 KiB
C
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
|
/*
|
|
*
|
|
* (C) COPYRIGHT 2016-2023 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.
|
|
*
|
|
*/
|
|
|
|
#ifndef _KBASE_IPA_H_
|
|
#define _KBASE_IPA_H_
|
|
|
|
#if defined(CONFIG_MALI_BIFROST_DEVFREQ) && defined(CONFIG_DEVFREQ_THERMAL)
|
|
|
|
struct devfreq;
|
|
|
|
/**
|
|
* enum kbase_ipa_block_type - Type of block for which power estimation is done.
|
|
*
|
|
* @KBASE_IPA_BLOCK_TYPE_USING_CLK_MALI:
|
|
* Blocks using clk_mali in dts.
|
|
* @KBASE_IPA_BLOCK_TYPE_TOP_LEVEL: Top-level block, that covers CSHW,
|
|
* MEMSYS, Tiler.
|
|
* @KBASE_IPA_BLOCK_TYPE_SHADER_CORES: All Shader cores.
|
|
* @KBASE_IPA_BLOCK_TYPE_FOR_CLK_GPU: Dummy for clk_gpu in dts.
|
|
* @KBASE_IPA_BLOCK_TYPE_NUM: Number of blocks.
|
|
*/
|
|
enum kbase_ipa_block_type {
|
|
KBASE_IPA_BLOCK_TYPE_USING_CLK_MALI,
|
|
KBASE_IPA_BLOCK_TYPE_TOP_LEVEL,
|
|
KBASE_IPA_BLOCK_TYPE_SHADER_CORES,
|
|
KBASE_IPA_BLOCK_TYPE_FOR_CLK_GPU,
|
|
KBASE_IPA_BLOCK_TYPE_NUM
|
|
};
|
|
|
|
/**
|
|
* struct kbase_ipa_model - Object describing a particular IPA model.
|
|
* @kbdev: pointer to kbase device
|
|
* @model_data: opaque pointer to model specific data, accessed
|
|
* only by model specific methods.
|
|
* @ops: pointer to object containing model specific methods.
|
|
* @params: head of the list of debugfs params added for model
|
|
* @missing_dt_node_warning: flag to limit the matching power model DT not found
|
|
* warning to once.
|
|
*/
|
|
struct kbase_ipa_model {
|
|
struct kbase_device *kbdev;
|
|
void *model_data;
|
|
const struct kbase_ipa_model_ops *ops;
|
|
struct list_head params;
|
|
bool missing_dt_node_warning;
|
|
};
|
|
|
|
/**
|
|
* kbase_ipa_model_add_param_s32 - Add an integer model parameter
|
|
* @model: pointer to IPA model
|
|
* @name: name of corresponding debugfs entry
|
|
* @addr: address where the value is stored
|
|
* @num_elems: number of elements (1 if not an array)
|
|
* @dt_required: if false, a corresponding devicetree entry is not required,
|
|
* and the current value will be used. If true, a warning is
|
|
* output and the data is zeroed
|
|
*
|
|
* Return: 0 on success, or an error code
|
|
*/
|
|
int kbase_ipa_model_add_param_s32(struct kbase_ipa_model *model, const char *name, s32 *addr,
|
|
size_t num_elems, bool dt_required);
|
|
|
|
/**
|
|
* kbase_ipa_model_add_param_string - Add a string model parameter
|
|
* @model: pointer to IPA model
|
|
* @name: name of corresponding debugfs entry
|
|
* @addr: address where the value is stored
|
|
* @size: size, in bytes, of the value storage (so the maximum string
|
|
* length is size - 1)
|
|
* @dt_required: if false, a corresponding devicetree entry is not required,
|
|
* and the current value will be used. If true, a warning is
|
|
* output and the data is zeroed
|
|
*
|
|
* Return: 0 on success, or an error code
|
|
*/
|
|
int kbase_ipa_model_add_param_string(struct kbase_ipa_model *model, const char *name, char *addr,
|
|
size_t size, bool dt_required);
|
|
|
|
struct kbase_ipa_model_ops {
|
|
char *name;
|
|
/* The init, recalculate and term ops on the default model are always
|
|
* called. However, all the other models are only invoked if the model
|
|
* is selected in the device tree. Otherwise they are never
|
|
* initialized. Additional resources can be acquired by models in
|
|
* init(), however they must be terminated in the term().
|
|
*/
|
|
int (*init)(struct kbase_ipa_model *model);
|
|
/* Called immediately after init(), or when a parameter is changed, so
|
|
* that any coefficients derived from model parameters can be
|
|
* recalculated
|
|
*/
|
|
int (*recalculate)(struct kbase_ipa_model *model);
|
|
void (*term)(struct kbase_ipa_model *model);
|
|
/*
|
|
* get_dynamic_coeff() - calculate dynamic power coefficient
|
|
* @model: pointer to model
|
|
* @coeffp: pointer to return value location
|
|
*
|
|
* Calculate a dynamic power coefficient, with units pW/(Hz V^2), which
|
|
* is then scaled by the IPA framework according to the current OPP's
|
|
* frequency and voltage.
|
|
*
|
|
* Return: 0 on success, or an error code. -EOVERFLOW error code will
|
|
* indicate that sampling interval was too large and no meaningful
|
|
* scaling for GPU utiliation can be done.
|
|
*/
|
|
int (*get_dynamic_coeff)(struct kbase_ipa_model *model, u32 *coeffp);
|
|
/*
|
|
* get_static_coeff() - calculate static power coefficient
|
|
* @model: pointer to model
|
|
* @coeffp: pointer to return value location
|
|
*
|
|
* Calculate a static power coefficient, with units uW/(V^3), which is
|
|
* scaled by the IPA framework according to the current OPP's voltage.
|
|
*
|
|
* Return: 0 on success, or an error code.
|
|
*/
|
|
int (*get_static_coeff)(struct kbase_ipa_model *model, u32 *coeffp);
|
|
|
|
/*
|
|
* reset_counter_data() - Reset the HW counter data used for calculating
|
|
* dynamic power coefficient
|
|
* @model: pointer to model
|
|
*
|
|
* This method is currently applicable only to the counter based model.
|
|
* The next call to get_dynamic_coeff() will have to calculate the
|
|
* dynamic power coefficient based on the HW counter data generated
|
|
* from this point onwards.
|
|
*/
|
|
void (*reset_counter_data)(struct kbase_ipa_model *model);
|
|
};
|
|
|
|
/**
|
|
* kbase_ipa_init - Initialize the IPA feature
|
|
* @kbdev: pointer to kbase device
|
|
*
|
|
* simple IPA power model is initialized as a fallback model and if that
|
|
* initialization fails then IPA is not used.
|
|
* The device tree is read for the name of ipa model to be used, by using the
|
|
* property string "ipa-model". If that ipa model is supported then it is
|
|
* initialized but if the initialization fails then simple power model is used.
|
|
*
|
|
* Return: 0 on success, negative -errno on error
|
|
*/
|
|
int kbase_ipa_init(struct kbase_device *kbdev);
|
|
|
|
/**
|
|
* kbase_ipa_term - Terminate the IPA feature
|
|
* @kbdev: pointer to kbase device
|
|
*
|
|
* Both simple IPA power model and model retrieved from device tree are
|
|
* terminated.
|
|
*/
|
|
void kbase_ipa_term(struct kbase_device *kbdev);
|
|
|
|
/**
|
|
* kbase_ipa_model_recalculate - Recalculate the model coefficients
|
|
* @model: pointer to the IPA model object, already initialized
|
|
*
|
|
* It shall be called immediately after the model has been initialized
|
|
* or when the model parameter has changed, so that any coefficients
|
|
* derived from parameters can be recalculated.
|
|
* Its a wrapper for the module specific recalculate() method.
|
|
*
|
|
* Return: 0 on success, negative -errno on error
|
|
*/
|
|
int kbase_ipa_model_recalculate(struct kbase_ipa_model *model);
|
|
|
|
/**
|
|
* kbase_ipa_model_ops_find - Lookup an IPA model using its name
|
|
* @kbdev: pointer to kbase device
|
|
* @name: name of model to lookup
|
|
*
|
|
* Return: Pointer to model's 'ops' structure, or NULL if the lookup failed.
|
|
*/
|
|
const struct kbase_ipa_model_ops *kbase_ipa_model_ops_find(struct kbase_device *kbdev,
|
|
const char *name);
|
|
|
|
/**
|
|
* kbase_ipa_counter_model_ops_find - Lookup an IPA counter model using its name
|
|
* @kbdev: pointer to kbase device
|
|
* @name: name of counter model to lookup
|
|
*
|
|
* Return: Pointer to counter model's 'ops' structure, or NULL if the lookup
|
|
* failed.
|
|
*/
|
|
const struct kbase_ipa_model_ops *kbase_ipa_counter_model_ops_find(struct kbase_device *kbdev,
|
|
const char *name);
|
|
|
|
/**
|
|
* kbase_ipa_model_name_from_id - Find the best model for a given GPU ID
|
|
* @gpu_id: GPU ID of GPU the model will be used for
|
|
*
|
|
* Return: The name of the appropriate counter-based model, or the name of the
|
|
* fallback model if no counter model exists.
|
|
*/
|
|
const char *kbase_ipa_model_name_from_id(struct kbase_gpu_id_props *gpu_id);
|
|
|
|
/**
|
|
* kbase_ipa_counter_model_name_from_id - Find the best counter model for a
|
|
* given GPU ID
|
|
* @gpu_id: GPU ID of GPU the counter model will be used for
|
|
*
|
|
* Return: The name of the appropriate counter-based model, or NULL if the
|
|
* no counter model exists.
|
|
*/
|
|
const char *kbase_ipa_counter_model_name_from_id(struct kbase_gpu_id_props *gpu_id);
|
|
|
|
/**
|
|
* kbase_ipa_init_model - Initilaize the particular IPA model
|
|
* @kbdev: pointer to kbase device
|
|
* @ops: pointer to object containing model specific methods.
|
|
*
|
|
* Initialize the model corresponding to the @ops pointer passed.
|
|
* The init() method specified in @ops would be called.
|
|
*
|
|
* Return: pointer to kbase_ipa_model on success, NULL on error
|
|
*/
|
|
struct kbase_ipa_model *kbase_ipa_init_model(struct kbase_device *kbdev,
|
|
const struct kbase_ipa_model_ops *ops);
|
|
/**
|
|
* kbase_ipa_term_model - Terminate the particular IPA model
|
|
* @model: pointer to the IPA model object, already initialized
|
|
*
|
|
* Terminate the model, using the term() method.
|
|
* Module specific parameters would be freed.
|
|
*/
|
|
void kbase_ipa_term_model(struct kbase_ipa_model *model);
|
|
|
|
/**
|
|
* kbase_ipa_protection_mode_switch_event - Inform IPA of the GPU's entry into
|
|
* protected mode
|
|
* @kbdev: pointer to kbase device
|
|
*
|
|
* Makes IPA aware of the GPU switching to protected mode.
|
|
*/
|
|
void kbase_ipa_protection_mode_switch_event(struct kbase_device *kbdev);
|
|
|
|
/**
|
|
* kbase_get_real_power() - get the real power consumption of the GPU
|
|
* @df: dynamic voltage and frequency scaling information for the GPU.
|
|
* @power: where to store the power consumption, in mW.
|
|
* @freq: a frequency, in HZ.
|
|
* @voltage: a voltage, in mV.
|
|
*
|
|
* The returned value incorporates both static and dynamic power consumption.
|
|
*
|
|
* Return: 0 on success, or an error code.
|
|
*/
|
|
int kbase_get_real_power(struct devfreq *df, u32 *power, unsigned long freq, unsigned long voltage);
|
|
|
|
/* Called by kbase_get_real_power() to invoke the power models.
|
|
* Must be called with kbdev->ipa.lock held.
|
|
* This function is only exposed for use by unit tests.
|
|
*/
|
|
int kbase_get_real_power_locked(struct kbase_device *kbdev, u32 *power, unsigned long freq,
|
|
unsigned long voltage);
|
|
|
|
extern struct devfreq_cooling_power kbase_ipa_power_model_ops;
|
|
|
|
/**
|
|
* kbase_ipa_reset_data() - Reset the data required for power estimation.
|
|
* @kbdev: Pointer to kbase device.
|
|
*
|
|
* This function is called to ensure a meaningful baseline for
|
|
* kbase_get_real_power(), when thermal governor starts the polling, and
|
|
* that is achieved by updating the GPU utilization metrics and retrieving
|
|
* the accumulated value of HW counters.
|
|
* Basically this function collects all the data required for power estimation
|
|
* but does not process it.
|
|
*/
|
|
void kbase_ipa_reset_data(struct kbase_device *kbdev);
|
|
|
|
#else /* !(defined(CONFIG_MALI_BIFROST_DEVFREQ) && defined(CONFIG_DEVFREQ_THERMAL)) */
|
|
|
|
static inline void kbase_ipa_protection_mode_switch_event(struct kbase_device *kbdev)
|
|
{
|
|
}
|
|
|
|
#endif /* (defined(CONFIG_MALI_BIFROST_DEVFREQ) && defined(CONFIG_DEVFREQ_THERMAL)) */
|
|
|
|
#endif
|