rk_timer: v1.2, update sched clock support, only use 32bits

This commit is contained in:
黄涛
2013-01-25 15:17:00 +08:00
parent 47ae543bed
commit 8e1889c13d
2 changed files with 39 additions and 36 deletions

View File

@@ -862,7 +862,6 @@ config ARCH_OMAP
config ARCH_RK29
bool "Rockchip RK29xx"
select PLAT_RK
select HAVE_SCHED_CLOCK
select CPU_V7
select ARM_GIC
select PL330
@@ -875,7 +874,6 @@ config ARCH_RK29
config ARCH_RK2928
bool "Rockchip RK2928"
select PLAT_RK
select HAVE_SCHED_CLOCK
select CPU_V7
select ARM_GIC
select RK_PL330_DMA
@@ -888,7 +886,6 @@ config ARCH_RK2928
config ARCH_RK30
bool "Rockchip RK30xx/RK3108/RK3168"
select PLAT_RK
select HAVE_SCHED_CLOCK
select CPU_V7
select ARM_GIC
select RK_PL330_DMA
@@ -1090,6 +1087,7 @@ config PLAT_PXA
config PLAT_RK
bool
select CLKDEV_LOOKUP
select HAVE_SCHED_CLOCK
select ARCH_HAS_CPUFREQ
select GENERIC_CLOCKEVENTS
select ARCH_REQUIRE_GPIOLIB

View File

@@ -22,6 +22,7 @@
#include <linux/platform_device.h>
#include <asm/localtimer.h>
#include <asm/sched_clock.h>
#define TIMER_NAME "rk_timer"
@@ -51,23 +52,9 @@ static inline void rk_timer_enable(void __iomem *base, u32 flags)
dsb();
}
static inline u64 rk_timer_read_current_value(void __iomem *base)
static inline u32 rk_timer_read_current_value(void __iomem *base)
{
/*
* 1. Read the upper 32-bit timer counter register
* 2. Read the lower 32-bit timer counter register
* 3. Read the upper 32-bit timer counter register again. If the value is different to the 32-bit
* upper value read previously, go back to step 2. Otherwise the 64-bit timer counter value
* is correct.
*/
u32 upper, lower;
do {
upper = readl_relaxed(base + TIMER_CURRENT_VALUE1);
lower = readl_relaxed(base + TIMER_CURRENT_VALUE0);
} while (upper != readl_relaxed(base + TIMER_CURRENT_VALUE1));
return ((u64) upper << 32) + lower;
return readl_relaxed(base + TIMER_CURRENT_VALUE0);
}
struct rk_timer {
@@ -181,11 +168,19 @@ static cycle_t rk_timer_read(struct clocksource *cs)
return ~rk_timer_read_current_value(timer.cs_base);
}
/*
* Constants generated by clocksource_hz2mult(24000000, 26).
* This gives a resolution of about 41ns and a wrap period of about 178s.
*/
#define MULT 2796202667u
#define SHIFT 26
#define MASK (u32)~0
static struct clocksource rk_timer_clocksource = {
.name = TIMER_NAME,
.rating = 200,
.read = rk_timer_read,
.mask = CLOCKSOURCE_MASK(64),
.mask = CLOCKSOURCE_MASK(32),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -208,6 +203,30 @@ static void __init rk_timer_init_clocksource(void)
printk(err, cs->name);
}
static DEFINE_CLOCK_DATA(cd);
unsigned long long notrace sched_clock(void)
{
cycle_t cyc;
if (!timer.cs_base)
return 0;
cyc = ~rk_timer_read_current_value(timer.cs_base);
return cyc_to_fixed_sched_clock(&cd, cyc, MASK, MULT, SHIFT);
}
static void notrace rk_timer_update_sched_clock(void)
{
u32 cyc = ~rk_timer_read_current_value(timer.cs_base);
update_sched_clock(&cd, cyc, MASK);
}
static void __init rk_timer_init_sched_clock(void)
{
init_fixed_sched_clock(&cd, rk_timer_update_sched_clock, 32, 24000000, MULT, SHIFT);
}
#ifndef CONFIG_LOCAL_TIMERS
static struct clock_event_device rk_timer_clockevent;
#endif
@@ -253,8 +272,9 @@ static int __init rk_timer_probe(struct platform_device *pdev)
rk_timer_clockevent.rating = 200;
rk_timer_init_clockevent(&rk_timer_clockevent, 0);
#endif
rk_timer_init_sched_clock();
printk("rk_timer: version 1.1\n");
printk("rk_timer: version 1.2\n");
return 0;
}
@@ -296,18 +316,3 @@ int local_timer_ack(void)
return 0;
}
#endif
/*
* Scheduler clock - returns current time in nanosec units.
*/
unsigned long long notrace sched_clock(void)
{
const struct clocksource *cs = &rk_timer_clocksource;
cycle_t cyc;
if (!timer.cs_base)
return 0;
cyc = ~rk_timer_read_current_value(timer.cs_base);
return clocksource_cyc2ns(cyc, cs->mult, cs->shift);
}