RealView: Use only the shadow mapping of ARM11MPCore local timers

All the cases where the local timer for a CPU is accessed happen on the
corresponding current CPU, hence no need to access the per-CPU local
timer mappings.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
Catalin Marinas 2008-12-01 14:54:57 +00:00
Родитель 4c3ea37171
Коммит ebac6546df
10 изменённых файлов: 32 добавлений и 44 удалений

Просмотреть файл

@ -114,7 +114,7 @@ extern void local_timer_interrupt(void);
/* /*
* Stop a local timer interrupt. * Stop a local timer interrupt.
*/ */
extern void local_timer_stop(unsigned int cpu); extern void local_timer_stop(void);
/* /*
* Platform provides this to acknowledge a local timer IRQ * Platform provides this to acknowledge a local timer IRQ
@ -123,7 +123,7 @@ extern int local_timer_ack(void);
#else #else
static inline void local_timer_stop(unsigned int cpu) static inline void local_timer_stop(void)
{ {
} }
@ -132,7 +132,7 @@ static inline void local_timer_stop(unsigned int cpu)
/* /*
* Setup a local timer interrupt for a CPU. * Setup a local timer interrupt for a CPU.
*/ */
extern void local_timer_setup(unsigned int cpu); extern void local_timer_setup(void);
/* /*
* show local interrupt info * show local interrupt info

Просмотреть файл

@ -181,7 +181,7 @@ int __cpuexit __cpu_disable(void)
/* /*
* Stop the local timer for this CPU. * Stop the local timer for this CPU.
*/ */
local_timer_stop(cpu); local_timer_stop();
/* /*
* Flush user cache and TLB mappings, and then remove this CPU * Flush user cache and TLB mappings, and then remove this CPU
@ -284,7 +284,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
/* /*
* Setup local timer for this CPU. * Setup local timer for this CPU.
*/ */
local_timer_setup(cpu); local_timer_setup();
calibrate_delay(); calibrate_delay();

Просмотреть файл

@ -629,7 +629,7 @@ void __init realview_timer_init(unsigned int timer_irq)
* The dummy clock device has to be registered before the main device * The dummy clock device has to be registered before the main device
* so that the latter will broadcast the clock events * so that the latter will broadcast the clock events
*/ */
local_timer_setup(smp_processor_id()); local_timer_setup();
#endif #endif
/* /*

Просмотреть файл

@ -52,8 +52,7 @@ extern struct clk realview_clcd_clk;
extern struct clcd_board clcd_plat_data; extern struct clcd_board clcd_plat_data;
extern void __iomem *gic_cpu_base_addr; extern void __iomem *gic_cpu_base_addr;
#ifdef CONFIG_LOCAL_TIMERS #ifdef CONFIG_LOCAL_TIMERS
extern void __iomem *twd_base_addr; extern void __iomem *twd_base;
extern unsigned int twd_size;
#endif #endif
extern void __iomem *timer0_va_base; extern void __iomem *timer0_va_base;
extern void __iomem *timer1_va_base; extern void __iomem *timer1_va_base;

Просмотреть файл

@ -49,16 +49,14 @@
#ifdef CONFIG_REALVIEW_EB_ARM11MP_REVB #ifdef CONFIG_REALVIEW_EB_ARM11MP_REVB
#define REALVIEW_EB11MP_SCU_BASE 0x10100000 /* SCU registers */ #define REALVIEW_EB11MP_SCU_BASE 0x10100000 /* SCU registers */
#define REALVIEW_EB11MP_GIC_CPU_BASE 0x10100100 /* Generic interrupt controller CPU interface */ #define REALVIEW_EB11MP_GIC_CPU_BASE 0x10100100 /* Generic interrupt controller CPU interface */
#define REALVIEW_EB11MP_TWD_BASE 0x10100700 #define REALVIEW_EB11MP_TWD_BASE 0x10100600
#define REALVIEW_EB11MP_TWD_SIZE 0x00000100
#define REALVIEW_EB11MP_GIC_DIST_BASE 0x10101000 /* Generic interrupt controller distributor */ #define REALVIEW_EB11MP_GIC_DIST_BASE 0x10101000 /* Generic interrupt controller distributor */
#define REALVIEW_EB11MP_L220_BASE 0x10102000 /* L220 registers */ #define REALVIEW_EB11MP_L220_BASE 0x10102000 /* L220 registers */
#define REALVIEW_EB11MP_SYS_PLD_CTRL1 0xD8 /* Register offset for MPCore sysctl */ #define REALVIEW_EB11MP_SYS_PLD_CTRL1 0xD8 /* Register offset for MPCore sysctl */
#else #else
#define REALVIEW_EB11MP_SCU_BASE 0x1F000000 /* SCU registers */ #define REALVIEW_EB11MP_SCU_BASE 0x1F000000 /* SCU registers */
#define REALVIEW_EB11MP_GIC_CPU_BASE 0x1F000100 /* Generic interrupt controller CPU interface */ #define REALVIEW_EB11MP_GIC_CPU_BASE 0x1F000100 /* Generic interrupt controller CPU interface */
#define REALVIEW_EB11MP_TWD_BASE 0x1F000700 #define REALVIEW_EB11MP_TWD_BASE 0x1F000600
#define REALVIEW_EB11MP_TWD_SIZE 0x00000100
#define REALVIEW_EB11MP_GIC_DIST_BASE 0x1F001000 /* Generic interrupt controller distributor */ #define REALVIEW_EB11MP_GIC_DIST_BASE 0x1F001000 /* Generic interrupt controller distributor */
#define REALVIEW_EB11MP_L220_BASE 0x1F002000 /* L220 registers */ #define REALVIEW_EB11MP_L220_BASE 0x1F002000 /* L220 registers */
#define REALVIEW_EB11MP_SYS_PLD_CTRL1 0x74 /* Register offset for MPCore sysctl */ #define REALVIEW_EB11MP_SYS_PLD_CTRL1 0x74 /* Register offset for MPCore sysctl */

