All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/8] riscv: Clean up timer drivers
@ 2020-09-09 20:09 Sean Anderson
  2020-09-09 20:09 ` [PATCH v4 1/8] riscv: Rework riscv timer driver to only support S-mode Sean Anderson
                   ` (7 more replies)
  0 siblings, 8 replies; 18+ messages in thread
From: Sean Anderson @ 2020-09-09 20:09 UTC (permalink / raw)
  To: u-boot

This series cleans up the timer drivers in RISC-V and converts them to DM.

This series needs to be tested! I have only tested it on QEMU and the K210.
Notably, this means that the HiFive and anything Andes is completely untested.

Changes in v4:
- Both the Andes PMLT and Sifive CLINT now fall back on timebase-frequency,
  per discussion with Anup Patel
- Introduce helper function for falling back on timebase-frequency
- Modify RISCV_TIMER KConfig
  - Now depends on RISCV
  - Implied by S-Mode (with or without SPL)
- Rebase
- Remove clock-frequency property from k210 clint binding because we fall
  back on timebase-frequency

Changes in v3:
- Don't initialize the IPI in spl_invoke_opensbi. Further testing has
  revealed it to be unnecessary.
- Rebase

Changes in v2:
- Fix SiFive CLINT not getting tick-rate from rtcclk
- Remove RISCV_RDTIME KConfig option
- Split Kendryte binding changes into their own commit

Sean Anderson (8):
  riscv: Rework riscv timer driver to only support S-mode
  timer: Add helper for drivers using timebase fallback
  riscv: Rework Andes PLMT as a UCLASS_TIMER driver
  riscv: Clean up initialization in Andes PLIC
  riscv: Rework Sifive CLINT as UCLASS_TIMER driver
  riscv: clk: Add CLINT clock to kendryte clock driver
  riscv: Update Kendryte device tree for new CLINT driver
  riscv: Update SiFive device tree for new CLINT driver

 arch/riscv/Kconfig                            | 16 -----
 arch/riscv/cpu/ax25/Kconfig                   |  2 +-
 arch/riscv/cpu/fu540/Kconfig                  |  2 +-
 arch/riscv/cpu/generic/Kconfig                |  2 +-
 arch/riscv/dts/ae350_32.dts                   |  1 +
 arch/riscv/dts/ae350_64.dts                   |  1 +
 arch/riscv/dts/fu540-c000-u-boot.dtsi         |  8 ++-
 .../dts/hifive-unleashed-a00-u-boot.dtsi      |  4 ++
 arch/riscv/dts/k210.dtsi                      |  7 +-
 arch/riscv/include/asm/global_data.h          |  3 -
 arch/riscv/lib/Makefile                       |  1 -
 arch/riscv/lib/andes_plic.c                   | 58 +++++++---------
 arch/riscv/lib/andes_plmt.c                   | 44 ++++++-------
 arch/riscv/lib/rdtime.c                       | 38 -----------
 arch/riscv/lib/sifive_clint.c                 | 66 ++++++++++---------
 drivers/clk/kendryte/clk.c                    |  4 ++
 drivers/ram/sifive/Kconfig                    |  2 +
 drivers/timer/Kconfig                         |  4 +-
 drivers/timer/riscv_timer.c                   | 39 +++++------
 drivers/timer/timer-uclass.c                  | 25 +++++++
 include/dt-bindings/clock/k210-sysctl.h       |  1 +
 include/timer.h                               | 15 +++++
 22 files changed, 170 insertions(+), 173 deletions(-)
 delete mode 100644 arch/riscv/lib/rdtime.c

-- 
2.28.0

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v4 1/8] riscv: Rework riscv timer driver to only support S-mode
  2020-09-09 20:09 [PATCH v4 0/8] riscv: Clean up timer drivers Sean Anderson
@ 2020-09-09 20:09 ` Sean Anderson
  2020-09-09 20:09 ` [PATCH v4 2/8] timer: Add helper for drivers using timebase fallback Sean Anderson
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 18+ messages in thread
From: Sean Anderson @ 2020-09-09 20:09 UTC (permalink / raw)
  To: u-boot

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>
---

Changes in v4:
- Modify RISCV_TIMER KConfig
  - Now depends on RISCV
  - Implied by S-Mode (with or without SPL)

Changes in v2:
- Remove RISCV_RDTIME KConfig option

 arch/riscv/Kconfig             |  8 -------
 arch/riscv/cpu/ax25/Kconfig    |  2 +-
 arch/riscv/cpu/fu540/Kconfig   |  2 +-
 arch/riscv/cpu/generic/Kconfig |  2 +-
 arch/riscv/lib/Makefile        |  1 -
 arch/riscv/lib/rdtime.c        | 38 ---------------------------------
 drivers/timer/Kconfig          |  4 ++--
 drivers/timer/riscv_timer.c    | 39 +++++++++++++++++-----------------
 8 files changed, 25 insertions(+), 71 deletions(-)
 delete mode 100644 arch/riscv/lib/rdtime.c

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 009a545fcf..21e6690f4d 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -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
 
diff --git a/arch/riscv/cpu/ax25/Kconfig b/arch/riscv/cpu/ax25/Kconfig
index 8d8d71dcbf..5cb5bb51eb 100644
--- a/arch/riscv/cpu/ax25/Kconfig
+++ b/arch/riscv/cpu/ax25/Kconfig
@@ -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
diff --git a/arch/riscv/cpu/fu540/Kconfig b/arch/riscv/cpu/fu540/Kconfig
index 53e19635c8..ac3f183342 100644
--- a/arch/riscv/cpu/fu540/Kconfig
+++ b/arch/riscv/cpu/fu540/Kconfig
@@ -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
diff --git a/arch/riscv/cpu/generic/Kconfig b/arch/riscv/cpu/generic/Kconfig
index b2cb155d6d..f4c2e2643c 100644
--- a/arch/riscv/cpu/generic/Kconfig
+++ b/arch/riscv/cpu/generic/Kconfig
@@ -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
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index 6c503ff2b2..10ac5b06d3 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -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
index e128d7fce6..0000000000
--- a/arch/riscv/lib/rdtime.c
+++ /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;
-}
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index 637024445c..d40d313011 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -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"
diff --git a/drivers/timer/riscv_timer.c b/drivers/timer/riscv_timer.c
index 9f9f070e0b..449fcfcfd5 100644
--- a/drivers/timer/riscv_timer.c
+++ b/drivers/timer/riscv_timer.c
@@ -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)
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v4 2/8] timer: Add helper for drivers using timebase fallback
  2020-09-09 20:09 [PATCH v4 0/8] riscv: Clean up timer drivers Sean Anderson
  2020-09-09 20:09 ` [PATCH v4 1/8] riscv: Rework riscv timer driver to only support S-mode Sean Anderson
@ 2020-09-09 20:09 ` Sean Anderson
  2020-09-10 13:38   ` Simon Glass
  2020-09-15  7:13   ` Bin Meng
  2020-09-09 20:09 ` [PATCH v4 3/8] riscv: Rework Andes PLMT as a UCLASS_TIMER driver Sean Anderson
                   ` (5 subsequent siblings)
  7 siblings, 2 replies; 18+ messages in thread
From: Sean Anderson @ 2020-09-09 20:09 UTC (permalink / raw)
  To: u-boot

This function is designed to be used when a timer used to be initialized by
the cpu (e.g. RISC-V timers), but now is initialized by dm_timer_init. In
such a case, the timer may prefer to use the clocks and clock-frequency
properties, but should be able to fall back on using the cpu's
timebase-frequency.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
---

Changes in v4:
- New

 drivers/timer/timer-uclass.c | 25 +++++++++++++++++++++++++
 include/timer.h              | 15 +++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/drivers/timer/timer-uclass.c b/drivers/timer/timer-uclass.c
index 14dde950a1..fb2f4c351a 100644
--- a/drivers/timer/timer-uclass.c
+++ b/drivers/timer/timer-uclass.c
@@ -4,6 +4,7 @@
  */
 
 #include <common.h>
+#include <cpu.h>
 #include <dm.h>
 #include <init.h>
 #include <dm/lists.h>
@@ -79,6 +80,30 @@ static int timer_post_probe(struct udevice *dev)
 	return 0;
 }
 
