Skip to content

Commit 576c564

Browse files
muenlindlezcano
authored andcommitted
clocksource/drivers/sprd: Enable register for timer counter from 32 bit to 64 bit
Using 32 bit for suspend compensation, the max compensation time is 36 hours(working clock is 32k).In some IOT devices, the suspend time may be long, even exceeding 36 hours. Therefore, a 64 bit timer counter is needed for counting. Signed-off-by: Enlin Mu <enlin.mu@unisoc.com> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com> Link: https://patch.msgid.link/20251106021830.34846-1-enlin.mu@linux.dev
1 parent dcb6fa3 commit 576c564

1 file changed

Lines changed: 18 additions & 6 deletions

File tree

drivers/clocksource/timer-sprd.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#define TIMER_VALUE_SHDW_HI 0x1c
3131

3232
#define TIMER_VALUE_LO_MASK GENMASK(31, 0)
33+
#define TIMER_VALUE_HI_MASK GENMASK(31, 0)
3334

3435
static void sprd_timer_enable(void __iomem *base, u32 flag)
3536
{
@@ -162,15 +163,26 @@ static struct timer_of suspend_to = {
162163

163164
static u64 sprd_suspend_timer_read(struct clocksource *cs)
164165
{
165-
return ~(u64)readl_relaxed(timer_of_base(&suspend_to) +
166-
TIMER_VALUE_SHDW_LO) & cs->mask;
166+
u32 lo, hi;
167+
168+
do {
169+
hi = readl_relaxed(timer_of_base(&suspend_to) +
170+
TIMER_VALUE_SHDW_HI);
171+
lo = readl_relaxed(timer_of_base(&suspend_to) +
172+
TIMER_VALUE_SHDW_LO);
173+
} while (hi != readl_relaxed(timer_of_base(&suspend_to) + TIMER_VALUE_SHDW_HI));
174+
175+
return ~(((u64)hi << 32) | lo);
167176
}
168177

169178
static int sprd_suspend_timer_enable(struct clocksource *cs)
170179
{
171-
sprd_timer_update_counter(timer_of_base(&suspend_to),
172-
TIMER_VALUE_LO_MASK);
173-
sprd_timer_enable(timer_of_base(&suspend_to), TIMER_CTL_PERIOD_MODE);
180+
writel_relaxed(TIMER_VALUE_LO_MASK,
181+
timer_of_base(&suspend_to) + TIMER_LOAD_LO);
182+
writel_relaxed(TIMER_VALUE_HI_MASK,
183+
timer_of_base(&suspend_to) + TIMER_LOAD_HI);
184+
sprd_timer_enable(timer_of_base(&suspend_to),
185+
TIMER_CTL_PERIOD_MODE|TIMER_CTL_64BIT_WIDTH);
174186

175187
return 0;
176188
}
@@ -186,7 +198,7 @@ static struct clocksource suspend_clocksource = {
186198
.read = sprd_suspend_timer_read,
187199
.enable = sprd_suspend_timer_enable,
188200
.disable = sprd_suspend_timer_disable,
189-
.mask = CLOCKSOURCE_MASK(32),
201+
.mask = CLOCKSOURCE_MASK(64),
190202
.flags = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP,
191203
};
192204

0 commit comments

Comments
 (0)