forked from Minki/linux
memory: tegra: Adapt for Tegra20 clock driver changes
Now Tegra20 and Tegra30 EMC drivers should provide clock-rounding functionality using the new Tegra clock driver API. Acked-by: Peter De Schrijver <pdeschrijver@nvidia.com> Signed-off-by: Dmitry Osipenko <digetx@gmail.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
parent
fa6749d40e
commit
77ab499dca
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk/tegra.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/interrupt.h>
|
||||
@ -421,6 +422,44 @@ static int emc_setup_hw(struct tegra_emc *emc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long emc_round_rate(unsigned long rate,
|
||||
unsigned long min_rate,
|
||||
unsigned long max_rate,
|
||||
void *arg)
|
||||
{
|
||||
struct emc_timing *timing = NULL;
|
||||
struct tegra_emc *emc = arg;
|
||||
unsigned int i;
|
||||
|
||||
min_rate = min(min_rate, emc->timings[emc->num_timings - 1].rate);
|
||||
|
||||
for (i = 0; i < emc->num_timings; i++) {
|
||||
if (emc->timings[i].rate < rate && i != emc->num_timings - 1)
|
||||
continue;
|
||||
|
||||
if (emc->timings[i].rate > max_rate) {
|
||||
i = max(i, 1u) - 1;
|
||||
|
||||
if (emc->timings[i].rate < min_rate)
|
||||
break;
|
||||
}
|
||||
|
||||
if (emc->timings[i].rate < min_rate)
|
||||
continue;
|
||||
|
||||
timing = &emc->timings[i];
|
||||
break;
|
||||
}
|
||||
|
||||
if (!timing) {
|
||||
dev_err(emc->dev, "no timing for rate %lu min %lu max %lu\n",
|
||||
rate, min_rate, max_rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return timing->rate;
|
||||
}
|
||||
|
||||
static int tegra_emc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np;
|
||||
@ -477,21 +516,28 @@ static int tegra_emc_probe(struct platform_device *pdev)
|
||||
return err;
|
||||
}
|
||||
|
||||
tegra20_clk_set_emc_round_callback(emc_round_rate, emc);
|
||||
|
||||
emc->clk = devm_clk_get(&pdev->dev, "emc");
|
||||
if (IS_ERR(emc->clk)) {
|
||||
err = PTR_ERR(emc->clk);
|
||||
dev_err(&pdev->dev, "failed to get emc clock: %d\n", err);
|
||||
return err;
|
||||
goto unset_cb;
|
||||
}
|
||||
|
||||
err = clk_notifier_register(emc->clk, &emc->clk_nb);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "failed to register clk notifier: %d\n",
|
||||
err);
|
||||
return err;
|
||||
goto unset_cb;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
unset_cb:
|
||||
tegra20_clk_set_emc_round_callback(NULL, NULL);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct of_device_id tegra_emc_of_match[] = {
|
||||
|
Loading…
Reference in New Issue
Block a user