+int timer_timebase_fallback(struct udevice *dev)
+{
+	struct udevice *cpu;
+	struct cpu_platdata *cpu_plat;
+	struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+
+	/* Did we get our clock rate from the device tree? */
+	if (uc_priv->clock_rate)
+		return 0;
+
+	/* Fall back to timebase-frequency */
+	dev_dbg(dev, "missing clocks or clock-frequency property; falling back on timebase-frequency\n");
+	cpu = cpu_get_current_dev();
+	if (!cpu)
+		return -ENODEV;
+
+	cpu_plat = dev_get_parent_platdata(cpu);
+	if (!cpu_plat)
+		return -ENODEV;
+
+	uc_priv->clock_rate = cpu_plat->timebase_freq;
+	return 0;
+}
+
 u64 timer_conv_64(u32 count)
 {
 	/* increment tbh if tbl has rolled over */
diff --git a/include/timer.h b/include/timer.h
index a49b500ce3..8b9fa51c53 100644
--- a/include/timer.h
+++ b/include/timer.h
@@ -15,6 +15,21 @@
  */
 int dm_timer_init(void);
 
+/**
+ * timer_timebase_fallback() - Helper for timers using timebase fallback
+ * @dev: A timer partially-probed timer device
+ *
+ * This is a helper function designed for timers which need to fall back on the
+ * cpu's timebase. This function is designed to be called during the driver's
+ * probe(). If there is a clocks or clock-frequency property in the timer's
+ * binding, then it will be used. Otherwise, the timebase of the current cpu
+ * will be used. This is initialized by the cpu driver, and usually gotten from
+ * ``/cpus/timebase-frequency`` or ``/cpus/cpu at X/timebase-frequency``.
+ *
+ * Return: 0 if OK, or negative error code on failure
+ */
+int timer_timebase_fallback(struct udevice *dev);
+
 /*
  * timer_conv_64 - convert 32-bit counter value to 64-bit
  *
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v4 3/8] riscv: Rework Andes PLMT as a UCLASS_TIMER driver
  2020-09-09 20:09 [PATCH v4 0/8] riscv: Clean up timer drivers Sean Anderson
  2020-09-09 20:09 ` [PATCH v4 1/8] riscv: Rework riscv timer driver to only support S-mode Sean Anderson
  2020-09-09 20:09 ` [PATCH v4 2/8] timer: Add helper for drivers using timebase fallback Sean Anderson
@ 2020-09-09 20:09 ` Sean Anderson
  2020-09-15  7:18   ` Bin Meng
  2020-09-09 20:09 ` [PATCH v4 4/8] riscv: Clean up initialization in Andes PLIC Sean Anderson
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 18+ messages in thread
From: Sean Anderson @ 2020-09-09 20:09 UTC (permalink / raw)
  To: u-boot

This converts the PLMT driver from the riscv-specific timer interface to be
a DM-based UCLASS_TIMER driver.

The clock-frequency/clocks properties are preferred over timebase-frequency
for two reasons. First, properties which affect a device should be located
near its binding in the device tree. Using timebase-frequency only really
makes sense when the cpu itself is the timer device. This is the case when
we read the time from a CSR, but not when there is a separate device.
Second, it lets the device use the clock subsystem which adds flexibility.
If the device is configured for a different clock speed, the timer can
adjust itself.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
Reviewed-by: Rick Chen <rick@andestech.com>
---
This patch builds but has NOT been tested.

Changes in v4:
- Use timer_timebase_fallback

 arch/riscv/Kconfig                   |  4 ---
 arch/riscv/dts/ae350_32.dts          |  1 +
 arch/riscv/dts/ae350_64.dts          |  1 +
 arch/riscv/include/asm/global_data.h |  3 --
 arch/riscv/lib/andes_plmt.c          | 44 +++++++++++++---------------
 5 files changed, 23 insertions(+), 30 deletions(-)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 21e6690f4d..d9155b9bab 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -177,10 +177,6 @@ config ANDES_PLIC
 config ANDES_PLMT
 	bool
 	depends on RISCV_MMODE || SPL_RISCV_MMODE
-	select REGMAP
-	select SYSCON
-	select SPL_REGMAP if SPL
-	select SPL_SYSCON if SPL
 	help
 	  The Andes PLMT block holds memory-mapped mtime register
 	  associated with timer tick.
diff --git a/arch/riscv/dts/ae350_32.dts b/arch/riscv/dts/ae350_32.dts
index 3f8525fe56..afcb9cfbbf 100644
--- a/arch/riscv/dts/ae350_32.dts
+++ b/arch/riscv/dts/ae350_32.dts
@@ -162,6 +162,7 @@
 				&CPU2_intc 7
 				&CPU3_intc 7>;
 			reg = <0xe6000000 0x100000>;
+			clock-frequency = <60000000>;
 		};
 	};
 
diff --git a/arch/riscv/dts/ae350_64.dts b/arch/riscv/dts/ae350_64.dts
index 482c707503..1c37879049 100644
--- a/arch/riscv/dts/ae350_64.dts
+++ b/arch/riscv/dts/ae350_64.dts
@@ -162,6 +162,7 @@
 				&CPU2_intc 7
 				&CPU3_intc 7>;
 			reg = <0x0 0xe6000000 0x0 0x100000>;
+			clock-frequency = <60000000>;
 		};
 	};
 
diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h
index 2eb14815bc..0dec5e669e 100644
--- a/arch/riscv/include/asm/global_data.h
+++ b/arch/riscv/include/asm/global_data.h
@@ -24,9 +24,6 @@ struct arch_global_data {
 #ifdef CONFIG_ANDES_PLIC
 	void __iomem *plic;	/* plic base address */
 #endif
-#ifdef CONFIG_ANDES_PLMT
-	void __iomem *plmt;	/* plmt base address */
-#endif
 #if CONFIG_IS_ENABLED(SMP)
 	struct ipi_data ipi[CONFIG_NR_CPUS];
 #endif
diff --git a/arch/riscv/lib/andes_plmt.c b/arch/riscv/lib/andes_plmt.c
index a7e90ca992..a28c14c1eb 100644
--- a/arch/riscv/lib/andes_plmt.c
+++ b/arch/riscv/lib/andes_plmt.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright (C) 2019, Rick Chen <rick@andestech.com>
+ * Copyright (C) 2020, Sean Anderson <seanga2@gmail.com>
  *
  * U-Boot syscon driver for Andes's Platform Level Machine Timer (PLMT).
  * The PLMT block holds memory-mapped mtime register
@@ -9,46 +10,43 @@
 
 #include <common.h>
 #include <dm.h>
-#include <regmap.h>
-#include <syscon.h>
+#include <timer.h>
 #include <asm/io.h>
-#include <asm/syscon.h>
 #include <linux/err.h>
 
 /* mtime register */
 #define MTIME_REG(base)			((ulong)(base))
 
-DECLARE_GLOBAL_DATA_PTR;
-
-#define PLMT_BASE_GET(void)						\
-	do {								\
-		long *ret;						\
-									\
-		if (!gd->arch.plmt) {					\
-			ret = syscon_get_first_range(RISCV_SYSCON_PLMT); \
-			if (IS_ERR(ret))				\
-				return PTR_ERR(ret);			\
-			gd->arch.plmt = ret;				\
-		}							\
-	} while (0)
-
-int riscv_get_time(u64 *time)
+static int andes_plmt_get_count(struct udevice *dev, u64 *count)
 {
-	PLMT_BASE_GET();
-
-	*time = readq((void __iomem *)MTIME_REG(gd->arch.plmt));
+	*count = readq((void __iomem *)MTIME_REG(dev->priv));
 
 	return 0;
 }
 
+static const struct timer_ops andes_plmt_ops = {
+	.get_count = andes_plmt_get_count,
+};
+
+static int andes_plmt_probe(struct udevice *dev)
+{
+	dev->priv = dev_read_addr_ptr(dev);
+	if (!dev->priv)
+		return -EINVAL;
+
+	return timer_timebase_fallback(dev);
+}
+
 static const struct udevice_id andes_plmt_ids[] = {
-	{ .compatible = "riscv,plmt0", .data = RISCV_SYSCON_PLMT },
+	{ .compatible = "riscv,plmt0" },
 	{ }
 };
 
 U_BOOT_DRIVER(andes_plmt) = {
 	.name		= "andes_plmt",
-	.id		= UCLASS_SYSCON,
+	.id		= UCLASS_TIMER,
 	.of_match	= andes_plmt_ids,
+	.ops		= &andes_plmt_ops,
+	.probe		= andes_plmt_probe,
 	.flags		= DM_FLAG_PRE_RELOC,
 };
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v4 4/8] riscv: Clean up initialization in Andes PLIC
  2020-09-09 20:09 [PATCH v4 0/8] riscv: Clean up timer drivers Sean Anderson
                   ` (2 preceding siblings ...)
  2020-09-09 20:09 ` [PATCH v4 3/8] riscv: Rework Andes PLMT as a UCLASS_TIMER driver Sean Anderson
@ 2020-09-09 20:09 ` Sean Anderson
  2020-09-09 20:09 ` [PATCH v4 5/8] riscv: Rework Sifive CLINT as UCLASS_TIMER driver Sean Anderson
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 18+ messages in thread
From: Sean Anderson @ 2020-09-09 20:09 UTC (permalink / raw)
  To: u-boot

This merges the PLIC initialization code from two functions into one.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
Reviewed-by: Bin Meng <bin.meng@windriver.com>
---
This patch builds but has NOT been tested.

(no changes since v1)

 arch/riscv/lib/andes_plic.c | 58 ++++++++++++++++---------------------
 1 file changed, 25 insertions(+), 33 deletions(-)

