]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
LoongArch: Derive timer max_delta from PRCFG1's timer_bits
authorJiaxun Yang <jiaxun.yang@flygoat.com>
Sat, 25 Jan 2025 10:51:33 +0000 (18:51 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Sat, 25 Jan 2025 10:51:33 +0000 (18:51 +0800)
As per arch spec, maximum timer bits is configurable and should not be
hardcoded in any way.

Probe timer bits from PRCFG1 and use that to determine the clockevent's
max_delta to be conformance.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
arch/loongarch/include/asm/cpu-info.h
arch/loongarch/include/asm/loongarch.h
arch/loongarch/kernel/cpu-probe.c
arch/loongarch/kernel/time.c

index 900589cb159de4e5997358443c5b5e3e50f92239..35e0a230a48495cb16a5c35deeb5f564e80c586e 100644 (file)
@@ -57,6 +57,7 @@ struct cpuinfo_loongarch {
        int                     global_id; /* physical global thread number */
        int                     vabits; /* Virtual Address size in bits */
        int                     pabits; /* Physical Address size in bits */
+       int                     timerbits; /* Width of arch timer in bits */
        unsigned int            ksave_mask; /* Usable KSave mask. */
        unsigned int            watch_dreg_count;   /* Number data breakpoints */
        unsigned int            watch_ireg_count;   /* Number instruction breakpoints */
index 64ad277e096edd7d77af6f37e234d68e571764a4..a3cc4f8d4c4a0b0521ef2b76c87fa57eca417d75 100644 (file)
 
 #define LOONGARCH_CSR_TCFG             0x41    /* Timer config */
 #define  CSR_TCFG_VAL_SHIFT            2
-#define         CSR_TCFG_VAL_WIDTH             48
 #define  CSR_TCFG_VAL                  (_ULCAST_(0x3fffffffffff) << CSR_TCFG_VAL_SHIFT)
 #define  CSR_TCFG_PERIOD_SHIFT         1
 #define  CSR_TCFG_PERIOD               (_ULCAST_(0x1) << CSR_TCFG_PERIOD_SHIFT)
index cbce099037b2728b82ecb9c5aa58e05b07695c5a..fedaa67cde410e2e0ae55da904e64b4f7dd91398 100644 (file)
@@ -190,6 +190,7 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
        set_cpu_asid_mask(c, asid_mask);
 
        config = read_csr_prcfg1();
+       c->timerbits = (config & CSR_CONF1_TMRBITS) >> CSR_CONF1_TMRBITS_SHIFT;
        c->ksave_mask = GENMASK((config & CSR_CONF1_KSNUM) - 1, 0);
        c->ksave_mask &= ~(EXC_KSAVE_MASK | PERCPU_KSAVE_MASK | KVM_KSAVE_MASK);
 
index a07d7eff4dc5fb0f41f5fad02698ff7a84c7bc8a..e2d3bfeb6366432ea8df08c4a28002e5af5dbdad 100644 (file)
@@ -132,7 +132,7 @@ int constant_clockevent_init(void)
 #else
        unsigned long min_delta = 1000;
 #endif
-       unsigned long max_delta = (1UL << 48) - 1;
+       unsigned long max_delta = GENMASK_ULL(boot_cpu_data.timerbits, 0);
        struct clock_event_device *cd;
        static int irq = 0, timer_irq_installed = 0;