lib: utils/timer: Allow ACLINT MTIMER driver to setup quirks
authorInochi Amaoto <inochiama@outlook.com>
Thu, 16 Nov 2023 09:07:13 +0000 (17:07 +0800)
committerAnup Patel <anup@brainfault.org>
Thu, 16 Nov 2023 11:20:42 +0000 (16:50 +0530)
The quirks checking will cause ACLINT step into a CLINT code path, this
is not expected when ACLINT needs custom quirks.

Add a new quirk to identify custom ACLINT, and apply the general quirks
after applying CLINT specific quirks.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
lib/utils/timer/fdt_timer_mtimer.c

index 9eaa11d855c7345bf7275fabfd9737af8ee90bbd..3d2dce02c413c67f20cc25e0a1129e326ac1a213 100644 (file)
 #include <sbi_utils/timer/aclint_mtimer.h>
 
 struct timer_mtimer_quirks {
-       unsigned int    mtime_offset;
+       bool            is_clint;
+       unsigned int    clint_mtime_offset;
+       bool            clint_without_mtime;
        bool            has_64bit_mmio;
-       bool            without_mtime;
 };
 
 struct timer_mtimer_node {
@@ -36,6 +37,7 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff,
        unsigned long addr[2], size[2];
        struct timer_mtimer_node *mtn, *n;
        struct aclint_mtimer_data *mt;
+       const struct timer_mtimer_quirks *quirks = match->data;
 
        mtn = sbi_zalloc(sizeof(*mtn));
        if (!mtn)
@@ -58,24 +60,20 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff,
                return rc;
        }
 
-       if (match->data) { /* SiFive CLINT */
-               const struct timer_mtimer_quirks *quirks = match->data;
-
+       if (quirks && quirks->is_clint) { /* SiFive CLINT */
                /* Set CLINT addresses */
                mt->mtimecmp_addr = addr[0] + ACLINT_DEFAULT_MTIMECMP_OFFSET;
                mt->mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE;
-               if (!quirks->without_mtime) {
+               if (!quirks->clint_without_mtime) {
                        mt->mtime_addr = addr[0] + ACLINT_DEFAULT_MTIME_OFFSET;
                        mt->mtime_size = size[0] - mt->mtimecmp_size;
                        /* Adjust MTIMER address and size for CLINT device */
-                       mt->mtime_addr += quirks->mtime_offset;
-                       mt->mtime_size -= quirks->mtime_offset;
+                       mt->mtime_addr += quirks->clint_mtime_offset;
+                       mt->mtime_size -= quirks->clint_mtime_offset;
                } else {
                        mt->mtime_addr = mt->mtime_size = 0;
                }
-               mt->mtimecmp_addr += quirks->mtime_offset;
-               /* Apply additional CLINT quirks */
-               mt->has_64bit_mmio = quirks->has_64bit_mmio;
+               mt->mtimecmp_addr += quirks->clint_mtime_offset;
        } else { /* RISC-V ACLINT MTIMER */
                /* Set ACLINT MTIMER addresses */
                mt->mtime_addr = addr[0];
@@ -84,6 +82,11 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff,
                mt->mtimecmp_size = size[1];
        }
 
+       /* Apply additional quirks */
+       if (quirks) {
+               mt->has_64bit_mmio = quirks->has_64bit_mmio;
+       }
+
        /* Check if MTIMER device has shared MTIME address */
        if (mt->mtime_size) {
                mt->has_shared_mtime = false;
@@ -133,13 +136,15 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff,
 }
 
 static const struct timer_mtimer_quirks sifive_clint_quirks = {
-       .mtime_offset   = CLINT_MTIMER_OFFSET,
-       .has_64bit_mmio = true,
+       .is_clint               = true,
+       .clint_mtime_offset     = CLINT_MTIMER_OFFSET,
+       .has_64bit_mmio         = true,
 };
 
 static const struct timer_mtimer_quirks thead_clint_quirks = {
-       .mtime_offset   = CLINT_MTIMER_OFFSET,
-       .without_mtime  = true,
+       .is_clint               = true,
+       .clint_mtime_offset     = CLINT_MTIMER_OFFSET,
+       .clint_without_mtime    = true,
 };
 
 static const struct fdt_match timer_mtimer_match[] = {