diff --git a/arch/riscv/lib/andes_plic.c b/arch/riscv/lib/andes_plic.c
index c2a8fe4d9e..267d6a191b 100644
--- a/arch/riscv/lib/andes_plic.c
+++ b/arch/riscv/lib/andes_plic.c
@@ -41,53 +41,45 @@ static int enable_ipi(int hart)
 	return 0;
 }
 
-static int init_plic(void)
+int riscv_init_ipi(void)
 {
-	struct udevice *dev;
-	ofnode node;
 	int ret;
+	long *base = syscon_get_first_range(RISCV_SYSCON_PLIC);
+	ofnode node;
+	struct udevice *dev;
 	u32 reg;
 
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+	gd->arch.plic = base;
+
 	ret = uclass_find_first_device(UCLASS_CPU, &dev);
 	if (ret)
 		return ret;
+	else if (!dev)
+		return -ENODEV;
 
-	if (dev) {
-		ofnode_for_each_subnode(node, dev_ofnode(dev->parent)) {
-			const char *device_type;
+	ofnode_for_each_subnode(node, dev_ofnode(dev->parent)) {
+		const char *device_type;
 
-			device_type = ofnode_read_string(node, "device_type");
-			if (!device_type)
-				continue;
+		device_type = ofnode_read_string(node, "device_type");
+		if (!device_type)
+			continue;
 
-			if (strcmp(device_type, "cpu"))
-				continue;
+		if (strcmp(device_type, "cpu"))
+			continue;
 
-			/* skip if hart is marked as not available */
-			if (!ofnode_is_available(node))
-				continue;
+		/* skip if hart is marked as not available */
+		if (!ofnode_is_available(node))
+			continue;
 
-			/* read hart ID of CPU */
-			ret = ofnode_read_u32(node, "reg", &reg);
-			if (ret == 0)
-				enable_ipi(reg);
-		}
-
-		return 0;
+		/* read hart ID of CPU */
+		ret = ofnode_read_u32(node, "reg", &reg);
+		if (ret == 0)
+			enable_ipi(reg);
 	}
 
-	return -ENODEV;
-}
-
-int riscv_init_ipi(void)
-{
-	long *ret = syscon_get_first_range(RISCV_SYSCON_PLIC);
-
-	if (IS_ERR(ret))
-		return PTR_ERR(ret);
-	gd->arch.plic = ret;
-
-	return init_plic();
+	return 0;
 }
 
 int riscv_send_ipi(int hart)
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v4 5/8] riscv: Rework Sifive CLINT as UCLASS_TIMER driver
  2020-09-09 20:09 [PATCH v4 0/8] riscv: Clean up timer drivers Sean Anderson
                   ` (3 preceding siblings ...)
  2020-09-09 20:09 ` [PATCH v4 4/8] riscv: Clean up initialization in Andes PLIC Sean Anderson
@ 2020-09-09 20:09 ` Sean Anderson
  2020-09-15  8:09   ` Bin Meng
  2020-09-09 20:09 ` [PATCH v4 6/8] riscv: clk: Add CLINT clock to kendryte clock driver Sean Anderson
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 18+ messages in thread
From: Sean Anderson @ 2020-09-09 20:09 UTC (permalink / raw)
  To: u-boot

This converts the clint driver from the riscv-specific interface to be a
DM-based UCLASS_TIMER driver. In addition, the SiFive DDR driver previously
implicitly depended on the CLINT to select REGMAP.

Unlike Andes's PLMT/PLIC (which AFAIK never have anything pass it a dtb),
the SiFive CLINT is part of the device tree passed in by qemu. This device
tree doesn't have a clocks or clock-frequency property on clint, so we need
to fall back on the timebase-frequency property. Perhaps in the future we
can get a clock-frequency property added to the qemu dtb.

Unlike with the Andes PLMT, the Sifive CLINT is also an IPI controller.
RISCV_SYSCON_CLINT is retained for this purpose.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
Reviewed-by: Pragnesh Patel <pragnesh.patel@openfive.com>
---
This patch builds but has only been tested on the K210 and QEMU. It has NOT
been tested on a HiFive.

Changes in v4:
- Use timer_timebase_fallback

Changes in v3:
- Don't initialize the IPI in spl_invoke_opensbi. Further testing has
  revealed it to be unnecessary.

 arch/riscv/Kconfig            |  4 ---
 arch/riscv/lib/sifive_clint.c | 66 +++++++++++++++++++----------------
 drivers/ram/sifive/Kconfig    |  2 ++
 3 files changed, 38 insertions(+), 34 deletions(-)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index d9155b9bab..aaa3b833a5 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -155,10 +155,6 @@ config 64BIT
 config SIFIVE_CLINT
 	bool
 	depends on RISCV_MMODE || SPL_RISCV_MMODE
-	select REGMAP
-	select SYSCON
-	select SPL_REGMAP if SPL
-	select SPL_SYSCON if SPL
 	help
 	  The SiFive CLINT block holds memory-mapped control and status registers
 	  associated with software and timer interrupts.
diff --git a/arch/riscv/lib/sifive_clint.c b/arch/riscv/lib/sifive_clint.c
index b9a2c649cc..c9704c596f 100644
--- a/arch/riscv/lib/sifive_clint.c
+++ b/arch/riscv/lib/sifive_clint.c
@@ -8,9 +8,9 @@
  */
 
 #include <common.h>
+#include <clk.h>
 #include <dm.h>
-#include <regmap.h>
-#include <syscon.h>
+#include <timer.h>
 #include <asm/io.h>
 #include <asm/syscon.h>
 #include <linux/err.h>
@@ -24,35 +24,19 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-int riscv_get_time(u64 *time)
-{
-	/* ensure timer register base has a sane value */
-	riscv_init_ipi();
-
-	*time = readq((void __iomem *)MTIME_REG(gd->arch.clint));
-
-	return 0;
-}
-
-int riscv_set_timecmp(int hart, u64 cmp)
-{
-	/* ensure timer register base has a sane value */
-	riscv_init_ipi();
-
-	writeq(cmp, (void __iomem *)MTIMECMP_REG(gd->arch.clint, hart));
-
-	return 0;
-}
-
 int riscv_init_ipi(void)
 {
-	if (!gd->arch.clint) {
-		long *ret = syscon_get_first_range(RISCV_SYSCON_CLINT);
+	int ret;
+	struct udevice *dev;
 
-		if (IS_ERR(ret))
-			return PTR_ERR(ret);
-		gd->arch.clint = ret;
-	}
+	ret = uclass_get_device_by_driver(UCLASS_TIMER,
+					  DM_GET_DRIVER(sifive_clint), &dev);
+	if (ret)
+		return ret;
+
+	gd->arch.clint = dev_read_addr_ptr(dev);
+	if (!gd->arch.clint)
+		return -EINVAL;
 
 	return 0;
 }
@@ -78,14 +62,36 @@ int riscv_get_ipi(int hart, int *pending)
 	return 0;
 }
 
+static int sifive_clint_get_count(struct udevice *dev, u64 *count)
+{
+	*count = readq((void __iomem *)MTIME_REG(dev->priv));
+
+	return 0;
+}
+
+static const struct timer_ops sifive_clint_ops = {
+	.get_count = sifive_clint_get_count,
+};
+
+static int sifive_clint_probe(struct udevice *dev)
+{
+	dev->priv = dev_read_addr_ptr(dev);
+	if (!dev->priv)
+		return -EINVAL;
+
+	return timer_timebase_fallback(dev);
+}
+
 static const struct udevice_id sifive_clint_ids[] = {
-	{ .compatible = "riscv,clint0", .data = RISCV_SYSCON_CLINT },
+	{ .compatible = "riscv,clint0" },
 	{ }
 };
 
 U_BOOT_DRIVER(sifive_clint) = {
 	.name		= "sifive_clint",
-	.id		= UCLASS_SYSCON,
+	.id		= UCLASS_TIMER,
 	.of_match	= sifive_clint_ids,
+	.probe		= sifive_clint_probe,
+	.ops		= &sifive_clint_ops,
 	.flags		= DM_FLAG_PRE_RELOC,
 };
diff --git a/drivers/ram/sifive/Kconfig b/drivers/ram/sifive/Kconfig
index 6aca22ab2a..31ad0a7e45 100644
--- a/drivers/ram/sifive/Kconfig
+++ b/drivers/ram/sifive/Kconfig
@@ -9,5 +9,7 @@ config SIFIVE_FU540_DDR
 	bool "SiFive FU540 DDR driver"
 	depends on RAM_SIFIVE
 	default y if TARGET_SIFIVE_FU540
+	select REGMAP
+	select SPL_REGMAP if SPL
 	help
 	  This enables DDR support for the platforms based on SiFive FU540 SoC.
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v4 6/8] riscv: clk: Add CLINT clock to kendryte clock driver
  2020-09-09 20:09 [PATCH v4 0/8] riscv: Clean up timer drivers Sean Anderson
                   ` (4 preceding siblings ...)
  2020-09-09 20:09 ` [PATCH v4 5/8] riscv: Rework Sifive CLINT as UCLASS_TIMER driver Sean Anderson
@ 2020-09-09 20:09 ` Sean Anderson
  2020-09-09 20:09 ` [PATCH v4 7/8] riscv: Update Kendryte device tree for new CLINT driver Sean Anderson
  2020-09-09 20:09 ` [PATCH v4 8/8] riscv: Update SiFive " Sean Anderson
  7 siblings, 0 replies; 18+ messages in thread
