Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

authored by

Enlin Mu and committed by
Daniel Lezcano
576c564e dcb6fa37

+18 -6
+18 -6
drivers/clocksource/timer-sprd.c
··· 30 30 #define TIMER_VALUE_SHDW_HI 0x1c 31 31 32 32 #define TIMER_VALUE_LO_MASK GENMASK(31, 0) 33 + #define TIMER_VALUE_HI_MASK GENMASK(31, 0) 33 34 34 35 static void sprd_timer_enable(void __iomem *base, u32 flag) 35 36 { ··· 163 162 164 163 static u64 sprd_suspend_timer_read(struct clocksource *cs) 165 164 { 166 - return ~(u64)readl_relaxed(timer_of_base(&suspend_to) + 167 - TIMER_VALUE_SHDW_LO) & cs->mask; 165 + u32 lo, hi; 166 + 167 + do { 168 + hi = readl_relaxed(timer_of_base(&suspend_to) + 169 + TIMER_VALUE_SHDW_HI); 170 + lo = readl_relaxed(timer_of_base(&suspend_to) + 171 + TIMER_VALUE_SHDW_LO); 172 + } while (hi != readl_relaxed(timer_of_base(&suspend_to) + TIMER_VALUE_SHDW_HI)); 173 + 174 + return ~(((u64)hi << 32) | lo); 168 175 } 169 176 170 177 static int sprd_suspend_timer_enable(struct clocksource *cs) 171 178 { 172 - sprd_timer_update_counter(timer_of_base(&suspend_to), 173 - TIMER_VALUE_LO_MASK); 174 - sprd_timer_enable(timer_of_base(&suspend_to), TIMER_CTL_PERIOD_MODE); 179 + writel_relaxed(TIMER_VALUE_LO_MASK, 180 + timer_of_base(&suspend_to) + TIMER_LOAD_LO); 181 + writel_relaxed(TIMER_VALUE_HI_MASK, 182 + timer_of_base(&suspend_to) + TIMER_LOAD_HI); 183 + sprd_timer_enable(timer_of_base(&suspend_to), 184 + TIMER_CTL_PERIOD_MODE|TIMER_CTL_64BIT_WIDTH); 175 185 176 186 return 0; 177 187 } ··· 198 186 .read = sprd_suspend_timer_read, 199 187 .enable = sprd_suspend_timer_enable, 200 188 .disable = sprd_suspend_timer_disable, 201 - .mask = CLOCKSOURCE_MASK(32), 189 + .mask = CLOCKSOURCE_MASK(64), 202 190 .flags = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP, 203 191 }; 204 192