Просмотреть файл

@ -77,8 +77,7 @@
*/ */
#define REALVIEW_TC11MP_SCU_BASE 0x1F000000 /* IRQ, Test chip */ #define REALVIEW_TC11MP_SCU_BASE 0x1F000000 /* IRQ, Test chip */
#define REALVIEW_TC11MP_GIC_CPU_BASE 0x1F000100 /* Test chip interrupt controller CPU interface */ #define REALVIEW_TC11MP_GIC_CPU_BASE 0x1F000100 /* Test chip interrupt controller CPU interface */
#define REALVIEW_TC11MP_TWD_BASE 0x1F000700 #define REALVIEW_TC11MP_TWD_BASE 0x1F000600
#define REALVIEW_TC11MP_TWD_SIZE 0x00000100
#define REALVIEW_TC11MP_GIC_DIST_BASE 0x1F001000 /* Test chip interrupt controller distributor */ #define REALVIEW_TC11MP_GIC_DIST_BASE 0x1F001000 /* Test chip interrupt controller distributor */
#define REALVIEW_TC11MP_L220_BASE 0x1F002000 /* L220 registers */ #define REALVIEW_TC11MP_L220_BASE 0x1F002000 /* L220 registers */

Просмотреть файл

@ -38,18 +38,14 @@ void local_timer_interrupt(void)
#ifdef CONFIG_LOCAL_TIMERS #ifdef CONFIG_LOCAL_TIMERS
#define TWD_BASE(cpu) (twd_base_addr + (cpu) * twd_size)
/* set up by the platform code */ /* set up by the platform code */
void __iomem *twd_base_addr; void __iomem *twd_base;
unsigned int twd_size;
static unsigned long mpcore_timer_rate; static unsigned long mpcore_timer_rate;
static void local_timer_set_mode(enum clock_event_mode mode, static void local_timer_set_mode(enum clock_event_mode mode,
struct clock_event_device *clk) struct clock_event_device *clk)
{ {
void __iomem *base = TWD_BASE(smp_processor_id());
unsigned long ctrl; unsigned long ctrl;
switch(mode) { switch(mode) {
@ -68,17 +64,16 @@ static void local_timer_set_mode(enum clock_event_mode mode,
ctrl = 0; ctrl = 0;
} }
__raw_writel(ctrl, base + TWD_TIMER_CONTROL); __raw_writel(ctrl, twd_base + TWD_TIMER_CONTROL);
} }
static int local_timer_set_next_event(unsigned long evt, static int local_timer_set_next_event(unsigned long evt,
struct clock_event_device *unused) struct clock_event_device *unused)
{ {
void __iomem *base = TWD_BASE(smp_processor_id()); unsigned long ctrl = __raw_readl(twd_base + TWD_TIMER_CONTROL);
unsigned long ctrl = __raw_readl(base + TWD_TIMER_CONTROL);
__raw_writel(evt, base + TWD_TIMER_COUNTER); __raw_writel(evt, twd_base + TWD_TIMER_COUNTER);
__raw_writel(ctrl | TWD_TIMER_CONTROL_ENABLE, base + TWD_TIMER_CONTROL); __raw_writel(ctrl | TWD_TIMER_CONTROL_ENABLE, twd_base + TWD_TIMER_CONTROL);
return 0; return 0;
} }
@ -91,19 +86,16 @@ static int local_timer_set_next_event(unsigned long evt,
*/ */
int local_timer_ack(void) int local_timer_ack(void)
{ {
void __iomem *base = TWD_BASE(smp_processor_id()); if (__raw_readl(twd_base + TWD_TIMER_INTSTAT)) {
__raw_writel(1, twd_base + TWD_TIMER_INTSTAT);
if (__raw_readl(base + TWD_TIMER_INTSTAT)) {
__raw_writel(1, base + TWD_TIMER_INTSTAT);
return 1; return 1;
} }
return 0; return 0;
} }
static void __cpuinit twd_calibrate_rate(unsigned int cpu) static void __cpuinit twd_calibrate_rate(void)
{ {
void __iomem *base = TWD_BASE(cpu);
unsigned long load, count; unsigned long load, count;
u64 waitjiffies; u64 waitjiffies;
@ -124,15 +116,15 @@ static void __cpuinit twd_calibrate_rate(unsigned int cpu)
waitjiffies += 5; waitjiffies += 5;
/* enable, no interrupt or reload */ /* enable, no interrupt or reload */
__raw_writel(0x1, base + TWD_TIMER_CONTROL); __raw_writel(0x1, twd_base + TWD_TIMER_CONTROL);
/* maximum value */ /* maximum value */
__raw_writel(0xFFFFFFFFU, base + TWD_TIMER_COUNTER); __raw_writel(0xFFFFFFFFU, twd_base + TWD_TIMER_COUNTER);
while (get_jiffies_64() < waitjiffies) while (get_jiffies_64() < waitjiffies)
udelay(10); udelay(10);
count = __raw_readl(base + TWD_TIMER_COUNTER); count = __raw_readl(twd_base + TWD_TIMER_COUNTER);
mpcore_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5); mpcore_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5);
@ -142,18 +134,19 @@ static void __cpuinit twd_calibrate_rate(unsigned int cpu)
load = mpcore_timer_rate / HZ; load = mpcore_timer_rate / HZ;
__raw_writel(load, base + TWD_TIMER_LOAD); __raw_writel(load, twd_base + TWD_TIMER_LOAD);
} }
/* /*
* Setup the local clock events for a CPU. * Setup the local clock events for a CPU.
*/ */
void __cpuinit local_timer_setup(unsigned int cpu) void __cpuinit local_timer_setup(void)
{ {
unsigned int cpu = smp_processor_id();
struct clock_event_device *clk = &per_cpu(local_clockevent, cpu); struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
unsigned long flags; unsigned long flags;
twd_calibrate_rate(cpu); twd_calibrate_rate();
clk->name = "local_timer"; clk->name = "local_timer";
clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
@ -178,9 +171,9 @@ void __cpuinit local_timer_setup(unsigned int cpu)
/* /*
* take a local timer down * take a local timer down
*/ */
void __cpuexit local_timer_stop(unsigned int cpu) void __cpuexit local_timer_stop(void)
{ {
__raw_writel(0, TWD_BASE(cpu) + TWD_TIMER_CONTROL); __raw_writel(0, twd_base + TWD_TIMER_CONTROL);
} }
#else /* CONFIG_LOCAL_TIMERS */ #else /* CONFIG_LOCAL_TIMERS */
@ -190,8 +183,9 @@ static void dummy_timer_set_mode(enum clock_event_mode mode,
{ {
} }
void __cpuinit local_timer_setup(unsigned int cpu) void __cpuinit local_timer_setup(void)
{ {
unsigned int cpu = smp_processor_id();
struct clock_event_device *clk = &per_cpu(local_clockevent, cpu); struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
clk->name = "dummy_timer"; clk->name = "dummy_timer";

Просмотреть файл

@ -238,7 +238,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
if ((machine_is_realview_eb() && if ((machine_is_realview_eb() &&
(core_tile_eb11mp() || core_tile_a9mp())) || (core_tile_eb11mp() || core_tile_a9mp())) ||
machine_is_realview_pb11mp()) machine_is_realview_pb11mp())
local_timer_setup(cpu); local_timer_setup();
#endif #endif
/* /*

Просмотреть файл

@ -344,8 +344,7 @@ static void __init realview_eb_timer_init(void)
if (core_tile_eb11mp() || core_tile_a9mp()) { if (core_tile_eb11mp() || core_tile_a9mp()) {
#ifdef CONFIG_LOCAL_TIMERS #ifdef CONFIG_LOCAL_TIMERS
twd_base_addr = __io_address(REALVIEW_EB11MP_TWD_BASE); twd_base = __io_address(REALVIEW_EB11MP_TWD_BASE);
twd_size = REALVIEW_EB11MP_TWD_SIZE;
#endif #endif
timer_irq = IRQ_EB11MP_TIMER0_1; timer_irq = IRQ_EB11MP_TIMER0_1;
} else } else

Просмотреть файл

@ -292,8 +292,7 @@ static void __init realview_pb11mp_timer_init(void)
timer3_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE) + 0x20; timer3_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE) + 0x20;
#ifdef CONFIG_LOCAL_TIMERS #ifdef CONFIG_LOCAL_TIMERS
twd_base_addr = __io_address(REALVIEW_TC11MP_TWD_BASE); twd_base = __io_address(REALVIEW_TC11MP_TWD_BASE);
twd_size = REALVIEW_TC11MP_TWD_SIZE;
#endif #endif
realview_timer_init(IRQ_TC11MP_TIMER0_1); realview_timer_init(IRQ_TC11MP_TIMER0_1);
} }