From: Sean Anderson @ 2020-09-09 20:09 UTC (permalink / raw)
  To: u-boot

Another "virtual" clock (in the sense that it isn't configurable). This
could possibly be done as a clock in the device tree, but I think this is a
bit cleaner.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
---
checkpatch still complains about this one, but I don't see any reason to
break it up even further. It doesn't make sense to me to split the header
file change from everything else.

(no changes since v2)

Changes in v2:
- Split Kendryte binding changes into their own commit

 drivers/clk/kendryte/clk.c              | 4 ++++
 include/dt-bindings/clock/k210-sysctl.h | 1 +
 2 files changed, 5 insertions(+)

diff --git a/drivers/clk/kendryte/clk.c b/drivers/clk/kendryte/clk.c
index 981b3b7699..bb196961af 100644
--- a/drivers/clk/kendryte/clk.c
+++ b/drivers/clk/kendryte/clk.c
@@ -646,6 +646,10 @@ static int k210_clk_probe(struct udevice *dev)
 	REGISTER_GATE(K210_CLK_RTC,   "rtc",   in0);
 #undef REGISTER_GATE
 
+	/* The MTIME register in CLINT runs at one 50th the CPU clock speed */
+	clk_dm(K210_CLK_CLINT,
+	       clk_register_fixed_factor(NULL, "clint", "cpu", 0, 1, 50));
+
 	return 0;
 }
 
diff --git a/include/dt-bindings/clock/k210-sysctl.h b/include/dt-bindings/clock/k210-sysctl.h
index 0e3ed3fb9f..fe852bbd92 100644
--- a/include/dt-bindings/clock/k210-sysctl.h
+++ b/include/dt-bindings/clock/k210-sysctl.h
@@ -55,5 +55,6 @@
 #define K210_CLK_OTP    43
 #define K210_CLK_RTC    44
 #define K210_CLK_ACLK   45
+#define K210_CLK_CLINT  46
 
 #endif /* CLOCK_K210_SYSCTL_H */
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v4 7/8] riscv: Update Kendryte device tree for new CLINT driver
  2020-09-09 20:09 [PATCH v4 0/8] riscv: Clean up timer drivers Sean Anderson
                   ` (5 preceding siblings ...)
  2020-09-09 20:09 ` [PATCH v4 6/8] riscv: clk: Add CLINT clock to kendryte clock driver Sean Anderson
@ 2020-09-09 20:09 ` Sean Anderson
  2020-09-15  9:07   ` Bin Meng
  2020-09-09 20:09 ` [PATCH v4 8/8] riscv: Update SiFive " Sean Anderson
  7 siblings, 1 reply; 18+ messages in thread
From: Sean Anderson @ 2020-09-09 20:09 UTC (permalink / raw)
  To: u-boot

The interrupt controller property is removed from the clint binding because
the clint is not an interrupt-controller. That is, no other devices have an
interrupt which is controlled by the clint.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
---

Changes in v4:
- Remove clock-frequency property from k210 clint binding because we fall
  back on timebase-frequency

Changes in v2:
- New

 arch/riscv/dts/k210.dtsi | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/dts/k210.dtsi b/arch/riscv/dts/k210.dtsi
index 2546c7d4e0..84cff51c36 100644
--- a/arch/riscv/dts/k210.dtsi
+++ b/arch/riscv/dts/k210.dtsi
@@ -17,6 +17,8 @@
 	compatible = "kendryte,k210";
 
 	aliases {
+		cpu0 = &cpu0;
+		cpu1 = &cpu1;
 		dma0 = &dmac0;
 		gpio0 = &gpio0;
 		gpio1 = &gpio1_0;
@@ -126,14 +128,13 @@
 			read-only;
 		};
 
-		clint0: interrupt-controller at 2000000 {
+		clint0: clint at 2000000 {
 			#interrupt-cells = <1>;
 			compatible = "kendryte,k210-clint", "riscv,clint0";
 			reg = <0x2000000 0xC000>;
-			interrupt-controller;
 			interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>,
 					      <&cpu1_intc 3>, <&cpu1_intc 7>;
-			clocks = <&sysclk K210_CLK_CPU>;
+			clocks = <&sysclk K210_CLK_CLINT>;
 		};
 
 		plic0: interrupt-controller at C000000 {
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v4 8/8] riscv: Update SiFive device tree for new CLINT driver
  2020-09-09 20:09 [PATCH v4 0/8] riscv: Clean up timer drivers Sean Anderson
                   ` (6 preceding siblings ...)
  2020-09-09 20:09 ` [PATCH v4 7/8] riscv: Update Kendryte device tree for new CLINT driver Sean Anderson
@ 2020-09-09 20:09 ` Sean Anderson
  2020-09-15  9:13   ` Bin Meng
  7 siblings, 1 reply; 18+ messages in thread
From: Sean Anderson @ 2020-09-09 20:09 UTC (permalink / raw)
  To: u-boot

We currently do this in a u-boot specific dts, but hopefully we can get
these bindings added in Linux in the future.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
Reviewed-by: Pragnesh Patel <pragnesh.patel@openfive.com>
---
This patch builds but has NOT been tested.

Changes in v4:
- Both the Andes PMLT and Sifive CLINT now fall back on timebase-frequency,
  per discussion with Anup Patel
- Rebase

Changes in v3:
- Rebase

Changes in v2:
- Fix SiFive CLINT not getting tick-rate from rtcclk

 arch/riscv/dts/fu540-c000-u-boot.dtsi           | 8 ++++++--
 arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi | 4 ++++
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/dts/fu540-c000-u-boot.dtsi b/arch/riscv/dts/fu540-c000-u-boot.dtsi
index 5302677ee4..a06e1b11c6 100644
--- a/arch/riscv/dts/fu540-c000-u-boot.dtsi
+++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi
@@ -55,9 +55,13 @@
 			reg = <0x0 0x10070000 0x0 0x1000>;
 			fuse-count = <0x1000>;
 		};
-		clint at 2000000 {
+		clint: clint at 2000000 {
 			compatible = "riscv,clint0";
-			interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7 &cpu1_intc 3 &cpu1_intc 7 &cpu2_intc 3 &cpu2_intc 7 &cpu3_intc 3 &cpu3_intc 7 &cpu4_intc 3 &cpu4_intc 7>;
+			interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7
+					       &cpu1_intc 3 &cpu1_intc 7
+					       &cpu2_intc 3 &cpu2_intc 7
+					       &cpu3_intc 3 &cpu3_intc 7
+					       &cpu4_intc 3 &cpu4_intc 7>;
 			reg = <0x0 0x2000000 0x0 0xc0000>;
 			u-boot,dm-spl;
 		};
diff --git a/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
index 5d0c928b29..1996149c95 100644
--- a/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
+++ b/arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi
@@ -34,6 +34,10 @@
 
 };
 
+&clint {
+	clocks = <&rtcclk>;
+};
+
 &qspi0 {
 	u-boot,dm-spl;
 
-- 
2.28.0

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v4 2/8] timer: Add helper for drivers using timebase fallback
  2020-09-09 20:09 ` [PATCH v4 2/8] timer: Add helper for drivers using timebase fallback Sean Anderson
@ 2020-09-10 13:38   ` Simon Glass
  2020-09-10 15:13     ` Sean Anderson
  2020-09-15  7:13   ` Bin Meng
  1 sibling, 1 reply; 18+ messages in thread
From: Simon Glass @ 2020-09-10 13:38 UTC (permalink / raw)
  To: u-boot

On Wed, 9 Sep 2020 at 14:09, Sean Anderson <seanga2@gmail.com> wrote:
>
> This function is designed to be used when a timer used to be initialized by
> the cpu (e.g. RISC-V timers), but now is initialized by dm_timer_init. In
> such a case, the timer may prefer to use the clocks and clock-frequency
> properties, but should be able to fall back on using the cpu's
> timebase-frequency.
>
> Signed-off-by: Sean Anderson <seanga2@gmail.com>
> ---
>
> Changes in v4:
> - New
>
>  drivers/timer/timer-uclass.c | 25 +++++++++++++++++++++++++
>  include/timer.h              | 15 +++++++++++++++
>  2 files changed, 40 insertions(+)
>

Reviewed-by: Simon Glass <sjg@chromium.org>

Can this be tested with sandbox?

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v4 2/8] timer: Add helper for drivers using timebase fallback
  2020-09-10 13:38   ` Simon Glass
