Skip to content

Commit

Permalink
arm64: move from arm_generic to arm_arch_timer
Browse files Browse the repository at this point in the history
The arch_timer driver supports a superset of the functionality of the
arm_generic driver, and is not tied to a particular arch.

This patch moves arm64 to use the arch_timer driver, gaining additional
functionality in doing so, and removes the (now unused) arm_generic
driver. Timer-related hooks specific to arm64 are moved into
arch/arm64/kernel/time.c.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
  • Loading branch information
Mark Rutland committed Jan 31, 2013
1 parent 1dac0dd commit 1aee5d7
Show file tree
Hide file tree
Showing 9 changed files with 162 additions and 363 deletions.
1 change: 1 addition & 0 deletions arch/arm64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ config ARM64
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
select ARM_AMBA
select ARM_ARCH_TIMER
select CLONE_BACKWARDS
select COMMON_CLK
select GENERIC_CLOCKEVENTS
Expand Down
133 changes: 133 additions & 0 deletions arch/arm64/include/asm/arch_timer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
* arch/arm64/include/asm/arch_timer.h
*
* Copyright (C) 2012 ARM Ltd.
* Author: Marc Zyngier <marc.zyngier@arm.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __ASM_ARCH_TIMER_H
#define __ASM_ARCH_TIMER_H

#include <asm/barrier.h>

#include <linux/init.h>
#include <linux/types.h>

#include <clocksource/arm_arch_timer.h>

static inline void arch_timer_reg_write(int access, int reg, u32 val)
{
if (access == ARCH_TIMER_PHYS_ACCESS) {
switch (reg) {
case ARCH_TIMER_REG_CTRL:
asm volatile("msr cntp_ctl_el0, %0" : : "r" (val));
break;
case ARCH_TIMER_REG_TVAL:
asm volatile("msr cntp_tval_el0, %0" : : "r" (val));
break;
default:
BUILD_BUG();
}
} else if (access == ARCH_TIMER_VIRT_ACCESS) {
switch (reg) {
case ARCH_TIMER_REG_CTRL:
asm volatile("msr cntv_ctl_el0, %0" : : "r" (val));
break;
case ARCH_TIMER_REG_TVAL:
asm volatile("msr cntv_tval_el0, %0" : : "r" (val));
break;
default:
BUILD_BUG();
}
} else {
BUILD_BUG();
}

isb();
}

static inline u32 arch_timer_reg_read(int access, int reg)
{
u32 val;

if (access == ARCH_TIMER_PHYS_ACCESS) {
switch (reg) {
case ARCH_TIMER_REG_CTRL:
asm volatile("mrs %0, cntp_ctl_el0" : "=r" (val));
break;
case ARCH_TIMER_REG_TVAL:
asm volatile("mrs %0, cntp_tval_el0" : "=r" (val));
break;
default:
BUILD_BUG();
}
} else if (access == ARCH_TIMER_VIRT_ACCESS) {
switch (reg) {
case ARCH_TIMER_REG_CTRL:
asm volatile("mrs %0, cntv_ctl_el0" : "=r" (val));
break;
case ARCH_TIMER_REG_TVAL:
asm volatile("mrs %0, cntv_tval_el0" : "=r" (val));
break;
default:
BUILD_BUG();
}
} else {
BUILD_BUG();
}

return val;
}

static inline u32 arch_timer_get_cntfrq(void)
{
u32 val;
asm volatile("mrs %0, cntfrq_el0" : "=r" (val));
return val;
}

static inline void __cpuinit arch_counter_set_user_access(void)
{
u32 cntkctl;

/* Disable user access to the timers and the physical counter. */
asm volatile("mrs %0, cntkctl_el1" : "=r" (cntkctl));
cntkctl &= ~((3 << 8) | (1 << 0));

/* Enable user access to the virtual counter and frequency. */
cntkctl |= (1 << 1);
asm volatile("msr cntkctl_el1, %0" : : "r" (cntkctl));
}

static inline u64 arch_counter_get_cntpct(void)
{
u64 cval;

isb();
asm volatile("mrs %0, cntpct_el0" : "=r" (cval));

return cval;
}

static inline u64 arch_counter_get_cntvct(void)
{
u64 cval;

isb();
asm volatile("mrs %0, cntvct_el0" : "=r" (cval));

return cval;
}

#endif
102 changes: 0 additions & 102 deletions arch/arm64/include/asm/arm_generic.h

This file was deleted.

29 changes: 27 additions & 2 deletions arch/arm64/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@
#include <linux/syscore_ops.h>
#include <linux/timer.h>
#include <linux/irq.h>
#include <linux/delay.h>

#include <clocksource/arm_generic.h>
#include <clocksource/arm_arch_timer.h>

#include <asm/thread_info.h>
#include <asm/stacktrace.h>
Expand All @@ -59,7 +60,31 @@ unsigned long profile_pc(struct pt_regs *regs)
EXPORT_SYMBOL(profile_pc);
#endif

static u64 sched_clock_mult __read_mostly;

unsigned long long notrace sched_clock(void)
{
return arch_timer_read_counter() * sched_clock_mult;
}

int read_current_timer(unsigned long *timer_value)
{
*timer_value = arch_timer_read_counter();
return 0;
}

void __init time_init(void)
{
arm_generic_timer_init();
u32 arch_timer_rate;

if (arch_timer_init())
panic("Unable to initialise architected timer.\n");

arch_timer_rate = arch_timer_get_rate();

/* Cache the sched_clock multiplier to save a divide in the hot path. */
sched_clock_mult = NSEC_PER_SEC / arch_timer_rate;

/* Calibrate the delay loop directly */
lpj_fine = arch_timer_rate / HZ;
}
5 changes: 0 additions & 5 deletions drivers/clocksource/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,5 @@ config CLKSRC_DBX500_PRCMU_SCHED_CLOCK
help
Use the always on PRCMU Timer as sched_clock

config CLKSRC_ARM_GENERIC
def_bool y if ARM64
help
This option enables support for the ARM generic timer.

config ARM_ARCH_TIMER
bool
1 change: 0 additions & 1 deletion drivers/clocksource/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,4 @@ obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o
obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o
obj-$(CONFIG_SUNXI_TIMER) += sunxi_timer.o

obj-$(CONFIG_CLKSRC_ARM_GENERIC) += arm_generic.o
obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
1 change: 1 addition & 0 deletions drivers/clocksource/arm_arch_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ static int __init arch_timer_register(void)

static const struct of_device_id arch_timer_of_match[] __initconst = {
{ .compatible = "arm,armv7-timer", },
{ .compatible = "arm,armv8-timer", },
{},
};

Expand Down
Loading

0 comments on commit 1aee5d7

Please sign in to comment.