ARM: tegra: use us counter as delay timer

Tegra has a micro-second counter whose rate doesn't vary with cpufreq
 changes. Register it so it can be used as the delay timer, so delays
 aren't influenced by cpufreq.
 
 I've made this a separate branch since it touches a few files outside
 arch/arm/mach-tegra/. This can be merged anywhere that conflicts need
 to be resolved, although I know of no such places at present.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.11 (GNU/Linux)
 
 iQIcBAABAgAGBQJTqJo3AAoJEMzrak5tbycxUbkP/1Rx2GqGYG2pvsQDEXuHGVJn
 3WuFRC7kvc1A/4smpSs+1UhZMwbyewCcdEYbCSjI28UVcYokdRnWAgYrPit3Q0VB
 8RGuqDXyW7nYJrRdwpeSddBlt+lW273nn1hz6BB5tvKYr+5IR8iUqkMB6e8Ri2cV
 QNG0H4/+OKvnlM6Mfk0yZ2F12ZmUdey0j7mEhzHNtxZhN3JXm5g+Ta58knRibkCO
 EJNip5nlZg6d07GAHkEtiegLPTfNsnBDh9RyiMq/FHb0NJ6WZxvCizesFg1Ph2rW
 QVjShShivEXB5F/7bNVmMlsySGWA6WTiWYCvZ+GB4Jf6HMLTv0ekyTP28pJdeaMN
 2A8Si4MueWx1E5sUPbHJznsk/zbB7A2Xgb+h59M3FyAbKNqMCf141cAg6YrPHkee
 I50H4G4xe2KwKRM01ErwRqOU3MEsPiJ/8CBgseEZ8G71SMj4cGvGglKj9cr6V4hC
 SzAyDkctJD9QNMozp6nyhhGEJ76WaNsvBV9FjqmthiRhTtRbusapyGle/tx5f0IP
 ieS3vlt7WGeLFJQ9NkuOI9Dn1p7KDlWSbCgjm3dFVYlCZyiGeJf7L6GzGvePBhOB
 eQ3O4zIXnjuW+HXOU9bEWU3yavviFewmf7IdygdjrYymq46KmDCT6fhxFppnSWTA
 SIbgbOwiZHD63RQSuYFv
 =flbE
 -----END PGP SIGNATURE-----

Merge tag 'tegra-for-3.17-delay-timer' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/soc

Merge "ARM: tegra: use us counter as delay timer" from Stephen Warren:

Tegra has a micro-second counter whose rate doesn't vary with cpufreq
changes. Register it so it can be used as the delay timer, so delays
aren't influenced by cpufreq.

* tag 'tegra-for-3.17-delay-timer' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux:
  clocksource: tegra: Use us counter as delay timer
  ARM: choose highest resolution delay timer
  kernel: add calibration_delay_done()

Signed-off-by: Olof Johansson <[email protected]>
This commit is contained in:
Olof Johansson 2014-07-06 17:47:28 -07:00
commit b040614c5b
3 changed files with 46 additions and 4 deletions

View file

@ -27,6 +27,7 @@
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/sched_clock.h>
#include <linux/delay.h>
#include <asm/mach/time.h>
#include <asm/smp_twd.h>
@ -53,6 +54,8 @@ static void __iomem *rtc_base;
static struct timespec persistent_ts;
static u64 persistent_ms, last_persistent_ms;
static struct delay_timer tegra_delay_timer;
#define timer_writel(value, reg) \
__raw_writel(value, timer_reg_base + (reg))
#define timer_readl(reg) \
@ -139,6 +142,11 @@ static void tegra_read_persistent_clock(struct timespec *ts)
*ts = *tsp;
}
static unsigned long tegra_delay_timer_read_counter_long(void)
{
return readl(timer_reg_base + TIMERUS_CNTR_1US);
}
static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id)
{
struct clock_event_device *evt = (struct clock_event_device *)dev_id;
@ -206,6 +214,11 @@ static void __init tegra20_init_timer(struct device_node *np)
BUG();
}
tegra_delay_timer.read_current_timer =
tegra_delay_timer_read_counter_long;
tegra_delay_timer.freq = 1000000;
register_current_timer_delay(&tegra_delay_timer);
ret = setup_irq(tegra_timer_irq.irq, &tegra_timer_irq);
if (ret) {
pr_err("Failed to register timer IRQ: %d\n", ret);