@ 2020-09-10 15:13     ` Sean Anderson
  0 siblings, 0 replies; 18+ messages in thread
From: Sean Anderson @ 2020-09-10 15:13 UTC (permalink / raw)
  To: u-boot

On 9/10/20 9:38 AM, Simon Glass wrote:
> On Wed, 9 Sep 2020 at 14:09, Sean Anderson <seanga2@gmail.com> wrote:
>>
>> This function is designed to be used when a timer used to be initialized by
>> the cpu (e.g. RISC-V timers), but now is initialized by dm_timer_init. In
>> such a case, the timer may prefer to use the clocks and clock-frequency
>> properties, but should be able to fall back on using the cpu's
>> timebase-frequency.
>>
>> Signed-off-by: Sean Anderson <seanga2@gmail.com>
>> ---
>>
>> Changes in v4:
>> - New
>>
>>  drivers/timer/timer-uclass.c | 25 +++++++++++++++++++++++++
>>  include/timer.h              | 15 +++++++++++++++
>>  2 files changed, 40 insertions(+)
>>
> 
> Reviewed-by: Simon Glass <sjg@chromium.org>
> 
> Can this be tested with sandbox?
> 

Probably. I can add a test in the next revision.

--Sean

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v4 2/8] timer: Add helper for drivers using timebase fallback
  2020-09-09 20:09 ` [PATCH v4 2/8] timer: Add helper for drivers using timebase fallback Sean Anderson
  2020-09-10 13:38   ` Simon Glass
@ 2020-09-15  7:13   ` Bin Meng
  1 sibling, 0 replies; 18+ messages in thread
From: Bin Meng @ 2020-09-15  7:13 UTC (permalink / raw)
  To: u-boot

On Thu, Sep 10, 2020 at 4:09 AM Sean Anderson <seanga2@gmail.com> wrote:
>
> This function is designed to be used when a timer used to be initialized by
> the cpu (e.g. RISC-V timers), but now is initialized by dm_timer_init. In
> such a case, the timer may prefer to use the clocks and clock-frequency
> properties, but should be able to fall back on using the cpu's
> timebase-frequency.
>
> Signed-off-by: Sean Anderson <seanga2@gmail.com>
> ---
>
> Changes in v4:
> - New
>
>  drivers/timer/timer-uclass.c | 25 +++++++++++++++++++++++++
>  include/timer.h              | 15 +++++++++++++++
>  2 files changed, 40 insertions(+)
>

Reviewed-by: Bin Meng <bin.meng@windriver.com>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v4 3/8] riscv: Rework Andes PLMT as a UCLASS_TIMER driver
  2020-09-09 20:09 ` [PATCH v4 3/8] riscv: Rework Andes PLMT as a UCLASS_TIMER driver Sean Anderson
@ 2020-09-15  7:18   ` Bin Meng
  2020-09-15 10:04     ` Sean Anderson
  0 siblings, 1 reply; 18+ messages in thread
From: Bin Meng @ 2020-09-15  7:18 UTC (permalink / raw)
  To: u-boot

Hi Sean,

On Thu, Sep 10, 2020 at 4:09 AM Sean Anderson <seanga2@gmail.com> wrote:
>
> This converts the PLMT driver from the riscv-specific timer interface to be
> a DM-based UCLASS_TIMER driver.
>
> The clock-frequency/clocks properties are preferred over timebase-frequency
> for two reasons. First, properties which affect a device should be located
> near its binding in the device tree. Using timebase-frequency only really
> makes sense when the cpu itself is the timer device. This is the case when
> we read the time from a CSR, but not when there is a separate device.
> Second, it lets the device use the clock subsystem which adds flexibility.
> If the device is configured for a different clock speed, the timer can
> adjust itself.
>
> Signed-off-by: Sean Anderson <seanga2@gmail.com>
> Reviewed-by: Rick Chen <rick@andestech.com>
> ---
> This patch builds but has NOT been tested.
>
> Changes in v4:
> - Use timer_timebase_fallback
>
>  arch/riscv/Kconfig                   |  4 ---
>  arch/riscv/dts/ae350_32.dts          |  1 +
>  arch/riscv/dts/ae350_64.dts          |  1 +
>  arch/riscv/include/asm/global_data.h |  3 --
>  arch/riscv/lib/andes_plmt.c          | 44 +++++++++++++---------------
>  5 files changed, 23 insertions(+), 30 deletions(-)
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index 21e6690f4d..d9155b9bab 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -177,10 +177,6 @@ config ANDES_PLIC
>  config ANDES_PLMT
>         bool
>         depends on RISCV_MMODE || SPL_RISCV_MMODE
> -       select REGMAP
> -       select SYSCON
> -       select SPL_REGMAP if SPL
> -       select SPL_SYSCON if SPL
>         help
>           The Andes PLMT block holds memory-mapped mtime register
>           associated with timer tick.
> diff --git a/arch/riscv/dts/ae350_32.dts b/arch/riscv/dts/ae350_32.dts
> index 3f8525fe56..afcb9cfbbf 100644
> --- a/arch/riscv/dts/ae350_32.dts
> +++ b/arch/riscv/dts/ae350_32.dts
> @@ -162,6 +162,7 @@
>                                 &CPU2_intc 7
>                                 &CPU3_intc 7>;
>                         reg = <0xe6000000 0x100000>;
> +                       clock-frequency = <60000000>;

Is this change required to make the PLMT timer work?

>                 };
>         };
>
> diff --git a/arch/riscv/dts/ae350_64.dts b/arch/riscv/dts/ae350_64.dts
> index 482c707503..1c37879049 100644
> --- a/arch/riscv/dts/ae350_64.dts
> +++ b/arch/riscv/dts/ae350_64.dts
> @@ -162,6 +162,7 @@
>                                 &CPU2_intc 7
>                                 &CPU3_intc 7>;
>                         reg = <0x0 0xe6000000 0x0 0x100000>;
> +                       clock-frequency = <60000000>;
>                 };
>         };
>
> diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h
> index 2eb14815bc..0dec5e669e 100644
> --- a/arch/riscv/include/asm/global_data.h
> +++ b/arch/riscv/include/asm/global_data.h
> @@ -24,9 +24,6 @@ struct arch_global_data {
>  #ifdef CONFIG_ANDES_PLIC
>         void __iomem *plic;     /* plic base address */
>  #endif
> -#ifdef CONFIG_ANDES_PLMT
> -       void __iomem *plmt;     /* plmt base address */
> -#endif
>  #if CONFIG_IS_ENABLED(SMP)
>         struct ipi_data ipi[CONFIG_NR_CPUS];
>  #endif
> diff --git a/arch/riscv/lib/andes_plmt.c b/arch/riscv/lib/andes_plmt.c
> index a7e90ca992..a28c14c1eb 100644
> --- a/arch/riscv/lib/andes_plmt.c
> +++ b/arch/riscv/lib/andes_plmt.c
> @@ -1,6 +1,7 @@
>  // SPDX-License-Identifier: GPL-2.0+
>  /*
>   * Copyright (C) 2019, Rick Chen <rick@andestech.com>
> + * Copyright (C) 2020, Sean Anderson <seanga2@gmail.com>
>   *
>   * U-Boot syscon driver for Andes's Platform Level Machine Timer (PLMT).
>   * The PLMT block holds memory-mapped mtime register
> @@ -9,46 +10,43 @@
>
>  #include <common.h>
>  #include <dm.h>
> -#include <regmap.h>
> -#include <syscon.h>
> +#include <timer.h>
>  #include <asm/io.h>
> -#include <asm/syscon.h>
>  #include <linux/err.h>
>
>  /* mtime register */
>  #define MTIME_REG(base)                        ((ulong)(base))
>
> -DECLARE_GLOBAL_DATA_PTR;
> -
> -#define PLMT_BASE_GET(void)                                            \
> -       do {                                                            \
> -               long *ret;                                              \
> -                                                                       \
> -               if (!gd->arch.plmt) {                                   \
> -                       ret = syscon_get_first_range(RISCV_SYSCON_PLMT); \
> -                       if (IS_ERR(ret))                                \
> -                               return PTR_ERR(ret);                    \
> -                       gd->arch.plmt = ret;                            \
> -               }                                                       \
> -       } while (0)
> -
> -int riscv_get_time(u64 *time)
> +static int andes_plmt_get_count(struct udevice *dev, u64 *count)
>  {
> -       PLMT_BASE_GET();
> -
> -       *time = readq((void __iomem *)MTIME_REG(gd->arch.plmt));
> +       *count = readq((void __iomem *)MTIME_REG(dev->priv));
>
>         return 0;
>  }
>
> +static const struct timer_ops andes_plmt_ops = {
> +       .get_count = andes_plmt_get_count,
> +};
> +
> +static int andes_plmt_probe(struct udevice *dev)
> +{
> +       dev->priv = dev_read_addr_ptr(dev);
> +       if (!dev->priv)
> +               return -EINVAL;
> +
> +       return timer_timebase_fallback(dev);
> +}
> +
>  static const struct udevice_id andes_plmt_ids[] = {
> -       { .compatible = "riscv,plmt0", .data = RISCV_SYSCON_PLMT },

RISCV_SYSCON_PLMT should be removed from arch/riscv/include/asm/syscon.h

> +       { .compatible = "riscv,plmt0" },
>         { }
>  };
>
>  U_BOOT_DRIVER(andes_plmt) = {
>         .name           = "andes_plmt",
> -       .id             = UCLASS_SYSCON,
> +       .id             = UCLASS_TIMER,
>         .of_match       = andes_plmt_ids,
> +       .ops            = &andes_plmt_ops,
> +       .probe          = andes_plmt_probe,
>         .flags          = DM_FLAG_PRE_RELOC,
>  };
> --

Regards,
Bin

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v4 5/8] riscv: Rework Sifive CLINT as UCLASS_TIMER driver
  2020-09-09 20:09 ` [PATCH v4 5/8] riscv: Rework Sifive CLINT as UCLASS_TIMER driver Sean Anderson
