diff options
author | Zhen Lei <thunder.leizhen@huawei.com> | 2020-09-18 16:22:36 +0300 |
---|---|---|
committer | Daniel Lezcano <daniel.lezcano@linaro.org> | 2020-09-24 11:51:04 +0300 |
commit | 549437a43f45ce70cf5012317633c635c43ba4f4 (patch) | |
tree | a1d1a8deafd03c00822cd56fbe0d99cf6314f13f /drivers/clocksource | |
parent | bd5a1936ffa2b69032815775fa54fc1c422d49d5 (diff) | |
download | linux-549437a43f45ce70cf5012317633c635c43ba4f4.tar.xz |
clocksource/drivers/sp804: Enable Hisilicon sp804 timer 64bit mode
A 100MHZ 32-bit timer will be wrapped up less than 43s. Although the
kernel maintains a software high 32-bit count in the tick IRQ. But it's
not applicable to the user mode APPs.
Note: The kernel still uses the lower 32 bits of the timer.
Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/20200918132237.3552-9-thunder.leizhen@huawei.com
Diffstat (limited to 'drivers/clocksource')
-rw-r--r-- | drivers/clocksource/timer-sp.h | 6 | ||||
-rw-r--r-- | drivers/clocksource/timer-sp804.c | 11 |
2 files changed, 17 insertions, 0 deletions
diff --git a/drivers/clocksource/timer-sp.h b/drivers/clocksource/timer-sp.h index 1ab75cbed0e0..811f840be0e5 100644 --- a/drivers/clocksource/timer-sp.h +++ b/drivers/clocksource/timer-sp.h @@ -33,12 +33,15 @@ struct sp804_timer { int load; + int load_h; int value; + int value_h; int ctrl; int intclr; int ris; int mis; int bgload; + int bgload_h; int timer_base[NR_TIMERS]; int width; }; @@ -46,12 +49,15 @@ struct sp804_timer { struct sp804_clkevt { void __iomem *base; void __iomem *load; + void __iomem *load_h; void __iomem *value; + void __iomem *value_h; void __iomem *ctrl; void __iomem *intclr; void __iomem *ris; void __iomem *mis; void __iomem *bgload; + void __iomem *bgload_h; unsigned long reload; int width; }; diff --git a/drivers/clocksource/timer-sp804.c b/drivers/clocksource/timer-sp804.c index f0783d19522f..6e8ad4a4ea3c 100644 --- a/drivers/clocksource/timer-sp804.c +++ b/drivers/clocksource/timer-sp804.c @@ -24,12 +24,15 @@ #define HISI_TIMER_1_BASE 0x00 #define HISI_TIMER_2_BASE 0x40 #define HISI_TIMER_LOAD 0x00 +#define HISI_TIMER_LOAD_H 0x04 #define HISI_TIMER_VALUE 0x08 +#define HISI_TIMER_VALUE_H 0x0c #define HISI_TIMER_CTRL 0x10 #define HISI_TIMER_INTCLR 0x14 #define HISI_TIMER_RIS 0x18 #define HISI_TIMER_MIS 0x1c #define HISI_TIMER_BGLOAD 0x20 +#define HISI_TIMER_BGLOAD_H 0x24 struct sp804_timer __initdata arm_sp804_timer = { @@ -43,7 +46,9 @@ struct sp804_timer __initdata arm_sp804_timer = { struct sp804_timer __initdata hisi_sp804_timer = { .load = HISI_TIMER_LOAD, + .load_h = HISI_TIMER_LOAD_H, .value = HISI_TIMER_VALUE, + .value_h = HISI_TIMER_VALUE_H, .ctrl = HISI_TIMER_CTRL, .intclr = HISI_TIMER_INTCLR, .timer_base = {HISI_TIMER_1_BASE, HISI_TIMER_2_BASE}, @@ -129,6 +134,10 @@ int __init sp804_clocksource_and_sched_clock_init(void __iomem *base, writel(0, clkevt->ctrl); writel(0xffffffff, clkevt->load); writel(0xffffffff, clkevt->value); + if (clkevt->width == 64) { + writel(0xffffffff, clkevt->load_h); + writel(0xffffffff, clkevt->value_h); + } writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, clkevt->ctrl); @@ -245,7 +254,9 @@ static void __init sp804_clkevt_init(struct sp804_timer *timer, void __iomem *ba clkevt = &sp804_clkevt[i]; clkevt->base = timer_base; clkevt->load = timer_base + timer->load; + clkevt->load_h = timer_base + timer->load_h; clkevt->value = timer_base + timer->value; + clkevt->value_h = timer_base + timer->value_h; clkevt->ctrl = timer_base + timer->ctrl; clkevt->intclr = timer_base + timer->intclr; clkevt->width = timer->width; |