Skip to content

Commit

Permalink
OPP: Add support of "opp-microwatt" for EM registration
Browse files Browse the repository at this point in the history
The Energy Model (EM) can be created based on DT entry:
'dynamic-power-coefficient'. It's a 'simple' EM which is limited to the
dynamic power. It has to fit into the math formula which requires also
information about voltage. Some of the platforms don't expose voltage
information, thus it's not possible to use EM registration using DT.

This patch aims to fix it. It introduces new implementation of the EM
registration callback. The new mechanism relies on the new OPP feature
allowing to get power (which is coming from "opp-microwatt" DT property)
expressed in micro-Watts.

The patch also opens new opportunity to better support platforms, which
have a decent static power. It allows to register the EM based on real
power measurements which models total power (static + dynamic), so better
reflects real HW.

Signed-off-by: Lukasz Luba <[email protected]>
Signed-off-by: Viresh Kumar <[email protected]>
  • Loading branch information
lukaszluba-arm authored and vireshk committed Mar 3, 2022
1 parent caeea9e commit 32bf8bc
Showing 1 changed file with 60 additions and 1 deletion.
61 changes: 60 additions & 1 deletion drivers/opp/of.c
Original file line number Diff line number Diff line change
Expand Up @@ -1438,6 +1438,38 @@ struct device_node *dev_pm_opp_get_of_node(struct dev_pm_opp *opp)
}
EXPORT_SYMBOL_GPL(dev_pm_opp_get_of_node);

/*
* Callback function provided to the Energy Model framework upon registration.
* It provides the power used by @dev at @kHz if it is the frequency of an
* existing OPP, or at the frequency of the first OPP above @kHz otherwise
* (see dev_pm_opp_find_freq_ceil()). This function updates @kHz to the ceiled
* frequency and @mW to the associated power.
*
* Returns 0 on success or a proper -EINVAL value in case of error.
*/
static int __maybe_unused
_get_dt_power(unsigned long *mW, unsigned long *kHz, struct device *dev)
{
struct dev_pm_opp *opp;
unsigned long opp_freq, opp_power;

/* Find the right frequency and related OPP */
opp_freq = *kHz * 1000;
opp = dev_pm_opp_find_freq_ceil(dev, &opp_freq);
if (IS_ERR(opp))
return -EINVAL;

opp_power = dev_pm_opp_get_power(opp);
dev_pm_opp_put(opp);
if (!opp_power)
return -EINVAL;

*kHz = opp_freq / 1000;
*mW = opp_power / 1000;

return 0;
}

/*
* Callback function provided to the Energy Model framework upon registration.
* This computes the power estimated by @dev at @kHz if it is the frequency
Expand Down Expand Up @@ -1488,6 +1520,24 @@ static int __maybe_unused _get_power(unsigned long *mW, unsigned long *kHz,
return 0;
}

static bool _of_has_opp_microwatt_property(struct device *dev)
{
unsigned long power, freq = 0;
struct dev_pm_opp *opp;

/* Check if at least one OPP has needed property */
opp = dev_pm_opp_find_freq_ceil(dev, &freq);
if (IS_ERR(opp))
return false;

power = dev_pm_opp_get_power(opp);
dev_pm_opp_put(opp);
if (!power)
return false;

return true;
}

/**
* dev_pm_opp_of_register_em() - Attempt to register an Energy Model
* @dev : Device for which an Energy Model has to be registered
Expand All @@ -1501,7 +1551,7 @@ static int __maybe_unused _get_power(unsigned long *mW, unsigned long *kHz,
*/
int dev_pm_opp_of_register_em(struct device *dev, struct cpumask *cpus)
{
struct em_data_callback em_cb = EM_DATA_CB(_get_power);
struct em_data_callback em_cb;
struct device_node *np;
int ret, nr_opp;
u32 cap;
Expand All @@ -1517,6 +1567,12 @@ int dev_pm_opp_of_register_em(struct device *dev, struct cpumask *cpus)
goto failed;
}

/* First, try to find more precised Energy Model in DT */
if (_of_has_opp_microwatt_property(dev)) {
EM_SET_ACTIVE_POWER_CB(em_cb, _get_dt_power);
goto register_em;
}

np = of_node_get(dev->of_node);
if (!np) {
ret = -EINVAL;
Expand All @@ -1538,6 +1594,9 @@ int dev_pm_opp_of_register_em(struct device *dev, struct cpumask *cpus)
goto failed;
}

EM_SET_ACTIVE_POWER_CB(em_cb, _get_power);

register_em:
ret = em_dev_register_perf_domain(dev, nr_opp, &em_cb, cpus, true);
if (ret)
goto failed;
Expand Down

0 comments on commit 32bf8bc

Please sign in to comment.