@ 2020-09-15  8:09   ` Bin Meng
  2020-09-15 10:06     ` Sean Anderson
  0 siblings, 1 reply; 18+ messages in thread
From: Bin Meng @ 2020-09-15  8:09 UTC (permalink / raw)
  To: u-boot

Hi Sean,

On Thu, Sep 10, 2020 at 4:09 AM Sean Anderson <seanga2@gmail.com> wrote:
>
> This converts the clint driver from the riscv-specific interface to be a
> DM-based UCLASS_TIMER driver. In addition, the SiFive DDR driver previously
> implicitly depended on the CLINT to select REGMAP.
>
> Unlike Andes's PLMT/PLIC (which AFAIK never have anything pass it a dtb),
> the SiFive CLINT is part of the device tree passed in by qemu. This device
> tree doesn't have a clocks or clock-frequency property on clint, so we need
> to fall back on the timebase-frequency property. Perhaps in the future we
> can get a clock-frequency property added to the qemu dtb.
>
> Unlike with the Andes PLMT, the Sifive CLINT is also an IPI controller.
> RISCV_SYSCON_CLINT is retained for this purpose.
>
> Signed-off-by: Sean Anderson <seanga2@gmail.com>
> Reviewed-by: Pragnesh Patel <pragnesh.patel@openfive.com>
> ---
> This patch builds but has only been tested on the K210 and QEMU. It has NOT
> been tested on a HiFive.
>
> Changes in v4:
> - Use timer_timebase_fallback
>
> Changes in v3:
> - Don't initialize the IPI in spl_invoke_opensbi. Further testing has
>   revealed it to be unnecessary.
>
>  arch/riscv/Kconfig            |  4 ---
>  arch/riscv/lib/sifive_clint.c | 66 +++++++++++++++++++----------------
>  drivers/ram/sifive/Kconfig    |  2 ++
>  3 files changed, 38 insertions(+), 34 deletions(-)
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index d9155b9bab..aaa3b833a5 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -155,10 +155,6 @@ config 64BIT
>  config SIFIVE_CLINT
>         bool
>         depends on RISCV_MMODE || SPL_RISCV_MMODE
> -       select REGMAP
> -       select SYSCON
> -       select SPL_REGMAP if SPL
> -       select SPL_SYSCON if SPL
>         help
>           The SiFive CLINT block holds memory-mapped control and status registers
>           associated with software and timer interrupts.
> diff --git a/arch/riscv/lib/sifive_clint.c b/arch/riscv/lib/sifive_clint.c
> index b9a2c649cc..c9704c596f 100644
> --- a/arch/riscv/lib/sifive_clint.c
> +++ b/arch/riscv/lib/sifive_clint.c
> @@ -8,9 +8,9 @@
>   */
>
>  #include <common.h>
> +#include <clk.h>
>  #include <dm.h>
> -#include <regmap.h>
> -#include <syscon.h>
> +#include <timer.h>
>  #include <asm/io.h>
>  #include <asm/syscon.h>
>  #include <linux/err.h>
> @@ -24,35 +24,19 @@
>
>  DECLARE_GLOBAL_DATA_PTR;
>
> -int riscv_get_time(u64 *time)
> -{
> -       /* ensure timer register base has a sane value */
> -       riscv_init_ipi();
> -
> -       *time = readq((void __iomem *)MTIME_REG(gd->arch.clint));
> -
> -       return 0;
> -}
> -
> -int riscv_set_timecmp(int hart, u64 cmp)
> -{
> -       /* ensure timer register base has a sane value */
> -       riscv_init_ipi();
> -
> -       writeq(cmp, (void __iomem *)MTIMECMP_REG(gd->arch.clint, hart));
> -
> -       return 0;
> -}
> -
>  int riscv_init_ipi(void)
>  {
> -       if (!gd->arch.clint) {
> -               long *ret = syscon_get_first_range(RISCV_SYSCON_CLINT);
> +       int ret;
> +       struct udevice *dev;
>
> -               if (IS_ERR(ret))
> -                       return PTR_ERR(ret);
> -               gd->arch.clint = ret;
> -       }
> +       ret = uclass_get_device_by_driver(UCLASS_TIMER,
> +                                         DM_GET_DRIVER(sifive_clint), &dev);
> +       if (ret)
> +               return ret;
> +
> +       gd->arch.clint = dev_read_addr_ptr(dev);
> +       if (!gd->arch.clint)
> +               return -EINVAL;
>
>         return 0;
>  }
> @@ -78,14 +62,36 @@ int riscv_get_ipi(int hart, int *pending)
>         return 0;
>  }
>
> +static int sifive_clint_get_count(struct udevice *dev, u64 *count)
> +{
> +       *count = readq((void __iomem *)MTIME_REG(dev->priv));
> +
> +       return 0;
> +}
> +
> +static const struct timer_ops sifive_clint_ops = {
> +       .get_count = sifive_clint_get_count,
> +};
> +
> +static int sifive_clint_probe(struct udevice *dev)
> +{
> +       dev->priv = dev_read_addr_ptr(dev);
> +       if (!dev->priv)
> +               return -EINVAL;
> +
> +       return timer_timebase_fallback(dev);
> +}
> +
>  static const struct udevice_id sifive_clint_ids[] = {
> -       { .compatible = "riscv,clint0", .data = RISCV_SYSCON_CLINT },
> +       { .compatible = "riscv,clint0" },
>         { }
>  };
>
>  U_BOOT_DRIVER(sifive_clint) = {
>         .name           = "sifive_clint",
> -       .id             = UCLASS_SYSCON,
> +       .id             = UCLASS_TIMER,
>         .of_match       = sifive_clint_ids,
> +       .probe          = sifive_clint_probe,
> +       .ops            = &sifive_clint_ops,
>         .flags          = DM_FLAG_PRE_RELOC,
>  };
> diff --git a/drivers/ram/sifive/Kconfig b/drivers/ram/sifive/Kconfig
> index 6aca22ab2a..31ad0a7e45 100644
> --- a/drivers/ram/sifive/Kconfig
> +++ b/drivers/ram/sifive/Kconfig
> @@ -9,5 +9,7 @@ config SIFIVE_FU540_DDR
>         bool "SiFive FU540 DDR driver"
>         depends on RAM_SIFIVE
>         default y if TARGET_SIFIVE_FU540
> +       select REGMAP
> +       select SPL_REGMAP if SPL

This should be dropped. Please see the patch below:
http://patchwork.ozlabs.org/project/uboot/patch/1600157107-57175-2-git-send-email-bmeng.cn at gmail.com/

>         help
>           This enables DDR support for the platforms based on SiFive FU540 SoC.
> --

Regards,
Bin

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v4 7/8] riscv: Update Kendryte device tree for new CLINT driver
  2020-09-09 20:09 ` [PATCH v4 7/8] riscv: Update Kendryte device tree for new CLINT driver Sean Anderson
@ 2020-09-15  9:07   ` Bin Meng
  0 siblings, 0 replies; 18+ messages in thread
From: Bin Meng @ 2020-09-15  9:07 UTC (permalink / raw)
  To: u-boot

On Thu, Sep 10, 2020 at 4:09 AM Sean Anderson <seanga2@gmail.com> wrote:
>
> The interrupt controller property is removed from the clint binding because
> the clint is not an interrupt-controller. That is, no other devices have an
> interrupt which is controlled by the clint.
>
> Signed-off-by: Sean Anderson <seanga2@gmail.com>
> ---
>
> Changes in v4:
> - Remove clock-frequency property from k210 clint binding because we fall
>   back on timebase-frequency
>
> Changes in v2:
> - New
>
>  arch/riscv/dts/k210.dtsi | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
>

LGTM
Reviewed-by: Bin Meng <bin.meng@windriver.com>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v4 8/8] riscv: Update SiFive device tree for new CLINT driver
  2020-09-09 20:09 ` [PATCH v4 8/8] riscv: Update SiFive " Sean Anderson
@ 2020-09-15  9:13   ` Bin Meng
  0 siblings, 0 replies; 18+ messages in thread
From: Bin Meng @ 2020-09-15  9:13 UTC (permalink / raw)
  To: u-boot

