]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
riscv: Rework riscv timer driver to only support S-mode
authorSean Anderson <seanga2@gmail.com>
Mon, 28 Sep 2020 14:52:21 +0000 (10:52 -0400)
committerAndes <uboot@andestech.com>
Wed, 30 Sep 2020 00:54:45 +0000 (08:54 +0800)
The riscv-timer driver currently serves as a shim for several riscv timer
drivers. This is not too desirable because it bypasses the usual timer
selection via the driver model. There is no easy way to specify an
alternate timing driver, or have the tick rate depend on the cpu's
configured frequency. The timer drivers also do not have device structs,
and so have to rely on storing parameters in gd_t. Lastly, there is no
initialization call, so driver init is done in the same function which
reads the time. This can result in confusing error messages. To a user, it
looks like the driver failed when trying to read the time, whereas it may
have failed while initializing.

This patch removes the shim functionality from the riscv-timer driver, and
has it instead implement the former rdtime.c timer driver. This is because
existing u-boot users who pass in a device tree (e.g. qemu) do not create a
timer device for S-mode u-boot. The existing behavior of creating the
riscv-timer device in the riscv cpu driver must be kept. The actual reading
of the CSRs has been redone in the style of Linux's get_cycles64.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
Reviewed-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Rick Chen <rick@andestech.com>
arch/riscv/Kconfig
arch/riscv/cpu/ax25/Kconfig
arch/riscv/cpu/fu540/Kconfig
arch/riscv/cpu/generic/Kconfig
arch/riscv/lib/Makefile
arch/riscv/lib/rdtime.c [deleted file]
drivers/timer/Kconfig
drivers/timer/riscv_timer.c

index 009a545fcf30a36eeba5ac5ea327b12dc99ad6fb..21e6690f4d245181ac64ce9335aa1e242613797d 100644 (file)
@@ -185,14 +185,6 @@ config ANDES_PLMT
          The Andes PLMT block holds memory-mapped mtime register
          associated with timer tick.
 
-config RISCV_RDTIME
-       bool
-       default y if RISCV_SMODE || SPL_RISCV_SMODE
-       help
-         The provides the riscv_get_time() API that is implemented using the
-         standard rdtime instruction. This is the case for S-mode U-Boot, and
-         is useful for processors that support rdtime in M-mode too.
-
 config SYS_MALLOC_F_LEN
        default 0x1000
 
index 8d8d71dcbf970e64a92849b35e366078cd68218e..5cb5bb51eb1a2d0daa84d292d37a6366b2e7894b 100644 (file)
@@ -3,7 +3,7 @@ config RISCV_NDS
        select ARCH_EARLY_INIT_R
        imply CPU
        imply CPU_RISCV
-       imply RISCV_TIMER
+       imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE)
        imply ANDES_PLIC if (RISCV_MMODE || SPL_RISCV_MMODE)
        imply ANDES_PLMT if (RISCV_MMODE || SPL_RISCV_MMODE)
        imply SPL_CPU_SUPPORT
index 53e19635c8311cf443eeb698e6fd88d94a405498..ac3f183342f9ce271f13f3b5ad67614c824a47fa 100644 (file)
@@ -10,7 +10,7 @@ config SIFIVE_FU540
        select SPL_RAM if SPL
        imply CPU
        imply CPU_RISCV
-       imply RISCV_TIMER
+       imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE)
        imply SIFIVE_CLINT if (RISCV_MMODE || SPL_RISCV_MMODE)
        imply CMD_CPU
        imply SPL_CPU_SUPPORT
index b2cb155d6dab2e645469694180cfa09794884c48..f4c2e2643c91053112c0fd485176e341e7a3206c 100644 (file)
@@ -7,7 +7,7 @@ config GENERIC_RISCV
        select ARCH_EARLY_INIT_R
        imply CPU
        imply CPU_RISCV
-       imply RISCV_TIMER
+       imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE)
        imply SIFIVE_CLINT if (RISCV_MMODE || SPL_RISCV_MMODE)
        imply CMD_CPU
        imply SPL_CPU_SUPPORT
