in imx8m-ddrc.c [230:272]
static int imx8m_ddrc_target(struct device *dev, unsigned long *freq, u32 flags)
{
struct imx8m_ddrc *priv = dev_get_drvdata(dev);
struct imx8m_ddrc_freq *freq_info;
struct dev_pm_opp *new_opp;
unsigned long old_freq, new_freq;
int ret;
new_opp = devfreq_recommended_opp(dev, freq, flags);
if (IS_ERR(new_opp)) {
ret = PTR_ERR(new_opp);
dev_err(dev, "failed to get recommended opp: %d\n", ret);
return ret;
}
dev_pm_opp_put(new_opp);
old_freq = clk_get_rate(priv->dram_core);
if (*freq == old_freq)
return 0;
freq_info = imx8m_ddrc_find_freq(priv, *freq);
if (!freq_info)
return -EINVAL;
/*
* Read back the clk rate to verify switch was correct and so that
* we can report it on all error paths.
*/
ret = imx8m_ddrc_set_freq(dev, freq_info);
new_freq = clk_get_rate(priv->dram_core);
if (ret)
dev_err(dev, "ddrc failed freq switch to %lu from %lu: error %d. now at %lu\n",
*freq, old_freq, ret, new_freq);
else if (*freq != new_freq)
dev_err(dev, "ddrc failed freq update to %lu from %lu, now at %lu\n",
*freq, old_freq, new_freq);
else
dev_dbg(dev, "ddrc freq set to %lu (was %lu)\n",
*freq, old_freq);
return ret;
}