On Thu, Sep 10, 2020 at 4:09 AM Sean Anderson <seanga2@gmail.com> wrote:
>
> We currently do this in a u-boot specific dts, but hopefully we can get
> these bindings added in Linux in the future.
>
> Signed-off-by: Sean Anderson <seanga2@gmail.com>
> Reviewed-by: Pragnesh Patel <pragnesh.patel@openfive.com>
> ---
> This patch builds but has NOT been tested.
>
> Changes in v4:
> - Both the Andes PMLT and Sifive CLINT now fall back on timebase-frequency,
>   per discussion with Anup Patel
> - Rebase
>
> Changes in v3:
> - Rebase
>
> Changes in v2:
> - Fix SiFive CLINT not getting tick-rate from rtcclk
>
>  arch/riscv/dts/fu540-c000-u-boot.dtsi           | 8 ++++++--
>  arch/riscv/dts/hifive-unleashed-a00-u-boot.dtsi | 4 ++++
>  2 files changed, 10 insertions(+), 2 deletions(-)
>

Reviewed-by: Bin Meng <bin.meng@windriver.com>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v4 3/8] riscv: Rework Andes PLMT as a UCLASS_TIMER driver
  2020-09-15  7:18   ` Bin Meng
@ 2020-09-15 10:04     ` Sean Anderson
  0 siblings, 0 replies; 18+ messages in thread
From: Sean Anderson @ 2020-09-15 10:04 UTC (permalink / raw)
  To: u-boot

On 9/15/20 3:18 AM, Bin Meng wrote:
> Hi Sean,
> 
> On Thu, Sep 10, 2020 at 4:09 AM Sean Anderson <seanga2@gmail.com> wrote:
>>
>> This converts the PLMT driver from the riscv-specific timer interface to be
>> a DM-based UCLASS_TIMER driver.
>>
>> The clock-frequency/clocks properties are preferred over timebase-frequency
>> for two reasons. First, properties which affect a device should be located
>> near its binding in the device tree. Using timebase-frequency only really
>> makes sense when the cpu itself is the timer device. This is the case when
>> we read the time from a CSR, but not when there is a separate device.
>> Second, it lets the device use the clock subsystem which adds flexibility.
>> If the device is configured for a different clock speed, the timer can
>> adjust itself.
>>
>> Signed-off-by: Sean Anderson <seanga2@gmail.com>
>> Reviewed-by: Rick Chen <rick@andestech.com>
>> ---
>> This patch builds but has NOT been tested.
>>
>> Changes in v4:
>> - Use timer_timebase_fallback
>>
>>  arch/riscv/Kconfig                   |  4 ---
>>  arch/riscv/dts/ae350_32.dts          |  1 +
>>  arch/riscv/dts/ae350_64.dts          |  1 +
>>  arch/riscv/include/asm/global_data.h |  3 --
>>  arch/riscv/lib/andes_plmt.c          | 44 +++++++++++++---------------
>>  5 files changed, 23 insertions(+), 30 deletions(-)
>>
>> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
>> index 21e6690f4d..d9155b9bab 100644
>> --- a/arch/riscv/Kconfig
>> +++ b/arch/riscv/Kconfig
>> @@ -177,10 +177,6 @@ config ANDES_PLIC
>>  config ANDES_PLMT
>>         bool
>>         depends on RISCV_MMODE || SPL_RISCV_MMODE
>> -       select REGMAP
>> -       select SYSCON
>> -       select SPL_REGMAP if SPL
>> -       select SPL_SYSCON if SPL
>>         help
>>           The Andes PLMT block holds memory-mapped mtime register
>>           associated with timer tick.
>> diff --git a/arch/riscv/dts/ae350_32.dts b/arch/riscv/dts/ae350_32.dts
>> index 3f8525fe56..afcb9cfbbf 100644
>> --- a/arch/riscv/dts/ae350_32.dts
>> +++ b/arch/riscv/dts/ae350_32.dts
>> @@ -162,6 +162,7 @@
>>                                 &CPU2_intc 7
>>                                 &CPU3_intc 7>;
>>                         reg = <0xe6000000 0x100000>;
>> +                       clock-frequency = <60000000>;
> 
> Is this change required to make the PLMT timer work?

With the addition of timer_timebase_fallback it is not.

>>                 };
>>         };
>>
>> diff --git a/arch/riscv/dts/ae350_64.dts b/arch/riscv/dts/ae350_64.dts
>> index 482c707503..1c37879049 100644
>> --- a/arch/riscv/dts/ae350_64.dts
>> +++ b/arch/riscv/dts/ae350_64.dts
>> @@ -162,6 +162,7 @@
>>                                 &CPU2_intc 7
>>                                 &CPU3_intc 7>;
>>                         reg = <0x0 0xe6000000 0x0 0x100000>;
>> +                       clock-frequency = <60000000>;
>>                 };
>>         };
>>
>> diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h
>> index 2eb14815bc..0dec5e669e 100644
>> --- a/arch/riscv/include/asm/global_data.h
>> +++ b/arch/riscv/include/asm/global_data.h
>> @@ -24,9 +24,6 @@ struct arch_global_data {
>>  #ifdef CONFIG_ANDES_PLIC
>>         void __iomem *plic;     /* plic base address */
>>  #endif
>> -#ifdef CONFIG_ANDES_PLMT
>> -       void __iomem *plmt;     /* plmt base address */
>> -#endif
>>  #if CONFIG_IS_ENABLED(SMP)
>>         struct ipi_data ipi[CONFIG_NR_CPUS];
>>  #endif
>> diff --git a/arch/riscv/lib/andes_plmt.c b/arch/riscv/lib/andes_plmt.c
>> index a7e90ca992..a28c14c1eb 100644
>> --- a/arch/riscv/lib/andes_plmt.c
>> +++ b/arch/riscv/lib/andes_plmt.c
>> @@ -1,6 +1,7 @@
>>  // SPDX-License-Identifier: GPL-2.0+
>>  /*
>>   * Copyright (C) 2019, Rick Chen <rick@andestech.com>
>> + * Copyright (C) 2020, Sean Anderson <seanga2@gmail.com>
>>   *
>>   * U-Boot syscon driver for Andes's Platform Level Machine Timer (PLMT).
>>   * The PLMT block holds memory-mapped mtime register
>> @@ -9,46 +10,43 @@
>>
>>  #include <common.h>
>>  #include <dm.h>
>> -#include <regmap.h>
>> -#include <syscon.h>
>> +#include <timer.h>
>>  #include <asm/io.h>
>> -#include <asm/syscon.h>
>>  #include <linux/err.h>
>>
>>  /* mtime register */
>>  #define MTIME_REG(base)                        ((ulong)(base))
>>
>> -DECLARE_GLOBAL_DATA_PTR;
>> -
>> -#define PLMT_BASE_GET(void)                                            \
>> -       do {                                                            \
>> -               long *ret;                                              \
>> -                                                                       \
>> -               if (!gd->arch.plmt) {                                   \
>> -                       ret = syscon_get_first_range(RISCV_SYSCON_PLMT); \
>> -                       if (IS_ERR(ret))                                \
>> -                               return PTR_ERR(ret);                    \
>> -                       gd->arch.plmt = ret;                            \
>> -               }                                                       \
>> -       } while (0)
>> -
>> -int riscv_get_time(u64 *time)
>> +static int andes_plmt_get_count(struct udevice *dev, u64 *count)
>>  {
>> -       PLMT_BASE_GET();
>> -
>> -       *time = readq((void __iomem *)MTIME_REG(gd->arch.plmt));
>> +       *count = readq((void __iomem *)MTIME_REG(dev->priv));
>>
>>         return 0;
>>  }
>>
>> +static const struct timer_ops andes_plmt_ops = {
>> +       .get_count = andes_plmt_get_count,
>> +};
>> +
>> +static int andes_plmt_probe(struct udevice *dev)
>> +{
>> +       dev->priv = dev_read_addr_ptr(dev);
>> +       if (!dev->priv)
>> +               return -EINVAL;
>> +
>> +       return timer_timebase_fallback(dev);
>> +}
>> +
>>  static const struct udevice_id andes_plmt_ids[] = {
>> -       { .compatible = "riscv,plmt0", .data = RISCV_SYSCON_PLMT },
> 
> RISCV_SYSCON_PLMT should be removed from arch/riscv/include/asm/syscon.h
> 
>> +       { .compatible = "riscv,plmt0" },
>>         { }
>>  };
>>
>>  U_BOOT_DRIVER(andes_plmt) = {
>>         .name           = "andes_plmt",
>> -       .id             = UCLASS_SYSCON,
>> +       .id             = UCLASS_TIMER,
>>         .of_match       = andes_plmt_ids,
>> +       .ops            = &andes_plmt_ops,
>> +       .probe          = andes_plmt_probe,
>>         .flags          = DM_FLAG_PRE_RELOC,
>>  };
>> --
> 
> Regards,
> Bin
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v4 5/8] riscv: Rework Sifive CLINT as UCLASS_TIMER driver
  2020-09-15  8:09   ` Bin Meng
@ 2020-09-15 10:06     ` Sean Anderson
  0 siblings, 0 replies; 18+ messages in thread
