clocksource/drivers/tegra: Lower clocksource rating for some Tegra's

Arch-timer is more preferable for a range of Tegra SoC generations as
it has higher precision and is not affect by any kind of problems.

Pointed-out-by: Peter De Schrijver <pdeschrijver@nvidia.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Acked-By: Peter De Schrijver <pdeschrijver@nvidia.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
This commit is contained in:
Dmitry Osipenko 2019-06-03 21:59:47 +03:00 committed by Daniel Lezcano
parent acb4bb3f37
commit 87bd4c26a6
1 changed files with 26 additions and 4 deletions

View File

@ -109,7 +109,6 @@ static DEFINE_PER_CPU(struct timer_of, tegra_to) = {
.clkevt = { .clkevt = {
.name = "tegra_timer", .name = "tegra_timer",
.rating = 460,
.features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
.set_next_event = tegra_timer_set_next_event, .set_next_event = tegra_timer_set_next_event,
.set_state_shutdown = tegra_timer_shutdown, .set_state_shutdown = tegra_timer_shutdown,
@ -219,7 +218,8 @@ static inline unsigned int tegra_irq_idx_for_cpu(int cpu, bool tegra20)
return TIMER10_IRQ_IDX + cpu; return TIMER10_IRQ_IDX + cpu;
} }
static int __init tegra_init_timer(struct device_node *np, bool tegra20) static int __init tegra_init_timer(struct device_node *np, bool tegra20,
int rating)
{ {
struct timer_of *to; struct timer_of *to;
int cpu, ret; int cpu, ret;
@ -282,6 +282,7 @@ static int __init tegra_init_timer(struct device_node *np, bool tegra20)
cpu_to = per_cpu_ptr(&tegra_to, cpu); cpu_to = per_cpu_ptr(&tegra_to, cpu);
cpu_to->of_base.base = timer_reg_base + base; cpu_to->of_base.base = timer_reg_base + base;
cpu_to->clkevt.rating = rating;
cpu_to->clkevt.cpumask = cpumask_of(cpu); cpu_to->clkevt.cpumask = cpumask_of(cpu);
cpu_to->clkevt.irq = irq_of_parse_and_map(np, idx); cpu_to->clkevt.irq = irq_of_parse_and_map(np, idx);
if (!cpu_to->clkevt.irq) { if (!cpu_to->clkevt.irq) {
@ -341,13 +342,34 @@ static int __init tegra_init_timer(struct device_node *np, bool tegra20)
static int __init tegra210_init_timer(struct device_node *np) static int __init tegra210_init_timer(struct device_node *np)
{ {
return tegra_init_timer(np, false); /*
* Arch-timer can't survive across power cycle of CPU core and
* after CPUPORESET signal due to a system design shortcoming,
* hence tegra-timer is more preferable on Tegra210.
*/
return tegra_init_timer(np, false, 460);
} }
TIMER_OF_DECLARE(tegra210_timer, "nvidia,tegra210-timer", tegra210_init_timer); TIMER_OF_DECLARE(tegra210_timer, "nvidia,tegra210-timer", tegra210_init_timer);
static int __init tegra20_init_timer(struct device_node *np) static int __init tegra20_init_timer(struct device_node *np)
{ {
return tegra_init_timer(np, true); int rating;
/*
* Tegra20 and Tegra30 have Cortex A9 CPU that has a TWD timer,
* that timer runs off the CPU clock and hence is subjected to
* a jitter caused by DVFS clock rate changes. Tegra-timer is
* more preferable for older Tegra's, while later SoC generations
* have arch-timer as a main per-CPU timer and it is not affected
* by DVFS changes.
*/
if (of_machine_is_compatible("nvidia,tegra20") ||
of_machine_is_compatible("nvidia,tegra30"))
rating = 460;
else
rating = 330;
return tegra_init_timer(np, true, rating);
} }
TIMER_OF_DECLARE(tegra20_timer, "nvidia,tegra20-timer", tegra20_init_timer); TIMER_OF_DECLARE(tegra20_timer, "nvidia,tegra20-timer", tegra20_init_timer);