index 6c503ff2b2b7a0dfd85bea8648348499a50982f0..10ac5b06d3c022e826ba088caf4f944b65d876ed 100644 (file)
@@ -15,7 +15,6 @@ obj-$(CONFIG_SIFIVE_CLINT) += sifive_clint.o
 obj-$(CONFIG_ANDES_PLIC) += andes_plic.o
 obj-$(CONFIG_ANDES_PLMT) += andes_plmt.o
 else
-obj-$(CONFIG_RISCV_RDTIME) += rdtime.o
 obj-$(CONFIG_SBI) += sbi.o
 obj-$(CONFIG_SBI_IPI) += sbi_ipi.o
 endif
diff --git a/arch/riscv/lib/rdtime.c b/arch/riscv/lib/rdtime.c
deleted file mode 100644 (file)
index e128d7f..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2018, Anup Patel <anup@brainfault.org>
- * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
- *
- * The riscv_get_time() API implementation that is using the
- * standard rdtime instruction.
- */
-
-#include <common.h>
-
-/* Implement the API required by RISC-V timer driver */
-int riscv_get_time(u64 *time)
-{
-#ifdef CONFIG_64BIT
-       u64 n;
-
-       __asm__ __volatile__ (
-               "rdtime %0"
-               : "=r" (n));
-
-       *time = n;
-#else
-       u32 lo, hi, tmp;
-
-       __asm__ __volatile__ (
-               "1:\n"
-               "rdtimeh %0\n"
-               "rdtime %1\n"
-               "rdtimeh %2\n"
-               "bne %0, %2, 1b"
-               : "=&r" (hi), "=&r" (lo), "=&r" (tmp));
-
-       *time = ((u64)hi << 32) | lo;
-#endif
-
-       return 0;
-}
index 637024445c16e7da67bfa292eea0029056775d22..d40d31301138c53941649f69153bc207f2727b48 100644 (file)
@@ -146,8 +146,8 @@ config RISCV_TIMER
        bool "RISC-V timer support"
        depends on TIMER && RISCV
        help
-         Select this to enable support for the timer as defined
-         by the RISC-V privileged architecture spec.
+         Select this to enable support for a generic RISC-V S-Mode timer
+         driver.
 
 config ROCKCHIP_TIMER
        bool "Rockchip timer support"
index 9f9f070e0b36589406b6204552ca8b0b9337682c..449fcfcfd5964c4c201f56bc3f861084c14f3dfb 100644 (file)
@@ -1,36 +1,37 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
+ * Copyright (C) 2020, Sean Anderson <seanga2@gmail.com>
  * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ * Copyright (C) 2018, Anup Patel <anup@brainfault.org>
+ * Copyright (C) 2012 Regents of the University of California
  *
- * RISC-V privileged architecture defined generic timer driver
+ * RISC-V architecturally-defined generic timer driver
  *
- * This driver relies on RISC-V platform codes to provide the essential API
- * riscv_get_time() which is supposed to return the timer counter as defined
- * by the RISC-V privileged architecture spec.
- *
- * This driver can be used in both M-mode and S-mode U-Boot.
+ * This driver provides generic timer support for S-mode U-Boot.
  */
 
 #include <common.h>
 #include <dm.h>
 #include <errno.h>
 #include <timer.h>
-#include <asm/io.h>
-
-/**
- * riscv_get_time() - get the timer counter
- *
- * Platform codes should provide this API in order to make this driver function.
- *
- * @time:      the 64-bit timer count  as defined by the RISC-V privileged
- *             architecture spec.
- * @return:    0 on success, -ve on error.
- */
-extern int riscv_get_time(u64 *time);
+#include <asm/csr.h>
 
 static int riscv_timer_get_count(struct udevice *dev, u64 *count)
 {
-       return riscv_get_time(count);
+       if (IS_ENABLED(CONFIG_64BIT)) {
+               *count = csr_read(CSR_TIME);
+       } else {
+               u32 hi, lo;
+
+               do {
+                       hi = csr_read(CSR_TIMEH);
+                       lo = csr_read(CSR_TIME);
+               } while (hi != csr_read(CSR_TIMEH));
+
+               *count = ((u64)hi << 32) | lo;
+       }
+
+       return 0;
 }
 
 static int riscv_timer_probe(struct udevice *dev)