From: Sean Anderson @ 2020-09-15 10:06 UTC (permalink / raw)
  To: u-boot

On 9/15/20 4:09 AM, Bin Meng wrote:
> Hi Sean,
> 
> On Thu, Sep 10, 2020 at 4:09 AM Sean Anderson <seanga2@gmail.com> wrote:
>>
>> This converts the clint driver from the riscv-specific interface to be a
>> DM-based UCLASS_TIMER driver. In addition, the SiFive DDR driver previously
>> implicitly depended on the CLINT to select REGMAP.
>>
>> Unlike Andes's PLMT/PLIC (which AFAIK never have anything pass it a dtb),
>> the SiFive CLINT is part of the device tree passed in by qemu. This device
>> tree doesn't have a clocks or clock-frequency property on clint, so we need
>> to fall back on the timebase-frequency property. Perhaps in the future we
>> can get a clock-frequency property added to the qemu dtb.
>>
>> Unlike with the Andes PLMT, the Sifive CLINT is also an IPI controller.
>> RISCV_SYSCON_CLINT is retained for this purpose.
>>
>> Signed-off-by: Sean Anderson <seanga2@gmail.com>
>> Reviewed-by: Pragnesh Patel <pragnesh.patel@openfive.com>
>> ---
>> This patch builds but has only been tested on the K210 and QEMU. It has NOT
>> been tested on a HiFive.
>>
>> Changes in v4:
>> - Use timer_timebase_fallback
>>
>> Changes in v3:
>> - Don't initialize the IPI in spl_invoke_opensbi. Further testing has
>>   revealed it to be unnecessary.
>>
>>  arch/riscv/Kconfig            |  4 ---
>>  arch/riscv/lib/sifive_clint.c | 66 +++++++++++++++++++----------------
>>  drivers/ram/sifive/Kconfig    |  2 ++
>>  3 files changed, 38 insertions(+), 34 deletions(-)
>>
>> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
>> index d9155b9bab..aaa3b833a5 100644
>> --- a/arch/riscv/Kconfig
>> +++ b/arch/riscv/Kconfig
>> @@ -155,10 +155,6 @@ config 64BIT
>>  config SIFIVE_CLINT
>>         bool
>>         depends on RISCV_MMODE || SPL_RISCV_MMODE
>> -       select REGMAP
>> -       select SYSCON
>> -       select SPL_REGMAP if SPL
>> -       select SPL_SYSCON if SPL
>>         help
>>           The SiFive CLINT block holds memory-mapped control and status registers
>>           associated with software and timer interrupts.
>> diff --git a/arch/riscv/lib/sifive_clint.c b/arch/riscv/lib/sifive_clint.c
>> index b9a2c649cc..c9704c596f 100644
>> --- a/arch/riscv/lib/sifive_clint.c
>> +++ b/arch/riscv/lib/sifive_clint.c
>> @@ -8,9 +8,9 @@
>>   */
>>
>>  #include <common.h>
>> +#include <clk.h>
>>  #include <dm.h>
>> -#include <regmap.h>
>> -#include <syscon.h>
>> +#include <timer.h>
>>  #include <asm/io.h>
>>  #include <asm/syscon.h>
>>  #include <linux/err.h>
>> @@ -24,35 +24,19 @@
>>
>>  DECLARE_GLOBAL_DATA_PTR;
>>
>> -int riscv_get_time(u64 *time)
>> -{
>> -       /* ensure timer register base has a sane value */
>> -       riscv_init_ipi();
>> -
>> -       *time = readq((void __iomem *)MTIME_REG(gd->arch.clint));
>> -
>> -       return 0;
>> -}
>> -
>> -int riscv_set_timecmp(int hart, u64 cmp)
>> -{
>> -       /* ensure timer register base has a sane value */
>> -       riscv_init_ipi();
>> -
>> -       writeq(cmp, (void __iomem *)MTIMECMP_REG(gd->arch.clint, hart));
>> -
>> -       return 0;
>> -}
>> -
>>  int riscv_init_ipi(void)
>>  {
>> -       if (!gd->arch.clint) {
>> -               long *ret = syscon_get_first_range(RISCV_SYSCON_CLINT);
>> +       int ret;
>> +       struct udevice *dev;
>>
>> -               if (IS_ERR(ret))
>> -                       return PTR_ERR(ret);
>> -               gd->arch.clint = ret;
>> -       }
>> +       ret = uclass_get_device_by_driver(UCLASS_TIMER,
>> +                                         DM_GET_DRIVER(sifive_clint), &dev);
>> +       if (ret)
>> +               return ret;
>> +
>> +       gd->arch.clint = dev_read_addr_ptr(dev);
>> +       if (!gd->arch.clint)
>> +               return -EINVAL;
>>
>>         return 0;
>>  }
>> @@ -78,14 +62,36 @@ int riscv_get_ipi(int hart, int *pending)
>>         return 0;
>>  }
>>
>> +static int sifive_clint_get_count(struct udevice *dev, u64 *count)
>> +{
>> +       *count = readq((void __iomem *)MTIME_REG(dev->priv));
>> +
>> +       return 0;
>> +}
>> +
>> +static const struct timer_ops sifive_clint_ops = {
>> +       .get_count = sifive_clint_get_count,
>> +};
>> +
>> +static int sifive_clint_probe(struct udevice *dev)
>> +{
>> +       dev->priv = dev_read_addr_ptr(dev);
>> +       if (!dev->priv)
>> +               return -EINVAL;
>> +
>> +       return timer_timebase_fallback(dev);
>> +}
>> +
>>  static const struct udevice_id sifive_clint_ids[] = {
>> -       { .compatible = "riscv,clint0", .data = RISCV_SYSCON_CLINT },
>> +       { .compatible = "riscv,clint0" },
>>         { }
>>  };
>>
>>  U_BOOT_DRIVER(sifive_clint) = {
>>         .name           = "sifive_clint",
>> -       .id             = UCLASS_SYSCON,
>> +       .id             = UCLASS_TIMER,
>>         .of_match       = sifive_clint_ids,
>> +       .probe          = sifive_clint_probe,
>> +       .ops            = &sifive_clint_ops,
>>         .flags          = DM_FLAG_PRE_RELOC,
>>  };
>> diff --git a/drivers/ram/sifive/Kconfig b/drivers/ram/sifive/Kconfig
>> index 6aca22ab2a..31ad0a7e45 100644
>> --- a/drivers/ram/sifive/Kconfig
>> +++ b/drivers/ram/sifive/Kconfig
>> @@ -9,5 +9,7 @@ config SIFIVE_FU540_DDR
>>         bool "SiFive FU540 DDR driver"
>>         depends on RAM_SIFIVE
>>         default y if TARGET_SIFIVE_FU540
>> +       select REGMAP
>> +       select SPL_REGMAP if SPL
> 
> This should be dropped. Please see the patch below:
> http://patchwork.ozlabs.org/project/uboot/patch/1600157107-57175-2-git-send-email-bmeng.cn at gmail.com/

Ok, I can drop this and add a dependency.

>>         help
>>           This enables DDR support for the platforms based on SiFive FU540 SoC.
>> --
> 
> Regards,
> Bin
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2020-09-15 10:06 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-09 20:09 [PATCH v4 0/8] riscv: Clean up timer drivers Sean Anderson
2020-09-09 20:09 ` [PATCH v4 1/8] riscv: Rework riscv timer driver to only support S-mode Sean Anderson
2020-09-09 20:09 ` [PATCH v4 2/8] timer: Add helper for drivers using timebase fallback Sean Anderson
2020-09-10 13:38   ` Simon Glass
2020-09-10 15:13     ` Sean Anderson
2020-09-15  7:13   ` Bin Meng
2020-09-09 20:09 ` [PATCH v4 3/8] riscv: Rework Andes PLMT as a UCLASS_TIMER driver Sean Anderson
2020-09-15  7:18   ` Bin Meng
2020-09-15 10:04     ` Sean Anderson
2020-09-09 20:09 ` [PATCH v4 4/8] riscv: Clean up initialization in Andes PLIC Sean Anderson
2020-09-09 20:09 ` [PATCH v4 5/8] riscv: Rework Sifive CLINT as UCLASS_TIMER driver Sean Anderson
2020-09-15  8:09   ` Bin Meng
2020-09-15 10:06     ` Sean Anderson
2020-09-09 20:09 ` [PATCH v4 6/8] riscv: clk: Add CLINT clock to kendryte clock driver Sean Anderson
2020-09-09 20:09 ` [PATCH v4 7/8] riscv: Update Kendryte device tree for new CLINT driver Sean Anderson
2020-09-15  9:07   ` Bin Meng
2020-09-09 20:09 ` [PATCH v4 8/8] riscv: Update SiFive " Sean Anderson
2020-09-15  9:13   ` Bin Meng

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.